100 Days After — complete playable survival strategy game

- 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)
This commit is contained in:
2026-08-23 06:58:47 +00:00
commit 486201655b
36 changed files with 9989 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
# 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.
![genre](https://img.shields.io/badge/genre-survival%20strategy%20%2F%20interactive%20story-e0784a)
![engine](https://img.shields.io/badge/built%20with-TypeScript%20%2B%20Canvas%20%2B%20WebAudio-5da9a1)
---
## 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 |
|------|-------|--------------|
| 120 | Early Survival | Scarcity, first strangers, learning the valley |
| 2150 | Expansion | New faces, bigger camp, the wide world opens |
| 5180 | Escalation | Raiders, herds of the Dust-Sick, hard choices |
| 8199 | 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.*