# Grid-Based 2D Lighting Problems

I am aware this question has been asked before, but unfortunately I am new to the language, so the complicated explanations I've found do not help me in the least.

I need a lighting engine for my game, and I've tried some procedural lighting systems. This method works the best:

if (light[xx - 1, yy] > light[xx, yy]) light[xx, yy] = light[xx - 1, yy] - lightPass;
if (light[xx, yy - 1] > light[xx, yy]) light[xx, yy] = light[xx, yy - 1] - lightPass;
if (light[xx + 1, yy] > light[xx, yy]) light[xx, yy] = light[xx + 1, yy] - lightPass;
if (light[xx, yy + 1] > light[xx, yy]) light[xx, yy] = light[xx, yy + 1] - lightPass;


(Subtracts adjacent values by 'lightPass' variable if they are more bright) (It's in a for() loop)

This is all fine and dandy except for:

The system favors whatever comes first in the for() loop

This is what the above code looks like applied to my game:

On the left side you can see some weirdness going on:

The loop goes top to down then to the right column:

This is how the for() loop goes:

Light provided from my mouse, should be a full light, but is only half:

If I could get some help on creating a new procedural or otherwise lighting system I would really appreciate it!

A recursive algorithm is a typical way to approach this. The algorithm "flows" outward until there's no more light to spread. Remember to put in a base case for your algorithm, or you'll never stop lighting. For example, if the next tile being selected is as bright or brighter than the current tile. Since you're likely to have large grids, you'll probably want to implement a list for your recursion instead of using the stack (it'll probably overflow). An example of this might be:

(note this is using the stack based approach, only recommended for shallow recursion, there's an example that's similar to the list approach below)

Light(x, y, value)
(x,y).lightvalue = value
if(value-1 > 0)
if((x-1, y).lightvalue < value-1)
Light(x-1,y,value-1)
if((x+1, y).lightvalue < value-1)
Light(x+1,y,value-1)
if((x, y-1).lightvalue < value-1)
Light(x,y-1,value-1)
if((x, y+1).lightvalue < value-1)
Light(x,y+1,value-1)


Clearly your case would be a lot more complex, since you want to account for sky light shining down, you'll have to keep track of if the tile has sky directly above it.

Another option is some kind of cellular automata. So each tile knows its state and can tell neighboring tiles they should update their state. Something like:

foreach(tile in tilesToUpdate)
if(tileToLeft.lightValue > thisLightValue + 1)
this.lightValue = tileToLeft.lightValue - 1
else if(tileToLeft.lightValue < thisLightValue)