Skip to main content

The Campaign (bounded ~100-turn shape, 3 acts, decision-resolved)

The Campaign (bounded ~100-turn shape, 3 acts, decision-resolved)

Status: IMPLEMENTED 2026-07-17 (Phase 2 of the vision build path). The campaign SHAPE layer plus the win-condition earnability + pacing fixes that Phase 2 owns.

Last updated: September 15, 2026

Blood Lineage — The Campaign (bounded ~100-turn shape, 3 acts, decision-resolved)

Status: IMPLEMENTED 2026-07-17 (Phase 2 of the vision build path). The campaign SHAPE layer plus the win-condition earnability + pacing fixes that Phase 2 owns.

Parent: index.md. Governed by: vision.md § "Mode 1 — The Campaign" (the north-star spec this doc implements). Bound by empire-4x-layer.md § "The seven rules every new 4X surface MUST obey" (the voice-memory budget). Composes with the shipped Chronicle (empire-4x-layer.md SE-3) and the Advisor (advisor.md, which already frames by Act). Measured against pacing.md (the ~100-turn earnability bands).

Why this doc exists

vision.md gives the single-player game a SHAPE: a bounded ~100-turn campaign with a beginning (Founding), a rising struggle (Ascendance), and a decision-authored resolution (Reckoning + Twilight-of-the-Age). This is a framing layer over the existing turn pipeline + Chronicle — it reuses , , and the emergent-story beats; it does not rewrite them. The completion data validates ~100 turns as the natural length (dedicated players finish ~turn 100+; see vision.md § evidence base). Phase 2 also OWNS the win-condition earnability fixes the pacing audit surfaced (pacing.md), so a chosen victory path is genuinely reachable near that target.

1 — The three acts (a spine over the existing turn loop)

The acts are pacing and narrative framing over the same endTurn() loop, not new mechanics. They are a pure function of LineageWorld.getCurrentTurn() — no new persisted state. The single source of truth is the CampaignAct enum (llitd.model.lineage.CampaignAct), which both (act-transition announcements) and (act-aware opening frame, advisor.md) read.

Act Turns Feel What changes
I — Founding 1–25 Guided, forgiving The Advisor is prominent (advisor.md onboarding hint fires turns 1–3); factions are cordial. The act the turn-1–5 churn-cliff fixes target.
II — Ascendance 26–70 The open struggle Factions actively pursue their agendas. This is the meat of the campaign.
III — Reckoning 71+ Escalating, decisive The drive to resolution: secure a victory path before the strongest rival, or reach the Twilight.

Announced on crossing. When endTurn() advances the turn across an act boundary (25→26, 70→71), the new act is announced in one short voice line (voice-memory rule 1 — a push the player is present for). It is never a wall the player must remember.

Re-readable on demand. The campaign / what act / my situation pull-screen (, LINEAGE_VIEW key CAMPAIGN) reads the current act, the turns remaining until the Twilight reckoning, the player's tracked path so far, and ends with an actionable handoff (voice-memory rules 2, 5, 7). The game holds the state; the player asks (empire-4x-layer.md thesis).

Act-aware framing today; deeper act pressure is a documented follow-up. The advisor prominence (Act I) and the announce + re-read framing are implemented now. Deeper act-gated faction pressure (e.g. raising AI aggression in Act III) is deliberately left as a follow-up rather than shipped in this pass: it touches the AI-balance loop () and is not hermetically testable, and vision.md is explicit that the campaign is a framing layer that must "reuse, do not rewrite." The CampaignAct enum is the seam a later, measured AI-pressure tune plugs into without touching the shape logic.

2 — The Century (~100-turn soft target)

The campaign targets ~100 turns — a soft target, not a wall.

  • A chosen victory ends it early, in triumph, at any turn. Reaching any of the five victory paths (progression.md) records the victory and offers the Empire-tier rule-on/rest choice exactly as today — the campaign shape does not change that. It only ADDS a resolution when no one has won by the target turn.
  • CENTURY_TARGET_TURN = 100 is the default reckoning turn. It is read from the world's configurable length target (LineageWorld.worldSettings["campaignLengthTarget"], defaulting to 100), so difficulty/scenario length can scale it — a Short Reign ≈ 50, an Age of Legends ≈ 150 — without a code change (vision.md 1a/1d). The difficulty selector that sets it is a future vision phase; the target is soft and scalable today via that setting.
  • The reckoning only fires for a single-player campaign world (worldType SINGLE_PLAYER or null), never in the Eternal Realm (Global, which has no ending) or once the world is in Empire tier.

