What it does
Pick an enemy kind the horde already knows (its health, size and sprite) and describe it as a boss: a list of phases, each lasting until its health falls to a share. The pack takes every enemy of that kind over. The horde keeps its health, flinches, death and voice; the boss controller moves it and fights with it.
Each phase has a way of moving and a pattern of attacks. It might hold its ground, chase, strafe round the player or keep its distance, and fire volleys, rings, aimed bursts, charges, slams, summons and teleports in order or at random. Every attack has a wind-up the game can show and sound, so the player can learn the pattern. A new phase can roar, turn the boss invulnerable for a moment, heal it, bring reinforcements and give it armour.
Like the horde, it reports what happens as events: shots for the game to fly, summons to spawn, slam and charge damage.
So the same bosses fight on a cell-dungeon corridor map or a sector-map level.
Features
- Phases by health — each with its own movement, attacks, pace and armour.
- Seven attacks — volleys, rings, bursts, charges, slams with knockback, summons and teleports.
- Warnings — every attack winds up first, as an event to draw and sound.
- Phase entrances — a roar, invulnerability, healing and reinforcements.
- A health bar — names, health and phase for each boss.
- Any map — works wherever
fps-enemiesdoes.
Good for
- The end of an episode — a three-phase guardian, as in
sector-shooter's Warden. - An arena finale — a teleporting boss after the waves.
- A mini-boss in a corridor — a single phase of volleys and a charge.
Make it yours
Phases, movement, attacks, timings, armour and entrances are all data. A slow chaser that fans fireballs, then strafes and rings the room, then charges and slams is one boss; a sniper that keeps away, teleports behind you and summons drones is another.
A quick look
Adopt the bosses among the enemies and run them each step.
const bosses = fpsBosses.createBosses([warden], horde, map.enemyWorld());
for (const e of horde.list()) bosses.adopt(e.id);
game.step('boss', dt => { for (const e of bosses.tick(dt, player)) apply(e); });
Works with
fps-enemies— the horde the bosses belong to.sector-shooter— uses it for its bosses.cell-dungeonandsector-map— the maps they fight on.
Good to know
- A boss fights one player and does not join in infighting.
- It draws nothing: show the wind-ups, the health bar and the shots yourself.






