ReadonlytextureThe GPU texture sampled by all fog-aware shader materials.
ReadonlywidthReadonlyheightReadonlyrevealSeconds for a newly-explored cell to fade from invisible to fully visible.
Raw RGBA bytes; index as [flatCellIndex * 4], R channel = visibility (0 or 255).
True if visibility changed since the last call to update().
True while any cells still have in-progress reveal animations.
How many cells have ever been explored — the "% of world discovered" stat.
Increments the visibility reference count for a cell. When the count goes from 0 → 1 the cell becomes visible (R=255) and permanently explored (G=255). Call once per visibility-granting source (unit, ability, etc.) that covers this cell.
Decrements the visibility reference count for a cell.
When the count reaches 0 the cell becomes not-visible (R=0) but remains
explored (G stays 255). Pair every increaseVisibility call with a
corresponding decreaseVisibility when the source moves away or is removed.
True if the cell is currently in some source's sight (the live tier). Out-of-bounds cells read as not visible.
True if the cell has ever been seen (the memory tier). Explored cells keep showing their remembered terrain and scatter after the last source moves away; use isVisible to decide whether transient things (units, current stockpiles) should be drawn there. Out-of-bounds cells read as not explored.
Number of sources currently granting sight of the cell (0 when not visible).
Marks a cell explored without granting visibility — the memory tier only. Use for scripted reveals (a map fragment, a scouting report) and for restoring saved exploration. No-op for out-of-bounds cells and for cells already explored.
Play the reveal fade-in. Default false, which is what you
want when restoring a save — remembered cells should already be there,
not fade in as if just discovered.
Takes a cell back to never-seen: clears exploration, any in-progress reveal animation, and the visibility count that would immediately re-explore it. The inverse of markExplored, for authoring tools and scripted "you forget this place" effects — normal play never needs it, since the memory tier only ever grows.
Any live sight source still standing here re-reveals the cell as soon as it reports in; clear or move the source too if the cell should stay dark. No-op for out-of-bounds cells and for cells that were never explored.
Serializes the explored set to a compact blob: a 13-byte header followed by run-length pairs over the cells in row-major order. Fully-explored and untouched maps both collapse to a handful of bytes.
Only the memory tier is written. Visibility is derived state — restore it
with UnitManager.reapplyFog() after the units are positioned.
Restores an explored set written by serialize, replacing the current
memory tier. Visibility counts are cleared — call UnitManager.reapplyFog()
afterwards to rebuild the live tier from where the units actually are.
Restored cells skip the reveal animation.
Throws if the blob is not fog data, is a newer format version, or was saved for a differently-sized map.
The serialize blob as base64 text, for JSON saves and localStorage.
Call once per frame before rendering. Advances reveal animations and uploads dirty texture data to GPU.
Reset all visibility and exploration state, including any in-progress reveal animations.
Fog-of-war state for a hex map, with two memory tiers.
Visible is the live tier: cells currently in some source's sight, tracked with integer reference counts so overlapping units are handled automatically. Explored is the memory tier: every cell ever seen, which never decreases. The gap between them is the classic Civ/AoE ghost state — an explored cell still shows its remembered terrain and scatter, dimmed, while anything transient there (see
UnitManager'shideUnitsInFog) is hidden until a source sees it again.The state is stored as a
DataTexture(RGBA) that shader materials sample at runtime: R channel = currently visible (0 or 255), G channel = ever explored (0 or 255, never decreases), B channel = reveal animation progress (0→255 overrevealDurationseconds when a cell is first explored).Pass the instance to
ChunkManagerandUnitManagerat construction time. Callreset()to wipe all state (e.g. new game), thenUnitManager.reapplyFog()to restore unit reveal contributions.The memory tier persists across sessions: serialize writes a compact run-length-encoded blob of the explored set (and toBase64 the same blob as text for JSON or
localStorage). Visibility is deliberately not saved — it is derived state, rebuilt byUnitManager.reapplyFog()once the units are back in place.Example