Melee

Arc, circle and line strikes with a visible windup, an active window that hits each target once through combat.damage, and a recovery, for players, enemies and traps.

Source: module-kits:kits/combat_melee/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs combat-meleeMCP tool: gripforge_docs { "topic": "combat-melee" }

Timed melee strikes (combat.melee) #

What it is for #

combat.melee computes timed strikes: windup, active window, recovery, end. On each tick of the active window it tests the living entities of another team inside the shape (an arc of a given angle, a circle around the source, or a line band), widened by hitRadius and the body radius, and deals the damage once per target through combat.damage (see the combat guide). The first tick that connects extends the window by hitStop. There is one strike per source; a new one cancels the previous one. Timers stop while the game is not playing. Weapons, enemy attacks, traps and boss patterns are all built from it. The presentation draws the shape flat on the ground as a telegraph, the blade trail as a ribbon and soft weapons (whips, chains) with their trail and light.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "combat.melee" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "combat.melee",
                              config: { "hitRadius": 0.4, "hitStop": 0.04, "followSource": true } }

It requires combat.core (health and damage) and game.engine.

First example #

<!-- test: kits/game_engine/host/tests/parity.rs::rust_host_matches_the_typescript_traces (fixture combat.melee.strikes) --> With the hit radius at 0.3, start a swing of the player entity e1, then ask whether it is busy. The call answers the strike id (st1 for the first one). The same fixture then saves, reloads, starts a line strike and an enemy circle strike, and the replay checks every result.

{ "op": "call", "service": "combat.melee", "method": "strike",
  "args": [{ "source": "e1", "kind": "attack", "shape": "arc", "range": 2, "arc": 90,
             "damage": 5, "windup": 0.1, "active": 0.1, "recovery": 0.2, "knockback": 1 }] }
{ "op": "call", "service": "combat.melee", "method": "busy", "args": ["e1"] }

Settings and defaults #

SettingDefaultMeaning
hitRadius0.4Body radius added to every shape test, in metres (0 to 2).
hitStop0.04Seconds the active window is extended when a strike connects (0 to 0.2).
followSourcetrueArc and line strikes follow their source while they run.

All three are moddable.

Services #

Service combat.melee:

  • strike(request): starts a strike and returns its id, or an empty id when the source is unknown or a tap refused it. The request has source and optional kind (attack by default; special, dash, status, boon, enemy, hazard or script), team (else the team of the source), shape (arc by default, circle, line), range (1), arc (90), width (1), offset, damage, windup, active, recovery (seconds), knockback, lunge, tags, at (a fixed point), yaw and blade.
  • cancel(source) and busy(source).
  • hits(shape, ...): the geometry test the kit uses.
  • Equipped melee driver (Rust, with the moveset and defense kits): weaponCommand(entity, command) with light, heavy or dodge, weaponCompatible, movementScale(entity), defendRanged(...), bladeSample(track, time) and bladeContact(query).

Script verb strike { instance | entity, ...keys }: the strike of an instance, taken from its melee component with the keys given overriding it. The component combat.hurtboxes gives named capsules for blade contacts.

Events #

  • combat.strike.started, combat.strike.hit (strike, source, targets) and combat.strike.ended (cancelled).
  • melee.contact (Rust blade contacts, once per strike and target), melee.move and melee.defended (equipped melee driver); combat.fired is sent with melee: true when a move starts. The kit listens to entity.despawned.

Hooks and modding #

HookMutableEffect
melee.strikerange, arc, width, offset, damage, windup, active, recovery, knockback, lungeA strike is about to start. Cancelled: strike returns an empty id and the running strike goes on.
melee.hitdamage, knockbackOne target of a running strike is about to be damaged. Cancelled: the target is skipped like a blocked hit and may be asked again on the next tick.

The three settings are moddable.

Engines #

Web and the native player run the Rust implementation; Godot, Unity and Unreal receive the strike logic as files and keep the simulation of kit version 1.2. The equipped melee driver and the blade contacts are Rust only.

When it does not do what you expect #

  • Nobody is hit: the target has no health in combat.health, is on the same team (a source without a team hits any team) or is outside the shape; check range, arc and offset.
  • The strike does not start: the source entity does not exist, or melee.strike was cancelled.
  • A target is hit once only: by design, each target is hit once per strike.

Limits #

One strike per source. No animation playback or weapon inventory: use weapons.loadout for the player weapon as data.

Versions #

Kit 1.9.0. Hooks since 1.3.0, equipped melee driver since 1.4.0. Requires combat.damage 1, combat.health 1 and game.engine 1.