Interaction system

Registers world entities as interactive, finds the closest one in reach of the player, shows its prompt with the player's own key, handles slow holds and refuses with a reason when a thing is locked or too far.

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

Also read offline — CLI: grip-forge docs interaction-systemMCP tool: gripforge_docs { "topic": "interaction-system" }

Interaction system (interaction.system) #

What it is for #

Registers world entities as interactive, finds the closest one in reach of the player, shows its prompt with the player's own key, handles slow holds and refuses with a reason when a thing is locked or too far.

It needs character.control, input.actions, game.engine; installing it brings them in.

Turn it on #

Install the kit in a project, then change a setting (the values shown are its defaults):

gripforge_gamekit_install   { project_id: "gkp_…", id: "interaction.system" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "interaction.system",
                              config: { "radius": 2.5, "action": "interact" } }

First example #

<!-- test: kits/interaction_system/tests/interaction_system.rs::the_thing_within_reach_becomes_the_candidate_with_a_prompt --> This is the body of the passing test the_thing_within_reach_becomes_the_candidate_with_a_prompt; the helper functions it calls are defined at the top of the same test file.

#[test]
fn the_thing_within_reach_becomes_the_candidate_with_a_prompt() {
    let (mut s, _, door) = scene(json!({}), [1.0, 0.0, 0.0], "Open door");
    step(&mut s, 1);
    assert_eq!(current(&mut s), json!(door));
    let p = prompt_var(&s);
    assert!(p.as_str().unwrap().contains("Open door"), "{p}");
    assert_eq!(call(&mut s, PROMPT, "text", json!([])).unwrap(), p);
    assert_eq!(
        call(&mut s, PROMPT, "label", json!([])).unwrap(),
        json!("Open door")
    );
    assert_eq!(
        call(&mut s, PROMPT, "action", json!([])).unwrap(),
        json!("interact")
    );
    assert_eq!(
        call(&mut s, PROMPT, "target", json!([])).unwrap(),
        json!(door)
    );
    assert_eq!(
        call(&mut s, USE, "labelOf", json!([door])).unwrap(),
        json!("Open door")
    );
    let seen = topics(&s, "interaction.available");
    assert_eq!(seen.len(), 1);
    assert_eq!(seen[0]["entity"], json!(door));
    assert_eq!(seen[0]["action"], "interact");
    // Still the same candidate a tick later: announced once.
    step(&mut s, 3);
    assert_eq!(topics(&s, "interaction.available").len(), 1);
}

Settings and defaults #

Descriptions come from the kit manifest and stay in English.

SettingTypeDefaultRange or valuesMeaning
radiusnumber2.50.5–10Reach in meters from the player.
actionstring"interact"Input action that triggers the use.
showPromptbooleantrue
holdSecondsnumber00–101.5.0: seconds the action is held before a use, for every interactive without its own hold (0: a press uses at once).
vehicleSchemestring"vehicle"1.6.0: the input.scheme scheme of a player at the wheel (input.scheme pushes it on vehicle.entered): then only the interactives…
vehicleRadiusnumber61–301.6.0: reach in metres from the vehicle the player drives.
pointerTargetbooleanfalse1.5.0: without input.scheme, the interactive under the pointer (the aim.target variable) is the candidate when in reach; with or…
clickApproachbooleanfalse1.7.0: with pointerTarget, a click on an interactive out of reach walks the player to it (an input.scheme move order) and uses it…
approachSecondsnumber80.5–301.7.0: the longest walk of a clickApproach before it is given up.

Services, events, variables #

  • Service interaction.use: register(entity, label, action?, kind?) / unregister; kindOf(entity), setLocked(entity, on), setHold(entity, seconds), setFromVehicle(entity, on); the nearest interactive in range receives interaction.requested.
  • Service interaction.prompt: The current prompt label as GameState interaction.prompt (E · Open door, key from labelFor); action() / label() / kind() / locked() of the current target, progress() of a hold (0..1, null when nothing is held) for ui.prompts and interaction.feedback.
  • Events emitted:
    • interaction.completed (entity, label) — A completion condition became true during play.
    • interaction.available (entity, targetId, label, action) — An interactive entered reach (the HUD shows the prompt); entity is the interactive.
    • interaction.hidden (entity) — No interactive in reach any more; entity is the one that was offered.
    • interaction.requested (entity, target, targetId, label, action) — The player (entity) pressed an action on the available interactive (target).
    • interaction.refused (entity, target, label, action, reason) — The use was refused: a tap of the hook interaction.use cancelled it (reason: the tap's, default refused), the interactive is locked (locked) or out…
    • interaction.hold.started (entity, target, action, seconds) — 1.5.0: the player started holding the action on an interactive that needs a hold (seconds: how long).
    • interaction.hold.cancelled (entity, target, action, progress) — 1.5.0: the hold stopped before its end (released, or the target changed).
    • interaction.approach (entity, target, label, action) — 1.7.0: clickApproach — the player (entity) clicked an interactive out of reach (target) and walks to it; used on arrival.
    • interaction.approach.cancelled (entity, target, action, reason) — 1.7.0: the walk of a clickApproach stopped before arrival (reason: replaced by another click, gone, timeout, no_player).
  • Events listened to: input.action, engine.state.changed, engine.visibility
  • Variables:
    • interaction.prompt (string) — Interaction prompt

Hooks and modding #

  • Hooks (a game or a mod can intercept them):
    • interaction.use (cancellable) — The player (entity) pressed action on the interactive in reach (target): a door the story keeps shut, a lever that needs a tool.
  • Moddable settings: radius, action, showPrompt, holdSeconds, vehicleScheme, vehicleRadius, pointerTarget, clickApproach, approachSeconds
  • Components: interactable

Engines #

Declared targets: web, godot, unity, unreal, rust. gripforge kit api interaction.system lists the exact settings and services of your version.

Versions #

Kit version 1.8.0.