Skip to main content

Realm Ranks and Polity

This page owns Valenar's polity ladder above the settlement layer.

Ladder

  • Settlement
  • Banner Network
  • Province
  • Crown
  • late-game reclamation projects operating at realm scale

Role

The polity ladder explains when the game stops being about one site or one settlement and becomes about administration, law, delegation, and large-scale military or civic work.

Current canon does not support one single Realm birth moment. The player-facing polity emerges through a ladder of expanding holdings, routes, obligations, authority, and administration.

Progression Framing

  • Act 2 begins the ladder with the first Outpost-tier Settlement.
  • Act 3 broadens that foothold into stable settlement-scale play.
  • Act 4 turns one holding into a Banner Network; Force becomes the canonical mobile actor for inter-Territory defense, escort, and patrol.
  • Act 5 formalizes Province rule; introduces ProvinceDefensePlans, DefenseZones, and standing Forces.
  • Act 6 reaches Crown-scale rule; introduces Fronts grouping multiple ProvinceDefensePlans under named Campaign Goals.
  • Later last-act reclamation projects use that Crown-scale capacity.

Design Rules

  • Avoid single-trigger "Realm birth" framing unless a stronger trigger is later committed.
  • Founding the Core does not create a player-facing Realm.
  • The first Outpost is the first settlement rung, not the full polity system.
  • Settlement, Banner Network, Province, and Crown are different rungs in the same polity ladder.
  • Province and Crown layers should change what kinds of questions the player is answering, not only add bigger numbers.
  • Governance must remain grounded in holdings, routes, people, and pressure the map already made real.

PolityRank Enum

The polity ladder's runtime carrier is committed by ad-0009: a singleton scope Realm (one row per saga, created at campaign start, retired at campaign end) carries the current ladder rung on a Base channel named PolityRank (working name — promotion to committed metadata is deferred to Wave 5a per ad-0009:172).

PolityRank enum values (working names; same Wave 5a deferral applies):

ValueNameMeaning
0OutpostThe Realm is anchored on a single Settlement (or scattered Settlements without Route coverage); the player has a foothold but not a connected polity
1BannerNetworkThe Realm covers at least two Settlements connected by Route coverage; standing Forces become the canonical mobile actor
2ProvinceAt least one Settlement under the Realm carries the ProvinceCapital SettlementRole; ProvinceDefensePlans and DefenseZones unlock
3CrownAt least two Provinces under the Realm carry ProvinceCapitals; Fronts unlock and grouped multi-Province campaign authority becomes available

Dual-meaning callout (per ad-0009:188-198). Two PolityRank value names collide with existing committed terms and require glossary disambiguation:

  • Outpost — also a per-Settlement size value on the existing Settlement.Stage ladder (the smallest population rung). The Realm-scope PolityRank == Outpost is a Realm-scale authority statement, not a per-Settlement population statement. Both meanings remain committed.
  • Province — also the existing geographic Province scope (a per-Province row on the strategic map). The Realm-scope PolityRank == Province is a Realm-scale authority statement, not a geographic-Province identity. Both meanings remain committed; the glossary must call out the dual usage.

Rank Transitions

Ladder transitions are driven by Realm-scale predicates evaluated against the Realm scope's view of its holdings; no single Settlement crossing a population threshold can advance the ladder.

TransitionPredicateCitation
Outpost -> BannerNetworkRealm.CoveredSettlements.Count >= Config.Realm.BannerNetworkSettlementThreshold && RouteCoverage(Realm)ad-0009:76-80
BannerNetwork -> ProvinceRealm.Settlements.Any(s => s.SettlementRole == ProvinceCapital)ad-0009:81-84
Province -> CrownRealm.Provinces.Count(p => p.HasProvinceCapital) >= Config.Realm.CrownProvinceThreshold (default 2, world-size parameterized)ad-0009:85-87

Route-coverage predicate (authored inline per the resolver R13 explicit Wave 3a authorization, citing ad-0009:76-80). RouteCoverage(Realm) holds when every unordered pair of Realm.CoveredSettlements has at least one Route path between them with no Routes in the Severed state along that path. The predicate is a connectivity check over the live Route graph filtered to non-Severed Routes; the Realm's CoveredSettlements set is the vertex set, and a path's existence under the filter satisfies the pair. If any pair is unreachable under the filter, RouteCoverage(Realm) is false and the transition does not fire.

Regressions are deferred to Wave 5a runtime-backing closure (<deferred-to-Wave-5a-runtime-backing>); design intent is recorded so the runtime wave has the shape to lower:

