The pack
platformHazards
function platformHazards(): Pack<{ platformHazards: typeof api }>
Install the platform-hazards API (game.platformHazards).
Helpers
hazardBehaviours
function hazardBehaviours(hooks: BehaviourHooks): Record<string, EnemyBehaviour>
The behaviours: register them with createEnemies({ behaviours: hazardBehaviours(hooks) }), then name one as a kind's
move: { type: 'custom', name }.
hunter: walks, turns at walls, jumps up through platforms toward a higher target, takes running jumps, decides at edges (edge: 'smart' falls toward a lower target, 'turn', 'fall'), optionally shoots (shoot,shootEvery,shootRange,shootRows,aim), dashes (dashspeed factor,dashRange,dashTime) and drifts toward the target (chase). Zen-chan, Mighta, Hidegons, Drunk; Titchi, Botchan, Boodoro, Sarada, Botom.wall-flyer: flies left and right, rebounding off walls, drifting vertically toward the target (vertical). Pulpul.invader: flies across, stepping down a row everydropEveryseconds, firing straight down. Invader.spring: bounces along in jump arcs, turning at walls. Banebou.sentry: stays put and fires (shoot,shootEvery,aim). Doskoi.perch: rests forrestseconds, then flies diagonally, rebounding, forflyseconds. Batchi.boss: holds a side of the screen (side: -1 left, 1 right, 0 anywhere), hops (hopEvery), summons minions (summon,summonEvery) and fires; withflyit ricochets diagonally instead. Mogera, Super Drunk.
Classes
Chasers
class Chasers
Invincible chasers.
constructor( private readonly map: PlatformMap, private readonly rng: Rng, )— Create over a map with a seeded random source (wanderers).get list(): Chaser[]— Copies.add(spec: ChaserSpec, x: number, y: number): string— Add a chaser at a point. Returns its id.step(dt: number, targets: { x: number; y: number }[]): void— Step toward the nearest of the given targets (positions of live players).hits(l: number, t: number, r: number, b: number): Chaser[]— Chasers overlapping a rectangle.teleport(id: string, x: number, y: number, stun = 0.6): void— Move a chaser somewhere else and stun it (a pumpkin head hit by snow).remove(id: string): void— Remove one.clear(): void— Remove every chaser.count(kind?: string): number— How many, optionally of a kind.snapshot(): { items: Chaser[]; seq: number }— Serialisable state.restore(s: { items: Chaser[]; seq: number }): void— Restore.
EnemyShots
class EnemyShots
Enemy projectiles.
readonly max: number— At most this many at once (resource bound).constructor( private readonly map: PlatformMap, max = 128, )— Create a pool over a map.get list(): Projectile[]— Copies of every projectile.fire(owner: string, spec: ShotSpec, x: number, y: number, dir: -1 | 1, target?: { x: number; y: number } | null): string | null— Fire a projectile from a point.diris the firer's facing;targetaims 'target' shots. Returns the id or null when full.step(dt: number): void— Advance every projectile one step.hits(l: number, t: number, r: number, b: number): Projectile[]— Projectiles overlapping a rectangle.remove(id: string): void— Remove one projectile.clear(): void— Remove every projectile.snapshot(): { items: Projectile[]; seq: number }— Serialisable state.restore(s: { items: Projectile[]; seq: number }): void— Restore a snapshot.
Types
BehaviourHooks
interface BehaviourHooks
What the behaviours may ask of the rules.
shoot(enemyId: string, shot: string, target: WalkerBody | null): void— Fire the named projectile from an enemy (the rules own the projectile table).summon(enemyId: string, kind: string): void— Spawn a minion next to an enemy (bosses).
Chaser
interface Chaser
An invincible chaser.
id: string— Stable id.kind: string— Spec kind.move: ChaserSpec["move"]— Movement.x: number— Centre x.y: number— Centre y.vx: number— Velocity x.vy: number— Velocity y.speed: number— Current speed.base: number— Starting speed.accel: number— Acceleration.max: number— Top speed.tire: number— Seconds before tiring (1e9: never).size: number— Size.deadly: boolean— Harmful.age: number— Seconds alive.axis: "x" | "y"— Axis being lined up ('axis' movers).snapped: boolean— Moved discontinuously (teleported) this step.stunned: number— Seconds left stunned (pumpkin hit by snow).shotHit: "none" | "teleport"— What a player's shot does to it.
ChaserSpec
interface ChaserSpec
How a chaser moves.
kind: string— Free name ('baron', 'pumpkin', 'ghost').move: "axis" | "home" | "wander"— 'axis': lines up with the target on one axis, then the other, alternately (Baron von Blubba); 'home': flies straight at the target (slime ghost); 'wander': drifts around the screen, rebounding off the edges (pumpkin head).speed: number— Starting speed, units per second.accel?: number— Speed gained per second. Default 0.max?: number— Top speed. Defaultspeed.tire?: number— Seconds of chasing after which it slows back to its starting speed (Baron). Default never.size?: number— Size (square). Default 16.deadly?: boolean— Harmful on touch. Default true.shotHit?: "none" | "teleport"— What a player's shot does to it: nothing, or it is stunned and thrown somewhere else on the screen (Snow Bros' pumpkin head). Default 'none'.
Projectile
interface Projectile
A projectile in flight.
id: string— Stable id.kind: string— Spec name.owner: string— Firing body id.x: number— Centre x.y: number— Centre y.vx: number— Velocity x.vy: number— Velocity y.w: number— Width.h: number— Height.age: number— Seconds alive.life: number— Seconds it lives.travelled: number— Distance flown.range: number— Distance before it vanishes or turns back (1e9: unlimited).gravity: number— Gravity.bounce: boolean— Rebounds off walls.returns: boolean— Turns back after range.returning: boolean— Has turned back.through: boolean— Ignores the map.burn: number— Burning patch seconds on impact.burning: boolean— A burning patch (no longer moving).
ShotSpec
interface ShotSpec
How an enemy projectile flies. Speeds in units per second, sizes in world units.
kind: string— Free name for renderers and rules ('rock', 'fireball', 'bottle', 'laser', 'bomb').speed: number— Speed along the aim.w: number— Width.h: number— Height.aim?: "facing" | "down" | "target" | "arc"— 'facing' (straight ahead), 'down' (straight down), 'target' (at the target), 'arc' (lobbed ahead). Default 'facing'.lift?: number— Upward launch speed for 'arc'. Default 160.gravity?: number— Gravity, units/s². Default 0 (arc: 520).life?: number— Seconds it lives. Default 4.range?: number— Distance before it vanishes (or turns back withreturns). Default unlimited.bounce?: boolean— Rebound off walls instead of breaking. Default false.returns?: boolean— Fly back toward the thrower afterrange(a boomerang bottle). Default false.through?: boolean— Ignore the map (lasers through floors). Default false.burn?: number— When it lands or hits a wall, leave a burning patch this many seconds (bombs). Default 0.


