A single-POV narrative life-simulation: one person lives a felt life among ~50 others in a cozy 2D town — and every behaviour underneath is driven by a real, equation-backed model from the cognitive-science and simulation literature.
"cozy 2d simulation, but under the hood is the top-tier ideas and theories of what science got so far from real serious papers, not a video game." — the owner's thesis, verbatim.
What you see is cozy: a hand-composed pixel-art town — a square with a fountain, shops with awnings, a glass office, a clinic, a park with a pond, a cottage row with gardens, ringed by forest. Villagers walk real paths, speak in dialogue bubbles, and sleep under a starfield while the sky runs dawn→dusk, weather falls, trees turn with the seasons, and windows glow at night. You watch one being live it from the inside — or flip to observer mode and click anyone in the town.
What's underneath is not a bag of if statements. Every mood, every drifting friendship,
every bad night's sleep, every rumour and false belief is produced by a named model — a real
paper or theory, reduced to a deterministic, bounded equation and pinned by a test that fails
CI if the claim stops being true. The cozy surface is the point; so is the refusal to fake the
machinery beneath it.
Each mechanism below is a faithful reduction of its source — the right equation or the right
structural claim, not a full-fidelity biology. Every one reaches the being's perception each
tick, and every one ships a deterministic scripted twin so reproducibility never bends. The full
science → code → enforcement audit trail is in
sim/REALISM_REPORT.md §10; the simplifications we knowingly made are
written down there rather than hidden.
| Mechanism | The paper / theory | How it shows up in the life |
|---|---|---|
PAD three-axis mood · emotion.py |
Mehrabian & Russell — pleasure/arousal/dominance affect space | Mood stops being one number; anger (−P +A +D), fear (−P +A −D) and grief (−P −A −D) become distinct feelings |
OCC-lite appraisal · emotion.py |
Ortony, Clore & Collins — appraisal theory | Each event is named: the same slight lands as resentment for one person, shame for another |
Emotion → action tendency · agent/disposition.py |
Approach/avoidance motivation (OCC · Roseman · Elliot) | The same blow is met head-on by a high-dominance temperament and fled by an anxious one |
Big Five / OCEAN · personality.py |
Costa & McCrae — five-factor model | One personality vector steers mood set-point, dialogue, habit and schedule; two lives diverge from the same seed |
| Mechanism | The paper / theory | How it shows up in the life |
|---|---|---|
ACT-R activation & decay · state/stores.py |
Anderson — ACT-R memory activation (frequency + recency) | The sim genuinely forgets: a twice-remembered moment outlives a one-off; core memories never fade |
Conway chapters · brain.py (nightly consolidation) |
Conway — the Self-Memory System | A sleep pass rolls episodes into general events and lifetime chapters — a life becomes narratable, not searchable |
| Reconsolidation · two-record stores | Memory reconsolidation — retrieval re-stores, coloured by the present | The remembered past drifts under mood while the factual record never does ("what happened / what she remembers") |
Typed memory · agent/brain.py |
MemGuard — typed memory (arXiv:2605.28009) | One bad night isn't filed as "he's always angry": traits, relationship-facts and raw episodes are kept apart |
| Mechanism | The paper / theory | How it shows up in the life |
|---|---|---|
Two-process sleep · sleep.py |
Borbély (1982) — homeostatic pressure S + circadian process C | Waking is threshold-driven by sleep pressure and chronotype; a short or broken night is felt as grogginess |
Photoperiod / seasonal affect · world/globals_state.py |
Seasonal affective disorder; Rosenthal et al. (1984) | The dark of the year sits an anxious soul lower — day-length held apart from weather |
Allostatic load · allostasis.py |
McEwen & Stellar — allostatic load (chronic-stress wear) | Sustained stress accumulates as standing wear that heals slowly and later raises illness risk |
| Mechanism | The paper / theory | How it shows up in the life |
|---|---|---|
Dunbar layers · npcs.py |
Dunbar — the number and its relationship layers | Everyone keeps ~5 close + ~15 warm ties; beyond that bonds decay — nobody has 49 friends |
Weak-tie gossip · npcs.py |
Granovetter (1973) — The Strength of Weak Ties | News reaches you through bridging acquaintances, not the clique; rumour favours the weak ties |
Friedkin–Johnsen opinions · opinion.py |
Friedkin & Johnsen; bounded-confidence clustering (Hegselmann–Krause 2002) | Opinions, not just facts, move: cliques come to agree; the street can be "of one mind" or "split" |
Network SIR contagion · lifecycle.py |
Kermack–McKendrick SIR on a graph (Pastor-Satorras & Vespignani) | Illness spreads person-to-person along the Dunbar contact graph — an outbreak can thin the whole town |
| Mechanism | The paper / theory | How it shows up in the life |
|---|---|---|
Spatial perception · perception.py |
Line-of-sight / earshot within a place (structural — no single source) | Sharing a room isn't sharing the moment: a scene splits into who is seen / overheard / unaware |
Theory of mind & false belief · tom.py |
The Sally–Anne test (Wimmer & Perner 1983; Baron-Cohen, Leslie & Frith 1985) | You still think Devi's at the café until you see otherwise — a false belief persists, then corrects with a jolt of surprise |
Homophily attraction · romance.py |
Homophily (McPherson et al. 2001); similarity-attraction (Byrne 1971) | The town falls in love along P ∝ exp(−Δtrait²/τ²) — drawn toward those near its own temperament |
Drama-manager pacing · director.py |
Façade beat-sequencing (Mateas & Stern 2003); the RimWorld / Left 4 Dead storyteller lineage | After a heavy stretch the next charged beat is held back — a breather — pacing the story across seeds |
Under these sit the structural layers built earlier in the program: the POV authors a day-plan
and can amend it; the town is a real web of NPC↔NPC bonds (homophily-seeded, Dunbar-capped);
the economy closes its loops and reconciles money to the cent daily; the population turns over
by birth → illness → death → arrival (children inherit blended temperament; estates pass on),
and the single life you follow can itself end — age- or illness-driven, rendered with restraint
rather than a game-over; and fractal time applies the salience idea to time itself, montaging
low-salience days so a year is watchable in an evening. Sources and the field survey (Stanford Generative Agents →
Project Sid → 2026) are in sim/REALISM_REPORT.md; the shipped blueprint
is sim/REALISM_UPGRADE_PLAN.md.
Real science, to be worth the name, has to be reproducible — so the whole build stands on one load-bearing invariant:
- The scripted provider is fully deterministic: same seed → byte-identical run. All 577 tests, the golden scenes, the 500-tick audit and the reproducibility check run on it — and a run can be saved and resumed byte-identically, even across processes.
- Every LLM mechanism ships a deterministic scripted twin. A live local model may only ever change the words — never the RNG stream, never an effect, never a state transition.
- Isolated RNG streams keep the POV's reproducible narration separate from the crowd's social draws; live voicing runs after all bookkeeping so it can only swap text.
That is what lets the science be enforced rather than asserted: validate.py is ALL GREEN —
golden 15/15 · audit 18/18 · probes (6 categories) · emergence 10/10 across seeds —
and an emergent story only counts once it recurs across seeds.
Runs with no model out of the box (the deterministic narrator) or against a real local model via LM Studio — no cloud, no API keys. If LM Studio isn't reachable it falls back to scripted and says so.
Windows, one click: double-click sim/start.bat — it serves the launcher at
http://127.0.0.1:8642 and opens your browser; stop.bat shuts it down.
Manual (from the sim/ directory):
python -m venv .venv
.\.venv\Scripts\Activate.ps1 # if blocked: Set-ExecutionPolicy -Scope Process -Bypass, then retry
pip install -r requirements.txt
python launch.py # ★ web launcher + 2D animated town at http://127.0.0.1:8642
python run.py --ticks 60 # or terminal mode, ~a day, no model needed
python validate.py # golden 15/15 · audit 18/18 · probes · emergence# macOS / Linux
cd sim && python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
python run.py --ticks 60The deps live in
.venv, not global Python.ModuleNotFoundError: No module named 'mesa'means the wrong interpreter — activate the venv or call.venv/Scripts/python.exedirectly.
To run live, pick LM Studio for both the mind and the NPC minds in the launcher (LM Studio up
on localhost:1234 with the models loaded). Full detail — the watch-it layer, the four dials, the
observer mode, the module→design-doc map — is in sim/README.md.
sim/— the runtime: Mesa/Python, stdlib-only server, vanilla-JS pixel-town frontend, SQLite state, local-first LLM. This is what you run. Seesim/README.md.SIM_WORLD_DESIGN_Edition11_FINAL/— the canonical, engine-agnostic design package (folders00_START_HERE→10_runtime_design): the world and the machine that runs it, specified as a source of truth the runtime binds to. Start with the World Design Compendium.- Key docs —
BUILD_STATUS.md(what's built · current truth) ·sim/REALISM_REPORT.md(the science mapping) ·sim/REALISM_UPGRADE_PLAN.md·sim/LIVING_TOWN_PLAN.md·sim/MODELS.md.
- Phases 2–17 shipped. The watch-it layer + dialogue (6), the ~50-person world met by living (7), the Living Town — OCEAN minds · locations/timetables · closed-loop economy · pixel-art observer (8), the will-and-weave / autobiography / a-year-in-the-town / a-life-whole structure (9–12), and the deep-realism program above (13–17).
- Since then: a realistic gender mix across the town, the POV's own mortality, and byte-identical save / resume of a running life.
- 577 tests, all on the deterministic scripted provider;
validate.pyALL GREEN — golden 15/15 · audit 18/18 · probes 6 categories · emergence 10/10. Single source of truth:BUILD_STATUS.md. - Runs with no cloud. No model needed (deterministic), or a local LLM via LM Studio — no keys, nothing leaves the machine.
- Art: CC0 pixel art by Kenney (RPG Urban Pack + Roguelike Modern City),
committed under
sim/static/assets/. Requires Python 3.10+ and Mesa; everything else is stdlib. - License: no project license file is declared in the repo yet.