What it does
The world is a grid of rooms addressed by coordinates. Each room has a pillar at every inner grid point, and each pillar grows one wall arm north, south, east or west. The original's generator derives those arms from the room's coordinates, so a world of 65,536 rooms needs no storage and a room looks the same every time you enter it; a hashed generator and authored rooms are there too. Walls are lethal to the player and to robots. Exits sit in the middle of the sides you choose, and the way you came in can be walled off behind you.
Robots spawn in slots by a density chance, wake after a short delay, walk toward the player in eight directions while refusing to cross nearby walls, and shoot when lined up horizontally, vertically or diagonally. How many robot bolts may be on screen, how often a robot may shoot and how fast bolts fly come from an escalation table indexed by your score. Robots die to walls, to each other, to each other's bolts and to the pursuer, and clearing a room pays a bonus for every robot it began with.
A shared movement clock gives the game its feel: robots and the pursuer take turns on one update, so a full room
crawls and the last robot moves at full speed. The pursuer enters at the doorway after a delay shortened by every kill,
bounces toward you through walls, and cannot be shot. You tick the game with a stick and a fire button, read state
for walls, robots, bolts, the pursuer, the player, the room and the score, and present the events it drains.
Features
- Rooms from coordinates — the original's generator, a hashed alternative or authored rooms, on a world that wraps.
- Electrified walls — pillars with one arm each, lethal to player and robots alike.
- Exits that close — exits on the sides you choose, with the entrance walled behind you if you like.
- Robots that escalate — eight-way seeking and shooting, with bolts, shot delay and fast bolts rising with the score.
- A room bonus — paid when the last robot dies, however it died.
- An unkillable pursuer — timed from the room's robots and bolts, sooner for each kill, bouncing through walls, and optionally deadly to robots too.
- Stand-and-shoot controls — hold fire to stand and shoot along the stick or your facing, with optional auto-fire.
- Difficulty — Arcade plays the tables exactly; Normal and Easy thin the robots, slow their fire and bolts and let them wake later.
- Deterministic — fixed 60 Hz steps, a seed and snapshots.
Good for
- Room-to-room robot shooters in the style of the 1980 arcade Berzerk.
- Maze shooters with time pressure, where lingering in a room lets the pursuer arrive.
- Dungeon-room shooters with authored rooms, smaller cells and side exits.
- Endless explorations, since rooms are generated from their coordinates on entry.
- Arcade collections that want the escalation, the movement clock and the pursuer to behave as remembered.
Make it yours
berzerkPreset returns the classic definition, and any field can then be replaced: the room grid and cell size, wall
thickness, exits and closing, the generator and authored rooms, the world size, the player's size, speed and bolts,
the robots' size, score, bonus, speed curve, spawn slots and densities, the escalation table, bolt speeds and aim
tolerances, and the pursuer's timing, speed, bounce and whether it kills robots.
Two very different games ship. The classic is a five by three grid of rooms with eleven spawn slots, robots that start
unarmed and arm as the score climbs, a pursuer that kills robots too, and three lives. mazeHuntPreset is a seven by
four grid of smaller cells with hashed mazes, side exits only and no closed entrance, a robot slot in every cell,
robots armed from the start with their own three-level table, faster robots, a faster pursuer that spares them,
held-fire auto-repeat and four extra lives.
A quick look
The classic game, ticked with a stick and a fire button, with its events and state:
const mr = game.mazeRooms;
const g = mr.createMazeRooms(mr.berzerkPreset());
g.tick(dt, { move: { x, y }, fire: keyDown('Space') }); // hold fire: stand and shoot along the stick
for (const e of g.drain()) { /* room-enter, robot-killed, room-bonus, player-killed, room-exit… */ }
const s = g.state; // walls, robots, bolts, the pursuer, player, room, level, score, lives
Works with
projectile-patterns— required: every bolt, the player's and the robots', is one of its shots.arena-layout— room graphs for finite authored maps, where rooms are not generated by coordinate.wave-arena— for waves in one open arena with families to rescue.
Good to know
- A room grid is at most 32 by 32 cells with 64 spawn slots, and
tickruns at most eight frames per call. - Collision uses boxes for actors and walls and circles for bolts, not pixel masks.
- The generators grow walls from pillars without checking connectivity; the classic grid has been checked across a 4,096-room sample, but other grids and authored rooms are yours to check.
- Robot pathing is the original's local wall sense, not a planner, so robots still walk into walls and each other.
- Bolt speeds, the player's box and the pursuer's bounce are estimates, and speech is left to your game.






