- Seeded procedural runs (survivors, locations, weather, events) - 100-day campaign with 5 phases, scripted story beats, Day-100 finale - 8 endings incl. hidden 'First Light Again' - Data-driven events (people/world/story packs) with callback chains - Relationships, memories, grief, karma/hope systems - Tactical encounters (fight/hide/run/negotiate) with honest odds - 8 upgradeable camp buildings, 13 location templates - Canvas parallax scenes, procedural SVG portraits, weather FX - Synthesized adaptive audio (WebAudio, no assets) - Save slots + autosave (localStorage), shareable seeds - Tests: headless multi-seed simulator + browser E2E (playwright)
100 DAYS AFTER
A survival story in one hundred days.
Lead a small band of survivors through a world ended by Grayfall — an engineered blight that came down with the dust. Every day you have a handful of actions, a ledger of hungry mouths, and a hundred ways to lose someone. What happens on Day 100 depends on what you built, learned, earned — and who you buried.
Play
npm install
npm run dev # → http://localhost:5199
Production build: npm run build then npm run preview.
Controls
- Everything is mouse-driven. Hover anything with a dotted underline for tooltips.
- Each day: spend limited actions (SCAVENGE / EXPLORE / HUNT / BUILD / TALK / TRADE / REPAIR / REST / TRAVEL), then press END DAY and read the night ledger.
- Click survivors for their full sheet: skills, traits, relationships, memories.
- The MAP tab previews each location's illustrated scene; the JOURNAL keeps your story.
- Encounters show honest odds for Fight / Hide / Run / Negotiate. Estimates. Not promises.
The shape of a run
| Days | Phase | What happens |
|---|---|---|
| 1–20 | Early Survival | Scarcity, first strangers, learning the valley |
| 21–50 | Expansion | New faces, bigger camp, the wide world opens |
| 51–80 | Escalation | Raiders, herds of the Dust-Sick, hard choices |
| 81–99 | Endgame | Radio fragments resolve; escape plans form |
| 100 | Finale | Convoy, boats, the last raid… or something nobody told you about |
Eight endings, including one hidden ending that requires three recovered radio parts, a seed vault, a running generator, and enough hope to be dangerous.
Runs are seeded and fully reproducible — same seed, same world. Share seeds.
Architecture
Clean separation of state, simulation, content and presentation:
src/
engine/ pure logic, zero DOM
types.ts all shared types (GameState is plain serializable data)
rng.ts seeded mulberry32 + cursor (exact reproducibility)
state.ts new-game generation (survivors, map, weather, stores)
sim-core.ts caps, morale floor, defense rating, relationship math
eventctx.ts the mutation API events are written against (+ death & grief)
sim.ts actions, tactical encounters, night resolution, story beats
ending.ts ending selection + epilogue data
save.ts slots + autosave (localStorage), versioned envelopes
content/ data-driven game content
survivors.ts names, occupations, traits, personalities, goals, weapons
locations.ts 13 location templates (loot tables, risk, specials)
buildings.ts 8 upgradeable structures
enemies.ts enemy archetypes
world.ts weather table, campaign phases, lore fragments
events/
people.ts strangers, traders, internal conflict, callback chains
world.ts storms, creatures, factions, discoveries
story.ts scripted beats (Day 2→99), Day-100 finale, all endings
ui/ presentation
portraits.ts procedural SVG character portraits with moods
scene.ts canvas parallax scenes, weather particles, camp rendering
ui.ts screens, HUD, modals, event/combat flow
audio/audio.ts synthesized wind/rain/thunder, adaptive music pads, SFX
scripts/
headless.ts auto-plays full campaigns across N seeds:
crash checks, determinism proof, balance histogram
smoke.mjs real-browser test: boot → play days → save → reload → load
Adding content never touches core systems: new events are entries in content/events/*
(a title, conditions, choices with requirements, and outcome functions using the ctx
helper API); new locations/buildings/enemies are plain data records.
Emergent storytelling systems
- Memory: every survivor logs what happened to them ("Skipped supper so others could eat").
- Grief: deaths ripple through relationships; close friends spiral, confront you, and remember on Day 99.
- Callback chains: rob the caravan and it returns; spare the stranger and he remembers; feed the family and a package appears at the fence weeks later.
- Feeding priority: food shortfalls feed the hungriest first — whoever's last in line develops opinions about leadership.
- Karma & hope quietly steer strangers' returns, tribute demands, and endings.
Testing
npm run sim # 12 seeded campaigns, headless: crashes/determinism/balance
npm run sim -- --seeds=40
npm run smoke # browser E2E through the real UI (needs the dev server)
npm run build # typecheck + production bundle
Built as a vertical-slice-first project, expanded to the full 100-day campaign.