What it does
An intent is an action named by your game and driven by any of its keys and pad buttons. pressed says it is held
this step, justPressed is true for exactly one fixed step, and justReleased for the step after it is let go. A
key tapped down and up between two steps still counts as a press, so fast taps are never lost. Asking about an intent
the player has no binding for throws, naming the ones that exist, so a typo surfaces at once.
axis('move') comes from the move keys or, when none is held, the move stick, normalised to a length of at most 1,
so the game cannot tell which was used. axis('aim') comes from the other stick while it is pushed, and otherwise is
a unit vector from the player to the pointer once you call aimFrom(player). The pointer is also available in world
units, with its press and release held for a step, so a click shorter than a frame is never missed.
Each of up to four players has their own move keys, intents and pad. bind, bindMove and usePad change them
while the game runs, and bindings() returns a copy for a settings screen or a save. Touch controls join in by
pressing codes such as 'Touch:fire', which an intent binds alongside its keys, so on-screen buttons need no second
code path.
Features
- Named intents — any action name, each driven by any of its keys and pad buttons.
- Latched presses —
justPressedandjustReleasedfor exactly one step, even for a tap shorter than a frame. - Move and aim axes — keys or a stick for movement, a stick or the pointer for aim, both normalised.
- Aim from the player —
aimFrommeasures pointer aim from any object, with a dead zone around it. - One to four players — each with their own keys, intents, pad and stick.
- Rebinding at run time —
bind,bindMove,usePadandbindingsfor a settings screen. - Touch codes — on-screen buttons press codes that intents bind like keys.
- Sensible defaults — WASD and the arrows move, Space, J or pad A fire, E, K or pad B act, Escape or Start pauses, left stick moves and right stick aims.
Good for
- Twin-stick shooters — move with one stick or WASD, aim with the other stick or the mouse from the ship.
- Platformers — jump and dash as named intents, with short taps never dropped.
- Top-down adventures — move and action on keys or a pad, the same code for both.
- Local multiplayer brawlers — two to four players on one keyboard and their own pads.
- Games with a controls menu — rebinding at run time, and bindings to show and save.
- Games for touch as well as keys — on-screen buttons that drive the same intents.
Make it yours
For one player, bindings overrides only what it names and keeps the defaults for the rest: new move keys, a jump
intent, a different pad. For several, players binds each one in full, with nothing shared, and a player without a
pad gets the pad in their own slot. aimDeadzone sets how close the pointer may come to the player before aim drops
to nothing.
Two very different setups: a single-player twin-stick shooter on the defaults, moving with WASD or the left stick and aiming with the mouse or the right stick from the ship; and a two-player platformer where one player jumps with G on the left of the keyboard and the other with the slash key on the right, each with their own pad, and a pause menu that lets either rebind their jump.
A quick look
Moving, firing on a tap and aiming at the mouse from the player:
const m = game.controls.axis('move'); // {x, y}, length ≤ 1
player.x += m.x * speed * dt; player.y += m.y * speed * dt;
if (game.controls.justPressed('fire')) shoot(); // true for one step
game.controls.aimFrom(player); // aim from the player, not the screen centre
const aim = game.controls.axis('aim'); // right stick, or towards the mouse
game.controls.player(1).bind('jump', { keys: ['Enter'], pad: ['a'] }); // from a rebinding screen
Works with
core-2dandcore-vector— both include it, so most 2D games have it already.world-sideorworld-topdown— required, for the pointer's world position.controls-touch— on-screen sticks and buttons that press the codes intents bind.rig-follow— the camera that follows the player these controls move.
Good to know
- Four players at most, sharing one keyboard and one pointer; each player's aim falls back to that pointer while their aim stick is still.
- Pad buttons are sampled once per step, so a pad press shorter than a step can be missed; keys are latched and are not.
- The move stick is read only while no move key is held.
- A pointer-only or touch-only game can read the engine's input directly instead.






