01 — Core Game Rules
This document specifies the world every other rules document acts upon: the entity model, the map and its coordinate system, the terrain set and the movement, vision and defensive data every subsystem reads from it, movement points and movement legality, occupancy and stacking, zones of control, cities as map entities and the exact procedure by which one changes hands, line of sight and fog of war, the setup parameters that build a game, and the public map furniture — Regions and Landmarks — that 14-victory.md counts its victory Tracks against. It also owns the Intelligence Picture — the model by which a player's knowledge of the world decays, and by which reconnaissance keeps a job after the last unexplored tile is revealed. It does not specify the turn structure (10-turn-model.md), combat resolution (11-combat.md), the economy (12-economy.md), command automation (13-command.md), victory (14-victory.md), or unit statistics (02-units-and-industry.md).
Status: Draft v0.2 · Owner: unassigned · Depends on: docs/design/00-direction.md, docs/design/01-decision-turn-model.md, 03-architecture.md (integer arithmetic, seeded PRNG, canonical hashing, tile storage, pathfinding tie-breaks), 14-victory.md (VC-1030 and VC-1080, the Region and Landmark contracts §12.2 exists to satisfy)
1. Scope, model, and vocabulary
GR-010 The simulation MUST model exactly five kinds of first-class entity: the Map, Tiles, Units, Cities, and Installations. Everything else in the rule set — orders, formations, production queues, victory tracks, works — MUST be state attached to one of these or to a Player, and MUST NOT be a sixth kind of thing occupying space on the map.
Rationale: an entity model that grows a new kind of map object per subsystem produces a simulation nobody can hold in their head and a save format nobody can version. Five kinds is enough: a tile is where things are, a unit is a thing that moves, a city is a thing that produces and can change hands, an installation is a thing built onto a tile, and the map is the container. Each of the other specifications extends these rather than adding to the list.
GR-020 A Player MUST be a seat in the game holding: a player index, a display identity, a set of owned units and cities, an Intelligence Picture (§10), and whatever state the economy, command and victory specifications attach. Player indices MUST be assigned at setup, MUST be contiguous from 0, and MUST NOT change for the life of the game — including when a seat is taken over by an AI substitute.
GR-030 A game MUST have between 2 and 8 players. Every Unit, City and Installation MUST have exactly one owner, or the neutral marker in the case of a City or Installation. Ownership MUST NOT be shared, divided, or held jointly by any mechanism.
GR-040 Players MAY be assigned to fixed Teams at setup. Team membership MUST NOT change during play. Teams MUST NOT share ownership, movement rights, stacking allowances, or production. A team's members MUST NOT be hostile to one another for any purpose in this document — capture, zones of control, movement blocking, or reactions. The setup flag teamVision, default true, MUST make every member of a team an observer for every other member (GR-1110).
Rationale: the direction says the game is adversarial by nature and that this is a default posture rather than a prohibition. Teams are the smallest thing that honours both: two players can be permanently on the same side, and nothing else about the game changes — there is still no diplomacy, no negotiated peace, no mid-game realignment, and no shared army. Making shared vision a flag rather than a rule is deliberate, because a team that must scout its own frontage plays a materially different and often better game than one that sees through its partner's eyes.
GR-050 Every entity that occupies or is placed on the map — every Unit, City and Installation — MUST carry a sequence number drawn from one monotonically increasing global counter shared by all entity kinds, unique for the life of the game, never reused after destruction.
Rationale: 10-turn-model.md's activation order is total only because its final tiebreak is unique, and the design decision record makes creation sequence that tiebreak. One counter across all entity kinds, rather than one per kind, means every ordering question anywhere in the rule set — which city produces first, which installation is resolved first, which of two contacts is listed first — has an answer already, at no cost.
GR-060 All rules arithmetic in this document MUST be integer, per 03-architecture.md AR-080. Fractional quantities MUST be expressed per-mille. Division MUST use the named rounding helpers, and every requirement here that divides MUST state its rounding. No requirement in this document MAY be satisfied by floating-point arithmetic.
GR-070 The following terms are defined here and used with these meanings throughout the specification set:
| Term | Meaning |
|---|---|
| Tile | One addressable cell of the map. |
| Adjacent | At Chebyshev distance exactly 1 (GR-170). Eight tiles, or fewer at a hard map edge. |
| Layer | One of the three occupancy planes a unit may sit in: Surface, Subsurface, Air (GR-700). |
| Domain | A unit's medium: land, sea, or air. Supplied per class by 02-units-and-industry.md. |
| Movement class | The row of the movement-cost table a unit indexes: foot, tracked, wheeled, naval, air (GR-510). |
| Installation | A player-built or map-generated feature attached to a tile or a tile edge (§4). |
| Port | A city whose tile is adjacent to water (GR-890). |
| Observed | Currently inside the effective vision radius of one of the player's observers, with line of sight (§8). |
| Explored | Observed at least once, ever, by that player. |
| Contact | A record in a player's Contact Register of a foreign unit, city or installation (§10). |
| Fidelity | How much a Contact tells its owner: an integer 0–3, Trace to Assessment (GR-1260). Never a grade: that word is reserved for veterancy in 11-combat.md. |
| Uncertainty area | The set of tiles a Contact might currently be in (GR-1330). Never a Region. |
| Region | One of M named, published divisions of the map, fixed at generation, partitioning every tile and therefore every City (§12.2). |
| Regional capital | The City a Region is anchored on and named for (GR-1644). Unrelated to the Seat of 14-victory.md. |
| Landmark | One of L named Cities whose location is public from turn 1 (GR-1646). |
GR-080 Where this document specifies a value that another specification also needs to modify — a defensive multiplier, a stacking limit, a vision radius — the value here MUST be the base, the modifying document MUST state its term additively or as a per-mille multiplier, and this document MUST state the clamp. A modifier that has no clamp stated here MUST NOT be applied.
GR-090 No requirement in this specification MAY branch on a unit's identifier or display name. All behaviour MUST derive from the attributes and capability flags 02-units-and-industry.md defines, so that a custom unit set is data.
GR-100 All rules in this document MUST behave identically for a human player, an AI seat, and an absent player's standing orders. Nothing here MAY consult which kind of controller owns a unit.
GR-110 Where a rule in this document could be satisfied by more than one tile, unit or contact, the choice MUST be made by an explicit, totally ordered tiebreak chain terminating in a value guaranteed unique. The standard terminal chain is: lowest tile index (GR-140), then lowest entity sequence number (GR-050). This is the chain 13-command.md CM-170 and 03-architecture.md AR-750 both terminate in.
2. The map
2.1 Coordinates and indexing
GR-120 The map MUST be a rectangular grid of width × height tiles. width and height MUST each be integers in [16, 2048].
GR-130 A tile MUST be addressed by an integer pair (x, y) with origin (0, 0) at the north-west corner, x increasing east, y increasing south.
GR-140 The tile index of (x, y) MUST be y × width + x. Tile index MUST be the canonical total order over tiles for every tiebreak, every serialisation, and every iteration over tiles whose order is observable in game state.
Rationale: 03-architecture.md AR-710 stores tiles in row-major typed arrays and AR-750 makes "lowest tile index wins" the pathfinding tiebreak; 13-command.md CM-1410 and CM-1510 both terminate in it. Fixing the definition here, once, is what makes those three consistent rather than coincidentally similar.
GR-150 The tile count MUST NOT exceed 4,194,304 (2048 × 2048). Tile index MUST therefore fit in an Int (03-architecture.md AR-080) with room for the sentinel value −1, which MUST mean "no tile" and MUST be the only such sentinel.
GR-160 Where a rule enumerates the neighbours of a tile, they MUST be enumerated in this fixed order, skipping any that lie beyond a hard boundary: N, NE, E, SE, S, SW, W, NW — that is, (0,−1), (+1,−1), (+1,0), (+1,+1), (0,+1), (−1,+1), (−1,0), (−1,−1).
Rationale: half the desyncs in a grid simulation come from two implementations walking the neighbourhood in different orders and a tiebreak somewhere downstream noticing. Fixing the order once, here, in the document that owns adjacency, removes the whole class — and it costs nothing, because every implementation has to pick an order anyway.
GR-170 Distance MUST be Chebyshev distance throughout the specification set: dist(A, B) = max(|Δx|, |Δy|), where Δx and Δy are the wrapped minimal displacements of GR-200. Every radius, range, reach and leash in every document — vision, bombard range, command leash, supply reach, uncertainty radius — MUST use this metric and no other.
Rationale: one metric for movement, sight, range and command is worth more than geometric fidelity. Under Chebyshev distance a "vision radius 4" unit sees exactly the 9×9 square around it, which a player can read off the screen without counting; under any octile or Euclidean metric they cannot. The honest cost is stated in GR-540.
GR-180 Movement MUST be eight-way: from any tile a unit may move to any of the up to eight tiles at Chebyshev distance 1.
2.2 Wrapping and edges
GR-190 A map MUST declare a topology, one of:
| Topology | East–west edge | North–south edge | Intended use |
|---|---|---|---|
flat |
hard boundary | hard boundary | Scenario maps, small skirmish maps, any map with a designed frontier |
cylinder |
wraps | hard boundary | Default. A world with poles. |
torus |
wraps | wraps | Abstract and symmetric maps; competitive ladder maps where no player may be given a corner |
GR-200 Where an axis wraps, the displacement along that axis between a and b MUST be the minimal wrapped displacement: of b − a and b − a ∓ span, the one of smaller absolute value; where the two are equal in absolute value, the positive one MUST be chosen. Where an axis does not wrap, the displacement MUST be b − a.
Rationale: the equal-magnitude tie is real — on a map of even width, two tiles exactly half the world apart have two equally short paths — and leaving it unspecified is precisely the kind of thing that produces a desync between two clients that both look correct.
GR-210 A hard boundary MUST behave as though every tile beyond it were absent: no unit may enter it, no line of sight passes through it, no radius extends across it, and no adjacency exists across it.
GR-220 On a cylinder map the generator MUST place terrain impassable to tracked, wheeled and naval classes along both non-wrapping edges to a depth of at least 2 tiles, using Icefield on temperate and northern terrain mixes and Mountains on arid and highland mixes.
Rationale: a hard edge that is good ground is a free flank — a player whose start sits against it defends half the frontage of a player in the middle. Making the polar strip crossable only on foot, and only slowly, removes the advantage without removing the edge, and it explains itself on sight.
2.3 Size tiers
GR-230 The shipped map size tiers MUST be exactly:
| Tier | Width × Height | Tiles | Players | Default city count | Typical game length |
|---|---|---|---|---|---|
| Duel | 40 × 28 | 1,120 | 2 | 8 | 40–80 turns |
| Small | 64 × 44 | 2,816 | 2–4 | 19 | 60–120 turns |
| Standard | 104 × 72 | 7,488 | 3–6 | 50 | 100–200 turns |
| Large | 160 × 112 | 17,920 | 4–8 | 120 | 150–300 turns |
| Vast | 240 × 168 | 40,320 | 6–8 | 269 | 250–400 turns |
Default city counts are the result of GR-1600 at the default land ratio and city density and are shown for orientation; the rule, not the table, is normative.
GR-240 A custom map of any dimensions within GR-120 MUST be playable. The tiers are presets, not a closed set. The engine MUST NOT reject a map for being between tiers.
GR-250 Dimensions above 1024 in either axis MUST be accepted but MUST be reported at setup as outside the tested performance envelope of 03-architecture.md.
Rationale: the largest tier is chosen so that a foot unit crossing the long axis on open ground takes roughly 120 turns and a road march roughly 60. That is the number that decides whether a map is one theatre or several, and it is the number the Engineer's road-building exists to change.
3. Terrain
3.1 The terrain set
GR-260 The base terrain set MUST be exactly eleven types: eight land, three water.
| # | Terrain | Family | One-line identity |
|---|---|---|---|
| 0 | Plains | open land | The reference terrain. Everything else is read against it. |
| 1 | Cropland | open land | Plains that is worth money. Mechanically identical to move and fight on. |
| 2 | Desert | open land | Hard on boots, easy on tracks, and you can see forever. |
| 3 | Woods | closed land | Cover and concealment; the vehicle's enemy. |
| 4 | Marsh | closed land | The slowest ground in the game and the worst place to be caught in. |
| 5 | Hills | high land | Cover, elevation, and a view. |
| 6 | Mountains | high land | The best defensive ground and the best observation post; foot only. |
| 7 | Icefield | closed land | Slow, exposed, and the reason the poles are not a highway. |
| 8 | Shallows | water, depth 1 | Coastal water, estuaries and navigable rivers. Small hulls only. |
| 9 | Coastal Sea | water, depth 2 | The approaches. |
| 10 | Open Ocean | water, depth 3 | Blue water. |
Rationale for the size of this set: eleven is the number at which every terrain answers a question no other terrain answers, and no more. Cropland is deliberately the cheapest addition in the set — it costs a player nothing to learn, because it moves and fights exactly like Plains, and it earns its place entirely by giving the map somewhere worth taking that is not a city. Desert and Icefield are the same terrain shape (open, slow on foot, long sightlines, poor cover) with different vehicle behaviour and different generation biomes, and they exist so that an arid map and a northern map do not play identically to a temperate one. Every remaining type is doing a job — Woods conceals, Hills elevates, Mountains blocks armour, Marsh punishes, and the three water depths are the entire naval geography.
GR-270 Terrain MUST NOT change during play. No unit, order, or event MAY convert one terrain type to another. Everything that modifies a tile MUST do so as an Installation (§4).
Rationale: permanent terrain is what makes the Terrain Record of GR-1150 permanent, which is what makes exploration a thing you finish. If terrain could change, either every player's map memory would have to decay — which is a great deal of state and a poor experience — or memory would silently lie. Installations get the interesting half of terraforming (roads, forts, bridges) and, because they are entities with owners and observation records, they can be learned and forgotten honestly.
3.2 Movement cost
GR-280 Movement is denominated in Movement Points (MP). A unit's MP allowance for one activation MUST be move × 4, where move is the class attribute 02-units-and-industry.md supplies.
Rationale for the factor of four: it buys three things for one multiplication. Terrain can be differentiated more finely than 1/2/3 without inflating the number on a unit card. A road can be genuinely faster than open ground — half cost, and a quarter for wheels — rather than nominally faster. And a river crossing can cost more than one tile of open ground without costing a fixed number of tiles, which is what makes a river a real barrier to infantry and a smaller one to armour. None of that is expressible when one tile costs one point.
GR-290 Entering a tile MUST cost the entry cost for the moving unit's movement class and the destination tile's terrain, from this table. — means the class MUST NOT enter that terrain.
| Terrain | foot |
tracked |
wheeled |
naval |
air |
|---|---|---|---|---|---|
| Plains | 4 | 4 | 4 | — | 4 |
| Cropland | 4 | 4 | 5 | — | 4 |
| Desert | 6 | 4 | 5 | — | 4 |
| Woods | 8 | 12 | 16 | — | 4 |
| Marsh | 12 | 16 | — | — | 4 |
| Hills | 8 | 8 | 12 | — | 4 |
| Mountains | 12 | — | — | — | 4 |
| Icefield | 10 | 14 | — | — | 4 |
| Shallows | — | — | — | 6 | 4 |
| Coastal Sea | — | — | — | 4 | 4 |
| Open Ocean | — | — | — | 4 | 4 |
GR-300 Leaving a tile MUST cost nothing. All movement cost MUST be charged on entry, plus the surcharges of GR-460 (river edges) and GR-690 (zones of control).
GR-310 Every land terrain MUST be enterable by the foot class. The generator MUST NOT produce a land tile no infantry can walk onto.
Rationale: a land tile that no unit can enter is a hole in the map that behaves like water without looking like it, and every pathfinder, every AI evaluation and every player intuition has to learn the exception. Mountains at cost 12 already means "three turns for a line battalion" — that is impassable enough.
GR-320 The wheeled movement class MUST be fully specified and supported even though no unit in the shipped roster uses it. It exists for custom unit sets and its identity is: fastest thing on a road, worst thing off one.
GR-330 A unit that has spent no MP during the current activation MAY enter one adjacent legal tile whose entry cost exceeds its entire allowance, spending all remaining MP and ending its movement. This is the minimum move.
Rationale: without it, a move 1 unit is frozen on any terrain costing more than 4 — which is most of the map — and its movement rating stops meaning "slow" and starts meaning "immobile in a way that depends on where it is standing". With it, "one tile per turn, everywhere" is a legible identity for the slowest units, and the cost gradient still shapes every unit above them.
GR-340 A unit MUST NOT enter a tile it cannot legally occupy or pass through under §5 and §6, regardless of MP remaining.
3.3 Terrain data read by other subsystems
GR-350 Each terrain MUST carry exactly these six rules-visible attributes, and no subsystem MAY read a terrain property not on this list:
| Terrain | defence‰ |
block |
view |
sight |
concealment |
depth |
|---|---|---|---|---|---|---|
| Plains | 1000 | 0 | 0 | 0 | 0 | — |
| Cropland | 1000 | 0 | 0 | 0 | 0 | — |
| Desert | 900 | 0 | 0 | +1 | 0 | — |
| Woods | 1250 | 1 | 0 | −1 | 1 | — |
| Marsh | 850 | 0 | 0 | −1 | 1 | — |
| Hills | 1300 | 1 | 1 | +1 | 0 | — |
| Mountains | 1400 | 2 | 2 | +2 | 1 | — |
| Icefield | 950 | 0 | 0 | +1 | 0 | — |
| Shallows | 1000 | 0 | 0 | 0 | 0 | 1 |
| Coastal Sea | 950 | 0 | 0 | 0 | 0 | 2 |
| Open Ocean | 900 | 0 | 0 | +1 | 0 | 3 |
defence— the terrain term of GR-380, per-mille.block— how much this tile obstructs a sightline crossing it (GR-1010).view— how high an observer standing here sees from (GR-1010).sight— modifier to an observer's effective vision radius (GR-1000).concealment— 1 if a unit here is harder to assess (GR-1270).depth— water depth class; the minimumdrafta naval unit needs to enter (GR-590).
Rationale for the two height numbers: one number cannot express both "a forest blocks the view" and "you cannot see out of a forest". Woods has block 1, view 0 — it stops sightlines and gives the unit inside it no advantage. Hills has block 1, view 1 — it stops sightlines and lets a unit on top see over other hills and over forest. That is two integers doing the work a real elevation model would need a heightmap for, and it is exactly enough for a game whose sight radii top out at 6.
Rationale for Marsh's defence 850: it is the only terrain in the set that is both slow and bad to defend, and that combination is what makes it feel like a trap rather than a wall. A unit caught crossing a marsh should be in trouble. Desert at 900 and Open Ocean at 900 say the same thing more mildly — open ground with nowhere to get out of the way.
GR-360 The values in the defence column MUST lie in [800, 1500] and the shipped set MUST use the full range. A custom terrain set MAY use other values within that range; values outside it MUST be rejected at load.
GR-370 A custom terrain set MUST be validated at load and rejected with a named reason if it: declares more than 256 types (03-architecture.md AR-710 stores TerrainId in a Uint8Array); omits any of the six attributes of GR-350 for any type; declares a defence outside GR-360's range; declares a block or view outside [0, 4]; declares a sight modifier outside [−2, +2]; leaves any movement class present in the loaded unit set with no land terrain it may enter; or declares a water terrain with a depth outside [1, 3].
Rationale: the modding promise is that a terrain set is data, and a data format with no validator is a data format that fails at runtime in the middle of somebody's game. Each of these bounds exists because something downstream assumes it — the Uint8Array, GR-380's clamp, GR-1010's height comparison, GR-1000's radius clamp, GR-310's walkability guarantee, GR-590's draft test — and a set that violates one produces a game that is wrong rather than one that refuses to start.
GR-380 The terrain defence value that 11-combat.md reads MUST be the single per-mille integer produced by this procedure, evaluated for a defender on tile D attacked from tile A, in exactly this order, each step flooring:
v = terrain[D].defence
if D carries a Fort installation: v = v × 1400 / 1000
if terrain[A].view < terrain[D].view: v = v × 1150 / 1000
if the move A→D crosses a river edge: v = v × riverMul / 1000 (GR-470)
v = clamp(v, 800, 2000)
GR-390 The terrain defence value MUST NOT include the city defensive term, the entrenchment term, or any unit-derived term. 11-combat.md owns those and composes them with this one.
Rationale: combat needs one number from terrain, not five, and it needs the order of operations fixed so that two implementations round identically. Handing combat a single clamped product also puts the ceiling in the terrain document, where the terrain values live, rather than leaving each subsystem to discover independently that a Fort on a mountain across a river was a mistake.
4. Installations and edge features
GR-400 An Installation MUST be a map entity attached to either a tile or a tile edge, carrying a sequence number (GR-050), a type, and an owner. Installations MUST be the only mechanism by which the traversability, defensive value or observation properties of a tile change during play.
GR-410 Where 13-command.md refers to a "work" as a Garrison target or a Posting location (CM-350, CM-630), it MUST mean an Installation of this section. Where 12-economy.md uses "Works" as a production resource, the two are unrelated terms and MUST NOT be conflated in code or interface.
GR-420 The tile Installations MUST be exactly:
| Installation | May be built on | Effect |
|---|---|---|
| Road | any land tile | A move between two adjacent tiles that both carry a Road costs 2 for foot and tracked, 1 for wheeled, in place of the destination's entry cost. |
| Fort | any land tile | Terrain defence × 1400 (GR-380); Surface stacking limit on the tile becomes 2 (GR-720); observer effective radius +2 (GR-1000); observation of units on this tile from outside it is capped at fidelity 1 (GR-1280). |
| Airfield | a land tile whose foot entry cost ≤ 8 |
Bases up to 3 air units (GR-770); resets air endurance (GR-620). |
GR-430 A tile MAY carry at most one Installation of each type and at most three in total. Road, Fort and Airfield MAY coexist on one tile and MUST compose: a fortified airfield on a road is a legal and intended thing to build.
GR-440 A tile Installation MUST NOT be built on a water tile, on a tile whose terrain the building unit's movement class may not enter, or on a tile occupied by a unit hostile to the builder. An Installation on a City tile MUST be permitted, and MUST transfer with the City under GR-930.
GR-450 The edge Installations and features MUST be exactly:
| Feature | Where | Crossing surcharge | riverMul |
|---|---|---|---|
| River | generated on an edge between two land tiles | +6 MP | 1200 |
| Ford | a River edge marked at generation, or built by a unit with the appropriate capability | +2 MP | 1100 |
| Bridge | built on a River or Ford edge | +0 MP | 1000 |
GR-460 A move whose destination lies across a River edge MUST cost the destination's entry cost plus the crossing surcharge of the highest-precedence feature on that edge, precedence being Bridge > Ford > River.
GR-470 riverMul in GR-380 MUST be the value of the highest-precedence feature on the crossed edge, and MUST be 1000 (no effect) where no river edge is crossed.
GR-480 A diagonal move from A to D MUST be treated as crossing a river if any of the four edges A|B, A|C, B|D, C|D carries a River or Ford and is not bridged, where B and C are the two tiles orthogonally adjacent to both A and D. Where more than one such edge carries a feature, the lowest-precedence feature among them MUST govern both the surcharge and riverMul.
Rationale: eight-way movement lets a unit cut the corner of a river bend and pay nothing, which turns every river into a suggestion. The conservative reading — a diagonal crosses if any of the four corner edges is a river, and the worst of them applies — closes it with no geometry and no special cases, at the cost of occasionally charging a crossing that a careful reading of the picture would not. That is the right side to err on: rivers should be respected.
GR-490 A diagonal move from A to D MUST be illegal if both orthogonally-adjacent tiles B and C are tiles the moving unit could not itself enter. A unit MUST NOT squeeze between two blocking corners.
Rationale: without it, a mountain range with a single diagonal gap between two peaks is a road, and a coastline with a diagonal notch is a canal. This rule is what makes a mountain chain a chain.
GR-500 Installations MUST be capturable, not destroyed, when the tile they sit on comes under a new owner's control (GR-930). A Bridge MUST additionally be destructible by any mechanism 11-combat.md defines; a destroyed Bridge MUST revert the edge to its underlying River or Ford.
GR-510 Road contiguity MUST be evaluated against Roads only, not against city tiles. A city tile MUST be treated as carrying a Road for the purposes of GR-420 if and only if a Road installation has actually been built there.
Rationale: making cities implicitly roaded creates a hidden road network that appears as cities are founded and captured, which is invisible on the map and disastrous for pathfinding stability. If a player wants their cities connected, they build the road, and the road is visible to everyone who can see the tile.
5. Movement
5.1 Movement classes and allowances
GR-520 Every unit MUST have exactly one movement class, one of foot, tracked, wheeled, naval, air, supplied by 02-units-and-industry.md and fixed for the life of the unit.
GR-530 A unit's MP allowance MUST be restored in full at the start of each turn. Unspent MP MUST NOT carry over between turns, except where 13-command.md CM-1600 (Banked Movement) explicitly preserves it for a unit that spent its activation asking for a decision.
GR-540 Diagonal and orthogonal moves MUST cost the same. The specification acknowledges that this makes diagonal travel geometrically cheaper — a unit crossing a map diagonally covers √2 times the ground per MP — and accepts the distortion in exchange for the single-metric property of GR-170. GR-490 (no diagonal squeeze) and GR-480 (conservative river crossing) MUST NOT be relaxed, since they are the two rules that keep the distortion from becoming exploitable at chokepoints.
Rationale: this is a known artefact of every eight-way uniform-cost grid and it produces armies that drift into diagonal columns. The alternatives are worse: charging 6 MP for a diagonal breaks the "radius 4 means the 9×9 square" reading that GR-170 exists to protect, and hexes were rejected because the whole rule set — bombard ranges, screens, stacking frontage, city adjacency — is easier to teach on squares. It is named here rather than hidden so that nobody rediscovers it as a bug.
5.2 Movement legality
GR-550 A move from A to D MUST be legal for unit U if and only if all of the following hold:
Dis adjacent toAunder GR-180 and GR-210.U's movement class has a defined entry cost forterrain[D](GR-290), orDis a Port tile and GR-900 permits it.U's remaining MP is at least the total cost of the move, or GR-330 (minimum move) applies.D's occupancy inU's layer permits entry or transit (§6).- GR-490 (no diagonal squeeze) does not forbid it.
- For a
navalunit,terrain[D].depth ≥ U.draft(GR-590). Ddoes not lie beyond a hard boundary (GR-210).
GR-560 A unit MUST be permitted to move through a tile occupied by a friendly unit in its own layer without stopping, provided it does not end its movement there and the destination is legal. A unit MUST NOT move through a tile occupied by a unit hostile to it in its own layer.
GR-570 A unit MUST NOT end its activation on a tile it may not legally occupy. Where the final tile of a route becomes illegal — occupied, stacked to its limit, or made unreachable — the unit MUST halt on the last legal tile of the route it can reach with its remaining MP. 10-turn-model.md owns what the unit's order does next.
GR-580 Routes MUST be planned against the owner's knowledge view (13-command.md CM-130, CM-140), never against the true world. A route that is legal when planned and illegal when walked MUST NOT be an error, MUST NOT consume the unit's activation without effect, and MUST NOT be reported as a rules violation.
Rationale: this is the map-rules half of the turn model's central principle — an order that is illegal when issued is rejected loudly, and an order that is legal when issued and unachievable at activation is the game. A pathfinder that peeks at the true world to avoid an embarrassing halt is a fog leak with good intentions, and it is the single easiest one to write by accident.
GR-590 A naval unit MUST carry a draft in [1, 3] from 02-units-and-industry.md and MUST NOT enter water whose depth is less than its draft. Draft 1 hulls therefore reach Shallows, estuaries and navigable rivers; draft 3 hulls are confined to Open Ocean and Ports that GR-900 admits them to.
GR-600 A navigable river MUST be represented as a contiguous chain of Shallows tiles running inland. It MUST NOT be represented as an edge feature. River edges (GR-450) and navigable rivers are distinct map objects with distinct purposes and MUST NOT interact: a River edge MUST NOT be placed on an edge where either tile is water.
Rationale: a stream that a battalion wades across and a waterway a corvette sails up are not the same object and forcing them into one representation ruins both. As edges, streams cost a tile of nothing and shape the land war everywhere; as tiles, waterways give small hulls somewhere to go that big hulls cannot follow, which is the entire reason the Corvette is not obsoleted by the Destroyer.
5.3 Air movement
GR-610 An air unit MUST pay 4 MP per tile regardless of terrain, MUST ignore River edges, MUST ignore zones of control, and MUST ignore GR-490.
GR-620 An air unit's endurance MUST be reset when it ends a turn based in a City, in an Airfield installation, or embarked in a unit carrying the airbase capability. 02-units-and-industry.md owns the endurance counter and the consequence of exhausting it; this document owns only the list of things that count as a base.
GR-630 A based air unit MUST be treated as embarked in its base and MUST NOT occupy the Air layer of the base's tile. It MUST count against the base's air capacity (GR-770), MUST be a hostile occupant for the purposes of capture (GR-920), and MUST be destroyed if its base is captured or destroyed.
Rationale: a squadron on the ground at a field that is about to be overrun is a squadron in trouble, and that is a real and dramatic decision — fly out now at the cost of a turn's endurance, or leave them and gamble on the garrison. Making based aircraft block capture is the other half of it: an enemy fighter wing sitting in an otherwise empty city denies that city to any unit that cannot shoot at aircraft.
5.4 Embarkation
GR-640 A land unit MAY embark onto a friendly transport that is on the same tile (in a Port) or on an adjacent water tile, spending all its remaining MP. A land unit MAY disembark onto a legal adjacent land tile or onto the transport's Port tile. Where the two are on adjacent tiles, embarkation and disembarkation MUST respect GR-490.
GR-650 A unit carried as cargo MUST NOT occupy a layer, MUST NOT count against tile stacking (GR-720), MUST NOT observe (GR-1000), MUST NOT be attacked independently of its carrier, and MUST NOT exert a zone of control.
GR-660 Timing constraints on embarkation and disembarkation — including whether a landed unit may act on the turn it lands — are owned by 10-turn-model.md. This document owns only where the move is legal.
GR-670 airdrop MUST require the destination land tile to be unoccupied in the Surface layer and legal for the dropped unit's movement class. assaultLanding MUST NOT require the destination to be unoccupied. 11-combat.md owns what happens on arrival in each case.
5.5 Zones of control
GR-680 A unit MUST exert a zone of control (ZOC) over the eight tiles adjacent to it if and only if 02-units-and-industry.md gives its class the zoc capability, it is not cargo, and it is in the Surface layer. A City MUST exert a ZOC over its eight adjacent tiles at all times.
GR-690 A move from A to D MUST cost +4 MP in addition to all other costs if A and D are both within a ZOC exerted by a unit or city hostile to the mover, unless A or D contains a unit friendly to the mover in the Surface layer.
GR-700 ZOC MUST NOT apply to air units, MUST NOT apply to units in the Subsurface layer, and MUST NOT make any move illegal. A ZOC surcharge MUST NOT by itself prevent a minimum move under GR-330.
Rationale: the obvious rule — entering a ZOC ends your movement — was considered and rejected, because 10-turn-model.md deliberately settles that a fast unit with a clear route can run through a gap in a line, and that interception is bought by standing still and holding a reaction. A hard-stop ZOC would overrule that decision from the wrong document. A cost of 4 MP is one open-ground tile: infiltrating a picketed frontage costs a line battalion half its turn and costs cavalry a fifth of one, so a picket line is worth building against slow forces and does not pretend to catch fast ones. The friendly-unit exemption is what lets a player open their own line for a counter-attack, which is the thing that would otherwise feel unfair.
6. Occupancy and stacking
GR-710 Every non-cargo unit MUST occupy exactly one layer of exactly one tile:
| Layer | Occupants |
|---|---|
| Surface | land units on land tiles and Port tiles; sea units on water tiles and Port tiles that admit them |
| Subsurface | sea units that are currently submerged |
| Air | air units that are not based |
GR-720 The stacking limit for the Surface layer of a tile MUST be:
| Tile | Surface limit |
|---|---|
| Open land or water | 1 |
| Land tile carrying a Fort | 2 |
| City tile | 6 |
Rationale for a Surface limit of 1 in the open: it is the rule that makes frontage a resource. Five cheap units hold five tiles and one expensive unit holds one, so mass and concentration stay genuinely different strategies at every tier rather than collapsing into "put everything on the best tile". It also makes bombard range meaningful, makes screens buildable, and keeps the Cascade from becoming a stack-management exercise. 02-units-and-industry.md tunes the roster against exactly this assumption and states the consequence of choosing otherwise, so this is the value that keeps that tuning honest.
Rationale for a City limit of 6: a city has to be a place an army can assemble and a place a defence can be layered, or its capture becomes a single coin-flip against a single unit. Six is enough for a garrison, a gun and a reserve, and low enough that a frontier town cannot become an unassailable stack. It is stated here as a flat number rather than derived from a city's development level because two other specifications currently propose incompatible development models and a stacking rule must not be hostage to that argument; GR-780 is the extension point if either wants one.
GR-730 The stacking limit for the Subsurface layer MUST be 1 on any tile. The stacking limit for the Air layer MUST be 1 on any tile.
GR-740 Layers MUST be independent for occupancy: a Surface unit, a Subsurface unit and an Air unit belonging to different players MAY occupy the same tile simultaneously. Movement blocking under GR-550(4) and GR-560 MUST consider only the mover's own layer.
GR-750 The occupants of a tile MUST be stored, iterated and serialised in ascending sequence number. No rule anywhere in the specification set MAY depend on any other ordering of a tile's occupants.
GR-760 Where a tile's stacking limit falls below its current occupancy — a Fort captured, destroyed, or lost with its tile — the excess units MUST NOT be destroyed, displaced, or damaged. No further unit MAY enter the tile until occupancy is below the limit, and the excess MUST be permitted to leave normally.
Rationale: a rule that kills units because a limit changed under them is a rule that turns a tactical setback into an arbitrary massacre, and players will never accept it as anything but a bug. Letting the tile drain naturally costs one comparison and produces the obviously correct behaviour.
GR-770 A City MUST additionally base up to 4 air units, and an Airfield installation up to 3. Units with the airbase capability base air units up to their own capacity, per 02-units-and-industry.md.
GR-780 12-economy.md or 02-units-and-industry.md MAY modify a city's Surface limit and air capacity by a stated additive term. The composed Surface limit MUST be clamped to [4, 12] and the composed air capacity to [2, 8].
GR-790 A unit whose move would exceed a stacking limit MUST NOT enter the tile. Where such a unit was moving under an order, it MUST halt on the last legal tile of its route; 10-turn-model.md owns the consequent order handling.
GR-800 Cargo MUST NOT count against any stacking limit. Based air units MUST count only against air capacity (GR-770), never against the Surface limit.
GR-810 A unit MUST be permitted to be in the same tile as a hostile Subsurface unit it has not detected, and MUST NOT be prevented from moving by an undetected Subsurface unit. Detection is governed by §8 and §10.
Rationale: an undetected submarine that silently blocks a destroyer's movement leaks its existence through the pathfinder, which is exactly the class of information leak the fog rules exist to prevent. Three layers rather than two is the cost of getting concealment right, and it is worth paying: it is what makes "detection becomes the game" a mechanic rather than a slogan.
7. Cities
7.1 The city entity
GR-820 A City MUST be a map entity carrying: a sequence number (GR-050), a tile, an owner or the neutral marker, a name, and whatever production, development and integration state 02-units-and-industry.md and 12-economy.md attach to it. A tile MUST carry at most one City.
GR-830 Cities MUST NOT be founded, built, settled or destroyed during play. The set of Cities and their tiles MUST be fixed at setup and MUST NOT change for the life of the game. Only ownership changes.
Rationale: this is one of the load-bearing decisions in the whole design and it deserves stating as a rule rather than leaving as an omission. Cities are the only production, the only victory currency, and the only thing worth fighting over; if players can make more of them, the scarcity that makes them contested evaporates and the game becomes a builder, which is a different and worse genre for this loop. A fixed city set also makes the map a fixed strategic problem — the same forty cities all game, in the same places, each with a known worth — which is what lets a player form a plan on turn 10 that is still coherent on turn 150.
GR-840 Every City MUST carry a name, unique across the map, drawn deterministically from the game seed and the City's sequence number. Names MUST NOT be reassigned when a City changes hands.
GR-850 A City MUST sit on a land tile. The generator MUST NOT place a City on Mountains, Marsh or Icefield.
Rationale: a city on impassable-to-vehicles ground is a fortress no armour can ever relieve or assault, decided at map generation rather than by play. Restricting placement to the five workable land terrains costs the generator nothing and removes a whole class of unwinnable map.
GR-860 A City MUST be an observer in its own right, with a base effective vision radius of 3, whether or not it contains a unit. 12-economy.md MAY add a development term; the composed radius MUST be clamped to [2, 6].
Rationale: a city that goes blind when its garrison marches out is a city that can be walked up to unseen, which makes every rear city a liability and every player garrison for vision rather than for defence. Cities watching their own approaches is also what makes the road network and the industrial geography scoutable at all in the late game.
GR-870 A City tile MUST carry block +1 and view +1 in addition to its terrain's values (GR-350), for the purposes of GR-1010.
GR-880 A City MUST exert a zone of control (GR-680) regardless of its garrison.
7.2 Ports
GR-890 A City MUST be a Port if and only if at least one of its eight adjacent tiles is water. A Port's admitted draft MUST be the maximum depth among its adjacent water tiles.
GR-900 A naval unit whose draft is at most the Port's admitted draft MAY enter, occupy and leave the Port's tile in the Surface layer, moving between the Port tile and any adjacent water tile it may legally enter. It MUST pay the Port tile's land entry cost for the naval class, fixed at 4 MP.
GR-910 A Port tile's Surface stacking limit MUST be the city limit of GR-720, shared between land and naval occupants.
Rationale: a Port whose stack is shared is a Port where a fleet in harbour crowds out the garrison, which is a real and interesting decision and needs no extra rule to produce it.
7.3 Capture
GR-920 A City MUST change hands when, and only when, a unit U carrying the capture capability and belonging to a player other than the City's owner enters the City's tile at a moment when that tile contains no unit hostile to U's owner in any layer, based air units included.
GR-930 The capture procedure MUST be executed in exactly this order, atomically, at the moment U enters:
Uoccupies the tile in its layer, subject to GR-720.- The former owner's ownership of the City is removed. Every Installation on the City's tile transfers to
U's owner. U's owner acquires the City.- The City's production and development state is reset as 02-units-and-industry.md specifies for capture, and its integration state as 12-economy.md specifies.
U's owner immediately gains the City's observation (GR-860), which resolves before any further activation.- The former owner immediately loses the City's observation. Every Contact the former owner held that was sustained solely by this City's observation begins to age from this turn (GR-1300).
U's activation ends.UMUST NOT move further, attack, or capture again during this activation, and MUST forfeit all remaining MP.- The ownership change is announced under GR-1430.
GR-940 A unit MUST NOT capture more than one City per turn. GR-930 step 7 is the mechanism and MUST NOT be waived by any capability, posture, or order.
Rationale: without it a move 5 scout takes five cities in a turn, and the game's central act — taking a city — becomes something that happens in passing. Ending the activation makes each capture a deliberate expenditure of a unit-turn, makes the tile the unit finishes on a decision, and gives the defender a turn to react to each capture rather than to a chain of five. It is also the only structural brake on the cheap-unit city-snatching failure mode that 02-units-and-industry.md names as a playtest alarm.
GR-950 Entering a City tile that contains a hostile unit MUST be an attack, resolved by 11-combat.md, and MUST NOT be a capture. Where 11-combat.md's resolution results in the attacking unit occupying the tile and the tile is then free of hostile units, GR-930 MUST execute in full, including step 7.
GR-960 A City MUST NOT be destroyed by any means. A City whose owner is eliminated MUST become neutral and MUST retain its Installations and its observation, which MUST be observation belonging to no player.
GR-970 A player MAY abandon a City they own, by an explicit order, at a cost 12-economy.md owns. An abandoned City MUST become neutral, MUST retain its Installations, and MUST NOT be recapturable by the abandoning player for 5 turns.
Rationale: abandonment must exist, because a player who cannot give up an indefensible salient is forced to feed units into it, and a five-turn lockout is what stops abandonment from becoming a way to dodge a victory-track city count for one turn and take it straight back.
7.4 Neutral cities
GR-980 A neutral City MUST NOT produce, MUST NOT be modified by any player, MUST observe (GR-860) for no player, and MUST exert a zone of control (GR-880).
GR-990 The setup parameter neutralDefence MUST take one of these values, with none as the default:
| Value | Meaning |
|---|---|
none |
Neutral cities contain no unit and are captured by entry under GR-920. |
garrison |
Each neutral City contains one immobile defending unit of the class 02-units-and-industry.md nominates for this purpose. |
scaled |
As garrison, but the number of defenders is 1 + floor(d / 12) capped at 3, where d is the Chebyshev distance to the nearest player start tile. |
Rationale for defaulting to none: the early land grab is the best thirty turns this genre has, and it is the only period in which exploring terrain and racing for ground is the whole game. Garrisoned neutrals kill it — a city defended at ×1500 needs roughly three infantry or an artillery preparation to take, which pushes a player's second city past turn 30 and makes the opening a build queue rather than a campaign. 02-units-and-industry.md's own worked economics assume three cities held by turn 18 on a tempo opening, and garrison makes that unreachable. The two other values exist because a slower, more deliberate opening is a legitimate thing to want, and scaled in particular gives a map a natural frontier — free cities near home, defended ones in the middle — which is a good shape for a long game.
8. Vision and line of sight
GR-1000 A player's observers MUST be exactly: their non-cargo units, and their Cities. An observer's effective vision radius R MUST be:
R = clamp( base + terrain[tile].sight + installationBonus , 1, 24 )
where base is the unit's vision attribute or the City radius of GR-860, installationBonus is +2 if the observer's tile carries a Fort and 0 otherwise, and terrain[tile].sight is 0 for any observer whose domain is air.
GR-1010 A tile T MUST be observed by observer O if and only if:
dist(O, T) ≤ R, anddist(O, T) ≤ 1, orO's domain isair, or no step of the sight ray fromOtoTis blocked.
A step k (for 1 ≤ k < dist(O, T)) of the sight ray MUST be blocked if and only if every candidate tile at that step satisfies block(X) > max(view(O), view(T)), where block and view are the terrain values of GR-350 plus the City adjustment of GR-870.
GR-1020 The candidate tiles at step k MUST be computed as follows. Let Δx, Δy be the wrapped displacements from O to T (GR-200) and d = max(|Δx|, |Δy|). Let nx = x_O × d + Δx × k and ny = y_O × d + Δy × k. The candidates are the tiles (x, y) with x ∈ {ifloorDiv(nx, d), iceilDiv(nx, d)} and y ∈ {ifloorDiv(ny, d), iceilDiv(ny, d)}, reduced by map wrapping, with duplicates removed. There MUST be at most four candidates and at least one.
GR-1030 Line of sight MUST be symmetric: for any two tiles A and B, the blocking test of GR-1010 clause 2 MUST return the same result evaluated in either direction. Implementations MUST NOT introduce a tiebreak that breaks this property.
Rationale: asymmetric line of sight — "he can see me but I cannot see him" — is the single most-complained-about property of grid vision systems, because it cannot be shown on a map and therefore cannot be planned around. Making it symmetric costs one design decision (the max in GR-1010) and removes the whole class of complaint. Vision radius remains asymmetric, which is fine, because that is a property of the unit and it is printed on its card.
GR-1040 An observer MUST always observe its own tile and every adjacent tile within R, without a blocking test.
GR-1050 A player MUST always observe every tile occupied by one of their own units or Cities, and MUST always have complete and current knowledge of their own units, including those carried as cargo.
GR-1060 Observing a carrier MUST NOT reveal what it carries below fidelity 3. At fidelity 2 the observer learns that the carrier is loaded and how many slots are filled; at fidelity 3 it learns the classes and strengths of the cargo.
Rationale: a convoy whose contents are visible from the horizon is a convoy nobody needs to intercept — you simply wait to see whether it is worth the torpedo. Making cargo a fact that only Assessment reveals means the decision to commit a submarine against a loaded transport is made on incomplete information, which is the decision worth having.
GR-1070 An air observer MUST ignore terrain blocking entirely and MUST receive no sight modifier from the tile beneath it. This is the only vision rule in the specification that depends on domain.
Rationale: aircraft see over everything, which is what they are for, and this one rule gives them a permanent late-game role without any dedicated reconnaissance machinery. It is deliberately paired with GR-1290, which caps what an aerial observation can tell you: an aircraft finds an army, it does not assess one.
GR-1080 A unit in the Subsurface layer MUST be observed only by an observer that carries the sonar capability and has T within R under GR-1010, or by any observer at dist ≤ 1.
GR-1090 A submerged unit occupying a Shallows tile MUST be treated as being in the Surface layer for all observation purposes, and MUST be observable by any observer under GR-1010.
Rationale: a submarine in twelve feet of water is a shadow anyone can see from a boat, and this rule is what stops the shallows from becoming a submarine highway that only a sonar hull can patrol. It also gives the Shallows terrain a second job beyond gating hulls by draft, and it means the answer to a submarine problem can be geographic — force it into the shallows — as well as technological.
GR-1100 Visibility MUST be recomputed at every activation during the Cascade, per 10-turn-model.md's per-activation fog requirement. Implementations MUST compute it incrementally, and the incremental result MUST be provably identical to a full recomputation under GR-1010 (03-architecture.md AR-950(d)).
GR-1110 A player's observation set MUST be the union over their observers. Observation MUST NOT be shared between players by any mechanism this specification defines, with the single exception of teamVision (GR-040). Contacts (§10) MUST NOT be shared under any circumstances, including within a team.
Rationale: sharing observation is cheap and sharing intelligence is not. Two teammates who both see a tile agree about it; two teammates who merged Contact Registers would need a rule for whose stale estimate wins, whose track projection survives, and what happens to a shared Contact when one of them is eliminated. Vision is a set union; intelligence is a history, and histories do not union cleanly.
9. Fog of war and the knowledge record
GR-1120 Every tile MUST be in exactly one of three states for each player:
| State | Terrain | Contents |
|---|---|---|
| Unexplored | unknown | unknown |
| Explored | known, from the Terrain Record | memory, possibly stale — see §10 |
| Observed | known and current | current and complete, subject to GR-1080 |
GR-1130 A tile MUST become Explored for a player the first time that player observes it, and MUST remain Explored for the rest of the game.
GR-1140 The Terrain Record MUST store, per player per explored tile: the terrain type, the tile Installations, the River-edge features on its edges, whether a City is present, and the observation turn — the most recent turn on which that player observed the tile.
GR-1150 Terrain type MUST be recorded permanently and MUST NOT decay, because terrain never changes (GR-270).
GR-1160 Installations, River-edge features and City presence MUST be recorded as of the observation turn and MUST NOT be updated while the tile is unobserved. A Road, Fort, Airfield or Bridge built, or a Bridge destroyed, on a tile a player is not observing MUST NOT appear in that player's Terrain Record until the tile is observed again.
Rationale: this is where late-game exploration lives. By turn 120 every tile is Explored and no terrain remains to discover — but a road network laid across an enemy's rear, or a line of forts across a frontier, is invisible until somebody goes and looks. That gives the Engineer's construction a genuine intelligence dimension: building infrastructure is also concealing your own mobility from an opponent who has stopped patrolling.
GR-1170 The observation turn of every tile MUST be exposed to the client and to 13-command.md as observation age = currentTurn − observationTurn, so that staleness is addressable by orders and displayable on the map.
GR-1180 A player's view MUST NOT contain, in any form — state, event stream, derived index, timing, or the absence of an expected value — information about any tile or unit that player has neither observed now nor observed before, except the public map facts of GR-1648, which are published to every player from turn 1 and are the only exception this specification admits. This is testable and MUST be tested per 03-architecture.md AR-950(c).
GR-1190 The client MUST NOT render remembered contents in a way that could be mistaken for observed contents. Every remembered unit, city garrison, installation and city ownership MUST be presented with its age and its fidelity (§10). 04-ui-ux.md owns how.
Rationale: the reason this is a rules requirement and not a presentation preference is that the whole intelligence design of §10 is worthless if the interface renders a three-turn-old contact identically to a live one. If memory looks like truth, players will treat it as truth, and every decay rule below becomes a source of unexplained bad outcomes instead of a source of tension.
10. The Intelligence Picture
This section addresses the weakness the design direction names and no proposal owns: exploration falls off a cliff once the map is known. The answer taken here is that terrain is the only thing you can finish learning. Everything else — where the enemy's army is, what it consists of, how badly it is hurt, what its cities are building, what infrastructure it has laid — is knowledge that decays, that is scaled by fidelity rather than binary, and that can only be refreshed by putting something at risk. The four rules that carry the weight are: fidelity is set by how close you got (GR-1270), fidelity decays with time (GR-1300), position becomes an uncertainty area rather than a tile (GR-1330), and sustained observation is worth far more than a glimpse (GR-1340).
10.1 The Contact Register
GR-1200 Each player MUST hold a Contact Register: a set of Contacts, each a record of one foreign unit, City or Installation. A Contact MUST NOT be a reference to the true entity and MUST NOT be updated by anything other than an observation or the decay rules of this section.
GR-1210 A Contact MUST carry exactly: the subject's entity sequence number, the observing player, lastTile, lastSeenTurn, fidelity at last observation, trackTurns, step, and the assessed attributes admitted at that fidelity by GR-1260.
GR-1220 A player MUST hold at most one Contact per subject. A second observation of a subject already in the Register MUST refresh the existing Contact under GR-1240 and MUST NOT create a second record.
GR-1230 A player's Contact Register MUST hold at most 4096 Contacts. Where the bound is reached, Contacts MUST be pruned in this order until it is not: greatest age first, then lowest current fidelity, then lowest subject sequence number. Pruning MUST be part of the once-per-turn decay evaluation of GR-1680.
Rationale: the bound exists because the Register is hashed state (GR-1660) and unbounded hashed state is an unbounded save file and an unbounded desync surface. Four thousand contacts is far more than any player can act on and roughly three times the unit count of the largest supported game, so in practice the prune never fires; it exists so that a pathological map cannot make the state grow without limit, and the ordering exists so that when it does fire it discards the least useful record rather than an arbitrary one.
GR-1240 A Contact MUST be created or refreshed whenever the player observes the subject under §8. Refreshing MUST set lastTile and lastSeenTurn to the current values and MUST set fidelity to the observation fidelity of GR-1270 — which MAY be lower than the fidelity previously held.
Rationale: a distant glimpse of a unit you once stood next to should not preserve your detailed assessment of it. Setting rather than raising the fidelity is what makes "I saw them, but only just" an honest state, and it is what stops a single scout on a hilltop from maintaining perfect intelligence on an army it can barely make out.
GR-1250 Where a Contact's subject is destroyed while the player is observing it, the Contact MUST be removed immediately. Where the subject is destroyed out of the player's observation, the Contact MUST persist and decay normally.
Rationale: intelligence about a unit that no longer exists is exactly as valuable as intelligence about one that does, until you go and check. Removing contacts on unobserved deaths would leak the death.
10.2 Fidelity
GR-1260 Fidelity MUST be an integer in [0, 3] and MUST determine exactly what the Contact tells its owner:
| Fidelity | Name | The Contact reports |
|---|---|---|
| 0 | Trace | Something is or was here. Domain only — land, sea, or air. No owner, no count, no identity. |
| 1 | Sighting | Position, domain, owner, and a count band: one, a few (2–4), many (5+). |
| 2 | Identification | The above, plus exact count and the class of every unit present. For a City: its owner, its development level, and its Installations. |
| 3 | Assessment | The above, plus each unit's current strength, its Stance, and any condition flags 11-combat.md exposes. For a City: its current production item and accumulated progress. |
Rationale for putting current strength at the top fidelity and nowhere else: strength is the single number that decides whether an attack is worth making, and making it the hardest thing to learn is what keeps reconnaissance dangerous forever. Position you can get from an aircraft at range; composition you can get from a scout on a ridge; whether that line is fresh or shot to pieces you can only get by being next to it. That is a permanent job for a permanently vulnerable unit, and it is the reason a Scout is still worth building on turn 200.
GR-1270 The observation fidelity MUST be computed at the moment of observation as clamp(base + modifiers, 0, 3), where base is:
Observation distance d |
base |
|---|---|
d ≤ 1 |
3 |
2 ≤ d ≤ iceilDiv(R, 2) |
2 |
iceilDiv(R, 2) < d ≤ R |
1 |
and the modifiers, all applied, are:
| Condition | Modifier |
|---|---|
The subject's tile terrain has concealment = 1 (GR-350) |
−1 |
The observer's class carries the recon capability |
+1 |
| The subject is a City or an Installation | floor of 2 |
GR-1280 These caps MUST be applied after GR-1270 and MUST override it:
| Condition | Fidelity cap |
|---|---|
| The subject occupies a tile carrying a Fort, and the observer is not on that tile | 1 |
The observer's domain is air |
2 |
The subject is submerged and was detected only by the adjacency clause of GR-1080 |
1 |
Rationale for the Fort cap: a fort should do two things, and defensive multipliers only do one. Capping external observation at Sighting means a fort's garrison is a known unknown — you can see that it is held, you cannot see by what or how strongly — and that converts a fort from a lump of defence value into a genuine intelligence problem. It also gives Engineers a second reason to exist in the late game, when the front has stabilised and there is nothing left to explore.
Rationale for the air cap: aerial reconnaissance that returned full assessments would obsolete every ground scout the moment the first aircraft flew, and the design would lose its most interesting recon unit exactly when the map stops needing exploring.
GR-1290 Where a player observes a City, the City's owner MUST always be reported regardless of fidelity. City ownership MUST NOT be subject to fidelity or decay.
Rationale: the political map is public information and the military map is not. That split is the right one: a player should always know which cities their opponent holds, because victory conditions are counted in cities and a player who cannot count them cannot tell whether they are winning; and a player should never know what is inside them without looking. Hiding ownership produces tedium — sweeping a known map to discover a fact everyone in the world would know — rather than tension.
10.3 Decay
GR-1300 A Contact's current fidelity MUST be fidelity − ifloorDiv(age, D), where age = currentTurn − lastSeenTurn and D is the decay interval in turns:
| Subject | D |
|---|---|
A unit whose assessed domain is land |
3 |
A unit whose assessed domain is sea |
2 |
A unit whose assessed domain is air |
1 |
| A City or Installation | never decays below fidelity 2 |
GR-1310 D MUST be doubled where the Contact's recorded fidelity was 3 and the recorded Stance was a non-moving one (10-turn-model.md's Hold or Entrench).
Rationale: this is the second reward for close reconnaissance and it is the more interesting one. A good look at a dug-in enemy tells you not only more, but for longer — because a unit that was entrenched three turns ago probably still is. A good look at a marching column tells you a great deal that is worthless by next turn. The rule makes "what were they doing?" as valuable a question as "what were they?", and it costs one conditional.
GR-1320 A Contact MUST be dropped when its current fidelity would fall below 0, when its uncertainty radius would exceed 16 (GR-1330), or when its uncertainty area is fully excluded (GR-1350).
10.4 Position uncertainty
GR-1330 A Contact's position MUST be an uncertainty area, not a tile: the set of tiles within Chebyshev radius U of a projected centre C, minus the exclusions of GR-1350. For an untracked Contact (trackTurns ≤ 1):
C = lastTile
U = min( 16, reach × age )
where reach is the subject's move attribute if the Contact's fidelity is 2 or higher, and otherwise the domain default: 3 for land, 8 for sea, 12 for air.
GR-1340 For a tracked Contact — one observed on at least two consecutive turns, so that step is the displacement observed over the most recent of them:
C = clampToMap( lastTile + step × age )
U = min( 16, iceilDiv( max(|step.x|, |step.y|) × age, 2 ) + 1 )
Rationale: this is the heart of the section. A single glimpse of a cavalry regiment three turns ago tells you it is somewhere in a 13×13 box — 169 tiles, which is nearly useless. Two consecutive turns of observation tell you where it was going, and a projection along that heading with half the spread narrows the same three-turn-old knowledge to a box of about 25 tiles centred where it is probably actually going to be. Watching is worth roughly seven times as much as looking. That is the incentive that keeps a screen of observers on the map for the whole game rather than a scout sortie every twenty turns, and it makes the loss of a picket line a genuine intelligence event rather than the loss of one cheap unit.
GR-1350 A tile MUST be excluded from a Contact's uncertainty area if the player observed that tile on a turn later than the Contact's lastSeenTurn and did not observe the Contact there. Exclusions MUST be derived from the Terrain Record's observation turns (GR-1140) and MUST NOT be stored per Contact.
GR-1360 A Contact whose age is 0 MUST have U = 0 and MUST report the exact tile. A Contact whose subject is a City or an Installation MUST always have U = 0.
Rationale for exclusion: it turns a search into a narrowing rather than a re-roll. A player who knows an enemy column is somewhere in a 25-tile box and sweeps eight of those tiles with a patrol has genuinely learned something even though they found nothing, and the map should show them that. It is also nearly free to compute, because the observation-turn map that fog already maintains is exactly the data it needs. The model can be wrong — the column can double back into a tile you swept — and it must be allowed to be wrong, because an estimate that is never wrong is the truth with extra steps.
10.5 The combat predictor and estimated intelligence
GR-1370 The estimated flag that 13-command.md CM-160 requires of the combat predictor MUST be false if and only if the relevant Contact has current fidelity 3 and age 0. In every other case it MUST be true, and CM-160's conservative default MUST apply.
GR-1380 Where a Contact's current fidelity is below 2, the predictor MUST NOT be given a unit class and MUST treat the subject as the domain default 13-command.md specifies.
10.6 Worked example
Non-normative, and included because a decay model that is not worked through is a decay model nobody will implement the same way twice.
Turn 108. Meridian's scout on a hill at (44, 30), vision 4, sight +1 from Hills, recon, so R = 5.
At d = 3 it observes a Karsk column at (47, 32) standing on Cropland. Base fidelity for 2 ≤ d ≤ iceilDiv(5,2) = 3 is 2; Cropland has no concealment; recon gives +1; result 3 — Assessment. Meridian learns: three units, two Line Infantry and a Field Gun, current strengths 6/6, 5/6 and 4/4, Stance Advance.
Turn 109. The scout still sees them; they are now at (46, 33). trackTurns = 2, step = (−1, +1).
Turn 110. The scout is driven off. lastSeenTurn = 109, age begins.
- Turn 111 (
age = 1): fidelity3 − ifloorDiv(1, 3) = 3.C = (46,33) + (−1,+1)×1 = (45, 34).U = iceilDiv(1×1, 2) + 1 = 2. A 5×5 box. Meridian still knows their strength. - Turn 113 (
age = 3): fidelity3 − 1 = 2.C = (43, 36).U = iceilDiv(3, 2) + 1 = 3. A 7×7 box, 49 tiles, and strength is gone — the predictor now returnsestimated = trueat 400‰, so aFavourableEngagement Sanction will not authorise an attack on them. - Turn 113, with a patrol. Meridian's cavalry sweeps six tiles of that box and finds nothing. Those six are excluded; the area is 43 tiles. Not decisive, but the map now shows where they are not, which is what a patrol is for.
- Turn 119 (
age = 9): fidelity3 − 3 = 0— Trace.U = iceilDiv(9, 2) + 1 = 6. Meridian knows only that something of Karsk's was in this quarter of the map ten turns ago. - Turn 122 (
age = 12): fidelity would be3 − 4 = −1. Contact dropped.
Had Meridian caught only a single glimpse on turn 109 rather than two consecutive turns, the same Contact at turn 113 would have U = min(16, 2 × 4) = 8 — a 17×17 box of 289 tiles, against 49. That factor of six is the entire argument for keeping observers on the map.
11. Perceptible events
Not everything a player learns comes from seeing it. Battles are loud, cities are political, and a map on which nothing is ever heard at a distance is a map that goes quiet in the late game exactly when the war gets large.
GR-1390 A perceptible event MUST create a Contact at fidelity 0 (Trace) at the named tile for every player meeting its perception condition, unless that player already holds a Contact of higher fidelity on the same subject at the same tile.
GR-1400 The perceptible events MUST be exactly:
| Event | Perceived by | Radius |
|---|---|---|
Combat resolved on tile T |
any player with an observer within the stated radius of T |
that observer's R + 4 |
A bombardment resolved against tile T |
as above | that observer's R + 6 |
A unit with the expendable capability resolving its attack on T |
every player | the whole map |
GR-1410 A perceptible event MUST NOT reveal the owner, count, class or strength of anything. It creates a Trace and nothing more.
Rationale: this rule exists to make large operations loud. A player who launches a six-unit assault forty tiles from anyone's border has, until now, done so in perfect silence; with this rule, any opponent with a picket in that quarter of the map knows that something happened over there, on that turn, and nothing else. That is exactly the right amount: enough to send someone to look, never enough to act on. It also gives a defender a reason to keep cheap observers scattered across their own depth, which is a second permanent job for the reconnaissance arm.
GR-1420 The radius bonus in GR-1400 MUST be applied to the perceiving observer's own effective radius, not to a fixed distance from the event, and MUST ignore line of sight. A perceptible event MUST NOT be blocked by terrain.
GR-1430 A City ownership change MUST be announced at the end of the turn in which it occurs to every player who has ever explored that City's tile, and MUST update that player's recorded owner for the City. It MUST NOT reveal the City's garrison, development, production, or Installations, and MUST NOT change the observation turn of the tile.
Rationale: see GR-1290. The political map is public; the military map is not.
GR-1440 A player MUST be notified when a unit or City they own is destroyed or captured, with the tile, regardless of whether they observe it.
GR-1450 A perceptible event MUST be evaluated at the instant it resolves within the Cascade, against observer positions as of that instant. It MUST NOT be batched to end of turn and MUST NOT be evaluated against positions from the start of the turn.
Rationale: a picket that rode past a valley at the top of the turn should not hear a battle that happens in it at the bottom, and a picket that arrived at the bottom should. Evaluating at the instant is also the only version consistent with 10-turn-model.md's per-activation fog, and evaluating it any other way would produce an audible event a player could correlate against the activation order — the exact leak the compacted event stream exists to close.
12. Setup
GR-1460 A game MUST be fully determined by: the rules version, the game seed (a 64-bit value), the setup parameters of this section, and the parameters the economy, victory and unit specifications own. Two games created from identical values MUST produce byte-identical initial states.
GR-1470 Map generation MUST draw exclusively from the seeded PRNG (03-architecture.md AR-350) and MUST complete before any player order is accepted. Nothing after setup MAY consume PRNG draws attributable to map generation.
GR-1480 The map setup parameters MUST be exactly:
| Parameter | Type | Default | Notes |
|---|---|---|---|
size |
tier or explicit width × height |
Standard |
GR-230, GR-120 |
topology |
flat | cylinder | torus |
cylinder |
GR-190 |
landRatio |
per-mille of tiles that are land | 400 |
GR-1510 |
terrainMix |
preset name | Temperate |
GR-1520 |
cityDensity |
land tiles per city | 60 |
GR-1530 |
minCitySpacing |
tiles | 3 |
Chebyshev, city to city |
regionCount |
integer or auto |
auto |
M; auto derives it by GR-1643 |
landmarkCount |
odd integer or auto |
auto |
L; auto derives it by GR-1646 |
riverDensity |
per-mille of land-tile edges carrying a River | 35 |
GR-1550 |
roadDensity |
per-mille of land tiles carrying a pre-generated Road | 0 |
Roads are built, not found, by default |
neutralDefence |
none | garrison | scaled |
none |
GR-990 |
startCities |
cities per player at turn 1 | 1 |
GR-1570 |
minStartSeparation |
tiles | by tier, GR-1580 | Chebyshev, start to start |
fogEnabled |
boolean | true |
GR-1630 |
intelligenceDecay |
boolean | true |
GR-1630 |
GR-1490 Setup MUST reject a parameter combination that cannot satisfy the invariants of §12.1 or §12.2 — most commonly a player count too high for the chosen size tier, or a minStartSeparation too large for the map — before generation is attempted, with a named, localisable reason naming the parameter to change. It MUST NOT be discovered by exhausting the retry budget of GR-1560. In particular, setup MUST reject where cityCount < 2 × M + startCities × playerCount, or where cityCount − startCities × playerCount < L, because neither the Region invariants of GR-1645 nor the Landmark selection of GR-1647 can be satisfied on such a map.
GR-1500 startCities MUST be in [1, 3], and startCities × playerCount MUST NOT exceed one third of the target city count of GR-1530.
Rationale: a game that begins with most of the map's cities already dealt out has no expansion phase, and the expansion phase is where a player learns the map, meets their neighbours, and forms the plan the rest of the game executes. One third is the point at which the neutral cities still outnumber the owned ones two to one on turn 1.
GR-1510 landRatio MUST be in [150, 850]. The shipped presets MUST be:
| Preset | landRatio |
Character |
|---|---|---|
| Islands | 150 | Naval game. Every expansion is an amphibious operation. |
| Archipelago | 250 | Mixed, naval-dominant. |
| Mixed | 400 | Default. Continents with real seas between them. |
| Continental | 550 | Land game with coastal flanks. |
| Pangaea | 700 | Land game. Navies are a convenience. |
| Lakes | 850 | Pure land game; water is terrain, not theatre. |
GR-1520 The terrainMix presets MUST be exactly these, as per-cent shares of land tiles, each summing to 100:
| Preset | Plains | Cropland | Desert | Woods | Marsh | Hills | Mountains | Icefield |
|---|---|---|---|---|---|---|---|---|
| Temperate | 32 | 16 | 1 | 24 | 5 | 16 | 6 | 0 |
| Arid | 26 | 6 | 28 | 8 | 2 | 20 | 10 | 0 |
| Northern | 24 | 8 | 0 | 30 | 8 | 18 | 8 | 4 |
| Highland | 18 | 8 | 2 | 18 | 4 | 30 | 20 | 0 |
GR-1530 The target city count MUST be iroundDiv(landTiles, cityDensity), clamped to [2 × playerCount, 400].
GR-1540 Water depth MUST be assigned by distance from the nearest land tile: Chebyshev distance 1 → Shallows, distance 2 → Coastal Sea, distance ≥ 3 → Open Ocean. The generator MAY additionally place Shallows inland as navigable rivers (GR-600) and MAY place Shallows shoals in deeper water.
Rationale: a one-tile shallows band and a one-tile coastal band put Open Ocean exactly two tiles from any coast, which is exactly the reach of the heaviest shore bombardment in the roster. That is not a coincidence and it should not be changed casually: it is what lets a draft-3 capital ship contribute to a coastal battle without being able to sit on top of it, and it is what makes the shallows a place where small hulls are genuinely safe from big ones.
GR-1550 A River edge MUST NOT be placed on an edge where either tile is water (GR-600). Rivers MUST be generated as connected chains running from higher view terrain toward water or a map edge, and every River chain of length 4 or more MUST carry at least one Ford.
Rationale: a river with no crossing is a wall, and a wall that the generator placed is a wall nobody chose. Guaranteeing a ford per four tiles of river guarantees that every river is a defensive line with a decision in it rather than a boundary.
12.1 Start positions and fairness invariants
GR-1560 Every generated map MUST satisfy all of the following before it is accepted. A generator that cannot satisfy them MUST retry with the next PRNG state, up to 64 attempts, and MUST then fail loudly rather than emit a map that violates one.
GR-1570 Each player MUST begin with startCities cities and with the starting units 02-units-and-industry.md specifies. Start cities MUST be Cities placed by the generator, not converted neutrals.
GR-1580 The Chebyshev distance between any two players' start cities MUST be at least minStartSeparation, defaulting by tier to: Duel 14, Small 16, Standard 20, Large 26, Vast 32.
GR-1590 Every start city MUST have at least 40 land tiles within Chebyshev radius 6, of which at least 20 MUST have a foot entry cost of 4 or 5.
GR-1600 Every start city MUST have at least one other city within Chebyshev radius 14 and at least three within radius 28.
GR-1610 For any two players, the count of cities within radius 14 of their start cities MUST differ by at most 1, and the count of land tiles within radius 10 MUST differ by at most 10%.
GR-1620 Every city on the map MUST be reachable from every other city by some path using foot movement, naval movement at draft 1, or a combination of the two via Ports. A map with an unreachable city MUST be rejected.
Rationale for stating fairness as generator invariants rather than as a scoring function: a scoring function produces maps that are usually fine and occasionally indefensible, and the indefensible one is the one that decides a tournament. Hard invariants with a retry budget produce maps that are always acceptable and sometimes less interesting, which is the correct trade for a game where the map is dealt rather than chosen. The 40-land-tiles rule is the one that matters most in practice: it is what stops a player being started on a peninsula.
GR-1630 fogEnabled = false MUST make every tile Observed for every player at all times and MUST disable §10 entirely. intelligenceDecay = false MUST retain fog but MUST hold every Contact at the fidelity and position of its last observation without decay, projection or exclusion.
Rationale: both exist for teaching and for post-game analysis, and intelligenceDecay = false in particular is the setting that lets a new player learn the map and the units before learning that their map lies to them. Neither is a competitive mode and the setup screen must say so.
GR-1640 Every setup parameter MUST be recorded in the game's manifest and MUST contribute to the canonical state hash.
12.2 Regions and Landmarks
Two families of public map furniture are generated here because 14-victory.md's Tracks need places on the board to point at, and a victory system whose every condition is "take more things" is the checkbox design the direction document rejects. VC-1030 requires the map's cities to be partitioned into M named Regions, each with a named regional capital; VC-1080 and VC-1090 require L named Landmarks whose locations are public from turn 1. Both are generated once, published to everybody, never move, and confer nothing. They are what let a Track say "hold the north" or "control these three places" instead of "own 60 per cent of everything".
GR-1641 The generator MUST partition every tile of the map into M disjoint Regions. Each Region MUST carry a Region index in [0, M − 1], a published name (GR-1649), a set of tiles that is 8-connected under GR-160 and the map's topology, and a regional capital (GR-1644). Every City MUST belong to exactly the Region containing its tile, which satisfies 14-victory.md VC-1030's requirement that every city on the map fall into exactly one of M named, disjoint Regions. Region indices, boundaries, membership and capitals MUST be fixed at generation and MUST NOT change for the life of the game. The partition MUST be recorded in the game manifest (GR-1640) and MUST contribute to the canonical state hash (GR-1660).
Rationale for partitioning tiles rather than cities directly: VC-1030 asks for city membership and for publishable boundaries, and a partition of the cities alone has no boundary to draw. Partitioning tiles gives both — a line on the map every player can see, and a city membership that falls out of it — and it means publishing the partition on turn 1 discloses geography rather than city locations, which is the distinction GR-1648 rests on.
GR-1642 No rule in this specification MAY branch on Region membership, and no other specification MAY attach a movement, supply, production, combat, vision, stacking or command effect to a Region or to a regional capital. Counting Regions for victory (14-victory.md VC-1040) and drawing them (GR-1870) are the only uses. The regional capital MUST be an ordinary City in every respect (GR-820) and MUST NOT be confused with the Seat of 14-victory.md VC-1440, which is a player's own capital, is chosen by the player, and moves.
Rationale: scaffolding that also pays a bonus stops being scaffolding. A Region that granted output would make its boundary a thing to litigate rather than a thing to read, and a regional capital that defended better would hand the map's most legible objectives an additional advantage to whoever reached them first. Both must be inert, and stating it here is cheaper than discovering it in 12-economy.md's next draft.
GR-1643 M MUST be:
M = clamp( max( iroundDiv(cityCount, 6), playerCount ), 3, min(16, ifloorDiv(cityCount, 2)) )
where cityCount is the generated city count of GR-1530. GR-1500 guarantees cityCount ≥ 3 × startCities × playerCount ≥ 6, so the lower bound of the clamp never exceeds the upper. The setup parameter regionCount MUST override the formula where set, in [3, 24].
| Tier | Cities | Players | M |
|---|---|---|---|
| Duel | 8 | 2 | 3 |
| Small | 19 | 4 | 4 |
| Standard | 50 | 6 | 8 |
| Large | 120 | 8 | 16 |
| Vast | 269 | 8 | 16 |
Rationale for the shape: about six cities to a Region is the size at which a Region is a campaign rather than a raid, and the player-count term is there because M also sets Hegemony's denominator — with fewer Regions than players, the Track becomes a race for two objects and stops describing a doctrine. The cap of 16 is a legibility limit, not an arithmetic one: a map painted in twenty-five colours is a map nobody reads. Note that a 48-city, 4-player map yields M = 8, which is the reference map 14-victory.md VC-580 fixes its worked examples against.
GR-1644 The partition MUST be constructed by this procedure, drawing from the mapgen stream (03-architecture.md AR-370) after city placement (GR-1530) and start assignment (GR-1570), and before the Landmark selection of GR-1647:
- The candidate set is every City that is not a start city.
- Seed 0 MUST be drawn uniformly from the candidate set, by the bounded-draw method of 03-architecture.md AR-360.
- Seeds 1 through
M − 1MUST each be the candidate maximising the minimum Chebyshev distance (GR-170) to the seeds already chosen, ties broken by GR-110. - Every tile MUST be assigned to the Region of the nearest seed by Chebyshev distance, ties broken by the seed's lowest tile index (GR-140).
- Region indices MUST be assigned in ascending seed tile index. This is the ascending Region index 14-victory.md VC-1070 orders its sites by.
- Each Region's seed City MUST be its regional capital.
GR-1645 A generated partition MUST satisfy all of the following, and one that does not MUST be discarded and rebuilt from step 2 of GR-1644 with a fresh draw, up to 16 attempts, after which the map MUST be rejected and regenerated under GR-1560:
| Invariant | Value |
|---|---|
| Cities per Region, minimum | max(2, ifloorDiv(cityCount, 2 × M)) |
| Cities per Region, maximum | iceilDiv(3 × cityCount, 2 × M) |
Start cities per Region, where playerCount ≤ M |
at most 1 |
| Regions any player fully holds at turn 1 | 0 |
| Regions whose tile set is not 8-connected (GR-1641) | 0 |
A regional capital MUST NOT be a start city, which step 1 of GR-1644 guarantees. Capture (GR-930), abandonment (GR-970) and the elimination of a capital's owner (GR-960) MUST NOT change any Region's index, name, boundaries, membership or capital: a captured regional capital is a captured city and nothing more. A Region MUST NOT be able to lose its last city, because GR-830 fixes the city set for the life of the game and GR-960 forbids destroying a City; a specification that introduces city destruction MUST state what it does to GR-1641's partition before it does so.
Rationale for freezing the boundaries and the capital: Regions are the goalposts of a victory Track, and goalposts that move are goalposts nobody aims at. A capital that migrated to whichever city its holder valued most would also make Hegemony's progress a function of an opponent's private decisions, which is exactly the property VC-1030 asks this document to remove. The cost is that a capital can end up in the middle of somebody's empire and stay there, and that is acceptable: it is a name on a map, not an advantage.
GR-1646 A Landmark MUST be a City carrying a Landmark marker, a Landmark index in [0, L − 1] assigned in ascending city sequence number (GR-050), and the published name of GR-1649. This satisfies 14-victory.md VC-1080's requirement that a Landmark be a city with a marker and a proper name, and supplies the indices VC-1180 draws its Lit rotations from and the ordering VC-1130 lists its sites in. The marker MUST confer nothing: no production, defence, vision, stacking, supply, command or movement term anywhere in the specification set MAY read it, and the generator MUST NOT place an Installation on a tile because it is a Landmark. L MUST be odd and MUST default by generated city count:
cityCount |
L |
|---|---|
| under 16 | 3 |
| 16 to 79 | 5 |
| 80 to 199 | 7 |
| 200 and above | 9 |
giving 5 on a Standard map and 7 on a Large one, as VC-1080 requires. The setup parameter landmarkCount MUST override the default where set, MUST be odd, and MUST be in [3, 15]; 14-victory.md VC-1100 derives the Keys threshold as (L + 1) / 2 and assumes an odd L.
Rationale for the marker conferring nothing, given that VC-1080 speaks of "the defensive terrain advantage the map generator assigns it": the advantage is assigned by where the generator puts the Landmark, not by the marker. GR-1647 seeds Landmarks onto cities that already stand on the best defensive ground the terrain set allows, so a Landmark is hard to take because it is on a hill, which every player can see and plan against. A marker that added its own multiplier would be a snowball vector — the player who takes the first Landmark would find the second one cheaper to hold — and it would be invisible on the map, which is worse.
GR-1647 Landmarks MUST be selected by this procedure, drawing from the mapgen stream, after GR-1644 and before the victory subsystem's generation-time draws of 14-victory.md VC-170:
- The eligible set is every City that is neither a start city nor a regional capital and whose terrain
defence(GR-350) is at least 1250 — under GR-850's placement restriction, Hills or Woods. Where fewer thanLsuch cities exist, the remaining non-start, non-capital cities MUST be added in descending terraindefence, ties by GR-110, until the set holdsL. Where the map still cannot supplyL, regional capitals MUST be admitted in ascending Region index until it does, and the overlap MUST be recorded in the manifest. - Landmark 0 MUST be drawn uniformly from the eligible set (03-architecture.md AR-360).
- Landmarks 1 through
L − 1MUST each be the eligible city maximising the minimum Chebyshev distance to the Landmarks already chosen, ties by GR-110.
The result MUST satisfy all of the following, and one that does not MUST be rebuilt from step 2 with a fresh draw, up to 16 attempts, after which the map MUST be rejected and regenerated under GR-1560:
| Invariant | Value |
|---|---|
| Minimum Chebyshev distance between any two Landmarks | S = max(6, ifloorDiv(min(width, height), L + 1)) |
| Minimum distance from a Landmark to any start city | ifloorDiv(minStartSeparation, 2) |
| Maximum difference between any two players in the distance from their start city to their nearest Landmark | iceilDiv(minStartSeparation, 4) |
Rationale: the first invariant stops the whole set clustering in one quarter of the map, which would make the Keys a single campaign rather than three; S is 12 tiles on a Standard map and 16 on a Vast one. The second and third are the fairness rules that matter — a Landmark inside somebody's opening radius is a free Key, and a player forty tiles from the nearest one while a rival is eight tiles away is playing a different game. They are stated as generator invariants with a retry budget rather than as a scoring term for the reason GR-1560 gives.
GR-1648 Exactly the following MUST be public to every player from turn 1, independent of fog, of the Terrain Record and of the Contact Register, satisfying 14-victory.md VC-1030 and VC-1090:
| Published | Not published |
|---|---|
M, and every Region's index, name and tile set |
The terrain of any tile in it |
| The number of Cities in each Region | Where those Cities are |
| Each regional capital's name and tile | Its owner, garrison, development, production or Installations |
L, and every Landmark's index, name and tile |
Its owner, garrison, development, production or Installations |
A tile published by this requirement MUST NOT thereby become Explored (GR-1130), MUST NOT gain an observation turn (GR-1140), MUST NOT enter the Terrain Record (GR-1160) and MUST NOT create a Contact (GR-1200). Ownership of a published City MUST reach a player only by observation (GR-1290) or by the announcement of GR-1430, both of which require the player to have explored the tile. This is the sole exception to GR-1180, and no other public map fact MAY be added to it without amending that requirement.
Rationale for publishing the city count per Region and not the city locations: Hegemony asks a player to hold every city of a Region, and a player who cannot count the denominator cannot tell whether they are one city short or five. The count is already half-public — 14-victory.md VC-920 publishes MAP_CITIES from turn 1 — and knowing that a Region holds seven cities while you have found four tells you to keep looking, which is a reason to scout rather than a substitute for it. Locations stay hidden because they are the thing scouting is for.
GR-1649 Region names, regional capital names and Landmark names MUST be derived positionally, exactly as GR-840 derives city names, from the game seed and the index being named — the Region index for a Region, the City's sequence number for a capital or a Landmark. They MUST NOT consume a PRNG stream, which is the construction 03-architecture.md AR-370 requires of city names and for the same reason. The pools MUST be:
| Pool | Minimum entries | Used for |
|---|---|---|
regionNames |
64 | Region names, drawn without repetition within a map |
landmarkNames |
64 | The city name of every Landmark, in place of the ordinary city pool |
| the city name pool of GR-840 | as GR-840 requires | every other City, regional capitals included |
Names MUST be unique across the map (GR-840); a collision MUST be resolved by advancing to the next unused entry in ascending pool index, and an exhausted pool MUST be extended by appending a deterministic ordinal. All three pools MUST be name-list assets under 07-modding-content.md MOD-490 and MUST be presentation-only: replacing a pool MUST change what places are called and nothing else, because the simulation addresses a Region by its index and a Landmark by its City's sequence number.
Rationale for a separate Landmark pool: the L Landmark names are the only city names every player reads on turn 1, and they are the names the whole game will be argued in. Drawing them from the ordinary pool would make the map's most important places sound like its least important ones. It is also the one piece of this section that is real content work rather than code — two pools of sixty-four names each — and naming the requirement is how that work gets scheduled rather than discovered.
Worked, non-normative, on 14-victory.md VC-580's reference map — 48 cities, 4 players, Standard tier: M = clamp(max(iroundDiv(48,6), 4), 3, min(16, 24)) = 8 Regions and L = 5 Landmarks, matching that document's fixture. Each Region holds between max(2, ifloorDiv(48,16)) = 3 and iceilDiv(144,16) = 9 cities. Landmarks sit at least max(6, ifloorDiv(72, 6)) = 12 tiles apart and at least ifloorDiv(20, 2) = 10 tiles from any start city, and no two players' nearest Landmarks differ by more than iceilDiv(20, 4) = 5 tiles. Thirteen of the map's forty-eight cities — eight capitals and five Landmarks — are named and located for everybody on turn 1; the other thirty-five have to be found.
13. Determinism obligations specific to this document
GR-1650 The following are the determinism hazards this specification introduces. Each MUST be covered by a test naming its requirement ID.
| # | Hazard | Requirement |
|---|---|---|
| 1 | Wrapped displacement at exactly half the map width or height | GR-200 |
| 2 | Sight-ray candidate sets differing by iteration or rounding | GR-1010, GR-1020 |
| 3 | Line-of-sight asymmetry introduced by an optimisation | GR-1030 |
| 4 | Incremental visibility diverging from full recomputation | GR-1100 |
| 5 | Terrain defence composed in a different order | GR-380 |
| 6 | Diagonal river detection depending on which corner edge is examined first | GR-480 |
| 7 | Contact decay evaluated at a different point in the turn | GR-1300 |
| 8 | Exclusion sets derived from a mutable per-contact store rather than the observation-turn map | GR-1350 |
| 9 | Map generation consuming PRNG draws in a platform-dependent order | GR-1470 |
| 10 | Stacking checks that depend on the order units are stored in a tile | GR-720, GR-750 |
| 11 | Neighbour enumeration in a different order | GR-160 |
| 12 | Team vision folded into a player's own observation set rather than unioned at read time | GR-1110, GR-040 |
| 13 | Contact Register pruning applied at a different point or in a different order | GR-1230 |
| 14 | Region seed selection, Voronoi assignment, or Region indexing resolving a tie differently | GR-1644 |
| 15 | Landmark selection order, or a Region or Landmark name drawn from a PRNG stream rather than positionally | GR-1647, GR-1649 |
GR-1660 The Terrain Record, the Contact Register and every tile's observation turn MUST be authoritative game state and MUST contribute to the canonical state hash.
Rationale: it is tempting to treat a player's knowledge as derived and recomputable, and it is not — GR-1350's exclusions and GR-1340's tracks both depend on the history of what was observed and when, which cannot be reconstructed from the current world state. Knowledge is state. Hashing it is also the only way a desync in the fog code trips in CI rather than in a player's game.
GR-1670 Perceptible events (§11) MUST be emitted deterministically by the core and MUST be covered by the advisory stream hash of 13-command.md CM-190 rather than by the rules hash.
GR-1680 Contact decay MUST be evaluated exactly once per turn, at the start of the Orders phase, after all end-of-turn bookkeeping. It MUST NOT be evaluated during the Cascade.
Rationale: decay evaluated mid-Cascade would make a Contact's fidelity depend on the activation index at which it was read, which is precisely the class of ordering dependency 10-turn-model.md freezes the initiative order to avoid.
GR-1690 No rule in this document MAY consume a PRNG draw after setup. Terrain, movement, vision, fog and intelligence MUST be entirely deterministic functions of state. Only combat resolution consumes randomness.
14. Contracts on other documents
Obligations this specification places on subsystems it does not own, recorded so that a change on either side is detectable.
GR-1700 02-units-and-industry.md MUST supply, per unit class: move, vision, movement class (GR-520), domain, draft for naval classes (GR-590), slots and capacity, and the capability flags this document reads by name: capture, zoc, submerged, sonar, airbase, airdrop, assaultLanding, expendable, and recon (GR-1270), which is a new flag this document requires and the source proposal's flag vocabulary does not yet contain.
GR-1710 02-units-and-industry.md MUST own the endurance counter and the consequence of exhausting it; this document owns only what counts as an air base (GR-620).
GR-1720 02-units-and-industry.md MUST nominate the immobile defending class used by neutralDefence (GR-990), or MUST record that the option ships unsupported.
GR-1730 02-units-and-industry.md MUST specify the capture reset of GR-930 step 4 — what happens to a captured city's production queue, accumulated progress and development level — and this document MUST NOT duplicate those values.
GR-1740 11-combat.md MUST read the terrain defence value of GR-380 as a single per-mille integer and MUST NOT read individual terrain attributes. It MUST compose the city term, the entrenchment term and every unit-derived term separately, and MUST NOT re-apply any term GR-380 has already applied.
GR-1750 11-combat.md MUST own advance-after-combat, and MUST state whether a victorious attacker occupies the defender's tile, because GR-950 keys the capture procedure to that answer.
GR-1760 11-combat.md MUST own bridge destruction (GR-500) and the strength prediction of GR-1370.
GR-1770 10-turn-model.md's worked example assumes a stacking limit of 3. The normative limit is GR-720 — 1 in the open, 2 in a Fort, 6 in a city — and the example needs restating against it. This document holds that a limit of 1 in the open is load-bearing for the roster tuning of 02-units-and-industry.md and for frontage as a resource, and asks that any change be argued against GR-720's rationale rather than transcribed from a worked example.
GR-1780 10-turn-model.md MUST own: when during an activation movement, capture and reaction occur; the Stance vocabulary GR-1310 reads; the per-activation visibility recomputation GR-1100 requires; and the timing of embarkation and landing (GR-660).
GR-1790 12-economy.md MUST own city development, integration, supply and repair rates; this document owns the map objects those rates apply to. Where 12-economy.md needs a distance, it MUST be Chebyshev (GR-170). Where it modifies a city's stacking limit or vision radius, it MUST do so within the clamps of GR-780 and GR-860.
GR-1800 12-economy.md and this document MUST reconcile the terms Works (an economic rate) and Installation (a map feature). They are currently distinct, GR-410 says so, and if 12-economy.md intends tile-level constructions they MUST be Installations.
GR-1810 13-command.md CM-140 assumes an unrevealed tile is routed as passable at the cheapest cost the unit's class pays. Under GR-290 that cheapest cost is 4 for every land class and 4 for naval, so CM-140 resolves to a constant of 4 MP per tile, and CM-1510's integer terrain costs are the GR-290 table.
GR-1820 13-command.md's Survey posture (CM-490 to CM-520) terminates when no reachable unrevealed tile remains, which means it has no late-game work. This document supplies observation age (GR-1170) and the Contact Register (§10) as the data a patrol or reconnaissance posture would need, and asks 13-command.md to consider a variant keyed on staleness rather than on unexplored terrain. This is the single largest interaction between the two documents and it is currently unclaimed.
GR-1830 13-command.md CM-160's estimated flag MUST be sourced from GR-1370 and MUST NOT be computed independently.
GR-1840 14-victory.md MUST count cities from ownership, which GR-1430 makes public, and MUST NOT require any victory track to be computed from information a player cannot see. Where a track depends on a hidden quantity, 14-victory.md MUST state what each player is told about it.
GR-1845 14-victory.md MUST source Regions and Landmarks from §12.2 and MUST NOT define, place or rename either. This document supplies: M named, disjoint Regions partitioning every city on the map, fixed for the game, each with a named regional capital (VC-1030), indexed as VC-1070 orders them; L Landmarks with L odd, each a City carrying a marker, a proper name and the defensive terrain its site is chosen for (VC-1080), indexed in [0, L − 1] for the rotation draw of VC-1180 and ordered by city sequence number for VC-1130; and the turn-1 publication of both, without their owners or garrisons (VC-1090, GR-1648). It supplies no mechanical effect for either (GR-1642, GR-1646): a Track MUST NOT assume a Landmark or a regional capital is any easier or harder to hold than its terrain and its garrison make it.
GR-1850 14-victory.md MUST own what a Team wins and how a track is scored across a team's members (GR-040). This document fixes only that teams are fixed at setup, share no ownership, and optionally share observation.
GR-1860 02-units-and-industry.md and 12-economy.md MUST NOT assume that a player may found a new city. GR-830 fixes the city set at setup, and any economic design that treats settlement as a growth path contradicts it and must be argued here rather than assumed there.
GR-1870 04-ui-ux.md MUST implement GR-1190: remembered contents rendered distinctly from observed contents, with age and fidelity shown, and Contact uncertainty areas (GR-1330) drawn as areas rather than as icons on a tile. It MUST additionally present the public map facts of GR-1648 — Region boundaries and names, regional capitals, and Landmarks — from turn 1, independent of fog, and distinctly from anything the player has actually observed.
GR-1880 03-architecture.md AR-750's pathfinding tiebreak, AR-710's tile storage order and AR-740's incremental fog MUST all use the tile index of GR-140.
Open questions
Is Chebyshev the right metric, given GR-540? The single-metric argument is strong and the diagonal-column artefact is real. The measurable question is whether players' armies visibly deform into diagonal lines in playtest, and the cheapest counter-experiment is an octile movement cost (4 orthogonal, 6 diagonal) with Chebyshev retained for every radius — which is inconsistent but may play better than it reads. Settle it with a build, not an argument.
Is a Surface stacking limit of 1 correct, or is 2 better? A limit of 1 gives frontage its meaning and matches the roster tuning. A limit of 2 would let a gun travel with its infantry rather than beside it, which is how combined arms actually works and would remove a great deal of fiddly adjacency management. The cost is that every "hits" value in the roster comes down about 15% and the whole balance surface moves. This is the most consequential open question in the document.
Should a captured Installation be usable immediately? GR-930 transfers Forts, Roads and Airfields on capture with no delay. An enemy airfield that can base your aircraft the turn you take it may be too generous, and a delay would give Engineers something to do behind an advance. Left immediate because a delay is one more timer for a player to track.
Should the
reconcapability be a flag or a derived property? GR-1700 asks 02-units-and-industry.md for a new flag. The alternative is to derive it — say, any class withvision ≥ 4andmove ≥ 4— which needs no schema change but makes the reconnaissance role an accident of two other numbers rather than a design decision. Leaning toward the flag.Does the intelligence model need a deception layer? Everything in §10 degrades the truth; nothing lets a player plant a falsehood. Decoy formations, false radio traffic and feint marches are the obvious next step and they would make the Contact Register a thing a player attacks rather than merely a thing that decays. They also risk making the map unreadable and belong at least partly to 13-command.md. Deliberately out of scope for v1, recorded so it is not lost.
Is the decay interval right at 3 turns for land? Three turns to lose a level of fidelity means a land Contact runs from full Assessment to dropped in about twelve turns, which is roughly one operational cycle. It is a guess. The measurement that would settle it is the fraction of attacks launched on
estimatedpredictions: if that number is very low, players are re-scouting constantly and decay is too fast; if it is very high, intelligence is not worth gathering and decay is too slow.Should perceptible events (§11) include production? A city completing a large unit is a plausible thing to notice at a distance, and it would give strategic bombing a target that announces itself. It was left out because it would leak production tempo to anyone with a picket anywhere nearby, which is a great deal of information for no risk.
How should a Contact behave when its subject is carried? A unit that boards a transport currently keeps its own Contact, which then decays in place while the transport sails away. Merging cargo Contacts into their carrier's would be more honest and would make convoy interception genuinely uncertain, but it requires the observer to have known the unit boarded — which is itself an observation with a fidelity of its own, and the recursion needs a stopping rule.
Is
neutralDefence: noneright for multiplayer specifically? The land-grab opening is excellent in a two- to four-player game and may be a pure speed contest at eight players on a Vast map, where nobody meets anybody for forty turns. A per-tier default —noneup to Standard,scaledabove it — is the obvious compromise and is deliberately not taken here, because a setting whose default changes with map size is a setting players will be surprised by.Are
MandLright, and should a Region be a Voronoi cell at all? GR-1643 produces 8 Regions on the reference map because that is what 14-victory.md VC-580's fixture assumes, and the rest of the curve is fitted to that one point rather than measured. The deeper question is the construction: GR-1644 draws Region boundaries around cities, so a Region's shape is an artefact of where the generator happened to put them. A partition seeded on the map's own geography — watersheds, mountain chains, coastlines — would read enormously better, because "everything north of the range" is a sentence a player understands without looking at a legend, and it would cost the generator a real terrain analysis it does not currently do. Worth building if Hegemony survives playtest.