feat(#52): era templates + shared scenario types/transforms

- presets/templates/: 3 light era templates (ww2/present/near-future) + index.json
  manifest (id, name, year, eraDescription, suggestedPowers, tensions).
- server/templates.ts: createTemplateStore (mirror of createPresetStore).
- shared/scenario.ts: dependency-free contract for the dynamic scenario path —
  SuggestedPower / EraTemplate / TemplateMeta / WorldNation / ScenarioEvent /
  WorldDraft / Checkpoint types, relationFromScore, validateWorldDraft (pure,
  defensive, never throws), worldDraftToGameState (region-key territory via the
  injected expand resolver, regionStats seeded, clean turn-1 state).
- tests: server/templates.test.ts (manifest order + file shape),
  server/scenario-shared.test.ts (15 cases: validation/clamp/dedup/null +
  transform).

Fixes #52
This commit is contained in:
2026-10-15 09:37:31 +00:00
parent 5d194636d0
commit 2191514db1
8 changed files with 805 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
{
"id": "present",
"name": "Present Day",
"year": 2026,
"eraDescription": "A multipolar world of blocs, sanctions, and tech supremacy. Climate strain, artificial intelligence, and great-power rivalry shape every decision the leaders of the age must make.",
"suggestedPowers": [
{ "name": "United States", "region": "USA", "note": "The military-technological leader of the Western bloc." },
{ "name": "People's Republic of China", "region": "CHN", "note": "The industrial giant pressing on the Western Pacific." },
{ "name": "Russian Federation", "region": "RUS", "note": "A resource-rich power testing its neighbors' resolve." },
{ "name": "European Union", "region": "FRA", "note": "A large, internally divided economic bloc." }
],
"tensions": [
"US–China tech and trade rivalry",
"The war in Europe and the eastern flank",
"AI and cyber dominance"
]
}