---
title: "The Dispatcher — How I orchestrate 13 AI agents on a game dev project"
description: "Deep dive into Aekan's dispatcher: a Node.js engine that drives 13 Claude agents autonomously, with learning, evaluation, and automatic coordination."
date: 2026-04-06T15:00:00+02:00
tags: ["Aekan", "Todo", "AI", "Tooling", "Software Architecture"]
image: /images/projects/todo-card.webp
---

In the article about [Todo](/blog/todo-agent-driven-kanban), I talked about a lightweight kanban designed to be driven by agents. But a kanban, even with a good API, doesn't run a team by itself. You need a conductor — something that watches the board, decides who does what, launches agents, and makes sure work keeps moving.

That's the role of the **dispatcher**.

---

## The idea

When I work on **Aekan: Call of Ruligon** (an open-world procedural exploration game in Unity), I don't launch agents by hand. I start the dispatcher, and it takes care of the rest.

The dispatcher is a Node.js script that runs in a loop and orchestrates **13 specialized agents** — each with its own role, skills, and memory. It connects to [Todo](https://github.com/Ekioo/Todo)'s API to read the board and dispatches work automatically.

No external cron job, no GitHub Actions workflow, no message queue. One script, one loop, one board. Simple.

![Dispatcher Architecture](/images/blog/dispatcher-architecture.en.svg)

---

## The agents

Each agent is a Claude instance with a dedicated **skill file** — a Markdown document that describes its role, constraints, and tools. Here's the team:

- **Producer** — coordinates, prioritizes, breaks features into actionable tickets
- **Game Designer** — designs mechanics, systems, gameplay loops
- **Narrative Designer** — writes lore, dialogue, narrative direction
- **Programmer** — implements in Unity (C#, ECS, shaders, systems)
- **Technical Artist** — visual pipelines, materials, effects, HDRP
- **3D Artist** — modeling, UVs, procedural assets
- **QA Tester** — tests, reproduces, reports bugs
- **Sound Designer** — sound design, ambiances, SFX
- **Community Manager** — writes devlogs, announcements, communications
- Plus a few support roles: **Groomer**, **Documentalist**, **Code Janitor**, **Evaluator**

Each agent has its tools (file read/write, Git, Todo API, Bash) and its limits (no direct commits — only the owner pushes).

---

## Dispatching: who does what, and when

Every 30 seconds, the dispatcher queries the Todo board and looks at pending tickets. The routing logic is simple:

1. **A ticket is assigned to an agent?** → launch it
2. **The agent is already working on this ticket?** → wait
3. **The owner posted a comment?** → the agent resumes its session with the new context

The key distinction: agents are split into two categories.

- **Text agents** (producer, game-designer, narrative-designer, sound-designer, community-manager) — they work on documents, not code. They run **in parallel**, with no conflict risk.
- **Code agents** (programmer, technical-artist, 3d-artist, qa-tester) — they touch Unity project files. They run **one at a time**, sequentially, to avoid filesystem conflicts.

When an agent is launched, the dispatcher sets the ticket to "In Progress". When it finishes (or crashes), the status is restored. No orphaned ticket stuck in "InProgress" forever.

![Ticket Lifecycle](/images/blog/dispatcher-ticket-lifecycle.en.svg)

---

## Secondary loops

The dispatcher doesn't just route tickets. It runs several loops in parallel:

### The Groomer (every 5 minutes)

Before dispatching a ticket to an agent, it checks that the description is sufficient. If it's under 50 characters, the groomer runs first to enrich it — adding context, acceptance criteria, references. An agent that receives a well-written ticket works better.

### The Documentalist (every 60 seconds)

It watches commits. When I push code, the documentalist wakes up, analyzes the diff, and updates the project specifications. Documentation stays in sync with code without manual effort.

### The Code Janitor (daily)

When there's no pending code work, the janitor quietly improves code health — cleanup, conventions, safe refactors. It respects the sequential code agent slot.

### The Evaluator (every 30 minutes)

After each completed ticket, the evaluator computes KPIs per agent:

- **First-pass success rate** — does the ticket reach Done without round-trips?
- **Feedback compliance** — does the agent address owner comments?
- **Delivery quality** — does the final comment describe the work and testing?
- **Block rate** — proportion of tickets that hit Blocked status

These scores are written to each agent's memory file. They serve as structured feedback to improve performance over time.

---

## Learning

This is the part that changes everything. When a ticket moves to **Done**, the dispatcher triggers a **learning session** for the assigned agent.

The agent re-reads the ticket, the owner's comments, recent commits, and draws lessons. These lessons are written to its `memory.md` file — a journal of 50 lines max that evolves continuously.

If a lesson is confirmed by multiple experiences, it can be **promoted**:

- To the agent's **skill file** (its permanent instructions)
- To the shared **knowledge base** (accessible to all agents)

Result: agents improve ticket after ticket. The programmer who was corrected on a naming convention won't make the mistake again. The game designer who learned the owner prefers short descriptions adjusts its style.

![Learning Loop](/images/blog/dispatcher-learning-loop.en.svg)

---

## Session continuity

A detail that makes a big difference: agents **resume their session** when they come back to a ticket.

If Claude worked on ticket #42 yesterday, and I post a comment today, the dispatcher relaunches Claude with the same session ID. It has all the context of what it did — files read, modifications made, decisions taken. No need to rediscover everything.

This is what makes the workflow fluid. Posting a comment like `@agent:programmer can you also add a fallback for when the terrain isn't loaded?` is enough. The agent resumes, reads the comment, adjusts, and delivers.

---

## Why a custom engine

You could orchestrate agents with LangChain, CrewAI, or AutoGen. I looked into it. The problem is that these frameworks impose their abstractions — chains, graphs, vector memory — and they quickly become opaque when you want fine-grained control.

My dispatcher is **one file**. No magic dependencies, no framework, no vector database. A Node.js script that calls the Todo API and spawns Claude subprocesses. I can read the code end to end in an hour, and modify any behavior in five minutes.

When you build an agentic system for a real project (not a demo), maintainability matters more than architectural elegance. A flat file I understand will always beat a framework I have to debug.

---

## What it looks like day to day

In the morning, I start the dispatcher and Todo. I look at the board, create a few tickets or adjust priorities. Then I work on something else — or on the same project, in parallel with my agents.

Tickets move forward. Agents comment on their progress. I review when it's ready. If an agent is blocked, it mentions `@owner` and the ticket shows up in my queue. If I want to correct a direction, I post a comment and the agent picks back up.

It's asynchronous management. The board is the source of truth, comments are the communication channel, and the dispatcher makes sure nobody stays idle.

---

## Follow the development

The dispatcher isn't open source yet — it's very tied to the Aekan project for now. But if the approach interests you, [Todo](https://github.com/Ekioo/Todo) is available right now and it's the foundation everything else is built on.

Join me on **Discord** to follow the system's evolution and ask questions.

**→ [Join the Discord](https://discord.gg/4MVPfw9wTQ)**
