ID:154455
 
This is sort of a theory paper on what I'm working on. Not a lot of actual code here, but if you can follow what I'm talking about, you too can create an advanced lighting/dithering system for your game.

I was going to keep this a secret until I could show it in action, but I thought I'd give people an idea of what I'm making. Feel free to try this yourself, if you want to beat me to the punch. Just don't ask me for any actual code... I won't share that part.

Imagine a torch object with a luminosity of 5. In a dark area, it will cause all objects within 5 squares to be visible. Now imagine laying black dithered mobs over top of items in those squares. The further away the square, the denser the black dither. The end effect is that items within 5 squares of the torch will be visible, but increasingly blackened out as distance increases. When we reach total blackness, we also reach the luminosity range of the torch.

The dithered mobs I call light_cells. Here we assign an icon containing a number of dithered icon states, representing for example, 0%, 25%, 50%, 75%, 100% darkness. If we create a proc owned by that mob to calculate its own light intensity, all we need to do is get the intensity of the owning light source and calculate this mob's distance to it.

We can set an arbitrary range to represent the distance at which light fades to black (let's call it black_dist), set a scale from the light source's intensity (source_str) to zero, then calculate the intensity by using something like the below formula:

source_str - (get_dist(src, my_light_source)/black_dist)

Then, rounding to the nearest .25, we have the dither pattern needed.

Actually, I prefer this following proc to get_dist():

proc/get_real_dist(from_x, from_y, to_x, to_y) var x_delta = abs(from_x - to_x) y_delta = abs(from_y - to_y) return sqrt(x_delta**2 + y_delta**2)

This returns the real distance between two points on the map, using good old Pythagoras's theorum. This will make more of a visual difference as black_dist is increased, and as you increase the number of dither patterns between 0%-100%.

There are just a couple more problems to solve. First is the hitting of an edge of a map, and keeping the light_cell from attempting to draw outside of your world. It's a fairly simple matter to check for proximity, and keep this from happening.

The second is what happens when the sphere of light produced by two or more of these sources overlaps. This is a bit trickier to fix, but I do have a solution. It involves calculating the combined light total, picking the appropriate dither pattern, assinging that pattern to only one of the light_cells, and hiding all other light_cells on the same square of the map.

At the moment, I have the whole system on paper, but I've yet to program it, since whenever I open BYOND, I feel obligated to work on MLAAS. However, my next game will be using this system extensively, so expect to see a little test project soon.

I welcome any ideas or comments on these ideas. I would be willing to post the whole thing as a library when it's perfected, but will not do so until my next game is well underway. If I make the library, I want to have the first game out that actually uses it. :-)

/mob/skysaw

Oddly enough, I just started (and am now just about finished with) a game that uses this sort of system extensively. Mine's pretty inefficient, as indeed a lot of dithered lighting systems are liable to be, but it doesn't matter so much in a small game with few, finite light sources.

Thanks for writing up this post, however--now if people bug me about how my dithered lighting works, I have somewhere to point them to.
A long time ago, I was going to make a library for fading to black, uh, that would use overlays or image somehow to make the light pass more smoothly into shadow, so everything wouldn't be all blocky like it is now. There'd be light on one side and black on the other and 1 tile of gradient between.

What's dithering?

Z
In response to Zilal
What's dithering?

There's a perfect smartass response to this floating just below the surface of my consciousness. I am going to be awake all night trying to figure out what it is. Thanks a lot.
In response to Zilal
Zilal wrote:
What's dithering?

I have a little tutorial on dithers: Shadowdarke.DitheredTransparencies
It's worth downloading for the cute little mouse pic if nothing else. ;)

Basically, a dither is using dot patterns to produce a gradient.
In response to Shadowdarke
Shadowdarke wrote:
Basically, a dither is using dot patterns to produce a gradient.

Oh! That's what I would have done. Well, dither me timbers.

I have a complaint about the tutorial library. A lot of them don't adequately explain what they do (i.e. what dithering is) and you don't want to download one just to find out it's nothing you're interested in.

Z
In response to Zilal
Zilal wrote:
I have a complaint about the tutorial library. A lot of them don't adequately explain what they do (i.e. what dithering is) and you don't want to download one just to find out it's nothing you're interested in.

I wasn't real pleased with how it turned out either. How should I say it in a way that people who haven't a clue about it would know they if need it?
I welcome any ideas or comments on these ideas. I would be willing to post the whole thing as a library when it's perfected, but will not do so until my next game is well underway. If I make the library, I want to have the first game out that actually uses it. :-)

I had something like this in my plans millenia ago, but lacked the gumption to go ahead and do it.