- 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)
109 lines
4.9 KiB
Markdown
109 lines
4.9 KiB
Markdown
# 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
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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.*
|