VM Per Room Is the Only Game Engine You Need

repoaiinfrastructureagent-loopsgamingmudlinzcapabilitiesminimal-platform

The four agent types (NPC/room-bound, Personal, World, Quest) map directly to ADR-0157's agent lifecycle model; the 'minimal platform + emergent everything' philosophy mirrors the gateway + system-bus architecture exactly.

Sean Grove (who built OneGraph before it got folded into Netlify) dropped this gist proposing a MUD built on Kandan — a chat platform with integrated terminals and AI agents — using Linz VMs. The premise is brutally simple: don’t build a game engine into the platform. Give every channel a full Linux VM and let users and their agents build whatever they want.

The three core primitives are the whole pitch. A VM per room means the “game engine” is just bash scripts and SQLite — no item schemas baked into the platform, no quest system to maintain. Agents are the NLP layer: when a non-technical user says “make this room a blacksmith shop,” a Codex session writes the on_message.sh hook script. The platform never touches natural language. And linz exec is the killer primitive — every VM has an ID, and VM IDs are tradeable secrets. Know the ID, you can execute commands on that room. The puzzle reveals lz-a8f3b2c1, you crack the vault. It’s capability-based access control disguised as D&D flavor text.

The agent taxonomy is worth stealing: NPC agents (room-bound, maintains channel state), Personal agents (follows a user across channels), World agents (omnipresent, global state and DM orchestration), and Quest agents (temporary, spawned for a storyline, despawned on completion). That’s a clean mental model for thinking about scope and lifecycle — not unlike the distinction between an Inngest function scoped to an event stream vs. one that orchestrates across the entire system.

What makes this interesting beyond the gaming angle is the architecture philosophy: minimal platform + emergent everything. The platform provides rooms with computers. Agents build everything else. That’s the exact same bet joelclaw makes — event bus, durable functions, Redis state, and then let the 110+ Inngest functions figure out what to do with it. The kandan CLI provisioned in every VM mirrors how the joelclaw CLI is the operator interface: a thin, composable tool that agents use to post back into the world.

Key Ideas

  • VM per room = no game engine needed — shell scripts, SQLite, and Python files stored in /home/linz/ ARE the game state; no platform schema required
  • VM IDs as capability tokens — tradeable secrets that grant cross-room exec access; discovery, espionage, revocation, and quests all fall out of this one primitive
  • Agents write the NLP layer — the platform never parses natural language; a Codex session writes the regex in on_message.sh so the platform doesn’t have to
  • Four agent types: NPC (room-bound), Personal (user companion), World (omnipresent narrator), Quest (ephemeral, despawns on complete) — clean lifecycle taxonomy
  • linz fork = free save points — btrfs copy-on-write snapshots give rollback and branch semantics to any VM state at zero cost
  • Hook scripts as event handlers.kandan/hooks/on_message.sh, on_mention.sh, on_join.sh form a convention-based event system that agents create and manage
  • linz exec cross-room — any VM can execute commands on any other VM it has the ID for; this is the cross-room communication primitive
  • Rapid spin-up/spin-down — DM improvises a new cave mid-session; World Agent creates a VM + channel + NPC + template scripts in seconds; tears it down when done
  • Minimal platform, maximal emergence — platform handles channels, VMs, chat↔VM bridge, snapshots, agent runtime, WebSockets; everything domain-specific is emergent