3 — Twilight of the Age (the turn-~100 reckoning)

When endTurn() advances to currentTurn >= campaignLengthTarget with no victor recorded and the world not completed / not empire-tier, the Twilight of the Age reckoning resolves the campaign by scoring every realm on the player's accumulated decisions and narrating which dynasty history remembers as ascendant. Logic lives in .

Realm Standing score (reuses numbers the player already has — voice-memory rule 3)

Each active realm is scored on its accumulated campaign decisions. No new number is minted; every term is an existing field the player already earns and can already read:

Term Source Weight
Territory owned-territory count ×10
Gold gold resource (÷100) ×1 per 100
Alliances active ALLIANCE/MILITARY_ALLIANCE treaties ×40
Tech discovered legendary techs ×30
Dynasty prestige getDynastyPrestige() ×1
Army total units across armies ×2
Faction standing morale + stability (the realm's health proxies) ×1 each

The highest-scoring realm is the ascendant dynasty. Weights are chosen so no single term runs away and a balanced player who pursued several paths partway is competitive — matching pacing.md's intent that a non-specialist reaches the Twilight without any one path having run away early.

Resolution

  • Player is ascendant → the campaign ends in the player's triumph. The NG+ earn hook fires (dynastyAscensionService.onVictory then applyVictory with a synthetic TWILIGHT victory, so the win banks New Game Plus exactly like a chosen victory), the world completes, and the decision-authored epilogue (below) narrates how the ascendant dynasty is remembered.
  • A rival is ascendant → the campaign ends in that rival's ascendancy (applyVictory, TWILIGHT), and the player hears the epilogue of how their own dynasty is remembered by their tracked path, plus which house history crowned.

The Twilight completes the campaign (it does not offer Empire-tier rule-on) — that is the whole point of a bounded campaign: it resolves. The chosen-victory paths remain the way to earn the Empire-tier continuation.

4 — Resolution authored by decisions (the path + epilogue)

The campaign's ending is not a bare "you won / you lost" — it is an epilogue that narrates how the dynasty is remembered, shaped by the player's path. The path is derived on demand from the same signals the five victory conditions already read (voice-memory rule 3 — no new persisted tracker):

Path Derived from Remembered as
Conqueror dominant territory + army banners over the realm, won by the sword
Diplomat dominant alliance count a web of alliances, the realm bound by treaty
Steward dominant gold / economy overflowing treasuries, wealth over war
Archmage dominant magic techs + mana arcane mastery, the Time-Stop age
Dynast dominant dynasty prestige / generations an enduring bloodline across generations

.derivePath(kingdom, mapData) normalizes the player's progress toward each victory condition (plus dynasty prestige) and returns the dominant path; ties resolve to a stable priority (Conqueror → Diplomat → Steward → Archmage → Dynast). The epilogue text interpolates the dynasty name so it is the player's own story, and it composes with the shipped Chronicle — the epilogue references the number of chapters the dynasty's chronicle holds (the fired beats, empire-4x-layer.md SE-3), pointing the player at chronicle to re-read the full story.

The epilogue fires on a chosen victory too. When the player wins by conquest, gold, alliance, tech, or magic, a one-line path-epilogue clause (keyed off the winning victoryType, which is the path) precedes the Empire-tier rule-on/rest offer — so "winning by conquest, by gold, by alliance, or by the Twilight reckoning each tells a different story" (vision.md 1c) is true across every ending.

5 — Win-condition earnability + pacing (Phase-2 owned, from pacing.md)

Phase 2 owns tuning each victory path toward the ~100-turn band (pacing.md). Fixes landed this pass:

# Path Was Fix Result
1 MAGICAL UNEARNABLE — TIME_STOP costs 200 mana, maxMana flat 100 maxMana is now computed from the magic-tech track (): base 100 → BASIC_MAGIC 125 → TIME_MAGIC 150 → ADVANCED_MAGIC 175 → LEGENDARY_MAGIC 250. getOrCreateManaPool recomputes the cap every access (so researching LEGENDARY_MAGIC raises it live) and clamps current mana to it. Global-mode casts go through / , which use the same helper. A legendary-magic kingdom banks 200 mana and casts TIME_STOP to win. Earnable.
2 TECHNOLOGICAL ~150–200 turns at 10 progress/turn raised 10 → 15 (a proportional lift across the whole tree; a single named constant). A committed tech build with research buildings (+8/turn) now finishes the ~1690-progress legendary chain near the target. ~90–110 turns committed. In band.
3 DOMINATION denominator grew as the map was explored () Already fixed before this pass — LineageWorld.dominationTerritoryBaseline snapshots the territory count the first time DOMINATION is evaluated, so frontier-tile materialization never moves the goalpost (report group 248, ). Stable denominator. Documented here; no new change.
4 DIPLOMATIC 3 alliances risked winning too fast once diplomacy worked A hold gate in : an alliance counts toward the 3 only once it has been held for DIPLOMATIC_HOLD_TURNS = 5 turns (currentTurn − treaty.signedTurn >= 5; a null signed-turn counts as long-held). Stateless — reads the treaty's existing signedTurn. 3 alliances must be sustained, not just formed. No instant win.

The empirical beeline audit (pacing.md § The empirical audit) re-runs on target:'local' after this pass; the tuned bands are recorded in pacing.md's scorecard. The setDiscoveredTechnologies / setMana harness seeds (below) let the audit drive the MAGICAL and TECHNOLOGICAL beelines it previously could not.

6 — Test harness seeds (for hermetic campaign/earnability tests)

The scenario/play_game harness (LineageUiPlayEntry.PlayRequest, honored in LineageWorldInitializer.applyCharacterModifications) gains two seeds so the tech-gated and mana-gated victory paths are hermetically seedable (the precondition the hermetic-scenario-tests rule requires):

  • setDiscoveredTechnologies (List<String>) — seeds LineageKingdom.discoveredTechnologies.
  • setMana (Long) — seeds the kingdom mana resource; the mana pool initializes current mana from it, clamped to the tech-derived maxMana. Because the clamp respects the cap, a MAGICAL scenario test is a genuine RED-before / GREEN-after of the cap fix (before: min(200,100)=100, cast fails; after: min(200,250)=200, cast succeeds).

Regression shape (hermetic)

Per hermetic-scenario-tests.md, each surface seeds its trigger state and asserts STABLE STRUCTURE:

Surface scenario_test (seedable) JUnit (deep state)
Act transitions setTurn:25; end turn → Act II announced; setTurn:70; end turn → Act III announced band boundaries
Twilight reckoning setTurn:99; end turn → Twilight fires, resolves, epilogue narrated scoring + path derivation
Epilogue path Twilight test asserts a path-flavored epilogue clause per path
Campaign screen campaign / what act → reads act + turns-to-Twilight + handoff —
MAGICAL earnable setDiscoveredTechnologies:[…LEGENDARY_MAGIC]; setMana:200; cast time stop; end turn → victory cap ladder + cast; MAGICAL fires on a COMPLETED TIME_STOP
DIPLOMATIC gate — (treaty state not scenario-seedable) — 3 fresh alliances do NOT win; 3 held ≥5 turns DO
TECH rate — LineageResearchConstantsTest.BASE_PROGRESS_PER_TURN == 15
  • vision.md — the north-star spec this doc implements (§ Mode 1 — The Campaign).
  • pacing.md — the win-condition earnability bands + the empirical audit this pass feeds.
  • empire-4x-layer.md — the seven voice-memory rules; the shipped Chronicle the epilogue composes with.
  • advisor.md — the Steward, which already frames by Act (shares CampaignAct).
  • progression.md — the five victory conditions + turn pipeline this shape frames.
  • .claude/rules/hermetic-scenario-tests.md — the regression discipline for these deterministic surfaces.