Game jam · 13 days · built with AI agents
Orb Knight: a 3D browser roguelite in 13 days
Gamedev.js Jam 2026 handed everyone the same theme — Machines — and the same 13 days. I had a decade of production web work behind me and exactly zero shipped games, so the bet was simple: build a real-time 3D action game in the browser, point coding agents at the implementation, and keep architecture, review and playtesting firmly in my own hands. Orb Knight came out the other side: a brass machine with a sword, a gun and a laser, cutting its way out of a foundry. It took 6th in Gameplay and 12th overall out of 495 entries.
01 · The result
6th in Gameplay, and one honest 79th
The category I care about most is Gameplay — how the game actually feels in your hands. Orb Knight scored 4.027/5 there, 6th across the whole jam, and players specifically called out the combat. The scoreboard is also honest about the weak spot, and I'll get to that.
02 · What shipped
A machine knight and the foundry it escapes
The submitted build is a complete run: fight through seeded foundry rooms, collect gears, rebuild your machine at the loadout bay, survive the shop keeper's prices, beat the Gate Keeper, and break out onto the castle road. Roughly 56k lines of TypeScript and Svelte, 113 commits, one browser tab — SvelteKit and Svelte 5 runes for the shell, Threlte and Three.js for rendering, Rapier for physics, Bun for everything else.
Combat that carries the game
Third-person movement, a sword, a gun and a chargeable laser against 12 enemy types and 3 bosses. Movement, hit resolution, Rapier physics, camera and enemy AI all share one frame budget.
Runs with actual structure
29 room templates across 7 kinds — combat, challenge, treasure, shop, secret, boss — validated with Zod and stitched into seeded dungeon layouts. Gears buy modules; 21 of them reshape your build mid-run.
Sound made of math
Every sound effect is synthesized in Web Audio at runtime — noise buffers and oscillators through a compressor. No sample packs; the laser windup, door grind and metal-shatter death are all code.
03 · Build log
13 days, compressed
The commit history tells the story better than any retrospective, so here it is, lightly annotated. 113 commits between April 15 and April 27.
- Apr 15
First Threlte prototype
A capsule, some targets, projectile shooting and a crosshair. Not a game yet, but it renders and shoots.
- Apr 18–21
Rooms become a language
Room templates move into JSON with a Zod schema, dungeon layout gets seeded generation, and the first real enemies start applying pressure.
- Apr 22–23
The outside world
Overworld chunks derived from the dungeon seed, road and grass shaders, a vegetation registry. The foundry gets somewhere to break out to.
- Apr 24
Loadout bay and adaptive music
The machine module bay lands — swap attack, body, utility and melee modules mid-run — and the soundtrack starts reacting to game state.
- Apr 25
The 25-commit day
Laser beam with charge-up, the shop and its keeper NPC, the Gate Keeper boss, the core prison setpiece, and a full pass of procedural SFX. The busiest day of the jam.
- Apr 26
Performance debt, all at once
Pixel-ratio cap, shadow-pass cuts, lights that mount only when their room is active, material pre-warming. Frame time on mid hardware finally behaves.
- Apr 27
Ship it
Run state persists across menus, resume works, screenshots taken, itch.io build uploaded with hours to spare.
04 · Live scenes
Poke the actual game
These are the same Storybook fixtures I used to build Orb Knight, embedded live — real production renderer, physics and AI with pinned state, so you can play with one system without fighting through a run to reach it. They're full WebGL apps, so only one runs at a time; there's also the complete Storybook if you want everything.
Scene 01 · Laser
Charge-up laser, live
The Laser Beam module in its weapon lab. Hold fire to charge, sweep the beam through targets, switch to the other five builds — split arc, wave, lob, rockets — in the panel. The electric windup you hear is synthesized in Web Audio; this weapon and its sound shipped together on the 25-commit day.
Scene 02 · Final boss
Gate Keeper sandbox
The final boss with its full moveset and none of the commute: triple shots, and a sweeping arc laser you jump over like the world's angriest skipping rope. This fixture is where its timings were tuned.
Scene 03 · Room grammar
Lava Lane, from JSON
One of 29 room templates: layout, hazards, platforms and enemy formation defined in JSON, validated with Zod, then assembled by the same code that builds every room in a seeded run. Lava included at no extra charge.
Scene 04 · The finale
Castle road, unlocked
What the whole run points at: the outside world past the broken dome. Seeded terrain chunks, road and grass shaders, and the gate that only opens when the Gate Keeper stops arguing.
Scene 05 · Environment kit
Foundry wall modules
The foundry is assembled from code-defined frames, lamps, vents, pipes and gears — no imported level meshes. This fixture lays out the source modules and their composed variants under one camera.
Scene 06 · Loadout
Try-on bay with live stats
The module try-on fixture: swap any of the 21 modules and watch the character model, damage, fire rate, health, magazine and reload react instantly. Stat math and rendered result share one review surface — which is exactly how bugs in either got caught.
05 · The workflow
How the agent collaboration actually worked
Branches in the repo are literally named codex/* — agents wrote a lot of this game.
But "agents wrote it" undersells what the job became: decomposing systems into tasks small enough
to review, keeping state boundaries clean enough that a wrong implementation was cheap to throw
away, and playtesting every change because no agent can feel a bad camera. The split, roughly:
What stayed mine
- Scope: what the game is, and the growing list of what it is not
- System boundaries between combat, rooms, progression and UI
- Review of every change, plus integration and browser playtesting
- Game feel: timing, camera, feedback — tuned by hand, repeatedly
- The release call and the competition submission
What agents did
- Implementation passes across Svelte, Threlte, Three.js and Rapier
- First drafts of combat behaviors, room templates, enemies and UI
- Mechanical refactors that touch thirty files without complaint
- Storybook fixtures that pin runtime state for review
- Codebase archaeology: "where does the damage number actually come from?"
06 · Notes to future me
What I'd keep, what I'd change
One observable behavior per loop
The unit of work that survived: one behavior, one implementation pass, one browser check. Every time I batched more into a prompt, review cost grew faster than the code was worth.
Correct is not the same as good
Agents will happily ship combat that satisfies every stated rule and still feels like hitting cardboard. State machines can be delegated; feel cannot. Playtest, tune, repeat.
Storybook was the highest-leverage tool
Deterministic fixtures turned "run to the boss and hope" into "mount the boss with fixed state". Most agent output got reviewed inside these scenes — the same ones embedded above.
Innovation cannot be patched in later
Gameplay ranked 6th; Innovation ranked 79th. Both are fair. A competent roguelite loop is buildable in 13 days — a distinctive mechanic has to be there from day one, and mine was not.