The pack
roomRun
function roomRun(): Pack<{ roomRun: RoomRunApi }>
The room-run pack: game.roomRun, Archero's rules. No options.
Helpers
checkRoomRunSave
function checkRoomRunSave(save: unknown, options: RoomRunOptions = {}): string | null
Why a save cannot be restored into a run made with these options, or null when it can: the room must be one of the
chapter's, the skills and choices the set's, every enemy one of the set's with the numbers it needs, every arrow and
bullet whole, the field null or a place and time, and the random stream a real one. restore throws with this reason.
createRoomAutopilot
function createRoomAutopilot(game: RoomRunGame, options: RoomAutopilotOptions = {}): RoomAutopilot
A room run's autopilot. It only reads game.
createRoomRun
function createRoomRun(options: RoomRunOptions = {}): RoomRunGame
Start a run. Throws, with every fault, on options validateRoomRun refuses.
roomBosses
const roomBosses: RoomBoss[]
The built-in bosses.
roomEnemies
const roomEnemies: RoomEnemyDef[]
The built-in enemies.
roomRosters
const roomRosters: RoomRoster[]
Which enemies come where in the built-in chapter.
roomSet
const roomSet: RoomSet
The built-in set: Archero's first chapter.
roomSkills
const roomSkills: SkillDef[]
The built-in skills.
validateRoomRun
function validateRoomRun(options: RoomRunOptions = {}): string[]
Check a run's options and set. Empty when it can be played.
Types
EnemyShot
interface EnemyShot
How an enemy shoots.
every: number— Seconds between volleys.pattern: 'aimed' | 'fan' | 'ring' | 'spiral'— The volley: one at the hero, a fan at the hero, a ring all round, or a ring that turns each volley.count?: number— Bullets a volley. Default 1.spread?: number— A fan's spread in radians. Default 0.6.speed: number— Bullet speed, units a second.damage: number— Damage a bullet.warn?: number— Seconds it shows it is about to fire (and holds still). Default 0.5.
RoomArrow
interface RoomArrow
One of the hero's arrows in flight. Positions are in the layout's units, speeds in units a second.
id: number— Its id, unique in the run.x: number— Where it is across the room.y: number— Where it is down the room.vx: number— Its speed across.vy: number— Its speed down.damage: number— Damage it does.pierce: number— Enemies it may still pass through.ricochet: number— Times it may still jump to another enemy.bounce: number— Times it may still bounce off a wall.hits: number[]— Ids of the enemies it has hit, which it does not hit again.life: number— Seconds it has left.
RoomAutopilot
interface RoomAutopilot
A player that picks the way to walk and the choices.
next(): { x: number; y: number; choose: number | null }— The way to walk now (zero to stand and shoot), and a pick when a choice waits.
RoomAutopilotOptions
interface RoomAutopilotOptions
How the autopilot plays.
prefer?: string[]— Skill ids in the order it takes them. Default the arrow skills first.wary?: number— How close it lets an enemy come before it backs off. Default 70: further off, it stands and shoots.
RoomBoss
interface RoomBoss
A boss and the room it holds.
room: number— The room, from 1, that the boss holds.enemy: string— Id of the boss'sRoomEnemyDef.
RoomBullet
interface RoomBullet
An enemy bullet in flight. Positions are in the layout's units, speeds in units a second.
id: number— Its id, unique in the run.x: number— Where it is across the room.y: number— Where it is down the room.vx: number— Its speed across.vy: number— Its speed down.damage: number— Damage it does to the hero.life: number— Seconds it has left.
RoomChoice
type RoomChoice = { kind: 'skill'; id: string } | { kind: 'heal'; amount: number }
A choice on offer.
RoomEnemy
interface RoomEnemy
An enemy in the room, as a save holds it. Positions are in the layout's units, times in seconds.
id: number— Its id, unique in the run.def: number— Index of its definition in the set'senemies.x: number— Its centre across the room.y: number— Its centre down the room.hp: number— Hit points left.maxHp: number— Hit points at full health.timer: number— Seconds until its next shot or move.warn: boolean— It is showing that it is about to fire or dash.dash: { vx: number; vy: number; t: number } | null— A dash under way: its velocity in units a second and the seconds left, or null.goal: { x: number; y: number } | null— Where a wanderer is heading, or null.goalT: number— Seconds until a wanderer picks a new goal.spin: number— A spiral shooter's turn so far, radians.flash: number— Seconds left of the flash after a hit.
RoomEnemyDef
interface RoomEnemyDef
An enemy.
id: string— Unique id; rosters, bosses and views refer to the enemy by it.hp: number— Hit points; above 0.speed: number— Units a second.radius: number— Body radius in arena units; above 0. It sets how the enemy meets walls, arrows and the hero.damage: number— Damage on contact.move: 'chase' | 'wander' | 'still' | 'dash' | 'fly'— How it moves: after the hero round the walls, about at random, not at all, in dashes at the hero, or flying over walls.shoot?: EnemyShot— How it shoots, if it does.xp: number— Experience for the kill.
RoomEvent
type RoomEvent = | { kind: 'room'; room: number; boss: string | null } | { kind: 'clear'; room: number } | { kind: 'door' } | { kind: 'shoot' } | { kind: 'hit'; enemy: string; damage: number; crit: boolean } | { kind: 'kill'; enemy: string; x: number; y: number } | { kind: 'warn'; enemy: string } | { kind: 'fire'; enemy: string } | { kind: 'hurt'; damage: number; hp: number } | { kind: 'level'; level: number } | { kind: 'angel' } | { kind: 'choose'; choice: RoomChoice } | { kind: 'over' } | { kind: 'won' }
Something that happened.
RoomHero
interface RoomHero
The hero's numbers, before skills.
hp: number— Hit points. Default 600.speed: number— Units a second. Default 150.radius: number— Its size. Default 14.attack: number— Damage an arrow. Default 50.rate: number— Volleys a second. Default 1.3.arrowSpeed: number— Arrow speed. Default 620.grace: number— Seconds after a hit with no other. Default 0.6.
RoomRoster
interface RoomRoster
Which enemies come to rooms, from a room on.
from: number— From this room (1 is the first).enemies: { id: string; weight?: number }[]— The enemies, by weight.count: [number, number]— How many to a room.
RoomRunApi
interface RoomRunApi
What the room-run pack adds to a game: game.roomRun.
create: typeof createRoomRun— Start a run.validate: typeof validateRoomRun— Check a run's options.checkSave: typeof checkRoomRunSave— Why a save cannot be restored into a run of these options, or null.set: typeof roomSet— The built-in set.autopilot: typeof createRoomAutopilot— A player for an attract mode or a test.
RoomRunGame
interface RoomRunGame
A run.
readonly state: RoomRunState— The live run state. Read it; do not write it.view().stateis a copy.readonly layout: ArenaLayout— The room now.readonly options: Readonly<{ hero: RoomHero; rooms: number; choices: number; set: RoomSet }>— The settings in force once defaults are applied: the hero, the chapter length, how many skills a level-up offers and the data set.move(x: number, y: number): void— Which way to walk; zero stands still (and shoots).choose(index: number): boolean— Take a choice by its place instate.choosing.step(dt: number): void— Advancedtseconds, in fixed steps of 1/60 s. Paused while a choice waits.view(): RoomView— What is where right now, as plain data a renderer can draw. The state in it is a copy.drain(): RoomEvent[]— Remove and return the events since the last call, oldest first. Only the latest 512 are kept.snapshot(): RoomRunSave— A plain-JSON copy of the whole run, for saving. The room's layout follows from the seed, so it is not stored.restore(save: RoomRunSave): void— Replace the run with a snapshot taken from a run created with the same options. Throwsroom-run.restore: …, changing nothing, on a savecheckRoomRunSaverefuses for these options.
RoomRunOptions
interface RoomRunOptions
A run's options.
seed?: number— The seed. Default 1.rooms?: number— Rooms in the chapter. Default 10.set?: RoomSet— Enemies, skills, rosters and bosses. DefaultroomSet.hero?: Partial<RoomHero>— The hero.choices?: number— Skills offered on a level-up. Default 3.xpFor?: (level: number) => number— Experience for each level, from level 1. Default 12, then 6 more a level.arena?: Omit<ArenaOptions, 'seed' | 'start' | 'exit'>— How the rooms are generated (arena-layout's options, the seed and start and exit aside). Default 11 by 15 cells of 40.angels?: boolean— An angel after each boss room but the last. Default true.
RoomRunSave
interface RoomRunSave
A run saved as plain JSON (the room's layout follows from the seed).
state: RoomRunState— The run state, asRoomRunGame.statehas it.enemies: Enemy[]— The enemies alive in the room.arrows: Arrow[]— The hero's arrows in flight.bullets: Bullet[]— Enemy bullets in flight.queue: number[]— Run times, in seconds ofstate.time, at which the multishot skill's repeat volleys are still due.serial: number— The last id handed out to an enemy, arrow or bullet; the next one is this plus 1.grace: number— Seconds of immunity left after the hero's last hit.fire: number— Seconds until the hero's next volley.after: 'fight' | 'clear'— The phase to return to when the pending choice is taken: 'fight' or 'clear'.field: { x: number; y: number; t: number } | null— Where the chasers' flow field was made (the hero's position then) and the secondstuntil it is remade; null if there is none.rng: RngState— The state of the run's random generator.
RoomRunState
interface RoomRunState
Where the run stands.
time: number— Seconds played; frozen while a choice waits and once the run is over or won.room: number— The room, from 1.rooms: number— Rooms in the chapter, fromRoomRunOptions.rooms.phase: 'fight' | 'clear' | 'choose' | 'over' | 'won'— Fighting; the room clear and its door open; a choice waiting (paused); the run lost or won.x: number— Hero x in the room, in arena-layout units (the layout'scellis the cell size, 40 by default); 0 is the left wall.y: number— Hero y in the room, in the same units asx; 0 is the top.hp: number— Hit points left; the run is lost when it reaches 0.maxHp: number— Hit points at full health; skills can raise it.aim: number— The way it aims, radians.level: number— Hero level, from 1.xp: number— Experience gathered towards the next level; the surplus carries over when a level is gained.nextXp: number— Experience needed for the next level, fromRoomRunOptions.xpFor.kills: number— Enemies killed this run.skills: Record<string, number>— Skills taken, by id, with how many times.choosing: RoomChoice[] | null— The choices on offer whilephaseis 'choose', otherwise null. Take one withchoose(index).pending: number— Level-ups still to choose.
RoomSet
interface RoomSet
A whole run's data.
enemies: RoomEnemyDef[]— Every enemy the set uses; ids must be unique.skills: SkillDef[]— The skills a level-up can offer; at least one.rosters: RoomRoster[]— Which enemies come to which rooms; at least one roster must start at room 1.bosses: RoomBoss[]— Boss rooms; each holds one boss instead of a roster.
RoomView
interface RoomView
What is where.
state: RoomRunState— A copy of the run state.layout: ArenaLayout— The current room's arena layout: walls, open cells, start and exit.radius: number— The hero's radius, in the layout's units.door: { x: number; y: number; open: boolean }— The exit door: its centre and whether it is open (the room is clear or the chapter won).enemies: { id: number; kind: string; x: number; y: number; r: number; hp: number; maxHp: number; warn: boolean; boss: boolean; flash: boolean; seen: boolean }[]—seen: one of the hero's front arrows has a clear line to it, so the hero aims at the nearest such.arrows: { id: number; x: number; y: number; angle: number }[]— The hero's arrows in flight;angleis the heading in radians.bullets: { id: number; x: number; y: number; vx: number; vy: number; r: number }[]— Enemy bullets in flight;vxandvyare units per second andris the bullet radius in layout units.
SkillDef
interface SkillDef
A skill.
id: string— Unique id;RoomRunState.skillsis keyed by it.name: string— Name shown when the skill is offered.effect: SkillEffect— What the skill changes; seeSkillEffect.value: number— Per pick: arrows for front, multishot, diagonal, side, rear; hits for ricochet, pierce, bounce; a fraction for attack, speed, crit, maxHp, heal.max?: number— How many times it can be picked. Default 1.
SkillEffect
type SkillEffect = | 'front' | 'multishot' | 'diagonal' | 'side' | 'rear' | 'ricochet' | 'pierce' | 'bounce' | 'attack' | 'speed' | 'crit' | 'maxHp' | 'heal'
What a skill does.


