Skip to content

Fog of war for the sim + cliffs line of sight - #12

Merged
goetchstone merged 1 commit into
mainfrom
fidelity/fog-of-war
Jul 9, 2026
Merged

Fog of war for the sim + cliffs line of sight#12
goetchstone merged 1 commit into
mainfrom
fidelity/fog-of-war

Conversation

@goetchstone

Copy link
Copy Markdown
Owner

Summary

Owner-reported: the AI saw through fog, and land should block sight (cliffs). The server's fog machinery moved into core as the single shared model, now gating AI decision scans, combat acquisition/casts, and snapshots — with new land line-of-sight blocking. Per-tick verdict memo keeps sim speed unchanged.

Test plan

  • New fog.test.ts: fog acquisition + spotter + cliffs LOS + AI-scan cases on the real map
  • Full suite 1,245 green incl. AI siege/trader/determinism probes under fog; lint clean
  • CI

🤖 Generated with Claude Code

"The AI seems to see through fog of war" — it did: sight-radius fog lived
only in the server's snapshot filter, so the AI brain decided on full-map
information and combat auto-fire acquired targets the owning team could not
see (weapon ranges reach 2500u vs 1800u max sight). And "you shouldn't be
able to see over the land — they were mountains/cliffs in the original" —
no line-of-sight model existed.

The fog machinery moved from packages/server into core (sim/vision.ts;
server/visibility.ts re-exports it) and now gates, with one shared model:
- the AI's enemy-unit scans (aggro, kill-commit, offensive casts) — the
  structure scans stay ungated (placement is public map knowledge, same as
  the snapshot rule);
- combat target validity: auto-fire acquisition, cast targeting, and the
  stop-to-engage gate — no firing into the fog without a spotter, for bots
  and humans alike;
- the server snapshot filter (unchanged semantics, now LOS-aware too).

NEW cliffs LOS: a sight circle does not see across land (coveredSight =
radius + segment-crosses-land), so enemies behind ridges are hidden from
snapshots, targeting and bots. Per-(state, tick, team, entity) verdict memo
(WeakMap, pure derivation — hashState/replays untouched) keeps the sim at
pre-fog speed: core suite 62s vs 286s un-memoized. The memo invalidates at
specials' vision recompute so combat always judges this tick's positions.

GEM true-sight constants moved to vision.ts (specials imports them) so
tests that mock specials don't sever the fog model; coveredSight degrades
to radius-only on stub/absent masks (legacy open-sea fixtures unchanged).

New fog.test.ts (real ruleset + terrain): a 2500u sniper cannot fire at an
unseen enemy at 2000u and a spotter restores acquisition; an enemy across a
land ridge is invisible inside sight radius and visible at the same
distance over open water; the AI aggro scan ignores kill-commit bait behind
the ridge. Full suite 1,245 green (AI siege/trader/determinism probes
pass under fog); lint clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@goetchstone
goetchstone merged commit 8dd7fc7 into main Jul 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant