Duel
A two-fighter arcade fight on one line: frame-timed attacks, guard, jumps, energy special, combos, rounds, reactive AI, local versus or solo.
Arcade duel, 2.5D (combat.duel) #
What it is for #
combat.duel is a complete versus-fighting game mode. Two fighters stand on a line; the kit simulates frame-timed attacks, high and low guard, jumps, projectiles, an energy special, three combos per fighter with their own clock, hit stop, rounds and a reactive opponent. It reads the duel.* and duel.p2.* input actions, mirrors the fighters as entities, publishes the round on variables, follows the arena scenes of game.engine and saves the whole match. The presenter draws it in 2.5D. It is the mode, not a building block for other kits: for the guard, parry and move logic as separate cores see the defense and moveset guides. Damage rules of the wider family are in the combat guide.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "combat.duel" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "combat.duel",
config: { "roundSeconds": 60, "winsRequired": 2, "difficulty": 0.55 } }
It requires input.actions and game.engine, and cannot be installed with a character kit (character.third_person, character.top_down, character.platformer), fps.tactical or race.kart. Assets to provide: fighter_a, fighter_b (rigged characters with idle, walk, guard, crouch, jump, punch, kick, projectile, super, hit, death, victory and combo1 to combo3 clips), duel_stage, and optional sounds and combo effects.
First example #
<!-- test: kits/game_engine/host/tests/combat_duel.rs::a_round_starts_and_a_punch_lands_in_local_versus --> Start a local versus match, wait for the intro (about 1.8 s), walk the first fighter up to the second and punch.
{ "op": "call", "service": "combat.duel", "method": "restart", "args": ["local"] }
{ "op": "step", "ticks": 110 }
{ "op": "key", "code": "KeyD", "down": true }
{ "op": "key", "code": "KeyJ", "down": true }
{ "op": "call", "service": "combat.duel", "method": "view", "args": [] }
The test sees duel.round, duel.attack and duel.hit events, duel.phase equal to fight, the second fighter at 92 health and the first fighter's energy meter at 12.
Settings and defaults #
| Setting | Default | Meaning |
|---|---|---|
roundSeconds | 60 | Length of a round (15 to 180). |
winsRequired | 2 | Rounds to win the match (1 to 5). |
moveSpeed | 3.5 | Walk speed in metres per second (1 to 7). |
arenaWidth | 14 | Width of the fighting line in metres (8 to 20). |
difficulty | 0.55 | Reactive AI strength (0 to 1), used in solo mode. |
firstStyle | boxer | Style of the first fighter: boxer or acrobat. |
secondStyle | acrobat | Style of the second fighter. |
comboColors | per style | #rrggbb colors combo1, combo2, combo3 for each style; an invalid color keeps the default. |
All are moddable. A scene whose world is { kit: "combat.duel", config? } is an arena: its config overrides the options for that scene, and first and second entries place the fighters. Entering the scene starts a new match; loading a save keeps the current one.
Services, events, variables #
- Service
combat.duel:restart(mode?)starts again inai(solo, default) orlocal(two players);view()returns the phase, clocks, mode, fighters (health, energy meter, style, combos) and shots;tactical(command)drives the resolution mode. - Events
duel.attack,duel.hit,duel.block,duel.shot,duel.round,duel.ko: payload{ type, x, y, actor, move?, damage?, strike?, limb?, finisher? },actorbeing 0, 1 or -1.duel.resolutioncarries the result of the tactical mode. - Variables
duel.phase(intro,fight,round_end,finished),duel.round,duel.remaining. - Actions: player one
duel.move(axis),duel.jump,duel.crouch,duel.guard,duel.punch,duel.kick,duel.projectile,duel.super, combo actions numbered 1 to 3; player two has the same set underduel.p2moveand the prefixduel.p2.(jump, crouch, guard, punch, kick, projectile, super and combos 1 to 3).
Hooks and modding #
| Hook | Mutable | Effect |
|---|---|---|
duel.attack | cost | A fighter is about to start a buffered move; cancel or too little energy: it does not start (the input stays buffered for 0.14 s). |
duel.guard | blocked | A strike reached a fighter; decide whether the guard holds. |
duel.hit | damage | A strike is about to land after the guard; cancel: nothing lands. |
duel.end_round | winner | A round is over (timeout says why); give it to either fighter or call a draw with -1. |
Engines #
Web and the native player run the Rust simulation. Godot, Unity and Unreal receive the gameplay as files and keep the simulation of kit version 1.2 until the hooks are ported to them.
When it does not do what you expect #
- Nothing happens after
restart: wait for the intro to finish (duel.phaseisfight). - The kit refuses to install: a character, tactical shooter or kart kit is already installed (they conflict).
- The second fighter ignores the second player keys: in the default
aimode it is the AI; userestart("local")for two players.
Limits #
Two fighters, one line, one arena. The arcade moves are the kit's own: it does not read arbitrary movesets from combat.moveset.
Versions #
Kit 1.5.0 (optional Rust tactical adapter: simultaneous decisions and bounded prediction, live duel hooks refused in that mode). Requires input.actions 1 and game.engine 1.