The mechanics that turn 33 LLM agents into a 1912 paranoid drama. The “how it works” half.
One tick is three simulated minutes. A full day is 480 ticks — 320 active, 160 overnight. Each tick processes nine steps in this exact order:
tick == 1, agents sharing a home_node receive a mutual-presence memory and are forced to interact. One-shot.self.tick += 1. Everything below this line is the new tick number.[reflection] cover-story memory. 10-tick cooldown.tick % 480 == 309), each agent gets a staggered retirement cue.tick % 480 == 319, all agents are hard-slept until dawn. The 160 overnight ticks spin near-instantly.Every agent starts at level 0 with no memory of who they are. Progression is a three-rung ladder, each rung gating which actions the LLM is allowed to use.
display_name. Item names resolve. Co-located agents shown with relationship labels. Social engagement is mandated — coldness is flagged as dangerous as overt tells.name_prop on the next interact.fear_prop and ≥ 480 ticks (~1 sim-day) have passed since reaching level 1.Every LLM action call must return a JSON object with exactly these six keys. Malformed responses become ACTION_FAIL memories and cost the agent one simulated minute.
{
"action_type": "interact", // interact | move | communicate | sleep | attack
"target_character": "Eleanor Vance", // display name, item name, room name, or null
"volume": "normal", // whisper | normal | shout (communicate only)
"dialogue": "…", // the exact string spoken; agents read each other’s strings
"duration_minutes": 3, // 1–480; sets busy_until_tick
"internal_monologue": "…" // private thought, never read by other agents
}Where you stand and how loud you speak determines who hears what. The acoustic matrix is the ship’s most consequential mechanic — it is why the promenades matter.
| Room scale | Volume | Who hears |
|---|---|---|
| small | any | Everyone in the room receives full HEARD. |
| vast | shout | Everyone in the room receives full HEARD. |
| vast | normal | Target receives HEARD; bystanders receive OBSERVED with no content. |
| vast | whisper | Target receives HEARD; bystanders see only “X whispered to Y.” |
Each agent’s LLM context is a hot window of recent memories plus compact summaries of everything older. Raw memories are never deleted.
The last hot_memory_limit raw rows (default 50), newest first. This is the agent’s working memory — sharp, full-text, with all monologue intact.
Compact LLM-generated summaries of older periods, oldest first. Written to a separate memory_summaries table; the raw memory_stream rows are untouched and remain queryable.
compaction_memory_count (default 200)compaction_soft_chars (160K) or compaction_hard_chars (800K)
38 rooms in a node graph. scale (small/vast) × ambient_noise (low/high) drives all routing logic. A simplified sketch of the dramatic core:
aletheia.db. Tables: memory_stream, trust_ledger, agent_state, memory_summaries. Safe to delete to reset.google/gemma-4-31b-it. Per-call reasoning override; action calls disable reasoning for speed, trust and compaction calls enable it.response_format: json_object for models that don’t support it../aletheia.db.