Skip to content

Read input from Lua

Lua scripts read input through named actions, not physical keys. The host application defines the action set in C# — mapping each action to whatever keys, mouse buttons, or gamepad controls it likes — and scripts query those actions by name. This keeps script input on the same configurable, rebindable footing as the rest of Tick UI: a script asks "is Jump down", never "is Space down", so the binding stays the host's to change.

Define the action set in C

Actions live on Configuration.Bindings.Actions, alongside the other binding categories. Populate an ActionBindings for the active input backend and key each action in by name. Any of the bindings listed for an action fires it, and the existing LegacyKeyBinding / InputSystemKeyBinding types apply (including modifiers).

// Legacy input backend.
var config = new Configuration
{
    Bindings = new InputBindings
    {
        Actions = new LegacyActionBindings
        {
            Actions =
            {
                ["Left"]  = new() { KeyCode.LeftArrow, KeyCode.A },
                ["Right"] = new() { KeyCode.RightArrow, KeyCode.D },
                ["Jump"]  = new() { KeyCode.Space },
                ["Menu"]  = new() { KeyCode.Escape, KeyCode.P },
                ["Dash"]  = new() { new LegacyKeyBinding(KeyCode.LeftShift, ModifierMask.None) },
            },
        },
    },
};

Under the Input System backend, use InputSystemActionBindings with Key values:

Actions = new InputSystemActionBindings
{
    Actions =
    {
        ["Left"] = new() { Key.LeftArrow, Key.A },
        ["Jump"] = new() { Key.Space },
    },
};

You can also swap the action set at runtime with ui.SetBindings(...). If you never set an Actions field, it defaults to an empty set — IsActionDown simply returns false for every name until you register some.

Query actions from Lua

function tick(ui, dt)
    if ui:IsActionDown('Left')  then move(-1) end   -- held
    if ui:IsActionDown('Right') then move( 1) end
    if ui:IsActionPressed('Jump') then jump() end   -- first frame only
end
  • ui:IsActionDown(name) — true while the action is held.
  • ui:IsActionPressed(name) — true only on the frame it is first pressed (use for menus, toggles, and one-shot actions).

An unknown action name returns false rather than erroring, so a script that references an action the host has not registered, fails quietly rather than crashing.

See also