Game Control
A compatible viewer can send an avatar’s game control input to scripts. It comes from a game controller, or from the keyboard and mouse when the viewer is set to translate avatar movement into game control; either way it arrives in a controller’s shape, as sticks, triggers and buttons. This is separate from captured controls. Part of the Input feature; lsl.dev lists these APIs together in the Game Control category.
Concepts
- Changes in game control input raise
game_control, but only for scripts in attachments or seats- id is the avatar supplying the input
- button_levels is a 32-bit mask of the physical buttons currently held down
- axes is a list of six floats in the range [-1.0, 1.0], the physical axes indexed by
GAME_CONTROL_AXIS_*
- A script can read the current game-control mode of an avatar, as a
GAME_CONTROL_MODE_*value- The viewer also maps the controls to semantic actions such as strafe, jump or camera dolly; a script reads them with
llGetGameControlModeAxesandllGetGameControlModeButtons, and element count, index and bit meanings vary by mode - AVATAR, MOUSELOOK and CAPTIVE share one layout (axes, buttons); CURSOR shares those buttons but has its own six cursor axes; FLYCAM has its own (axes, buttons). See semantic actions by mode
- Physical and semantic constants share the
GAME_CONTROL_AXIS_*andGAME_CONTROL_BUTTON_*prefixes and reuse the same values, so check the mode before reading a semantic action
- The viewer also maps the controls to semantic actions such as strafe, jump or camera dolly; a script reads them with
PERMISSION_GAME_CONTROLis a script permission for game control
Functions and events
event | game_control(key id, integer button_levels, list axes) |
integer | llGetGameControlMode(key id) |
list | llGetGameControlModeAxes(key id) |
integer | llGetGameControlModeButtons(key id) |
Scripting Details
event | game_control(key id, integer button_levels, list axes)Triggered when a compatible viewer sends game controller input changes for the avatar specified by id. Only triggers for scripts in attachments or seats. |
integer | llGetGameControlMode(key id)Returns a GAME_CONTROL_MODE_* integer indicating the current game-control mode for the avatar specified by id. |
list | llGetGameControlModeAxes(key id)Returns a list of floats representing the modal axes for the current game-control mode of the avatar specified by id. Element count and index meanings vary by mode; use the GAME_CONTROL_AXIS_* constants as indices. |
integer | llGetGameControlModeButtons(key id)Returns a bitmask of the modal buttons currently active for the current game-control mode of the avatar specified by id. Bit meanings vary by mode; use the GAME_CONTROL_BUTTON_* constants as masks. |
Keyboard and mouse
Section titled “Keyboard and mouse”Besides a game controller, the viewer translates the avatar’s movement controls into game control: movement keys, mouse buttons bound to movement, and click-to-walk, which moves the avatar through the same controls. A held key counts as half deflection, or full when running, and adds to any controller input on the same axis, so a keyboard-only user still produces semantic axes. Movement the viewer applies directly is not included: turning by dragging with the mouse changes the avatar’s rotation without reaching the TURN axis.
Mouse clicks are not translated. In mouselook, GAME_CONTROL_BUTTON_CURSOR_BUTTON_LEFT and RIGHT are set by the controller’s shoulder buttons, which also simulate a mouse click; a real mouse click sets no game control bit. To catch mouse clicks, take controls with llTakeControls (CONTROL_ML_LBUTTON) and handle the control event, as before. A script that only listens to game_control misses mouse users.
The viewer only sends any game control data when its game control “send data to server” setting is on, which it is not by default, and only in regions that support game control.
Constant groups
Section titled “Constant groups”Game-control modes
Section titled “Game-control modes”llGetGameControlMode returns one of these GAME_CONTROL_MODE_* values for the avatar given by id.
Constant groups GameControlMode 5
integer GAME_CONTROL_MODE_AVATAR = 0;integer GAME_CONTROL_MODE_MOUSELOOK = 1;integer GAME_CONTROL_MODE_FLYCAM = 2;integer GAME_CONTROL_MODE_CAPTIVE = 3;integer GAME_CONTROL_MODE_CURSOR = 4;
How the viewer picks the mode
Section titled “How the viewer picks the mode”The script cannot choose the mode; the viewer derives it from the avatar’s state every frame. In the Second Life viewer’s game control release the first match wins:
- CURSOR: the left stick is driving the on-screen mouse cursor. This wins even over flycam; the flycam keeps running underneath and keeps any controls the cursor does not use.
- FLYCAM: the flycam is engaged.
- MOUSELOOK: the camera is in mouselook. This is checked before sitting, so a seated avatar in mouselook reports MOUSELOOK, not CAPTIVE.
- CAPTIVE: the avatar is sitting.
- AVATAR: otherwise.
CAPTIVE is documented in the viewer as “sitting, or controls have been taken”, but this release only checks sitting: an avatar standing while a script holds its controls with llTakeControls reports AVATAR. Captive and avatar modes share one action layout, and in both the controller still moves the avatar, so a script that took controls keeps receiving control events from controller movement.
This is observed viewer behaviour rather than a documented guarantee, and other viewers may differ.
Physical axes
Section titled “Physical axes”The sticks and triggers as laid out on the controller, whatever the mode: the six entries of the axes list in game_control. The LSL definitions call this the canonical layout.
Constant groups GameControlAxis 6
integer GAME_CONTROL_AXIS_LEFTX = 0; // Left stick X axisinteger GAME_CONTROL_AXIS_LEFTY = 1; // Left stick Y axisinteger GAME_CONTROL_AXIS_RIGHTX = 2; // Right stick X axisinteger GAME_CONTROL_AXIS_RIGHTY = 3; // Right stick Y axisinteger GAME_CONTROL_AXIS_LEFT_TRIGGER = 4; // Left triggerinteger GAME_CONTROL_AXIS_RIGHT_TRIGGER = 5; // Right trigger
Physical buttons
Section titled “Physical buttons”The controller’s buttons, whatever the mode: bits of button_levels in game_control.
Constant groups GameControlButton 21
Semantic actions by mode
Section titled “Semantic actions by mode”Indices into the list returned by llGetGameControlModeAxes, and masks for the bitmask returned by llGetGameControlModeButtons. Their meaning depends on the mode, so the same values are reused. In the Second Life viewer’s game control release (axis slots, default button bindings):
| Mode | Semantic axes | Semantic buttons |
|---|---|---|
| AVATAR, CAPTIVE | 5: avatar axes | avatar buttons, except CURSOR_BUTTON_LEFT/RIGHT |
| MOUSELOOK | 5: avatar axes | avatar buttons |
| CURSOR | 6: cursor movement and position (no constants yet) | avatar buttons |
| FLYCAM | 7: flycam axes | flycam buttons, see below |
These groups are lsl.dev’s own: the LSL definitions do not group the semantic constants yet. The viewer source calls them semantic; the LSL definitions call them modal.
Avatar, mouselook and captive modes
Section titled “Avatar, mouselook and captive modes”CURSOR mode uses these buttons too, but not these axes: its six axes are the cursor’s movement (0, 1), pixel position (2, 3) and normalized position (4, 5), which have no GAME_CONTROL_AXIS_* names yet.
Constant groups GameControlAvatarAxis 5GameControlAvatarButton 13
integer GAME_CONTROL_AXIS_STRAFE = 0; // Left/right movementinteger GAME_CONTROL_AXIS_ADVANCE = 1; // Forward/backward movementinteger GAME_CONTROL_AXIS_TURN = 2; // Turning left/rightinteger GAME_CONTROL_AXIS_LOOK = 3; // Looking up/downinteger GAME_CONTROL_AXIS_RISE = 4; // Up/down movement
// Otherinteger GAME_CONTROL_BUTTON_JUMP = 0x1; // Jumpinteger GAME_CONTROL_BUTTON_CROUCH = 0x2; // Crouchinteger GAME_CONTROL_BUTTON_SIT = 0x4; // Toggle sitting// GAME_CONTROL_BUTTON_TOGGLE_*integer GAME_CONTROL_BUTTON_TOGGLE_CURSOR = 0x10; // Toggle cursor modeinteger GAME_CONTROL_BUTTON_TOGGLE_SPEAK = 0x20; // Toggle voice speakinteger GAME_CONTROL_BUTTON_TOGGLE_MOUSELOOK = 0x40; // Toggle mouselook modeinteger GAME_CONTROL_BUTTON_TOGGLE_FLYCAM = 0x100; // Toggle flycam mode// GAME_CONTROL_BUTTON_CURSOR_*integer GAME_CONTROL_BUTTON_CURSOR_BUTTON_LEFT = 0x200; // Left mouse button clickinteger GAME_CONTROL_BUTTON_CURSOR_BUTTON_RIGHT = 0x400; // Right mouse button click// GAME_CONTROL_BUTTON_ADVANCE_*integer GAME_CONTROL_BUTTON_ADVANCE_FORWARD = 0x800; // Move forwardinteger GAME_CONTROL_BUTTON_ADVANCE_BACK = 0x1000; // Move backward// GAME_CONTROL_BUTTON_STRAFE_*integer GAME_CONTROL_BUTTON_STRAFE_LEFT = 0x2000; // Strafe leftinteger GAME_CONTROL_BUTTON_STRAFE_RIGHT = 0x4000; // Strafe right
Flycam mode
Section titled “Flycam mode”The definitions list more flycam buttons than the viewer sends. A button only gets a bit when the action has a default binding, and in this release only ZOOM_OUT (0x1), ZOOM_IN (0x8), TOGGLE_FLYCAM (0x100), toggle cursor (0x10, the value of GAME_CONTROL_BUTTON_TOGGLE_CURSOR and of TOGGLE_ALT_ZOOM) and orbit (0x400, the value of ROLL_CW, no constant of its own) are bound. The pan, dolly, truck, roll, reset and follow buttons are never set.
Constant groups GameControlFlycamAxis 7GameControlFlycamButton 14
integer GAME_CONTROL_AXIS_TRUCK = 0; // Camera lateral (left/right) movementinteger GAME_CONTROL_AXIS_DOLLY = 1; // Camera forward/backward movementinteger GAME_CONTROL_AXIS_PAN = 2; // Camera pan left/rightinteger GAME_CONTROL_AXIS_TILT = 3; // Camera tilt up/downinteger GAME_CONTROL_AXIS_BOOM = 4; // Camera up/down movementinteger GAME_CONTROL_AXIS_ROLL = 5; // Camera rollinteger GAME_CONTROL_AXIS_ZOOM = 6; // Camera zoom in/out
// Otherinteger GAME_CONTROL_BUTTON_RESET = 0x80; // Reset camera to default view// GAME_CONTROL_BUTTON_ZOOM_*integer GAME_CONTROL_BUTTON_ZOOM_OUT = 0x1; // Zoom camera outinteger GAME_CONTROL_BUTTON_ZOOM_IN = 0x8; // Zoom camera in// GAME_CONTROL_BUTTON_PAN_*integer GAME_CONTROL_BUTTON_PAN_RIGHT = 0x2; // Camera pan rightinteger GAME_CONTROL_BUTTON_PAN_LEFT = 0x4; // Camera pan left// GAME_CONTROL_BUTTON_TOGGLE_*integer GAME_CONTROL_BUTTON_TOGGLE_ALT_ZOOM = 0x10; // Toggle alt-zoominteger GAME_CONTROL_BUTTON_TOGGLE_FOLLOW = 0x40; // Toggle camera follow modeinteger GAME_CONTROL_BUTTON_TOGGLE_FLYCAM = 0x100; // Toggle flycam mode// GAME_CONTROL_BUTTON_ROLL_*integer GAME_CONTROL_BUTTON_ROLL_CCW = 0x200; // Roll camera counter-clockwiseinteger GAME_CONTROL_BUTTON_ROLL_CW = 0x400; // Roll camera clockwise// GAME_CONTROL_BUTTON_DOLLY_*integer GAME_CONTROL_BUTTON_DOLLY_FORWARD = 0x800; // Camera dolly forwardinteger GAME_CONTROL_BUTTON_DOLLY_BACK = 0x1000; // Camera dolly backward// GAME_CONTROL_BUTTON_TRUCK_*integer GAME_CONTROL_BUTTON_TRUCK_LEFT = 0x2000; // Camera truck leftinteger GAME_CONTROL_BUTTON_TRUCK_RIGHT = 0x4000; // Camera truck right
Related
Section titled “Related”See also Feature InputCategory Game ControlSL Wiki Game controlSL Wiki LSL GameControls