What it does
A run is a chapter of rooms, one at a time, each laid out by arena-layout from the run's seed, from the bottom of
the room to a door at the top. You pass the way to walk; zero stands still, and standing still the hero shoots at the
nearest enemy one of its front arrows has a clear line to. Walking, it faces the way it walks and holds its fire. That
single rule is the genre's tension: every shot is a moment you are not dodging.
Killing enemies earns experience, and each level pauses the run with a draft of skills. Arrow skills add arrows side by side, repeat volleys, diagonal, side and rear arrows, ricochets that jump to another enemy, piercing and bounces off walls; hero skills raise attack, attack speed, crit chance and maximum health, or heal. Further level-ups queue while a choice waits, and when everything has been taken as often as it can be, a level offers a heal instead.
Enemies chase round the walls on a flow field, wander, stand still, dash at the hero then rest, or fly over the walls.
Shooters hold still for a moment before firing aimed shots, fans, rings or turning spirals, so a careful player can
read them. A boss holds its room alone, and after a boss an angel offers a heal or a skill. The pack draws nothing:
view() gives the room, the hero, every enemy with whether the hero can hit it, every arrow and bullet, and the door.
Features
- Stop to shoot — auto-aim at the nearest reachable enemy while standing, no fire while walking.
- Generated rooms — each room from the seed, with the arena's size, cell size and obstacle count as options.
- Skill drafts — a choice of skills each level, queued level-ups, and a heal when the pool is spent.
- Arrow skills — front, multishot, diagonal, side and rear arrows, ricochet, pierce and wall bounce.
- Hero skills — attack, attack speed, crits, maximum health and heals, each with a limit on how often it is taken.
- Enemy behaviours — chase, wander, still, dash and fly, with telegraphed aimed, fan, ring and spiral fire.
- Bosses and angels — boss rooms by number, and an angel after each boss but the last.
- A built-in chapter — bats, slimes, archers, mages, turrets and chargers, a golem and a warlock, and thirteen skills.
- An autopilot — dodges bullets, keeps away from walkers, hunts enemies, picks skills and walks to the door.
- Saves — the whole run as plain JSON that restores exactly, with a check that explains why a save does not fit.
Good for
- Stop-to-shoot roguelites in the style of Archero, with a chapter of rooms and a build chosen as you go.
- Mobile action games played with one thumb, where moving and stopping are the only controls.
- Short dungeon runs with a boss every few rooms and a reward after each.
- Bullet-reading shooters, where enemies telegraph rings and spirals before they fire.
- Attract modes and balance tests, with the autopilot playing a fair game from a seed.
Make it yours
createRoomRun takes a seed, the number of rooms, the set, the hero's health, speed, radius, attack, fire rate, arrow
speed and grace after a hit, the draft size, the experience curve, the arena's options and whether angels appear.
The set is { enemies, skills, rosters, bosses }: each enemy's health, speed, radius, damage, movement, shooting and
experience; each skill's effect, value and limit; rosters that say which enemies come to which rooms and how many;
and which rooms hold which boss. validateRoomRun lists every fault before you start.
Two different runs from the same rules: the built-in ten-room chapter with its golem and warlock and thirteen skills; or a twenty-room chapter of your own with a larger arena, five skill choices per level, flying enemies that fire rings from the start, a boss every fifth room and no angels.
A quick look
A run stepped from input, with the draft and the view for drawing:
const run = game.roomRun.create({ seed: 4, rooms: 10 });
run.move(input.x, input.y);
run.step(dt);
if (run.state.choosing) showCards(run.state.choosing); // then run.choose(i)
const v = run.view();
for (const e of v.enemies) drawEnemy(e.kind, e.x, e.y, e.warn, e.flash);
if (v.door.open) drawDoor(v.door.x, v.door.y);
Works with
arena-layout— generates each room and the movement round its walls.nav— the flow field enemies chase along.survivor-rules— for auto-firing weapons against a swarm on an endless field.wave-arena— for twin-stick arena waves.projectile-patterns— for bullet patterns in a game of your own.
Good to know
- Bodies are circles in a grid of walls, and enemies do not push one another apart; there is no physics engine.
- Shields, breakable walls, traps, pets, equipment, talents and a chapter map between runs are not modelled.
- Skills have no rarity or weights: a draft draws evenly from what can still be taken.
- The autopilot is a fair player, not a planner.






