Input map format
VGAI Reference 0.3
Planned versioned generated-schema truth covering Typed input actions, devices, prompts, and rebinding.
planned · generated · immutable Reference 0.3
Lifecycle and constraints
Detailed constraints will publish with the generated or reviewed entry.
Runnable Learn material
- Tune an Unseen Combat Encounter
- Build the Solo Combat Loop
- Build and Verify a Damage Budget
- VGAI Essentials
- Input and rebinding
- 2D Game
- First-Person
- Third-Person Action
- Top-Down
Generated format inventory
Inventory only — AC-REF-002 is not passed. Valid parser-verified examples, narrative guidance, complete cross-field/runtime constraints, and version history remain deferred. This page must not be treated as a complete format contract.
Source: packages/engine/schemas/inputmap.schema.json ·
50 branch-sensitive field records ·
35 source-described.
input-map · file · 50 fields
| Field / branch | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
# $ | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.version | number | yes | none | none | Input map file format version (RESERVED — no range check yet) |
# $.actions | object | yes | none | {"additionalProperties":{"type":"object","properties":{"valueType":{"default":"digital","description":"This action's declared value shape (F1, spec §12). 'digital' (boolean, with pressed/justPressed/justReleased edges) is the default when omitted, matching every action authored before F1. 'scalar' is a single deadzone-rescaled float axis. 'vector2' is a radial-deadzoned, unit-circle-normalized {x,y}. 'pointerDelta' is a per-frame {x,y} movement delta, summed across sources. 'pointerPosition' is an absolute {x,y}, last-write-wins across sources. InputManager enforces this at read time: reading an action through the wrong typed getter (e.g. getScalar on a 'digital' action) throws.","type":"string","enum":["digital","scalar","vector2","pointerDelta","pointerPosition"]},"bindings":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"key","description":"Binding kind: a keyboard key (KeyboardEvent.code)"},"code":{"type":"string","description":"KeyboardEvent.code value, e.g. \"KeyW\", \"Space\", \"ArrowUp\""}},"required":["type","code"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"mouse_button","description":"Binding kind: a mouse button"},"button":{"type":"number","description":"MouseEvent.button index (0 = left, 1 = middle, 2 = right)"}},"required":["type","button"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"mouse_move","description":"Binding kind: raw mouse movement (F2, spec §12 \"Complete Device Backends\"). Feeds a 'pointerDelta'-valueType action with the raw accumulated mouse delta (no deadzone), and can also feed a 'vector2'-valueType action (the same delta, radial-deadzoned + unit-circle-clamped via `deadzone`)."},"deadzone":{"description":"Radial deadzone magnitude applied only when this binding feeds a 'vector2'-valueType action (default 0 — no deadzone; ignored for 'pointerDelta' reads, which are never deadzoned).","type":"number"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"gamepad_button","description":"Binding kind: a gamepad face/shoulder button"},"button":{"type":"number","description":"Standard Gamepad API button index"}},"required":["type","button"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"gamepad_axis","description":"Binding kind: a single thresholded gamepad axis"},"axis":{"type":"number","description":"Standard Gamepad API axis index"},"direction":{"type":"string","enum":["positive","negative"],"description":"Which side of the deadzone counts as \"pressed\""},"deadzone":{"description":"Deadzone magnitude (default 0.15 if omitted)","type":"number"}},"required":["type","axis","direction"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"gamepad_axis_pair","description":"Binding kind: a coupled (x, y) gamepad axis pair, e.g. a stick used as a 2D vector (look/aim/movement) (F2, spec §12 \"Complete Device Backends\"). Feeds a 'vector2'-valueType action: (xAxis, yAxis) read together, radial-deadzoned + unit-circle-clamped the same way a real analog stick is."},"xAxis":{"type":"number","description":"Standard Gamepad API axis index for the X component"},"yAxis":{"type":"number","description":"Standard Gamepad API axis index for the Y component"},"deadzone":{"description":"Deadzone magnitude (default 0.15 if omitted)","type":"number"}},"required":["type","xAxis","yAxis"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"test_axis","description":"Binding kind: an injected synthetic scalar value for a 'scalar'-valueType action (InputManager.injectAxis/getScalar) — the \"injected test input\" backend named in F2, built in F1 as the typed scalar value model's testable source."},"sourceId":{"type":"string","description":"Names the injected test source this binding reads (InputManager.injectAxis)."},"deadzone":{"description":"1D deadzone magnitude applied to the injected raw value before combine (default 0 — no deadzone). Values below it read as 0; values at/above it rescale from 0 (at the deadzone edge) to ±1 (at |raw| = 1), sign preserved.","type":"number"}},"required":["type","sourceId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"test_vector2","description":"Binding kind: an injected synthetic {x,y} value for a 'vector2'-valueType action (InputManager.injectVector2/getVector2) — the \"injected test input\" backend named in F2, built in F1 as the typed Vector2 value model's testable source."},"sourceId":{"type":"string","description":"Names the injected test source this binding reads (InputManager.injectVector2)."},"deadzone":{"description":"Radial deadzone magnitude applied to the injected raw {x,y} before combine (default 0 — no deadzone). Vectors whose magnitude is below it read as {0,0}; at/above it, direction is preserved and magnitude rescales the same way the scalar deadzone does, then the result is clamped to the unit circle (magnitude <= 1).","type":"number"}},"required":["type","sourceId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"test_pointer_delta","description":"Binding kind: an injected synthetic per-frame {x,y} delta for a 'pointerDelta'-valueType action (InputManager.injectPointerDelta/getPointerDelta) — the \"injected test input\" backend named in F2. No deadzone (deltas are not deadzoned)."},"sourceId":{"type":"string","description":"Names the injected test source this binding reads (InputManager.injectPointerDelta)."}},"required":["type","sourceId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"test_pointer_position","description":"Binding kind: an injected synthetic absolute {x,y} position for a 'pointerPosition'-valueType action (InputManager.injectPointerPosition/getPointerPosition) — the \"injected test input\" backend named in F2."},"sourceId":{"type":"string","description":"Names the injected test source this binding reads (InputManager.injectPointerPosition)."}},"required":["type","sourceId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"touch_button","description":"Binding kind: a virtual on-screen button for a 'digital' action (InputManager.setTouchButton/isPressed) — edge-tracked (isJustPressed/isJustReleased) the same way a real mouse/keyboard button is."},"sourceId":{"type":"string","description":"Names the virtual control zone this binding reads (InputManager.setTouchButton) — a touch-UI-chosen id, not a real device index."}},"required":["type","sourceId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"touch_stick","description":"Binding kind: a virtual on-screen analog stick for a 'vector2' action (InputManager.setTouchStick/getVector2) — radial-deadzoned + unit-circle-clamped the same way a real gamepad stick is."},"sourceId":{"type":"string","description":"Names the virtual control zone this binding reads (InputManager.setTouchStick) — a touch-UI-chosen id, not a real device index."},"deadzone":{"description":"Radial deadzone magnitude applied to the raw {x,y} before combine (default 0 — no deadzone).","type":"number"}},"required":["type","sourceId"],"additionalProperties":false}]},"description":"Bindings that all trigger/feed this action. Digital actions combine via OR (any one binding satisfied is enough). Scalar actions combine via max-magnitude across contributing bindings (ties keep the first-listed binding). Vector2 actions combine by summing contributing {x,y} values then clamping to the unit circle. PointerDelta actions sum contributing deltas. PointerPosition actions use the most-recently-written contributing source (last-write-wins)."}},"required":["valueType","bindings"],"additionalProperties":false},"propertyNames":{"type":"string"}} | Named actions, each with a list of bindings (InputManager.loadMap) |
# $.actions{key} | object | no | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.valueType | enum (5) | yes | "digital" | {"enum":["digital","scalar","vector2","pointerDelta","pointerPosition"]} | This action's declared value shape (F1, spec §12). 'digital' (boolean, with pressed/justPressed/justReleased edges) is the default when omitted, matching every action authored before F1. 'scalar' is a single deadzone-rescaled float axis. 'vector2' is a radial-deadzoned, unit-circle-normalized {x,y}. 'pointerDelta' is a per-frame {x,y} movement delta, summed across sources. 'pointerPosition' is an absolute {x,y}, last-write-wins across sources. InputManager enforces this at read time: reading an action through the wrong typed getter (e.g. getScalar on a 'digital' action) throws. |
# $.actions{key}.bindings | array | yes | none | none | Bindings that all trigger/feed this action. Digital actions combine via OR (any one binding satisfied is enough). Scalar actions combine via max-magnitude across contributing bindings (ties keep the first-listed binding). Vector2 actions combine by summing contributing {x,y} values then clamping to the unit circle. PointerDelta actions sum contributing deltas. PointerPosition actions use the most-recently-written contributing source (last-write-wins). |
# $.actions{key}.bindings[] | oneOf (12) | yes | none | none | Missing source description |
# $.actions{key}.bindings[]oneOf[0] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[0] | const "key" | yes | none | {"const":"key"} | Binding kind: a keyboard key (KeyboardEvent.code) |
# $.actions{key}.bindings[].codeoneOf[0] | string | yes | none | none | KeyboardEvent.code value, e.g. "KeyW", "Space", "ArrowUp" |
# $.actions{key}.bindings[]oneOf[1] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[1] | const "mouse_button" | yes | none | {"const":"mouse_button"} | Binding kind: a mouse button |
# $.actions{key}.bindings[].buttononeOf[1] | number | yes | none | none | MouseEvent.button index (0 = left, 1 = middle, 2 = right) |
# $.actions{key}.bindings[]oneOf[2] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[2] | const "mouse_move" | yes | none | {"const":"mouse_move"} | Binding kind: raw mouse movement (F2, spec §12 "Complete Device Backends"). Feeds a 'pointerDelta'-valueType action with the raw accumulated mouse delta (no deadzone), and can also feed a 'vector2'-valueType action (the same delta, radial-deadzoned + unit-circle-clamped via `deadzone`). |
# $.actions{key}.bindings[].deadzoneoneOf[2] | number | no | none | none | Radial deadzone magnitude applied only when this binding feeds a 'vector2'-valueType action (default 0 — no deadzone; ignored for 'pointerDelta' reads, which are never deadzoned). |
# $.actions{key}.bindings[]oneOf[3] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[3] | const "gamepad_button" | yes | none | {"const":"gamepad_button"} | Binding kind: a gamepad face/shoulder button |
# $.actions{key}.bindings[].buttononeOf[3] | number | yes | none | none | Standard Gamepad API button index |
# $.actions{key}.bindings[]oneOf[4] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[4] | const "gamepad_axis" | yes | none | {"const":"gamepad_axis"} | Binding kind: a single thresholded gamepad axis |
# $.actions{key}.bindings[].axisoneOf[4] | number | yes | none | none | Standard Gamepad API axis index |
# $.actions{key}.bindings[].directiononeOf[4] | enum (2) | yes | none | {"enum":["positive","negative"]} | Which side of the deadzone counts as "pressed" |
# $.actions{key}.bindings[].deadzoneoneOf[4] | number | no | none | none | Deadzone magnitude (default 0.15 if omitted) |
# $.actions{key}.bindings[]oneOf[5] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[5] | const "gamepad_axis_pair" | yes | none | {"const":"gamepad_axis_pair"} | Binding kind: a coupled (x, y) gamepad axis pair, e.g. a stick used as a 2D vector (look/aim/movement) (F2, spec §12 "Complete Device Backends"). Feeds a 'vector2'-valueType action: (xAxis, yAxis) read together, radial-deadzoned + unit-circle-clamped the same way a real analog stick is. |
# $.actions{key}.bindings[].xAxisoneOf[5] | number | yes | none | none | Standard Gamepad API axis index for the X component |
# $.actions{key}.bindings[].yAxisoneOf[5] | number | yes | none | none | Standard Gamepad API axis index for the Y component |
# $.actions{key}.bindings[].deadzoneoneOf[5] | number | no | none | none | Deadzone magnitude (default 0.15 if omitted) |
# $.actions{key}.bindings[]oneOf[6] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[6] | const "test_axis" | yes | none | {"const":"test_axis"} | Binding kind: an injected synthetic scalar value for a 'scalar'-valueType action (InputManager.injectAxis/getScalar) — the "injected test input" backend named in F2, built in F1 as the typed scalar value model's testable source. |
# $.actions{key}.bindings[].sourceIdoneOf[6] | string | yes | none | none | Names the injected test source this binding reads (InputManager.injectAxis). |
# $.actions{key}.bindings[].deadzoneoneOf[6] | number | no | none | none | 1D deadzone magnitude applied to the injected raw value before combine (default 0 — no deadzone). Values below it read as 0; values at/above it rescale from 0 (at the deadzone edge) to ±1 (at |raw| = 1), sign preserved. |
# $.actions{key}.bindings[]oneOf[7] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[7] | const "test_vector2" | yes | none | {"const":"test_vector2"} | Binding kind: an injected synthetic {x,y} value for a 'vector2'-valueType action (InputManager.injectVector2/getVector2) — the "injected test input" backend named in F2, built in F1 as the typed Vector2 value model's testable source. |
# $.actions{key}.bindings[].sourceIdoneOf[7] | string | yes | none | none | Names the injected test source this binding reads (InputManager.injectVector2). |
# $.actions{key}.bindings[].deadzoneoneOf[7] | number | no | none | none | Radial deadzone magnitude applied to the injected raw {x,y} before combine (default 0 — no deadzone). Vectors whose magnitude is below it read as {0,0}; at/above it, direction is preserved and magnitude rescales the same way the scalar deadzone does, then the result is clamped to the unit circle (magnitude <= 1). |
# $.actions{key}.bindings[]oneOf[8] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[8] | const "test_pointer_delta" | yes | none | {"const":"test_pointer_delta"} | Binding kind: an injected synthetic per-frame {x,y} delta for a 'pointerDelta'-valueType action (InputManager.injectPointerDelta/getPointerDelta) — the "injected test input" backend named in F2. No deadzone (deltas are not deadzoned). |
# $.actions{key}.bindings[].sourceIdoneOf[8] | string | yes | none | none | Names the injected test source this binding reads (InputManager.injectPointerDelta). |
# $.actions{key}.bindings[]oneOf[9] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[9] | const "test_pointer_position" | yes | none | {"const":"test_pointer_position"} | Binding kind: an injected synthetic absolute {x,y} position for a 'pointerPosition'-valueType action (InputManager.injectPointerPosition/getPointerPosition) — the "injected test input" backend named in F2. |
# $.actions{key}.bindings[].sourceIdoneOf[9] | string | yes | none | none | Names the injected test source this binding reads (InputManager.injectPointerPosition). |
# $.actions{key}.bindings[]oneOf[10] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[10] | const "touch_button" | yes | none | {"const":"touch_button"} | Binding kind: a virtual on-screen button for a 'digital' action (InputManager.setTouchButton/isPressed) — edge-tracked (isJustPressed/isJustReleased) the same way a real mouse/keyboard button is. |
# $.actions{key}.bindings[].sourceIdoneOf[10] | string | yes | none | none | Names the virtual control zone this binding reads (InputManager.setTouchButton) — a touch-UI-chosen id, not a real device index. |
# $.actions{key}.bindings[]oneOf[11] | object | yes | none | {"additionalProperties":false} | Missing source description |
# $.actions{key}.bindings[].typeoneOf[11] | const "touch_stick" | yes | none | {"const":"touch_stick"} | Binding kind: a virtual on-screen analog stick for a 'vector2' action (InputManager.setTouchStick/getVector2) — radial-deadzoned + unit-circle-clamped the same way a real gamepad stick is. |
# $.actions{key}.bindings[].sourceIdoneOf[11] | string | yes | none | none | Names the virtual control zone this binding reads (InputManager.setTouchStick) — a touch-UI-chosen id, not a real device index. |
# $.actions{key}.bindings[].deadzoneoneOf[11] | number | no | none | none | Radial deadzone magnitude applied to the raw {x,y} before combine (default 0 — no deadzone). |