LAB—47
Software · Systems · Games
Portfolio/ DOC-003/PRJ-002 Mulk

Engineering dossier

An Agent’s Eyes & Hands

A browser-delivered god-game world-simulation (Godot 4.7) built end-to-end by directing Claude Code, where the real engineering wasn’t the code generation but the apparatus built to let an AI agent observe and operate an emergent simulation it cannot see or play.

DesignationPRJ-002 · solo build
DomainWorld simulation · browser
EngineGodot 4.7 · web export
World512×256 grid · seven ages
Channels3 MCP servers
StatusPlayable now

Section 01

The problem

PRJ-002 · a solo build structured as a director-and-agent division of labour. The codebase is largely agent-written; the engineering documented here is the workflow that made that possible and kept it correct.

Mulk (Arabic: dominion) is a discrete-tick world-simulation: civilizations arise on a real Earth (loaded from a GEBCO elevation heightmap) or on procedural worlds, and spread, trade, war, convert, invent, fragment and collapse on their own across seven ages, while the player reaches in with ~37 god-powers. It runs two modes (a free-form Sandbox and a scored Shepherd challenge) over a 512×256 world grid, exported to the browser.

The development challenge, and the actual subject of this dossier, is that an AI coding agent has two blind spots: it cannot see the screen, and it cannot play. For ordinary software that’s survivable. For an emergent simulation whose behaviour only appears over thousands of ticks, it’s fatal: you cannot tell whether mega-nations fragment correctly, or whether the climate model depopulates the subarctic, by reading code or glancing at a single frame. The entire workflow is an apparatus engineered to close those two gaps: to give the agent eyes (visual and numeric) and hands (drive the editor and the running game).

write / operate observe / verify Hands: write & operate Eyes: observe & verify Claude Code agent director-driven godot MCP author scripts & scenes · ~70 tools godot-enhanced MCP heavy editor systems · ~35 tools MCPBridge puppeteer the live game · TCP 9081 Mulk emergent tick sim colony_sim.gd + main.gd Headless probes quantitative summaries Screenshot pipeline deterministic visual evidence
Agent & the closed loop MCP channels & instruments The running game

Section 02

The hands: three control channels

The project drives Godot through three distinct channels, configured in .mcp.json / project.godot:

ChannelTargetWhat it does
godot MCPeditor · WS 6505everyday authoring: scripts, scene nodes, settings, errors (~70 tools)
godot-enhancededitor · TCP 9090heavier systems: animation, navmesh, themes, export, headless validation (~35 tools)
MCPBridgelive game · TCP 9081inspect scene tree, set whitelisted props, inject input, watch signals, automate UI

The two editor MCPs let the agent write the game; the runtime bridge lets it observe and puppeteer the game while it runs, clicking buttons and sampling a property every N frames into a ring buffer. All three are security-hardened (shared-secret auth with lockout, constant-time compare, value whitelists, read-only allowlists) because they expose a live engine to an automated client. The tooling co-evolved with the game: when the enhanced server’s auth key rotated on every reload and trapped the client in a connect→auth-fail loop, the fix was to patch the server to reuse a stable key, the agent maintaining its own instruments mid-project.

Section 03

The eyes: the agent builds its own instruments

This is the distinctive part. A god-game’s behaviour is emergent over thousands of ticks, so instead of eyeballing, the workflow builds bespoke headless diagnostic harnesses that print quantitative summaries, runs them, reads the numbers, tunes constants, and re-runs. Empirical, measurement-driven tuning via CLI flags (Godot --headless … -- --flag):

ProbeWhat it measures
--balancelatitude-band capacity scan + six cradle realms, 2000 ticks: regional fairness / “cold cliff”
--worldsim110 rivals, 2400 seeded ticks: alive / fragment / mega-nation / size / era / route counts
--toolsoakdrives simulated clicks through the real tool dispatch: proves every god-power still fires
--stress / --savetest / --striketestlate-game performance, save-load round-trips, WMD-math assertions

Reproducible seeding is the key: it lets the agent A/B a constant change against a fixed world and trust that a metric delta came from its edit, not RNG. For the things judged by eye, a separate deterministic screenshot pipeline (~35 --shot<name> recipes) seeds a state, parks the camera, optionally fast-forwards, and saves a PNG, so the agent generates and curates its own visual evidence. The signature move of the whole project: when it can’t watch, it builds a measuring instrument and reads it.

Section 04

Cross-session memory & the inner loop

The build spanned many sessions over nine days, so Claude Code’s file-based memory carries hard-won operational knowledge forward: nine cross-linked memory files encoding the non-obvious: the port→plugin map and how to diagnose “not connected,” the auth-key rotation fix, a six-place checklist for adding a god-power, and the design rationale for each major system. This is what kept a multi-day, 15k-line build coherent.

in range metrics off → re-edit Plan against design docs Edit sim via MCP Validate headless · errors = 0 Measure run probe · tune Look screenshots / live Commit root cause + check Persist gotcha to memory

A typical feature/balance cycle: plan against the design docs, edit the simulation via MCP, validate headlessly (errors = 0), measure with the relevant probe and tune until metrics land in range, look by regenerating screenshots or driving the live game over the runtime bridge, commit with a structured body stating root cause and verification, and persist any new gotcha into memory. A recurring discipline: substantial changes are staged in the working tree and confirmed with the director before committing, rather than self-committed.

Section 05

Numbers

Real figures from the codebase and history: measured, not estimated.
131,072
Grid cells (512×256)
~37
God-powers
24
Commits · 5 active days

Measured tuning outcomes Measured

The empirical loop, working: each delta traced to a deliberate constant change against a seeded world:

InterventionResult
Cold-cliff fix62–70° latitude band carrying capacity ↓ ~64%
Fragmentation reworklargest realm ~11k cells (monotonic) → ~3.5–7k (fragment-prone)
Naval tradeearly-game sea routes ~5 → ~23
Shepherd balance bug--toolsoak root-caused ~29% of tool uses blocked by insufficient Favor
Late-game stress240-realm run completed clean in ~55s

The point of these isn’t the game balance. It’s that an agent that couldn’t watch the simulation still produced quantified, verifiable results, because the measurement apparatus existed.

Section 06

What I'd do differently & known limitations

Stated plainly: these are real.

  • No conventional test suite. The diagnostic harnesses are the test suite. Defensible for a solo simulation build, but a true assertion-based regression suite would catch silent breakage the probes don’t.
  • Web build size. The browser export’s index.wasm is large (~38 MB), a downstream consequence of targeting web export from this engine/pipeline; worth a size-reduction pass.
  • Documentation drift. The design docs ran ahead of (then behind) the implementation as the game evolved emergently from its original concept. Trivial to reconcile; worth doing before anything is public.

Transferable

Competencies

What this build demonstrates, in hiring terms:

Agent orchestration via MCP (multi-server) Observability for agents that can’t see Measurement-driven tuning Reproducible-seed A/B methodology Cross-session agent memory design Security-hardened tool exposure Directing an agent to an invariant set
The transferable lesson: anyone can have an LLM write code; the value is building the instruments that let an agent observe and verify a system it can’t directly perceive. That generalises far beyond games.

Lab-47 · PRJ-002 Mulk · agentic development workflow