Lua

From SRB2 Wiki
Jump to navigation Jump to search

Lua is a scripting language that can be used by SRB2. It allows users to write custom game logic without editing the game's source code, in addition to many of the capabilities SOC also has. For these reasons, Lua scripting is considered a more powerful method of modification available to SRB2 compared to SOC. However, Lua does not supersede SOC completely – there are still a number of aspects of modding that can only be configured through SOC. A file created in the Lua language is commonly called a "Lua script".

SRB2's implementation of Lua is based on a modification of Lua 5.1 called BLUA (which stands for "bastardized Lua"; see below for an overview of the differences). The reference manual for Lua 5.1 can be found here. The name "Lua" itself derives from the Portuguese word for moon (pronounced LOO-ah); it should not be referred to as "L.U.A.", as it is not an acronym.

Script writing

For users new to the Lua language, it is highly recommended to read the Lua Tutorial on the lua-users wiki to learn the basics of Lua.

Changes from standard Lua

SRB2's implementation of Lua is based on BLUA, which has some syntax differences compared to standard Lua, bringing it closer to C. Additionally, some further changes have been made to adapt BLUA for SRB2's purposes. The differences are as follows:

  • Whereas standard Lua uses floating-point doubles for all of its math, SRB2's implementation uses signed integers. In situations where real numbers are required, SRB2's Lua uses fixed-point numbers with a base unit of FRACUNIT (65536). For example, the number 1.5 is represented by FRACUNIT + FRACUNIT/2 or 3*FRACUNIT/2 (98304). Fixed-point math functions such as FixedMul() and FixedDiv() are available to assist with math in these situations.
  • The only standard libraries loaded are the basic library (including the coroutine library), string manipulation, and table manipulation. The other libraries were removed either because they are not useful for SRB2's purposes or because they could be used to write potentially harmful code. Some useful functions from the missing libraries are replaced by SRB2-specific functions.
  • All standard bitwise operations are supported. Note that, since Lua uses ^ for powers, bitwise XOR is represented as ^^.
  • C-style syntax is supported for several operators in addition to standard Lua's syntax, including comments (// and /* ... */) and the "not equals" operator (!=).
  • String concatenation can be done with the syntax "string"+var+"string" or "string\$var\string" in addition to standard Lua's "string"..var.."string".
  • The continue keyword is supported in for loops, whereas standard Lua only supports break and return. Additionally, break N can be used to break out of N loops at once.
  • Pseudo-numbers ($1, $2, and so on) can be used in variable assignments to reference the variables being assigned. These represent the values of the referenced variables before the line is executed, so var, var2 = $2, $1 can be used to swap two values, for instance.
  • The keywords do after for and while, and then after if have been made optional.
  • Inline definitions of functions without arguments can be done with the syntax do ... end, in addition to standard Lua's function() ... end.
  • In strings, ASCII- and Unicode-encoded hexadecimal characters can be supplied with the \x and \u escape sequence, respectively.
  • The __usedindex metatable event, for assigning an index/value to an existing key/variable, has been added.

Syntax

Main article: Lua/Syntax

This article gives an overview of the basic language features and syntax of SRB2's Lua implementation. It is not, however, a complete documentation of the Lua language – for this, consult the reference manual for Lua 5.1.

Constants

Main article: Constants

There are a variety of constants supplied by SRB2 to aid script-writing. The three most commonly used constants are:

  • FRACUNIT (65536, or 1<<FRACBITS): The basic unit of measurement in SRB2, for positions, speeds, scales, and other things. Commonly used when conversion to and from a fixed-point representation is desired.
  • TICRATE (35): The number of tics (game frames) in one second.

Special characters

Certain ASCII characters have special effects for text printed using the functions print or CONS_Printf.

Chat text

These characters are reserved for use with player chat messages. They give the text special effects such as playing a sound effect when the text is printed, or changing the text color.

Decimal Hexadecimal Usage
3 0x03 Plays a chat beep sound
4 0x04 Plays a chat beep sound and colors text yellow

Text colors

See also: SOC > Custom colors

These characters change the color of text displayed on the screen. All text following any of these characters will use their respective colors, until a different color is set or the text ends. Use the code for White/Reset to reset the text color back to the default color where appropriate.

Decimal Hexadecimal Color Example
128 0x80 White/Reset
129 0x81 Magenta
130 0x82 Yellow
131 0x83 Green
132 0x84 Blue
133 0x85 Red
134 0x86 Gray
135 0x87 Orange
136 0x88 Sky
137 0x89 Purple
138 0x8A Aqua
139 0x8B Peridot
140 0x8C Azure
141 0x8D Brown
142 0x8E Rosy
143 0x8F Inverted

Script execution

The most common way to load Lua scripts is to add them to a WAD or PK3 file as a text lump. In PK3 files, lumps in the Lua/ folder are recognized as Lua scripts by SRB2 and are loaded automatically upon loading the PK3 file, in the order that they are found in the file. In WAD files, lumps with the name prefix LUA_ are loaded automatically. Lua scripts that do not meet these requirements are not loaded automatically, and there is no method of loading them after the file containing them has been added. It is important to note that all Lua scripts in a WAD or PK3 file will be loaded before any SOC lumps also within the file, regardless of lump ordering. This means that any changes to the game in the file's SOC lumps will not be recognized in the file's Lua scripts.

