Multi-agent activity rendered as a game world: sprites, rooms, artifacts, an economy. It works, and it was the wrong instrument. This README is the postmortem.
| Status | A failed experiment, kept public. |
| Built | 27 February – 3 March 2026. v0.1.0 is the only release |
| Source | ~5,800 lines: 4,400 Rust (Bevy, ten plugins, WASM), 1,400 TypeScript (Preact HUD, SQLite bridge) |
| Build artifacts | 17 GB on disk |
| The part that answered the question | the text list in the right-hand panel |
| Licence | MIT. Copyright 2026 TODOMODO.IO AGENCY LLC |
Real-time observability is one of three pillars of multi-agent work, beside the orchestrator and agent lifecycle management (IndyDevDan, The One Agent to RULE them ALL). If five agents are running across three workspaces, the operator should be able to point at the one that is stuck. Moonshot AI's K2.5 launch included a short clip of agent swarms interacting visually, in motion. That was the prompt: make the agents visible, and if visible, why settle for boxes and arrows.
A game world. Characters in roles, rooms to walk between, artifacts picked up and handed off. Seven role sprites, five animation states, nineteen event types, ten Bevy plugins compiled to WebAssembly, a SQLite bridge, a Preact HUD, eight procedural Web Audio sounds, three themed rooms with ambient particles, portal transitions, and a 27-section manual with 24 annotated screenshots. It worked. It added nothing.
The operator's question was "which agent is stuck, and on what." AgentWorld answered it by making the operator watch a sprite cross a room. A game world is built to reward a player with hours to explore; an instrument is built for an operator with four seconds and one question. The architecture of the first was copied while the second was needed, and the copy was worse at being a game than a game and worse at being an instrument than a log file. Setup told the same story: to see the agents, install Rust 1.89, add a WASM target, install Trunk and Bun, start two servers, open a URL with a query parameter.
One HTML page: a connection dot, a live activity strip, and a searchable event stream showing agent name, tool, event type and timestamp. No sprites, no build step. It answers the question on sight.
Observability is a reading problem, not a rendering problem. The five-day build time should have been the warning: nothing that answers a real operational question is that easy to finish.
The code builds and runs; demo mode needs no event source.
rustup target add wasm32-unknown-unknown && cargo install trunk
cd frontend && bun install && cd ..
trunk serve --address 0.0.0.0 --port 8080 # demo mode, 5 scripted agents, offlineLive mode runs bun run bridge/server.ts --replay alongside, then
http://localhost:8080/?ws=ws://localhost:9090/ws. The bridge reads any SQLite table shaped
like (hook_event_type, event_category, team_name, agent_name, agent_type, payload, summary, timestamp); anything else emits the nineteen WorldEvent types from
crates/core/src/events.rs over a WebSocket.
World state is a pure projection of the event stream, so replay and time travel come free.
That part is worth reusing. The manual is docs/manual.html,
self-contained.
| Role sprites, status rings, thought bubbles | |
![]() |
Inspector panel with carried artifacts |
![]() |
Portal transitions between rooms |
![]() |
Roster, world view, event log, minimap |
Archived. No issues, no roadmap, no maintenance. It stays public because the postmortem is more useful than the code.



