Key remapping

Lets the player rebind the game's input actions: keyboard and mouse controls, gamepad buttons, whole sticks, press-a-key capture and conflict handling, saved for the player.

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

Also read offline — CLI: grip-forge docs input-remapMCP tool: gripforge_docs { "topic": "input-remap" }

Key remapping (input.remap) #

What it is for #

Lets the player rebind the game's input actions: keyboard and mouse controls, gamepad buttons, whole sticks, press-a-key capture and conflict handling, saved for the player.

It needs 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: "input.remap" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "input.remap",
                              config: { "actions": [], "exclude": [] } }

First example #

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

#[test]
fn a_captured_key_replaces_the_one_the_input_reads() {
    let mut s = session(json!({}));
    assert_eq!(
        call(&mut s, "capture", json!(["jump", "primary"])),
        json!(true)
    );
    assert_eq!(
        call(&mut s, "press", json!(["KeyK"]))["status"],
        json!("bound")
    );
    assert_eq!(
        call(&mut s, "bindings", json!([]))["jump"],
        json!({ "keys": ["KeyK"], "buttons": [0] })
    );
    topics(&mut s);
    key(&mut s, "Space", true);
    assert!(!s.host.input.pressed("jump"), "the old key is free");
    key(&mut s, "Space", false);
    key(&mut s, "KeyK", true);
    assert!(s.host.input.pressed("jump"));
    assert!(topics(&mut s).contains(&"input.action".to_string()));
    // The player settings are not in the game save: a reload of the same host keeps them, a save does not carry them.
    assert_eq!(call(&mut s, "reload", json!([])), json!(true));
    let save = s.apply(&json!({ "op": "save" })).unwrap();
    assert!(save["kits"].get("input.remap").is_none());
    s.apply(&json!({ "op": "reload" })).unwrap();
    assert_eq!(call(&mut s, "values", json!([])), json!({ "rows": {} }));
}

Settings and defaults #

Descriptions come from the kit manifest and stay in English.

SettingTypeDefaultRange or valuesMeaning
actionsarray[]The remappable actions; empty = every action the game declares (input.actions and the other kits).
excludearray[]Actions the player cannot rebind (hidden from the Controls tab).
conflictsstring"ask"ask, swap, allowA control already used in the same group: ask to replace it, swap the two, or allow both.
reservedarray["Escape"]Controls that cannot be bound (they cancel the capture).
gamepadbooleantrueShow and capture the gamepad column.
secondarybooleantrueShow and capture a secondary keyboard control.

Services, events, variables #

  • Service input.remap: rows(lang), capture(row, slot), press(control), resolve(accept), cancel(), clear(row, slot), reset(row?), conflicts(), bindings(), sticks(), setStick(row, source), setInvert(row, x|y, on), setDeadzone(row, value), reload(); options tab controls.
  • Events emitted:
    • remap.capture (row, slot) — Waiting for the next key (slot primary / secondary) or gamepad button (pad).
    • remap.changed (row, slot, control, freedRow, freedSlot) — A slot got a control (null = cleared); freedRow / freedSlot lost it.
    • remap.conflict (row, slot, control, otherRow, otherSlot) — The control is used by another action of the group: resolve(true) replaces, resolve(false) cancels.
    • remap.cancelled (row, slot) — A capture or a pending conflict was given up (Escape, a reserved control, the same control, resolve(false), cancel()).
    • remap.stick (row, source, invertX, invertY, deadzone) — An inversion or the deadzone of a stick action changed (a new source is a remap.changed on its pad slot: StickLeft, StickRight, DPad).
    • remap.reset (row, freed) — row null = every action; freed lists the slots that lost a default control.
  • Events listened to: game.phase

Hooks and modding #

  • Moddable settings: conflicts, gamepad, secondary

Engines #

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

Versions #

Kit version 1.5.2.