What it does
An attack is data: how long it winds up, how long it can hit, how long the fighter recovers, its reach, the width of
its arc, its damage and knockback, and which attacks can follow it inside a combo window. attack starts a move from
ready, or queues the next one if the current attack's window is open; the queued attack begins when the current one
completes. phase tells you whether a fighter is ready, in startup, active or recovery, blocking or stunned, so your
animation can follow it.
During the active time, a swing hits any fighter of another team within its reach plus that fighter's radius and
inside its arc, once per swing. A guard faced toward the attacker blocks the damage and cuts the knockback to 15 %;
a guard raised within the parry window, 0.14 seconds by default, parries and stuns the attacker. Hits from behind still
land. An optional canHit test lets walls stop a swing.
The pack owns no movement or health. You update positions, facing and who is alive before each tick, and drain
returns events, swing, hit, blocked, parried and complete, each with damage and a knockback vector for your
combat and collision code to apply.
Features
- Attack timelines — startup, active and recovery in seconds, with reach, arc, damage and knockback per attack.
- Combo windows — next attacks queued inside a window and started when the current attack completes.
- One hit per swing — each target struck at most once by a swing, and teammates never.
- Directional blocks and parries — a guard facing the attacker blocks; a fresh one parries and stuns it.
- Knockback as data — a vector away from the attacker in every hit event, reduced on a block.
- A duel bot — closes to striking range, swings, follows up and guards by seeded chance, with any moveset.
Good for
- Top-down action games with sword swings, shield blocks and parries.
- Arena brawlers where several fighters on two teams swing at once.
- Duels against an AI fighter, using the bot with your own moveset.
- Action RPG combat, where events feed your own health, damage and knockback systems.
- Server-side or headless checks, since the rules need no renderer, browser or input device.
Make it yours
The moveset is yours: duelAttacks supplies a quick jab and a slow, wide cleave that can follow each other, and any
list of your own attacks replaces it. Fighters carry a team, a radius and a facing, and the duel bot takes an opener,
a reach, an aggression rate, a combo chance, a guard chance, a reaction time and a seed.
Two different uses: a fencing duel of quick thrusts with narrow arcs, short combo windows and a bot that guards often
and reacts fast, where parries decide the fight; or a crowd brawl of wide, slow cleaves with heavy knockback on two
teams, where canHit keeps swings from passing through walls and the bot rarely guards.
A quick look
A hero and a foe, a jab, a tick, and the events to apply:
import { createMelee, meleeActor } from '@phaser-ae/melee-combat';
const melee = createMelee([
meleeActor('hero', 'party', 100, 100), meleeActor('foe', 'foes', 140, 100, Math.PI),
]);
melee.attack('hero', 'jab');
melee.tick(1 / 60);
const feedback = melee.drain(); // swing, hit, blocked, parried, complete
Works with
maths— used for the angle tests of arcs and facing.combat-rules— damage, healing, armour and status effects to apply hit events through.
Good to know
- The hit test is a 2D sector against a circle, with an optional occlusion test; it is not a skeletal hitbox system.
- Knockback is reported, not applied: the pack moves nothing.
- It is not an animation controller, a ragdoll or a full fighting-game ruleset.
- Tick in small fixed steps, so input windows and parry timing stay exact.






