Controllers

The Controllers API provides an interface for handling gamepads connected to the user’s system. This API is built as a wrapper over the browser’s native Gamepad API, providing a simplified Lua-based access for game controllers in the context of the game engine.

This documentation describes how to detect, manage, and interact with game controllers (gamepads) connected to the system.

Controllers Overview

The Controllers API is used to query the status of connected game controllers, such as the state of their buttons, axes (joysticks), and other inputs. It allows your game to respond to player input in real-time using the gamepad’s buttons and axes.

To access any controllers attached to the system, you need to first load the Controllers module using Lua’s require statement. This module gives you access to various methods that interact with the connected gamepads.

The code snippet below demonstrates the basic usage:

Accessing any controllers connected to the system
local Controllers = require 'engine/controllers'

local MyEntity = Class.new(Entity)

function MyEntity:update()
    -- Get the list of currently connected controllers
    local list = Controllers.getList()

    -- Iterate through the list of connected controllers
    for _, id in ipairs(list) do
        -- Get detailed information about the controller with the given ID
        local controller = Controllers.getInfo(id)

        -- Read the horizontal and vertical axes of the controller
        local axisH = controller.axes[1]
        local axisV = controller.axes[2]

        -- Print out the controller ID and its current axis values
        print("Gamepad " .. controller.name .. ": " .. axisH .. "/" .. axisV)
    end
end

return MyEntity

API Methods

### Controllers.getList()

Description: This method returns a list of controller IDs that represent the currently connected game controllers. Each controller has a unique identifier (ID), which can be used to access more detailed information.

Returns: A Lua table (array) containing the IDs of all connected game controllers.

Example:

Get the list of connected game controllers
local controllers = Controllers.getList()
for _, id in ipairs(controllers) do
    print("Controller ID: " .. id)
end

### Controllers.getInfo(id)

Description: This method retrieves detailed information about a specific controller, identified by its ID. The returned object contains data about the controller’s buttons, axes, and other input elements.

Parameters:

  • id (integer): The unique identifier of the controller.

Returns: A Lua table representing the controller’s current state. This table includes:

  • axes: A table of axis values representing the current positions of the controller’s joysticks or triggers. For example: - axes[1]: Horizontal movement (typically the left joystick’s X-axis). - axes[2]: Vertical movement (typically the left joystick’s Y-axis).

  • buttons: A table of button states, where each button can be in a pressed (1) or unpressed (0) state.

Example:

Access the current state of a controller by its ID
local controller = Controllers.getInfo(1)  -- Get the controller with ID 1
local horizontal = controller.axes[1]   -- Read the X-axis (horizontal)
local vertical = controller.axes[2]     -- Read the Y-axis (vertical)

print("Controller 1 Axes: " .. horizontal .. ", " .. vertical)

### Controller Object Structure

When using Controllers.getInfo(id), the returned controller object contains the following structure:

  • axes: A table of axis values (usually representing the joysticks or triggers). The exact number of axes can vary depending on the controller model.

  • buttons: A table of button states. Each index corresponds to a specific button, and its value is either 0 (not pressed) or 1 (pressed).

  • connected: A boolean indicating whether the controller is currently connected.

  • id: The unique identifier of the controller.

  • mapping: A string indicating the layout or type of the controller (e.g., standard).

Example of the controller object:

Example controller object structure
{
    id = "Name of Gamepad",
    axes = {0, 0},       -- Two axes (e.g., horizontal and vertical movement)
    buttons = {0, 1, 0}, -- Three buttons (one pressed)
    connected = true,
    mapping = 'standard'
}

Handling Controller Input

The Controllers module is generally used within the game loop, particularly in the update method of an entity or object, so that the controller inputs can be continuously checked and used to update the game state.

The axes are typically used for continuous input (e.g., joystick movement), and the buttons for discrete actions (e.g., jumping or shooting).

Here’s a full example that checks for controller input in the update loop:

Full example of handling controller input
local Controllers = require 'engine/controllers'

local Player = Class.new(Entity)

function Player:update()
    local controllers = Controllers.getList()

    for _, id in ipairs(controllers) do
        local controller = Controllers.getInfo(id)

        -- Get the X and Y axes (for movement)
        local moveX = controller.axes[1] or 0
        local moveY = controller.axes[2] or 0

        -- Apply movement to the player entity
        self.position.x = self.position.x + moveX
        self.position.y = self.position.y + moveY

        -- Check if a specific button is pressed
        if controller.buttons[1] == 1 then
            print("Button 1 pressed!")
        end
    end
end

return Player

Browser Gamepad API Mapping

This API directly wraps around the browser’s Gamepad API, which is part of the Web API suite. The browser’s Gamepad API allows web applications to access and respond to user input via connected gamepads.

  • The axes array corresponds to the gamepad’s analog sticks and triggers. Depending on the controller, this can include up to several axes.

  • The buttons array includes all digital inputs on the gamepad, such as the face buttons (A, B, X, Y), triggers, and bumpers.

For more information on the underlying browser API, refer to the Gamepad API documentation.