Gessa Docs
Recipes

Recipe

Input mapping actions bindings keyboard mouse gamepad touch

Whenever the player needs to control something. All input flows through ONE InputProfileComponent per controllable entity. Movement, jump, fire, and look are just actions in its actions array.
engine v1.0.234since component-field-contract ecs.component-field-contract.v1, input.v1Copy for LLM

Use this for

mapping keys, mouse, gamepad, or touch to gameplay actions; movement axes; jump and fire buttons; look sensitivity; per-action prediction

Not for

transient editor or menu shortcuts (client-local, not this component); camera math (see first-person-controls)

Pairs with: First-person camera movement and mouselook controls, Third-person follow camera and platformer jump movement, Combat damage health and respawn scripting

The recipe

  1. Attach InputProfileComponent with project_add_component (project.entity.component.set): { "type":"InputProfileComponent", "version":1, "actions":[ ... ] }.
  2. Each action object needs: key (stable id), valueType (one of boolean, float, vector1d, vector2d, vector3d, world_target, screen2d, trigger, composite), contexts (for example ["gameplay"]), triggers, processors, policy, prediction, and bindings.
  3. policy.effectSystem routes the action: movement, action, script, or look. Set movement for WASD, look for mouselook (add the policy.look block), action for verbs (fire, interact).
  4. prediction.mode is client_predicted (responsive movement), client_only (look), or server_authoritative (anti-cheat verbs).
  5. A binding maps sources to the action: { "id":"binding.move.wasd", "sources":[{ "device":"keyboard", "control":"KeyW", "event":"down", "modifiers":[] }, ...], "triggerOverrides":[], "processors":[], "priority":0 }. Valid devices: keyboard, mouse, gamepad, touch, xr. Valid events: down, up, press, move, axis, sample.
  6. For a jump button, add a boolean action with a keyboard Space down binding. For gamepad, add a second binding with device:"gamepad". For mobile, add a touch binding to the same action; one action, many devices.
  7. Shape raw input with processors[].kind: deadzone, curve, invert, sensitivity, clamp, normalize, axisComposition, stickComposition, threshold, quantize. Shape timing with triggers[].kind: pressed, released, held, tap, doubleTap, hold, chord, continuous, continuous_delta, step, cancel.

Pitfalls

  • Trigger and processor parameters are discriminated by kind. A hold trigger needs parameters.durationMs (1..60000); a curve processor needs scale/exponent. Mismatched parameters are rejected; you cannot edit one leaf at a time and stay valid.
  • policy.look.sensitivityDeg is clamped 0.001..45 and pitch bounds -89..89.
  • version is readonly to most surfaces; keep it 1 unless you are migrating.
  • The removed InputActionDeclarationComponent, InputBindingSetComponent, and InputContextStackComponent all fold into this one component; never author them.

Verify

  • engine_get_component_schema on InputProfileComponent for projected field contracts before writing a binding. Device-dependent control checks live in InputSourceSpecSchema in packages/ecs/src/index.ts; use the native mouse binding shown in the first-person-controls playbook for look input.
  • simulation_run to confirm the action fires on the mapped control.
Was this helpful?Report an issueContact support

On this page