Module input

Input management facilities.

The module returns a single function, input.

You can find in the module uqt.input.default (in file input/default.lua) some common input configuration for 2D movement, confirmation and cancellation (for both keyboard and joystick). Feel free to use them as-is, or as a base for your own inputs.

Requires ubiquitousse.signal.

Usage:

    local input = require("ubiquitousse.input")
    
    -- Joystick-only control for player 1
    local player1 = {
    	move = {
    		-- 2D movement, clamped on a circle
    		"clamped(child.right - child.left, child.down - child.up)",
    		dimension = 2,
    
    		-- All the directions we can go, using both the left joystick and the D-pad
    		right = { "axis.leftx.p", "button.dpright" },
    		left = { "axis.leftx.n", "button.dpleft" },
    		down = { "axis.lefty.p", "button.dpdown" },
    		up = { "axis.lefty.n", "button.dpup" }
    	},
    
    	fire = { "button.a" }
    }
    
    -- Only consider inputs from the first joystick (in practice you will want to check if the joystick exists before running this line)
    player1:setJoystick(love.joystick.getJoysticks()[1])
    
    -- Player 2, using a second gamepad!
    local player2 = player1:clone()
    player2:setJoystick(love.joystick.getJoysticks()[2])
    
    -- Define input callbacks.
    player1.fire.event:bind("pressed", function() print("player 1 starts firing!") end)
    player1.fire.event:bind("released", function() print("player 1 stop firing...") end)
    
    function love.update()
    	-- Get player 1's 2D movement
    	local x, y = player1.move:value()
    	movePlayer1(x, y)
    
    	-- Check current state of the firing input
    	if player1.fire:down() then
    		-- currently firing!
    	end
    
    	-- Update inputs.
    	player1:update()
    	player2:update()
    end
    

Functions

input ([config]) Make a new input object.

Input expressions

floor (x) Same as Lua’s math.floor.
floor (x) Same as Lua’s math.ceil.
floor (x) Same as Lua’s math.abs.
clamp (x, xmin, xmax) Clamp x between xmin and xmax.
min (x, y, ...) Returns the minimal value among all parameters.
max (x, y, ...) Returns the maximal value among all parameters.
deadzone (x, deadzone) If x < deadzone, returns 0; otherwise returns the value.
normalize (x, y) Returns a normalized version of the vector (x,y), i.e.
passive (source) Mark an input source as passive.
passive (source) Mark an input source as active.

Input objects