TransitionPredicate shapeDesign intent
BannerNetwork -> Outpost<deferred-to-Wave-5a-runtime-backing>Realm regression when Route coverage fails (e.g., the connecting Route is Severed and no alternative path exists) or when the covered-Settlements count falls below threshold; predicate shape deferred per ad-0009:172
Province -> BannerNetwork<deferred-to-Wave-5a-runtime-backing>Realm regression on loss of every ProvinceCapital (e.g., Province capital destroyed, demoted, or captured); predicate shape deferred per ad-0009:172
Crown -> Province<deferred-to-Wave-5a-runtime-backing>Realm regression on Crown-scale catastrophe (e.g., loss of all but one ProvinceCapital); predicate shape deferred per ad-0009:172

Capability Gates

Capability gates are declared against Realm.PolityRank, not against per-Settlement state or Act number. The Act-progression framing in this doc's "Progression Framing" section remains the design-pacing description; the runtime-backing form is the PolityRank gate. Both forms must agree.

  • DefenseZones unlock at Realm.PolityRank >= Province (per ad-0009:89-92). See gd-defense-zones.md.
  • Fronts unlock at Realm.PolityRank == Crown (per ad-0009:89-92). See gd-fronts.md.

Stage Vocabulary Overload Follow-Up

Per ad-0009:98-105 and ad-0009:219-230, the noun "Stage" currently carries two different meanings in committed Valenar docs: Settlement.Stage (per-Settlement population size on the 0..VII ladder authored in gd-settlements-and-outposts.md) and Act-stage / Act-progression "stage" wording (the 0..7 Act ladder in the ../acts/ tree). PolityRank is orthogonal to both, but the surviving Stage overload remains a documentation hazard.

This overload is flagged here as a follow-up rename concern. It is NOT executed in this wave: the no-fallback redesign-propagation rule and the file-rename stop in .claude/rules/orchestrator-mode.md § Source freshness and no-fallback redesign propagation require a separate deliberate migration prompt naming exact source and destination paths (the gd-settlements-and-outposts.md doc, the ../acts/gd-act-*.md docs, the Settlement.Stage Generated declarations, and the React client UI labels). Until that migration prompt lands, Settlement.Stage remains the per-Settlement population field and Act-ladder docs continue to use "act" rather than "stage" as the canonical ladder noun.

Runtime Backing Status

Status: contract-only.

  • Host/runtime owner: proposed legacy/v1/examples/valenar/Host/Data/RealmData.cs (singleton Realm host data) and legacy/v1/examples/valenar/Host/Systems/RealmRankSystem.cs (evaluates ladder predicates, drives PolityRank transitions). Neither file exists today.
  • Generated/.secs owner: proposed legacy/v1/examples/valenar/Content/realm/scopes.secs (declares scope Realm) and legacy/v1/examples/valenar/Content/realm/systems/rank_transition.secs (declares the rank-transition system body), with matching Generated stand-ins under legacy/v1/examples/valenar/Generated/. Neither file exists today.
  • Read-model/UI owner: proposed legacy/v1/examples/valenar/Host/ReadModels/RealmReadModel.cs. UI surfaces consuming Realm.PolityRank: the Crown-scale strategic map polity overlay and the Settlement-screen tier indicator that names the current Realm rung.
  • Tests: <deferred-to-Wave-5a-runtime-backing>.
  • Known gaps: the RouteCoverage(Realm) runtime predicate is not implemented (graph traversal over filtered Routes); the regression predicates (BannerNetwork -> Outpost, Province -> BannerNetwork, Crown -> Province) are not committed at the predicate-shape level; the on_action transition labels (working names PolityRankAdvanced(newRank) and PolityRankRegressed(newRank)) are not promoted to committed metadata.
  • Illegal fallback behavior: no Settlement.Stage value may stand in for Realm.PolityRank (no "promote first Settlement's Stage" path). No tag-set may stand in for the PolityRank enum. No silent default to Outpost when the channel is unread. No silent advance based on Settlement count alone without RouteCoverage(Realm) returning true. Attempting a rank transition without predicate evaluation must throw InvalidStateException at the runtime boundary; no DefenseZone or Front authoring path may unlock without Realm.PolityRank reading the correct value through the 6-phase channel pipeline.
  • Next closure wave: Wave 5a (parallel with ad-0008 labor + pressure + storyBias closure) authors the host data, the scope, the channels, the host system, the on_action transition labels, the regression predicates, and the matching Generated stand-ins.