2026-05-24announceby Roman Sanine

Two projects, one stack: architecture of Decent TD and Sidebar Agent

agentsarchitecturedeep-diveannouncement

Two shipped projects. Same Nuxt 4 + Vue 3 + TypeScript foundation. One is a real-time multiplayer game; the other is an agentic dev-tools surface embedded in the app itself. Both were built predominantly by coding agents — Claude sessions steering architecture, implementation, and iteration — with human oversight on scope and review.

This post breaks down the stack choices, key architectural decisions, and what agent-driven development actually looks like once you push past toy demos.

The shared foundation

Both projects run on Nuxt 4 with Nitro as the server layer. The choice was deliberate: file-based routing, auto-imports, and server routes in the same repo eliminates glue code between frontend and backend. TypeScript end-to-end means types flow from database schema to rendered component without manual DTO mapping.

Common infrastructure decisions:

  • HTTPS everywhere, even in dev — SSL certs from a shared ~/certs/ directory, bound to 0.0.0.0 for LAN testing on mobile
  • Bootstrap 5 + SCSS over Tailwind — agents produce more consistent markup with utility classes they can name explicitly, and the component library (BsButton, BsCard, BsModal) stays stable across refactors
  • MongoDB for content and user state; PostgreSQL + Drizzle ORM where relational integrity matters (game state, tower definitions, upgrade trees)
  • Port isolation via a registry (PORT-REGISTRY.md) — each project owns a 20-port range, no collisions

Decent TD: real-time game on a web stack

A multiplayer cooperative tower defense where agents wrote the overwhelming majority of gameplay code.

Server-authoritative game loop

The server owns all game state. Clients are pure renderers. This prevents cheating and simplifies the mental model: the WebSocket handler in server/routes/_ws.ts receives player actions, validates them against current state, mutates the GameRoom, and broadcasts diffs.

// server/game/GameRoom — simplified tick
tick(dt: number) {
  this.spawnEnemies(dt)
  this.moveEnemies(dt)
  this.fireTowers(dt)
  this.checkWaveComplete()
  this.broadcastState()
}

Fog of war at scale

A 100×100 grid (10,000 cells) with three visibility states: unexplored, explored, and in-vision. Server calculates vision from tower ranges every second; clients receive delta updates (only changed cells). On the GPU side, fog renders as instanced meshes — single draw call, <1ms per frame.

3D with Three.js

Towers render as CAD-generated meshes (via replicad). The admin panel has an interactive 3D tower catalog where you rotate, zoom, and inspect each tower definition before it goes live. Procedural audio via Tone.js means no asset pipeline for sound effects — agents synthesize new sounds by tweaking oscillator parameters.

Stack summary

Layer Choice Why
Rendering Three.js Agents handle imperative 3D APIs well; scene graph is explicit
Audio Tone.js Procedural — no asset files to manage
State Pinia Vue-native reactivity for UI overlays on the canvas
DB PostgreSQL + Drizzle Relational data (towers, upgrades, player stats)
Real-time Nitro WebSocket Same-process, no separate WS server to deploy
Auth OAuth (Google/GitHub/Discord) Standard; agents scaffold OAuth flows reliably

Sidebar Agent: agentic surface inside the app

The second project puts Claude directly into the running application as two components.

The chat panel

A docked sidebar holding a persistent agent session. Route-aware — it knows what page you're viewing, can read surrounding application state, and operates against the project from inside the running app. Tool calls, file reads, and AskUserQuestion cards stream inline.

The key architectural decision: the agent session is bound to the current route. Navigation doesn't destroy context; it enriches it. The agent accumulates understanding of what the user is doing across pages.

The issue reporter

A modal that captures complaints — typed text, voice transcription, or screenshot-with-annotation — and routes them to a structured triage pipeline:

  1. User submits a report
  2. Agent classifies: hotfix-shaped bug vs. feature request
  3. HMAC-authenticated callback triggers a detached agent process
  4. SSE streams status back to the UI (triaging → working → resolved)
  5. Queue watchdog recovers from crashes; retries with exponential backoff

The result: the loop from "this is broken" to "tracked and being worked on" collapses to a single in-app interaction.

DevTools proxy: closing the feedback loop

Both projects are developed with the help of a custom MCP proxy server that gives coding agents eyes and hands in the browser. The proxy bridges multiple Chrome controllers:

  • local-chrome-client — headless Puppeteer for automated testing
  • devtools-ws-client — Chrome extension on a real browser for GPU-rendered screenshots
  • browser-tab-bridge — read-only access to all open tabs

Agents can navigate, take snapshots, evaluate scripts, click elements, and read console output. This turned frontend development from "agents write code blindly and hope" into a genuine feedback loop where the agent sees its own output and self-corrects.

What agent-driven development actually looks like

The agents aren't generating boilerplate and walking away. The pattern that emerged:

  1. Architecture spec — human defines the shape (a .architecture/ folder with YAML records and a constitution)
  2. TDD gates — agents write tests first; implementation must pass before moving on
  3. Session continuity — CLAUDE.md files and architecture records let cold sessions pick up where the last one left off
  4. Visual verification — devtools-proxy screenshots let agents confirm their UI changes render correctly

Interventions are mostly scope corrections ("don't build that subsystem yet") and taste decisions ("use instanced meshes, not individual objects"). The agents handle implementation depth, edge cases, and cross-cutting concerns autonomously.

Next steps

  • Decent TD: deploy matchmaking as a separate Nitro service; add spectator mode via read-only WebSocket connections
  • Sidebar Agent: voice input for the issue reporter; persistent agent memory across browser sessions

Looking forward

These two projects serve as proof points for a specific thesis: coding agents can drive real, production-quality software when you give them the right scaffolding — architecture records for memory, TDD for correctness, and visual feedback for UI work. The stream documents this process as it evolves, building in public with the tools rather than just talking about them.

Comments
No comments yet.
Comments are reviewed before appearing.