Overview
A Python desktop app in the generative-agents lineage: roughly a dozen hand-authored characters move around a grid town, satisfy needs, form relationships, and talk to one another using an LLM -; Claude or a local Ollama model. It runs with a tkinter GUI (split-pane map plus info panels) or fully headless, and persists everything to a SQL Server database. A captured run shows it genuinely working: "Successfully loaded 11 characters... Status: Sunday 01:24 AM."
Background
The concept sits squarely in the wake of Stanford's generative-agents work -; LLM NPCs with memory, relationships and routines producing emergent storytelling -; but this is a from-scratch implementation, not a fork: tkinter and SQL Server rather than a web stack. It was built solo with Claude Code as a sandbox for watching characters' social lives unfold on their own.
One honest note: an internal hub document oversells the scope (zoning, job markets, a mayor role, dynasties). None of that is in the code. The real, working scope is needs, emotions, movement, and LLM conversations for about eleven characters -; which is plenty interesting on its own.
How It Works
A tick loop advances an in-world clock (1 real second ≈ 2 sim minutes), updates weather hourly, then steps every character and every active conversation. Each character carries five decaying needs (energy, hunger, social, entertainment, hygiene), a state machine (sleeping, eating, working, socializing…), and twelve emotional states with their own intensity and decay.
Personalities are written as natural-language bios, and a keyword scan derives numeric traits from the prose -; so the same text drives both the behaviour model and the LLM prompt. When two characters come within two grid cells and both want company, a conversation spins up. The LLM must answer in structured JSON:
# every generated line comes back structured { "dialogue": "...", "emotional_tone": "friendly", # sets memory importance "suggested_next_speaker": "...", "end_conversation": false } # tone nudges the pairwise relationship (+1 friendly, -5 hostile), # which re-enters the next prompt -- a closed social-feedback loop
Memories carry importance scores; the five most recent feed each prompt. Weather is a first-class emotional driver -; introverts get cozy in the rain, extroverts get bored -; scaled by each character's weather-sensitivity trait. Movement uses a cost-weighted A* so characters prefer sidewalks over roads. There's even an adaptive clock that slows in-world time when a local LLM's request queue backs up, so slow models don't break causality.
Current Status
Archived as a working prototype. It runs and produces conversations, but several pieces are stubbed.
- Needs, emotions, traits, relationships, weather and the LLM conversation loop all function.
- Schedule generation isn't wired up; activity choice falls back to time-of-day plus needs heuristics.
- No save/load of sim state; "New Town," "Load Town" and the town editor are all "not implemented yet." Needs a SQL Server instance to run.