Controls
Controls give a feature its own named input actions instead of reading a hard
coded game button. The compiler writes the declarations to inputs.json; the
game creates InputAction objects and lets the player remap them in the module
settings.
Controls exist only on the client.
Declare actions
Section titled “Declare actions”import { Gamepad, Keyboard, defineControls,} from "@killscript/sdk/client";
export const controls = defineControls("camera", { toggle: Keyboard.F6, boost: Keyboard.LeftShift, controllerToggle: Gamepad.North,});The namespace produces action names such as camera.toggle. It prevents a
generic name from colliding with another declaration in the same module.
defineControls() must initialize a top-level const, but the declaration may
live in any imported client file.
React to one action
Section titled “React to one action”Use an event when something should happen once, and polling when behavior continues while the button is held:
controls.toggle.onPressed(() => { cameraEnabled = !cameraEnabled;});
const boostLoop = controls.boost.whilePressed(() => { moveCamera(fastSpeed);});
if (controls.boost.isPressed()) { drawBoostIndicator();}| Handle method | Behavior |
|---|---|
onPressed(callback) | Uses the native performed event; intended for a module-lifetime handler |
onChanged(callback) | Reports both press and release transitions |
onReleased(callback) | Reports only a pressed-to-released transition |
whilePressed(callback) | Runs every client frame while held |
isPressed() | Reads the current state safely |
native() | Returns the underlying InputAction, if available |
The polling watchers return an EventSubscription. Cancel it directly or add
it to a feature scope when the watcher
belongs to a toggleable feature.
Hold, tap and release interactions
Section titled “Hold, tap and release interactions”import { Keyboard, Mouse, control, defineControls } from "@killscript/sdk/client";
const actions = defineControls("movement", { charge: control.hold(Keyboard.F, 0.4), quickTap: control.tap(Keyboard.G, 0.2), doubleTap: control.multiTap(Keyboard.W, 2, 0.3), onRelease: control.onRelease(Keyboard.Space),});These helpers generate Unity Input System interaction strings. The duration is
in seconds. Use control(...) with a binding object for processors, groups or
a custom interaction, and control.raw(...) when you need to specify the
action type as well:
const look = defineControls("camera", { delta: control.raw({ type: "PassThrough", binding: { path: Mouse.Delta }, }),});Combine actions
Section titled “Combine actions”The input helpers accept generated control handles and native InputAction
objects:
import { input } from "@killscript/sdk/client";
if (input.anyPressed([controls.toggle, controls.boost])) { showInputIndicator();}
const chord = input.onChord( [controls.toggle, controls.boost], resetCamera,);
const enabledState = input.toggle(controls.toggle, false, (value) => { value ? enableFeature() : disableFeature();});
print(`Enabled: ${enabledState.value}`);anyPressed()andallPressed()read the current combined state;onAnyPressed()runs when the group changes from idle to at least one press;onChord()runs when every supplied action becomes pressed;toggle()keeps a boolean state and flips it on each performed event.
toggle() is runtime state. It does not add a persistent setting to
config.json.
ToggleState member | Behavior |
|---|---|
value | Current boolean state |
set(value) | Replaces the state and calls the callback |
flip() | Flips the state, calls the callback and returns the new value |