Input.config Input configuration table.
Input.children [read-only] List and map of children Inputs.
Input.name [read-only] Name of the input.
Input.enabled [read-only] false if the input is disabled, true otherwise.
Input.grabbed [read-only] false if the input is currently not grabbed, the grabbing Input otherwise.
Input.grabbing [read-only] false if the input is not grabbing another input, the Input it is grabbing from otherwise.
Input.event Input event registry.
Input:update () Update the input and its children.
Input:clone ([copyState=false]) Create a new input object based on this input config data.
Input:reload () Reload the input config, and do the same for its children.
Input:disable () Disable the input and its children, preventing further updates and events.
Input:enable () Enable the input and its children, allowing further updates and events.
Input:onNextActiveSource (fn[, filter]) Will call fn(source) on the next activated source (including sources not currently used by this input).
Input:grab () Grab the input and its children and returns the resulting grabbing input.
Input:release () Release an input that is currently grabbing another and its children.
Input:neutralize () Set the state of this input and its children to a neutral position (i.e.
Input:set (...) Manually set the state of this input.
Input:setJoystick (joystick) Set the joystick associated with this input.
Input:getJoystick () Returns the currently selected joystick.
Input:down () Returns true if the input is currently down, false otherwise.
Input:pressed () Returns true if the input has just been pressed, false otherwise.
Input:released () Returns true if the input has just been released, false otherwise.
Input:value () Returns the current value of the input.
Input:delta () Returns the delta value of the input since the last call to update.

Input sources

key.X Keyboard input: 1 if the key X is down, 0 otherwise.
scancode.X Keyboard input: 1 if the key with scancode X is down, 0 otherwise.
text.X Text input: 1 if the text X was entered, 0 otherwise.
mouse Mouse input: mouse[N] is 1 if the mouse button is down, 0 otherwise.
mouse.x Mouse input: X position of the mouse cursor in the game window.
mouse.y Mouse input: Y position of the mouse cursor in the game window.
mouse.dx Mouse input: latest X movement of the mouse cursor.
mouse.dy Mouse input: latest Y movement of the mouse cursor.
wheel.dx Mouse input: latest X movement of the mouse wheel.
wheel.dy Mouse input: latest Y movement of the mouse wheel.
button.X Gamepad input: 1 if the button X is down, 0 otherwise.
axis.X Gamepad input: current value of the gamepad axis (between -1 and 1).
dt On new frame: current delta time value since last frame.
child.X Children inputs: current value of a child input of the current input.
value Current input: current value of the current input.


Functions

input ([config])
Make a new input object.

This constructor is returned by the uqt.input module.

Parameters:

Returns:

    Input Input object

Usage:

    local player = uqt.input {
       fire = { "key.a" },
       jump = { "key.space" }
    }
    player.fire.event:bind("pressed", function() print("pew pew") end)

Input expressions

Each Input is associated with a list of input expressions.

An input expression is a string representing a valid Lua expression. These Lua expressions are used to compute the values returned by the input. An input expression should returns as many values as the dimension of its input.

When referring to a variable in an expression, it will be interpreted as an input source. An input source is where the initial input data comes from: for example, an input source could be the current state of the Q key: "key.q" (=1 when the key is down, 0 otherwise). See sources for details on how to define sources and built-in sources.

When a source that is present is the expression is updated, the input will be automatically updated in a reactive way, unless the input is passive – that is, it can not trigger input update.

Additionally, you can also define your own variables to be used in input expression by giving arguments.

In input expression, you have no access to the Lua standard library; some other, more specific functions are available instead and described below.

Usage:

 -- Example input configs for various input expression features.
 fire = {
    -- Basic input expression: 1 when Q is pressed, 0 otherwise. Will automatically update when Q is pressed.
    "key.q",
    -- Example using two inputs sources: when either A or Q is pressed, this will update, and returns 1 is at least one of them is pressed.
    "max(key.q, key.a)",
    -- This input has two input expression: it will be updated when either of them is updated and keep the value of the expression that was updated last.
 }
 horizontal = {
    -- Another example, typically used to define an input for horizontal movement: returns 1 when pressing only right, -1 when pressing only left, and 0 otherwise.
    "key.right - key.left",
 }
 arguments = {
    -- You can give arguments to an expression by wrapping the expression in a table containing the arguments.
    { "axis.leftx + offset", offset = 1 }
 }
 passive = {
   -- Same as the example above, but this will only update when Q is pressed - pressing A will not update the input on its own.
   -- Passive input are typically used for modifiers keys (shift, alt, etc.) that should not trigger an update when pressed on their own.
   "max(key.q, passive(key.a))"
 }
 dimension = {
   -- A two-dimensional input should have input expressions that return two values.
   -- Here a common example that could be used to move something in 2D.
   "key.right - key.left, key.down - key.up",
   dimension = 2
 }
 mouse = {
   -- Example input that returns the position of the mouse cursor, that can be controlled both using an actual mouse or
   -- through a joystick.
   dimension = 2,
   "mouse.x, mouse.y",
   { "value[1] + axis.leftx * speed * dt, value[2] + axis.lefty * speed * dt", speed = 300 } -- contains dt, so updated only once per frame. Thus speed here is the speed in pixel/second, as expected.
 }
 mouse = {
   -- A special case: if the dt source is present in an expression, it will make every other input source passive by default in the expression.
   -- This is the case since dt will trigger an update every frame, and is therefore mostly relevant for input that is used once per frame only
   -- (while other input sources might cause the input to update several times per frame).
   "axis.leftx * dt"
 }
 child = {
   -- Children input can be used as input sources using the child.name syntax.
   -- If the children input has more than one dimension, you will need to specify it using a numeric index like child.fire[2] (for the dimension 2 of the child).
   "child.fire",
   fire = { "key.q" }
}
floor (x)
Same as Lua’s math.floor.

Parameters:

  • x number number to round

Returns:

    number floored value
floor (x)
Same as Lua’s math.ceil.

Parameters:

  • x number number to round

Returns:

    number ceiled value
floor (x)
Same as Lua’s math.abs.

Parameters:

  • x number number to absolute

Returns:

    number absolute value
clamp (x, xmin, xmax)
Clamp x between xmin and xmax.

Parameters:

  • x number number clamp
  • xmin number minimal value
  • xmax number maximal value

Returns:

    number clamped value
min (x, y, ...)
Returns the minimal value among all parameters.

Parameters:

  • x number first value
  • y number second value
  • ... number other values

Returns:

    number smallest value among the arguments
max (x, y, ...)
Returns the maximal value among all parameters.

Parameters:

  • x number first value
  • y number second value
  • ... number other values

Returns:

    number biggest value among the arguments
deadzone (x, deadzone)
If x < deadzone, returns 0; otherwise returns the value.

Parameters:

  • x number value
  • deadzone number deadzone

Returns:

    number 0 if x < deadzone; x otherwise
normalize (x, y)
Returns a normalized version of the vector (x,y), i.e. “clamp” the returned x,y coordinates into a circle of radius 1. Typically used to avoid faster movement on diagonals, as if both horizontal and vertical values are 1, the (1,1) vector has √2 magnitude, higher than the 1 magnitude of a purely vertical or horizontal movement.

Parameters:

  • x number value
  • y number value

Returns:

  1. number clamped x value
  2. number clamped y value
passive (source)
Mark an input source as passive.

Parameters:

  • source InputSource input source to mark as passive

Returns:

    InputSource the same input source
passive (source)
Mark an input source as active. Note that input sources are active by default in most cases.

Parameters:

  • source InputSource input source to mark as active

Returns:

    InputSource the same input source

Input objects

Input methods.

Methods and attributes available on Input objects. See input to create such an object.

Input.config
Input configuration table.

It can be used to recreate this input object later (by passing the table as an argument for the input constructor). This table does not contain any userdata and should be easily serializable (e.g. to save custom input binding config). This doesn’t include input state, grab state, the event registry and the selected joystick since they may change often during runtime.

Can be changed anytime, but you will need to call reload to apply changes.

See expressions for an explanation on how to write input expressions.

Usage:

    player.config = {
      -- list of input sources expressions: either a string, or a table to specify some arguments for the expression
      "key.a", "key.d - key.a", {"key.left + x", x=0.5},
      -- children input: the table take the same fields as this
      jump = {...},
      -- The deadzone for analog inputs (e.g. joystick axes): if the input absolute value is strictly below this, it will be considered as 0. 0.05 by default.
      -- This is applied automatically after the evaluation of input expressions.
      deadzone = 0.05,
      -- The pressed threshold: an input is considered down if above or equal to this value. 0.05 by default.
      -- This is considered when determining if the input is pressed, odwn and released.
      threshold = 0.05,
      -- Dimension of the input (i.e. the number of values returned by this input). 1 by default.
      dimension = 1
    }
Input.children [read-only]
List and map of children Inputs.

Takes the form {[child1.name]=child1, [child2.name]=child2, child1, child2…}. Each child input is present both an element of this list and as the value associated with its name in the table.

Note that children are also set directly on the input object for easier access.

Usage:

    local player = input{ fire = "button.a" }
    local fire = player.fire
    -- Is the same as:
    local fire = player.children.fire
Input.name [read-only]
Name of the input. Defined on children inputs only.

Type:

    string
Input.enabled [read-only]
false if the input is disabled, true otherwise. If the input is disabled, its children are also disabled.
Input.grabbed [read-only]
false if the input is currently not grabbed, the grabbing Input otherwise.
Input.grabbing [read-only]
false if the input is not grabbing another input, the Input it is grabbing from otherwise.
Input.event

Input event registry. The following events are available:

  • "moved": called when the input value change, with arguments (new value, delta since last event). For inputs with dimension > 1, arguments are (new value[1], new value[2], …, delta[1], delta[2], …).

  • "pressed": called when the input is pressed, with arguments (1, new value, delta since last event). For inputs with dimension > 1, arguments are (dimensions that was pressed, new value[1], new value[2], …, delta[1], delta[2], …).

  • "released": called when the input is released, with arguments (1, new value, delta since last event). For inputs with dimension > 1, arguments are (dimensions that was pressed, new value[1], new value[2], …, delta[1], delta[2], …).

Input:update ()
Update the input and its children. Should be called every frame, typically after you've done all your input handling (otherwise pressed and released may never return true and delta might be wrong).

If the input is grabbed, will update the input that grabbed it instead.

(Note: this do not need to be called on inputs that are grabbing another input as the grabbed input will update it automatically)

Input:clone ([copyState=false])
Create a new input object based on this input config data. Unless copyState is set, the clone will only keep the config data and the input name; other state will be set to the default values.

Parameters:

  • copyState boolean if true, will copy the currrent state of the input into the clone. The input states includes the current input value, if it is enabled/disabled, and the current joystick; note that the grabbed state (i.e. the grabbed and grabbing fields) is not copied. (default false)
Input:reload ()
Reload the input config, and do the same for its children.
Input:disable ()
Disable the input and its children, preventing further updates and events. The input can be reenabled using enable.
Input:enable ()
Enable the input and its children, allowing further updates and events. The should be called after disabling the input using disable.
Input:onNextActiveSource (fn[, filter])
Will call fn(source) on the next activated source (including sources not currently used by this input). Typically used to detect an input in your game input binding settings.

Parameters:

  • fn function that will be called on the next activated source matching the filter
  • filter list of string patterns that sources must start with (example {"button", "key"} to only get buttons and key sources) (optional)
Input:grab ()
Grab the input and its children and returns the resulting grabbing input.

Grabbed inputs are set to a neutral position and disabled (will no longer update) and will instead pass all new updates to the grabbing input.

This is typically used for contextual action or pause menus: by grabbing the player input, all the direct use of this input in the game will stop (can’t move caracter, …) and instead you can use the grabbing input to handle input in the pause menu. To stop grabbing an input, you will need to call release on the grabbing input.

The grabbing input is created by cloning the current input and starts with the same state as the input when it was grabbed.

Input:release ()
Release an input that is currently grabbing another and its children. The parent grabbed input will be re-enabled (will update again). This grabbing input will be reset to a neutral position and disabled when released.
Input:neutralize ()
Set the state of this input and its children to a neutral position (i.e. value = 0 for every dimension).
Input:set (...)
Manually set the state of this input.

Parameters:

  • ...
Input:setJoystick (joystick)
Set the joystick associated with this input. This input will then ignore every other joystick. Set joystick to nil to disable and get input from every connected joystick.

Parameters:

  • joystick LÖVE jostick object to associate
Input:getJoystick ()
Returns the currently selected joystick.

Returns:

    joystick LÖVE jostick object
Input:down ()
Returns true if the input is currently down, false otherwise.

Returns:

    boolean if input is down on at least one dimensions
Input:pressed ()
Returns true if the input has just been pressed, false otherwise.

Returns:

    boolean if input has just been pressed on at least one dimensions
Input:released ()
Returns true if the input has just been released, false otherwise.

Returns:

    boolean if input has just been released on at least one dimensions
Input:value ()
Returns the current value of the input. If dimension > 1, this will return several values, one per dimension.

Returns:

    number,... current value of the input for every dimension
Input:delta ()
Returns the delta value of the input since the last call to update. If dimension > 1, this will return several values, one per dimension.

Returns:

    number,... delta of the input for every dimension

Input sources

Input sources are the initial source of input data; each input source can return a single number value. They are identified by a Lua identifier name. See expressions on how to use them in expressions.

Input sources are provided for common input methods (keyboard, mouse, gamepad) by default; see below for a list of built-in input sources.

Additionally, you can define your own input sources, by emitting events in the SignalRegistry returned by uqt.input.event. See the file input/event.lua to see a description of the events you will need to emit. The file also contains the definition of the built-in input sources that you may use as an example.

key.X
Keyboard input: 1 if the key X is down, 0 otherwise. X can be any of LÖVE’s KeyConstant.
scancode.X
Keyboard input: 1 if the key with scancode X is down, 0 otherwise. X can be any of LÖVE’s Scancode.
text.X
Text input: 1 if the text X was entered, 0 otherwise. X can be any text.
mouse
Mouse input: mouse[N] is 1 if the mouse button is down, 0 otherwise. N is either 1 for the primary mouse button, 2 for secondary or 3 for middle button.
  • mouse mouse[N]
mouse.x
Mouse input: X position of the mouse cursor in the game window.
mouse.y
Mouse input: Y position of the mouse cursor in the game window.
mouse.dx
Mouse input: latest X movement of the mouse cursor.

mouse.dx.p and mouse.dx.n will respectively only report movement in the positive or negative direction and return absolute value.

mouse.dy
Mouse input: latest Y movement of the mouse cursor.

mouse.dy.p and mouse.dy.n will respectively only report movement in the positive or negative direction and return absolute value.

wheel.dx
Mouse input: latest X movement of the mouse wheel.

wheel.dx.p and wheel.dx.n will respectively only report movement in the positive or negative direction and return absolute value.

wheel.dy
Mouse input: latest Y movement of the mouse wheel.

wheel.dy.p and wheel.dy.n will respectively only report movement in the positive or negative direction and return absolute value.

button.X
Gamepad input: 1 if the button X is down, 0 otherwise. X can be any of LÖVE’s GamepadButton.
axis.X
Gamepad input: current value of the gamepad axis (between -1 and 1). X can be any of LÖVE’s GamepadAxis.

axis.X.p and axis.X.n will respectively only report movement in the positive or negative direction and return absolute value.

dt
On new frame: current delta time value since last frame. Updated on each call to love.update. Note that if this input source is present in an expression, the other input sources in the same expression will be set as passive by default.
  • dt
child.X
Children inputs: current value of a child input of the current input. For child inputs of dimension 1. Replace X with the name of the child input.

If the child input is of dimension at least 2, instead use child.X[N], which gives the current value of the Nth dimension of a child input of the current input. Replace X with the name of the child input, and N with the index of the dimension you want.

value
Current input: current value of the current input. For inputs of dimension 1.

If the input is of dimension at least 2, instead use value[N], which gives the current value of the Nth dimension of the current input. Replace N with the index of the dimension you want.

Note that is input is passive by default. Think twice before marking it active as this may create a feedback loop (the input being updated will trigger it to be updated again, and so on).

  • value
generated by LDoc 1.4.6 Last updated 2022-10-13 00:23:58