Stealth takedown

Usage guide of stealth.takedown: silent takedowns from behind, carrying, dropping and stowing bodies, hiding spots for the player, settings, service, events and hooks.

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

Also read offline — CLI: grip-forge docs stealth-takedownMCP tool: gripforge_docs { "topic": "stealth-takedown" }

Stealth takedowns and hiding (stealth.takedown) #

What it is for #

The player side of stealth. The player sneaks up behind a perceiver that has noticed nothing and takes it down silently, carries the body and hides it in a container before someone finds it, or hides in a locker, a wardrobe or under a bed so nothing can see them, then steps out again. It works on the perceivers of Stealth perception and offers its actions through the interaction prompt (see Interaction guide). Animations, models and the guards' patrols stay with the other kits.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "stealth.takedown" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "stealth.takedown",
                              config: { "reach": 1.6, "behindAngle": 120, "immuneTags": ["boss"] } }

It requires stealth.detection, interaction.use, npc.behavior and game.engine. A hiding place is an entity with the hiding_spot component:

{ "label": "Hide in the locker", "capacity": 1 }

First example #

<!-- test: kits/game_engine/host/tests/parity.rs::rust_host_matches_the_typescript_traces (fixture stealth.takedown.bodies) --> The parity scenario puts a player among unaware guards, a locker and a crate, and replays the whole cycle: canTakedown is true only for a guard the player stands behind within reach, takedown lays it down (tag downed, event stealth.takedown), downed() lists the bodies, carry(body), drop() and stow(spot) move a body, and hide(spot) then leave() take the player in and out of a spot.

canTakedown ["e1"]   -> true or false, depending on where the player stands
takedown    ["e1"]   -> true       (the guard lies down: a body others may find)
carry       ["e1"]   -> true
stow        ["e4"]   -> true       (event stealth.body_hidden: nobody will find it)

Settings and defaults #

SettingDefaultMeaning
reach1.6how close behind a perceiver the player must stand (m)
behindAngle120the player must stand at least this far (degrees) off the perceiver's facing
allowSuspiciousfalsealso take down a suspicious perceiver (never a searching or alert one)
immuneTagsstalker, bossperceivers with one of these tags are never taken down
noiseRadius2radius of the almost silent noise of a takedown (0: none)
noiseLoudness20suspicion that noise adds at its source
carryDistance0.6how far behind the player a carried body follows (m)
dropDistance0.9how far in front of the player a dropped body lands (m)
downClipdeathanimation of a downed body
takedownLabelTakedownprompt label
carryLabelCarry bodyprompt label
hideLabelHideprompt label
hideBodyLabelHide bodyprompt label
leaveLabelLeaveprompt label

A hiding_spot accepts label, player (the player can hide in it, default true), bodies (bodies can be hidden in it, default true), capacity (bodies it holds, default 1) and exit (metres in front where the player steps out, default 1).

Services, events, variables #

  • stealth.takedown (service): canTakedown(entity), candidate(), takedown(entity), downed(), carry(body), drop(), carrying(), stow(spot), hide(spot), leave(), hidingIn(), spots().
  • Events: stealth.takedown (a perceiver was taken down), stealth.body_carried, stealth.body_dropped, stealth.body_hidden (a body went into a spot: nobody will find it), stealth.hid, stealth.left.
  • Variables: takedown.count, takedown.carrying, takedown.hiding, takedown.available.
  • Script verbs: condition takedowns_at_least, NPC behaviour stealth_down.

A downed body stays a body that other perceivers can find until it is stowed. State is kept in the components stealth.body, stealth.spot and stealth.hiding, saved with their entities.

Hooks and modding #

HookPayloadEffect
stealth.take_downentity, player, noiseRadiusmutable noiseRadius; cancelled: nothing happens and takedown() answers false
stealth.body.carrybodycancelled: the body stays where it lies
stealth.body.dropbodycancelled: the player keeps carrying it
stealth.body.stowbody, spotcancelled: the player keeps carrying it
stealth.hidespotcancelled: the player stays outside
stealth.leavespot, exitmutable exit; cancelled: the player stays inside
{ "id": "silent_arms", "hook": "stealth.take_down", "set": { "noiseRadius": 0 } }

A mod may override every setting above.

Engines #

The web player and the native kit host run the same rules. Hiding and leaving move the player through character.control; the stealth_down behaviour is handed to npc.behavior. A status pastille on the HUD shows hidden, carrying a body, or a takedown within reach.

When it does not do what you expect #

  • canTakedown is false: the perceiver is searching or alert (or suspicious without allowSuspicious), too far, not behind enough, or carries an immune tag.
  • The prompt shows but the takedown does nothing: a tap of stealth.take_down cancelled it; use immuneTags to hide the prompt too.
  • A body cannot be stowed: the spot has no bodies or is at capacity.

Limits #

  • It does not detect anything: awareness belongs to stealth.detection.
  • Only perceivers of stealth.detection can be taken down, and only the player takes them down.

Versions #

Kit 1.1.1, service contract 1.0.0. 1.1.0: the game.engine hook contract; 1.0.0: first release.