From SRB2 Wiki
Jump to: navigation, 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 supercede 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 known as a "Lua script".

The name "Lua" itself is from the Portuguese for moon; it should not be referred to as "LUA", as it is not an acronym.


The base version of Lua used by SRB2 is Lua 5.1. The reference manual for Lua 5.1 can be found here: [1]

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 and syntax of Lua.

Changes from vanilla Lua

SRB2's implementation of Lua has a few changes from most implementations of the language. Some of the most important changes are:

  • While vanilla Lua uses floating-point doubles for all of its math, SRB2's implementation uses signed integers. Variables that require greater precision than whole numbers are dealt with in multiples of FRACUNIT (65536) to accommodate. Fixed-point math functions such as FixedMul() and FixedDiv() exist to assist with math in these situations.
  • The only standard libraries loaded are the basic libraries, string manipulation, and table manipulation. File I/O in particular is nonexistent. Useful functions are replaced by SRB2-specific functions.
  • All standard bitwise operations, as well as C-style comments, are supported. (Note that, since Lua uses ^ for powers, bitwise XOR is represented as ^^.)
  • The continue keyword is supported in for loops, whereas vanilla Lua only supports break and return. Additionally, break N can be used to break out of N loops.
  • String concatenation can be done with "string"+var+"string" or "string\$var\string" as well as vanilla Lua's "string"..var.."string".
  • Psuedo-numbers ($1, $2, and so on) can be used to reference the variables being assigned. These represent the variables before the line is executed, so var, var2 = $2, $1 can be used to swap two values, for instance.
  • "do" after for and while, and "then" after if have been rendered optional.


Main article: Lua/Basics

The main article covers how to use Lua properly with SRB2, and while it won't cover the complete Lua language, it does go over a few basic ideas.

Useful constants

Main article: Constants

There are a variety of constants supplied by SRB2 to ease scriptwriting. The three most useful constants are:

  • FRACBITS (16): The number of bits that represent the decimal in a FRACUNIT. Commonly used in bitshifting functions to get "whole" numbers.
  • FRACUNIT (65536, or 1<<FRACBITS): The basic unit of measurement in SRB2, for positions, speeds, scales, and other things. More commonly used than FRACBITS 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 Sampletext-none.png
129 0x81 Purple Sampletext-purple.png
130 0x82 Yellow Sampletext-yellow.png
131 0x83 Green Sampletext-green.png
132 0x84 Blue Sampletext-blue.png
133 0x85 Red Sampletext-red.png
134 0x86 Gray Sampletext-gray.png
135 0x87 Orange Sampletext-orange.png

Script execution

The most common way to load Lua scripts is to add them to a WAD file as a text lump. Lumps with the name prefix LUA_ are recognized as Lua scripts by SRB2 and are loaded automatically upon loading the WAD file, in the order that they are found in the file. Lua scripts with other names are not loaded automatically, and there is no method of loading them after the WAD file containing them has been added. It is important to note that all Lua scripts in a WAD 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 WAD file's SOC lumps will not be recognised in the file's Lua scripts.

Alternatively, Lua scripts can be stored as standalone files with the file ending .lua. The console command ADDFILE can be used to load standalone Lua script files.

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.


These userdata types represent components of the game to do with 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.


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.


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.


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).


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.


Main article: Lua/Hooks

Most of a script's meat, and almost all of its interactivity with SRB2, is handled via hooks. Hooks are added with the addHook() function, which takes three arguments: a string with the hook's name, a function to be added to the hook (the arguments passed to this function will vary depending on the hook), and a third argument that may or may not be present, and may take a different type of variable depending on the hook. 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. The third argument to addHook() must be passed, and is a string containing the name of the function that must be written across the triggering linedef's front upper texture to execute the function. This is useful when using Lua scripting in combination with a map, to execute custom code via a map trigger.


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


These tutorials are designed to demonstrate some of Lua's use cases in SRB2. Each one demonstrates different functionality, so for the most effectiveness, it is suggested to follow all of them. These are not designed to be substitutes for learning the language itself.

ToDoIcon.png To do
More tutorials should be written to cover other methods of interaction between the game and Lua scripts.