7
\$\begingroup\$

How is fog of war implemented in RTS games such as StarCraft II or Age of Empires? I'm making an RTS, and plan for every unit on the field to have circular vision up to a certain radius.

My first thought was having a mask that is black for every point except for points close to units, where it is transparent. The masking operation itself is fast in most graphics APIs (e.g. just call mix in a shader). The hard part is figuring out what mask to use and how to update it: updating it when any unit moves is very processor-heavy.

Is there any simpler way to manage this type of fog of war?

\$\endgroup\$
5
\$\begingroup\$

If your game has cell based occupancy, you can reduce the fog of war calculations by restricting up dates to the moments when a unit crosses the threshold from one cell to the next.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Yeah, just thought about this. I can have square cells in my game field, say 128x128 or something like that. I could have 3 cell states, fully seen, not seen, and partially seen. That could work out. \$\endgroup\$ – ChemiCalChems Dec 6 '16 at 21:35
9
\$\begingroup\$

Following answer is based on own RTS experience, which visually aligns with Age Of Empires and other RTS games

Nowadays there is not one, but 2 Fog Of Wars (FOW)

Static FOW is simpler (once revealed, remains open):

First FOW is calculated on CPU and is used for games logic to test what units "see" in the game and can/cannot do. For an RTS it must be 100% identical between all players machines and graphics settings and be 100% repeatable, assuming that RTS traditionally use lock-step multiplayer. Given that, to avoid extra CPU load, it has to be more granular - e.g. 1 sample per tile per 5 game logic's ticks (or you can optimize by updating units sight only when they arrive at new tile).

Second FOW is rendered on GPU and is more dynamic / detailed. This FOW is what player sees. GPU can render/update it every frame at much higher resolution that CPU could handle (e.g. 4096*4096 pixels), to produce smooth sight circles. The FOW being much more accurate, can mismatch game logics FOW slightly, which is okay, since typical mismatches happen on FOW edge where exact judgement is vague.

Why not use GPU FOW for both logic and visuals? It takes a lot of time to stream texture data from GPU back to CPU. GPU rendering can not be trusted, it can greatly differ between players configurations / drivers / settings.

For static FOW you can get away with a sort of "additive" updates - each time for each FOW sample - pick the brightest and keep it.


Making FOW dynamic is another complex problem. In simplest, dynamic FOW can take 5 states: fully covered, semi-explored, explored, semi-revealed, fully revealed. You can map these states to be 0, 1-49, 50, 51-99, 100-255. Now when unit reveals fog, it reveals it to 255. Each tick you dim "semi-revealed" and "fully revealed" FOW by e.g. 10. This means that when unit leaves, FOW remains "fully revealed" for 15 ticks before starting to fade to semi-revealed and then another 5 ticks before stopping at "explored".

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ How to get the information about positions and radius that should be masked or not? Where to store the values for how many ticks this area still should be visible? If those parts aren't done efficiently as asked in the question - then there is no reason to call it an efficient solution. If you can explain how to do this you will be the best! It's too bad that OP closed this question as answered. Because he didn't get a real idea of a solution of a fog of war implementation. The answer gives good practices, but there is still so much to it. \$\endgroup\$ – Candid Moon _Max_ Oct 11 '17 at 16:30
  • \$\begingroup\$ For example, would you go over every unit O(n) or every tile O(n^2)? Or maybe add every unit that changed his tile to Heap and do it with O(2log(n)) (Addition + Removal). \$\endgroup\$ – Candid Moon _Max_ Oct 11 '17 at 16:31
  • \$\begingroup\$ You can also add a Fibonacci Heap, that would make it O(log(n)). \$\endgroup\$ – Candid Moon _Max_ Oct 11 '17 at 16:38
-2
\$\begingroup\$

Unity allows you to add a "cookie" to a light source, which will mask the light based on an image texture - which you can update by using a RenderTexture for that texture and then updating that with your fog of war.

I would suggest keeping and updating the raw fog of war data in main memory, and then, once per frame, flushing whatever you need for your fog of war mask over to the RenderTexture.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This doesn't answer the question. \$\endgroup\$ – Sean Middleditch Dec 6 '16 at 22:03
  • 2
    \$\begingroup\$ I think you were downvoted because it answers the question in a specific context: unity, in a generic question \$\endgroup\$ – MVCDS Dec 7 '16 at 20:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.