User:Monster Iestyn/Lua scripting tutorial/Getting started
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 |
---|---|
FRACUNIT 1*FRACUNIT 1<<FRACBITS
|
1.0 |
2*FRACUNIT FRACUNIT*2
|
2.0 |
FRACUNIT/2
|
0.5 |
FRACUNIT/4
|
0.25 |
(3*FRACUNIT)/4
|
0.75 |
(3*FRACUNIT)/2 FRACUNIT + (FRACUNIT/2)
|
1.5 |
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 0FixedFloor(-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 0FixedTrunc(-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
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
.