Fog of War: The Art of Hiding the Map
Fog of war is a system for rationing knowledge, and every part of it, from the visibility grid to the shader to the server, exists to decide who is allowed to know what, and when.

There is a peculiar kind of dread that belongs only to strategy games, and it lives at the edge of the map. Beyond the last scout, beyond the small circle of ground your soldiers can actually see, the world dissolves into grey or into a black that seems to have weight. Something may be moving out there. Nothing may be. The player cannot tell, and that inability, carefully engineered, is one of the oldest and most effective devices the genre possesses.
We call the device fog of war, and the name is borrowed from military theory. It is usually attributed to Carl von Clausewitz, the Prussian general whose treatise On War described how a great part of the information on which a commander acts lies hidden, as if in a fog, or distorted by uncertainty. The famous three word phrase is not literally his; it was coined later by writers summarizing him. But the idea is his, and it translates into software with surprising fidelity.
What follows is an account of how that translation is done: the states a patch of ground can occupy, the grids and algorithms that decide what a unit sees, the textures and shaders that paint the darkness, and the uncomfortable truth that in a multiplayer game the fog drawn on the screen is worthless unless the machine underneath it also refuses to know too much.
Three states of knowing
Most fog of war systems distinguish three conditions for any piece of the map, and the distinction is more subtle than it first appears. A region may be unexplored, meaning the player has never had eyes on it; it is drawn as solid black and reveals nothing, not even the shape of the terrain. It may be visible, meaning some friendly unit or building can see it right now, so everything there, enemies included, is shown live and in full color.
Between these lies the third state, the one that gives the system its psychological depth: explored but not currently visible. The player has seen this ground before, so the terrain, the rivers and perhaps the buildings that stood there are remembered and drawn, usually dimmed or desaturated. Moving units, however, are hidden, because no one is watching them. The map shows the player not the world as it is, but the world as it was the last time someone looked.
That last point has a consequence designers sometimes forget. A remembered structure should be drawn as it was last seen, even if it has since been destroyed or replaced, which means the game must store a snapshot of what the player believes rather than simply querying the true state. A barracks that burned while no one watched should keep standing on the player's map, intact and quietly false, until a scout returns and the truth arrives.
The three states are therefore really two separate pieces of data. One is a permanent record of exploration that only ever grows, a set of cells that have been seen at least once. The other is a transient record of present visibility, rebuilt continuously as units move. Keeping them apart in code, rather than packing them into a single tangled flag, makes almost every later problem, from saving games to rendering, considerably simpler to reason about.
Grids and lines of sight
Computing visibility directly against every polygon in a detailed world would be ruinously expensive, so nearly every implementation works on a coarse visibility grid laid over the terrain. A map of five hundred by five hundred meters divided into two meter cells gives a grid of two hundred fifty by two hundred fifty, or 62,500 cells, which fits comfortably in a byte array. Each frame, or every few frames, the system clears the visible layer and asks each viewer to mark the cells it can see.
The simplest viewer marks every cell within a radius, a filled circle stamped onto the grid. That is cheap and often sufficient for an overhead game on flat ground. As soon as walls, forests or hills are meant to block sight, however, the circle is not enough, and the system needs a genuine line of sight test: can a straight line from the viewer reach this cell without passing through anything opaque? Tracing such a line cell by cell, with Bresenham's line algorithm, is the classic approach.
Tracing a separate ray to every cell in the radius wastes work, because neighboring rays cross the same cells again and again. Recursive shadowcasting, popular in roguelike development, solves this elegantly by sweeping outward in eight octants and tracking the angular shadows that blocking cells throw behind them, visiting each cell only once. In a Unity project with real colliders one may instead fire a ring of rays with Physics.Raycast against an obstacle layer and fill the resulting polygon, trading grid purity for geometric accuracy.
Painting the dark
Once the grid knows what is seen, the result must be drawn, and the most common technique is to copy the grid into a small texture. Each cell becomes a texel; perhaps the red channel holds present visibility and the green channel holds the exploration record. The texture is uploaded with Texture2D.SetPixelData and Apply, or written on the GPU by a compute shader, and the terrain and unit shaders sample it using world position remapped into texture coordinates.
A raw grid texture looks like a chessboard of hard squares, which is where bilinear filtering earns its keep. Sampling the mask with filtering enabled blends neighboring texels, so a crisp cell boundary becomes a soft gradient. Many games go further and blur the mask with a separable Gaussian pass, or lerp the texture toward its new state over a fraction of a second, so that darkness retreats from an advancing scout like mist burning off rather than snapping away in blocks.
The final color is then a simple matter of arithmetic in the fragment shader. Where the visible channel is high, the scene is drawn untouched; where only the explored channel is high, the color is multiplied down and perhaps pushed toward grey; where both are zero, the pixel becomes black. Units are usually handled separately, with their renderers disabled on the CPU when their cell is not visible, since a half faded enemy soldier would leak exactly the information the fog exists to hide.
Some games render the fog as a separate layer instead, a plane of volumetric cloud or painted parchment hovering above the map and cut away by the same mask. The choice is largely aesthetic. A grim medieval game might prefer a heavy, smoky darkness that seems to press against the light of a few torches, as Crown & Ashes does around its settlement at night, while a cleaner tactics game may want a flat tint that never obscures the readability of the board.
Information as a resource
It is tempting to think of the fog as a visual effect, but its real function is economic. Fog of war turns information into a resource that must be spent for, exactly like wood or gold. A scout unit costs production and attention; a watchtower costs materials and a position that could have held something else. The player who invests in sight gains the right to act on knowledge, while the player who does not must act on guesses, and the gap between them is where strategy lives.
This changes the meaning of nearly every other mechanic. Without fog, an army's composition is public, so counters are trivial and surprise is impossible. With fog, a player can feint, hide a second base, or march the main force along a valley the opponent has not watched. Deception, scouting and the deliberate denial of enemy scouts all exist only because vision is scarce, and they are among the most interesting decisions a strategy game can offer.
Designers tune this economy through a handful of levers: the sight radius of each unit type, the persistence of revealed ground, whether high ground grants vision over low ground but not the reverse, and whether some abilities reveal an area briefly. Each lever adjusts the price of knowledge. A long sight radius makes information cheap and the game more predictable; a short one makes it dear, and every scout that dies at the edge of the dark becomes a small tragedy with real consequences.
The problem of the honest client
In a single player game the fog need only be convincing, since the only person it deceives is the one who chose to be deceived. Multiplayer is a harsher world. If the client machine holds the full position of every enemy unit and merely declines to draw the ones under fog, then the information is sitting in memory, and a determined cheater can read it. A program that does so and reveals the hidden map is called a map hack, and it has plagued competitive strategy games for decades.
The vulnerability is built into a common networking model. Many classic real time strategy games use deterministic lockstep, in which every client runs the entire simulation and only player commands are sent over the network. It is wonderfully economical with bandwidth, because thousands of units can move while only a few bytes of orders travel, but it requires every machine to know everything. Under lockstep the fog can be nothing more than a rendering decision, and the client is trusted to look away.
The only real defense is server side visibility. In a server authoritative architecture the server runs the simulation, computes what each player can see using the same grid and line of sight logic described above, and sends each client only the units that fall inside its vision, sometimes with a margin so that units do not pop into view a moment late. Riot Games has written publicly about applying exactly this principle in Valorant to blunt wallhacks.
The cost is real. The server must run a visibility pass for every player, network traffic grows with the number of units in view, and the client can no longer predict the movement of things it has never been told about. Yet the principle is beautifully simple: a client cannot leak what it was never given. In a competitive game the true fog lives on the server, and what the player sees on screen is merely its shadow.
Fog in a Unity project
Putting the pieces together in Unity is less daunting than the theory suggests. A plain C# class can own two byte arrays, one for exploration and one for present visibility, plus a list of registered viewers. Each viewer is a MonoBehaviour with a sight radius that adds itself to the list in OnEnable and removes itself in OnDisable. A manager updates the grid on a fixed cadence, perhaps ten times a second, since visibility rarely needs the precision of every rendered frame.
The update itself clears the visible array, loops over the viewers, converts each world position to a cell index, and runs either a radius stamp or shadowcasting from that cell, setting both arrays as it goes. For large maps or hundreds of viewers this loop is a natural candidate for the Job System and Burst, or for a compute shader that writes straight into a RenderTexture, keeping the main thread free for the rest of the game.
Two habits save a great deal of grief later. First, expose a single query method, something like IsVisible for a world position, and route every gameplay decision through it: whether to show a unit, whether a tooltip may display enemy health, whether an attack order can target something. Second, save the exploration array with the game, because players notice immediately when ground they spent an hour scouting slips back into darkness after a reload, and they are right to feel cheated.