Alternatively, Lua scripts can be stored as standalone files with the file ending .lua. They can be loaded via the Addons menu or by using the console command addfile.

Global variables

Main article: Lua/Global variables

As well as the global variables that come with Lua (e.g.: _G and _VERSION), SRB2 allows access to a number of its own pre-defined global variables for use in Lua scripting.

Userdata types

There are many types of userdata that may be encountered in Lua scripts for SRB2. Some of the most commonly used types are mobj_t, player_t, mobjinfo_t and state_t. The full list of userdata types recognised by SRB2 is given below for reference – note that the type names themselves have no meaning to Lua scripts whatsoever.

General

These userdata types represent components of the game related to Objects or players.

Type name Accessibility Allows custom variables Description
mobj_t Read + Write Yes This userdata type represents an Object.

This is not to be confused with an Object type (e.g., MT_PLAYER) – these are just constants representing Object type numbers, and will not be accepted in functions requiring mobj_t variables (e.g., P_SpawnGhostMobj(MT_PLAYER) will cause Lua to give an error).

player_t Read + Write Yes This userdata type represents the properties of a player that are independent of the player Object, which may carry over between maps. This is not to be confused with mobj_t or vice versa.
ticcmd_t Read + Write No This userdata type represents a player's current button information, i.e., what buttons are being pressed currently.
skin_t Read-only No This userdata type represents the properties of a character skin, which are defined in a character's S_SKIN lump.

SOC

These userdata types represent components of the game that can also be modified by SOC.

Type name Accessibility Allows custom variables Description
mobjinfo_t Read + Write Yes This userdata type represents the properties of an Object type.
state_t Read + Write No This userdata type represents the properties of a state.
sfxinfo_t Read + Write No This userdata type represents the properties of a sound.
hudinfo_t Read + Write No This userdata type represents the properties of a HUD item.
mapheader_t Read-only SOC-only This userdata type represents the properties of a level header.

Map

These userdata types represent components of the the game that are part of a map.

Type name Accessibility Allows custom variables Description
mapthing_t Read + Write No This userdata type represents a Thing.
sector_t Read + Write No This userdata type represents a sector.
subsector_t Read-only No This userdata type represents a subsector.
line_t Read-only No This userdata type represents a linedef.
side_t Read + Write No This userdata type represents a sidedef.
vertex_t Read-only No This userdata type represents a vertex.
ffloor_t Read + Write No This userdata type represents an FOF.
pslope_t Read + Write No This userdata type represents a slope.
polyobj_t Read + Write No This userdata type represents a PolyObject.

Miscellaneous

These userdata types represent components of the game that do not fit into the above groups.

Type name Accessibility Allows custom variables Description
camera_t Read-only No This userdata type represents a player's camera.
consvar_t Read-only No This userdata type represents a console variable.
patch_t Read-only No This userdata type allows access to the properties of a graphics patch (see the HUD library).

Functions

Main article: Lua/Functions

There are many functions in SRB2 available for usage by Lua. A few useful functions available include:

  • print(output, [output2, ...]): Prints the output specified into the console. Each output string is separated into different lines.
  • P_SpawnMobj(x, y, z, type): Spawns an Object at the x, y, and z coordinates specified. Returns the Object spawned.
  • addHook(hook, function, [extra]): Adds a hook into the game. See below for more information on hooks.

Hooks

Main article: Lua/Hooks

Most of a script's interactivity with SRB2 is handled via hooks. At certain pre-determined points in SRB2's source code, the game checks to see if any hooks of a particular type have been added via a loaded Lua script, and if so, executes the Lua code of these hooks. Hooks are added with the addHook() function, which takes three arguments: a string with the hook's name, a function to be run when the hook is executed (the arguments passed to this function will vary depending on the hook), and a third argument whose purpose depends on the hook (and which is omitted for some hooks). Some of the most-used hooks are:

  • ThinkFrame: A function with no arguments (function()) is executed once every frame while in-game, after all Object thinkers have run.
  • MobjThinker: A function with up to one argument (function(mobj)) is executed once per Object every frame while in-game. mobj is the Object in question, and is of type mobj_t. An Object type may be passed as the third argument to addHook() to limit this hook to Objects of the specified type.
  • LinedefExecute: A function with up to three arguments (function(line, mobj, sector)) is executed when called by linedef type 443 (Call Lua Function). line is the linedef that called the function (of type line_t), mobj is the Object that triggered the linedef executor (of type mobj_t), and sector is the triggering sector the Object touched (of type sector_t), if it exists. As a third argument, a string must be passed to addHook() – the same string must be written across the triggering linedef's front upper texture in order to execute the function. This is useful when using Lua scripting in combination with a map, to execute custom code via a map trigger.

Actions

Lua can be used to call or override existing actions, as well as create new actions that can be used in SOC.

Tutorials

These tutorials are designed to demonstrate some of Lua's use cases in SRB2. Each one demonstrates different functionality, so it is recommended to read all of them. These are not designed to be substitutes for learning Lua itself; they assume that you have a basic understanding of how the language works.

To do
More tutorials should be written to cover other methods of interaction between the game and Lua scripts.
  Lua [view]
Language features SyntaxMetatables
SRB2 data ActionsConstantsFunctionsGlobal variablesHooksUserdata structures
SRB2Kart data Kart Userdata structuresKart FunctionsKart HooksKart Global Variables and Constants
Tutorials Freeslots and Object resourcesCustom player ability