User:Monster Iestyn/Lua scripting tutorial/Getting started

From SRB2 Wiki
Jump to: navigation, search
Test.png This article or section is incomplete. It doesn't have all of the necessary core information on this topic. Please help the SRB2 Wiki by finishing this article.

Unlike SOC, Lua is a proper scripting language. As such, this section does not go over the basics and syntax of vanilla Lua, but goes over the more important changes made to it, as well as provide helpful tips.

Useful links

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

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.

Numbers and math in SRB2's Lua

In vanilla Lua, all numbers are double-precision floating point numbers. In SRB2, Lua is instead designed to use signed integers for everything: specifically, SRB2's Lua uses signed 32-bit integers, allowing for any whole number between -2147483648 (- 231) and 2147483647 (231 - 1) to be used. However, this also means numbers with fractions (e.g.: 0.5, 1.2, 3.14) cannot be used in SRB2's Lua, and that division will truncate anything that would be after the decimal point (e.g.: 1/2 is 0 rather than 0.5).

For precision greater than whole numbers, SRB2's Lua instead uses fixed-point numbers for all such calculations that need non-integers – numbers are multiplied by the constant FRACUNIT (or bit-shifted to the left by FRACBITS) to become an integer in this scale, and anything smaller than FRACUNIT is a fraction. The following table illustrates how this system works:

Fixed-point scale Floating-point equivalent
(3*FRACUNIT)/4 0.75

Several fixed-point math functions are included to allow fixed point numbers to be multiplied together, divided by each other, etc., in this scale:

Operation Function Example
Multiplication (a * b) FixedMul(a, b) FixedMul(2*FRACUNIT, 3*FRACUNIT) returns 6*FRACUNIT
Division (a / b) FixedDiv(a, b) FixedDiv(6*FRACUNIT, 3*FRACUNIT) returns 2*FRACUNIT
Remainder of a / b FixedRem(a, b) FixedRem(3*FRACUNIT, 2*FRACUNIT) returns FRACUNIT
Square root (√a or sqrt(a)) FixedSqrt(a) FixedSqrt(16*FRACUNIT) returns 4*FRACUNIT
Hypotenuse1 (hypot(a, b)) FixedHypot(a, b) FixedHypot(3*FRACUNIT, 4*FRACUNIT) returns 5*FRACUNIT
Floor (⌊a⌋ or floor(a)) FixedFloor(a) FixedFloor(FRACUNIT/2) returns 0
FixedFloor(-FRACUNIT/2) returns -FRACUNIT
Ceiling (⌈a⌉ or ceil(a)) FixedCeil(a) FixedCeil(FRACUNIT/2) returns FRACUNIT
FixedCeil(-FRACUNIT/2) returns 0
Trunc (trunc(a), rounds towards zero) FixedTrunc(a) FixedTrunc(FRACUNIT/2) returns 0
FixedTrunc(-FRACUNIT/2) returns 0
Round (rounds away from zero) FixedRound(a) FixedRound(FRACUNIT/2) returns FRACUNIT
FixedRound(-FRACUNIT/2) returns -FRACUNIT

1 calculates the square root of the sum of the squares of two given numbers


Pseudo-numbers are a new concept added to Lua in SRB2; they are used to simplify assigning new values to variables by modifying their existing values, such as increasing or decreasing a number value by a certain amount. The old value for a variable is represented by the dollar symbol ($). An example of a pseudo-number in use is shown below:

local variable = 0
// without pseudo-numbers
variable = variable + 1
// with pseudo-numbers
variable = $ + 1

// in either case, variable now has a value of 1

This concept also extends to multiple variable assignment:

local var1, var2 = 20, 16
// without pseudo-numbers
var1, var2 = var1+5, var2-10
// with pseudo-numbers
var1, var2 = $+5, $-10

// in either case, var1 now has a value of 25, and var2 a value of 6

Note that, in the above example, $ is the old value of var1 for var1's new value, and then the old value of var2 for var2's own new value.

Numbers can be placed after the $ symbol if needed, for identification of the individual variables – $1, $2, $3 and so on then represent the first, second, third and further variables in an assignment. This is particularly useful for the ability to swap the values of two variables, for example:

local var1, var2 = 2, 7
var1, var2 = $2, $1
// var1 is now 7, var2 is now 2

This results in var1 now having the old value of var2, and var2 the old value of var1.