I'm implementing fog of war into my tile based game. It's chunky, meaning that a tile either has the fog, or does not have the fog. Every frame I set all tiles to "not visible". Then, I loop through all the entities, lighting up circles of tiles around them. For the circle, I use this algorithm:

I know it look shady, but it produces really good looking circles for its low complexity. I fear this method of having, and maintaining fog of war is not the best. Here's an overview of the task, each frame:

Loop through entire map, setting "not visible" on each tile.

Loop through all Actors, light up circle (r=3) around the Actor

The "lighting up" procedure loops through 6*6 tiles, for a radius 3 circle.

I would very much like some input as to how this can be improved! I ruled out only updating the changing parts (as opposed to recalculating every point every frame), because a lot of the vision from actors close to eachother overlap. Because of this, I can not simply "turn off" the circle of vision around an actor.

1: Is your light changing every frame? If not you could save some time by only calculating it when it changes.2: Do you have a performance problem with the way you're doing it? Seriously I would like to know

Alright, only frames that has updates to the fog of war will recalculate it. If this calculation proves costly, this will result in lag-spikes every time the fog of war updates.Currently, I have no problems. However, I have not tried a real scenario with many units moving on a large map. This means I actually don't know how well this scales. It does not seem like it would, though.

you could only update the fog of war in locations where an actor moves, instead of checking every actor within view every time it updates, you could have only the tiles around the actor to update.

I don't see how this would work, seeing as the circle of vision might overlap with other nearby actors. I cannot simply fill the circle around a dead Actor with fog, because some other entity might have shared some of that vision. I hope this makes sense.

That's nothing. You're prematurely optimizing. Test it, time it and if it's slow fix it. The only thing you should optimize right now is possibly pooling your GridPoint2 instances so you don't generate as much garbage.

That's nothing. You're prematurely optimizing. Test it, time it and if it's slow fix it. The only thing you should optimize right now is possibly pooling your GridPoint2 instances so you don't generate as much garbage.

The pooling is easily fixable. Thanks for the suggestion, by the way.

I know I should not prematurely optimize, although I would like a solution that scales a little bit better than this does. I know my game is not going to be able to run the levels I would like it to, if I do not fix this.

I imagine the final product to have levels the size of 512^2, or even 1024^2. I seriously doubt a 256^2-size world would be any fun to explore. This is a building game, akin to Warcraft I. That's a lot of tiles. In this world there would be actors running around. Not one or two, but 50 or 80. Each with a lighting distance of 3, that is (80 * (3*2)^2) 2880 tiles to light up. The player would then have made around 10 buildings, each taking up 4 * 6 tiles. Each of the tiles also light up the world around them, in a circle with a radius of 3. That is another 240 checks through the getCirclePoints code, checking another 8640 tiles. I don't have time for 11520 checks, even if I limit it to once every movement cycle. This means the game is just not feasible.

Even if this is not possible, I want to get as close as I can. How can this be faster?

A little late for my input, but maybe it still matters. As @Hermasetas said: you usually don't need to calculate the FOW every frame. What I did was I set up a Timer that runs every 500 ms to recalculate the fog.

You could just recalculate the fog every 100 frames or so, but the big advantage of doing it in a timer thread is a second thread taking care of these calculations. So you can use multi threading, that means with today's hardware (almost everybody has more than one core) you can transfer cpu load away from your main thread.

Be warned though, that it will get more complicated. You have to take care of concurrent updates to maps and lists (and maybe also other data structures) you need in your fog calculations. That means you have to implement a locking mechanism.

The whole multi threading topic is quite complex, but concerning performance optimisations it is worth learning.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org