# 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](guide:combat)). 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 ```text 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 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. ```json { "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 | Setting | Default | Meaning | |---|---|---| | `hitRadius` | `0.4` | Body radius added to every shape test, in metres (0 to 2). | | `hitStop` | `0.04` | Seconds the active window is extended when a strike connects (0 to 0.2). | | `followSource` | `true` | Arc 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 | Hook | Mutable | Effect | |---|---|---| | `melee.strike` | `range`, `arc`, `width`, `offset`, `damage`, `windup`, `active`, `recovery`, `knockback`, `lunge` | A strike is about to start. Cancelled: `strike` returns an empty id and the running strike goes on. | | `melee.hit` | `damage`, `knockback` | One 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.