Skip to content

feat: gate terrain behind live vision and let armies see - #14

Closed
JJiang28 wants to merge 1 commit into
feat/server-generated-terrainfrom
feat/ephemeral-vision
Closed

feat: gate terrain behind live vision and let armies see#14
JJiang28 wants to merge 1 commit into
feat/server-generated-terrainfrom
feat/ephemeral-vision

Conversation

@JJiang28

@JJiang28 JJiang28 commented Aug 3, 2026

Copy link
Copy Markdown

Summary

  • Terrain was the only thing in the game not filtered by vision — cities, buildings, armies and tiles all go through the fog filters, so any authenticated client could read the entire world. GetTerrain now returns only currently visible ground.
  • Replaces the cities-only vision helpers with a Watcher box so any entity can grant sight, and makes armies see. They previously could not: they were merely filtered by city vision, so marching one across the map revealed nothing and a player's view never changed after founding.
  • StreamState carries a fresh VisibleTerrain whenever the visible set moves.

Notes for reviewers

Vision is ephemeral by design. Ground is lit only while a city or army is actually watching it and goes dark when that thing leaves. There is deliberately no remembered-terrain model: holding sight of the map is meant to be maintained, which is the groundwork for buildable watchtowers and fortresses on captured neutral tiles — vision you build, and can lose.

VisibleTerrain is always sent whole, never as a reveal-only delta. Because vision is ephemeral, tiles leave the set as readily as they enter it. Sending only reveals would require the client and server to agree on concealments too, and any drift leaves ground permanently lit that should be dark. Replacing the set outright makes that unrepresentable.

Recomputation is skipped on stream ticks that cannot have moved vision (resource-only updates), since it costs a query per subscriber and most ticks change nothing.

Follow-up, not in this PR

Watchtower and fortress buildings, and conquering neutral tiles, are deliberately out of scope. A fortress that grants defence is meaningless until combat exists — armies can currently move and merge but not fight.

VisionRadius is still 3. With ephemeral vision and no remembered terrain, that is a fairly small window on a 75×75 map; it may want raising once watchtowers land and there is a way to extend sight deliberately.

Test plan

  • go build ./..., go vet ./... and gofmt -l internal/ cmd/ clean
  • buf lint clean; buf generate reproduces the committed output
  • Boots against a local Postgres and serves; world generates and towns seed as before
  • Verified in a browser: only the ground around the player's city renders, everything else is shroud
  • Tile detail reports the correct terrain for a visible tile
  • No console errors on the client against this backend

Terrain was the only thing in the game not filtered by vision. Cities,
buildings, armies and tiles all went through the fog filters; the map
did not, so any authenticated client could read the whole world —
where the fertile land is, where the chokepoints are, where the gold
sits. That is exactly what an opponent should have to scout for.

Vision is now ephemeral and contested rather than a property of
ownership. It comes from watchers: a city watches its footprint, an
army watches the tile it stands on. Ground is lit only while something
is actually looking at it and goes dark again when that thing leaves,
so holding sight of the map becomes a thing to maintain rather than
something granted permanently by founding a city.

Replace the cities-only vision helpers with a Watcher box so any entity
can contribute. Armies previously could not see at all — they were
merely filtered by city vision — which meant marching one across the
map revealed nothing and a player's view never changed after founding.

GetTerrain now returns only currently visible ground, and StreamState
carries a fresh VisibleTerrain whenever that set moves. It is always
sent whole rather than as a reveal-only delta: tiles leave the set as
readily as they enter it, and replacing it outright is the only way
client and server cannot drift about what is still lit. Recomputation
is skipped on ticks that cannot have moved vision, since it costs a
query per subscriber.

This is groundwork for buildable watchtowers and fortresses on captured
neutral tiles: vision you build, and can lose.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@JJiang28 JJiang28 closed this Aug 4, 2026
@JJiang28
JJiang28 deleted the feat/ephemeral-vision branch August 4, 2026 00:48
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