# Timmy Tower World

A Three.js 3D visualization of the Timmy agent network. Agents appear as
glowing icosahedra connected by lines, pulsing as they process jobs. A
matrix-rain particle effect fills the background.

## Quick start

```bash
npm install
npm run dev      # Vite dev server with hot reload → http://localhost:5173
npm run build    # Production bundle → dist/
npm run preview  # Serve dist/ locally
```

## Configuration

Set these in a `.env.local` file (not committed):

```
VITE_WS_URL=ws://localhost:8080/ws/agents
```

Leave `VITE_WS_URL` unset to run in offline/demo mode (agents animate but
receive no live updates).

## Adding custom agents

**Edit one file only: `js/agent-defs.js`**

```js
export const AGENT_DEFS = [
  // existing agents …
  {
    id:        'zeta',      // unique string — matches WebSocket message agentId
    label:     'ZETA',      // displayed in the 3D HUD
    color:     0xff00aa,    // hex integer (0xRRGGBB)
    role:      'observer',  // shown under the label sprite
    direction: 'east',      // cardinal facing direction (north/east/south/west)
    x:         12,          // world-space position (horizontal)
    z:         0,           // world-space position (depth)
  },
];
```

Nothing else needs to change. `agents.js` reads positions from `x`/`z`,
and `websocket.js` reads colors and labels — both derive everything from
`AGENT_DEFS`.

## Architecture

```
js/
├── agent-defs.js   ← single source of truth: id, label, color, role, position
├── agents.js       ← Three.js scene objects, animation loop
├── effects.js      ← matrix rain particles, starfield
├── interaction.js  ← OrbitControls (pan, zoom, rotate)
├── main.js         ← entry point, rAF loop
├── ui.js           ← DOM HUD overlay (FPS, agent states, chat)
└── websocket.js    ← WebSocket reconnect, message dispatch
```

## WebSocket protocol

The backend sends JSON messages on the agents channel:

| `type`          | Fields                              | Effect                        |
|-----------------|-------------------------------------|-------------------------------|
| `agent_state`   | `agentId`, `state`                  | Update agent visual state     |
| `job_started`   | `agentId`, `jobId`                  | Increment job counter, pulse  |
| `job_completed` | `agentId`, `jobId`                  | Decrement job counter         |
| `chat`          | `agentId`, `text`                   | Append to chat panel          |

Agent states: `idle` (dim pulse) · `active` (bright pulse + fast ring spin)

## Stack

- [Three.js](https://threejs.org) 0.171.0 — 3D rendering
- [Vite](https://vitejs.dev) 5 — build + dev server
- `crypto.randomUUID()` — secure client session IDs (no external library)
