Lua Language

Lua is an interpreted language that is used for scripting in Total War. It's lightweight, fast, and easy to use.

Lua instructions are written in a text file, which is generally given a .lua file extension. The game looks to load certain script files when loading, and may be configured to load specific scripts when loading a particular campaign or battle.

Version 5.1 of lua is used in Total War scripting - the latest at time of writing is version 5.3.5.

Whitespace in lua is ignored, so scripts can be spaced out according to the scripters preference. Lua statements may optionally be terminated with a semicolon. Individual lines may be commented with -- - this causes the rest of the line to be ignored. Blocks of script of any size may be commented with --[[ script ]]. These blocks may not be nested, however.

Lua is case-sensitive, so variables named value, Value and VALUE are all different. This is a common source of bugs.

Example:

-- this line is commented
--[[
this line is also commented
]]
value = 6
print(value);        -- semicolon optional
print(Value)
6
nil
Relevant in Battle loaded in battle
Relevant in Campaign loaded in campaign
Relevant in Frontend loaded in frontend
Back to top

More Information

More information about lua can be found on the following sites:

https://www.lua.orgLua homepage.
https://www.lua.org/demo.htmlLua demo site - allows snippets of script to be tested outside of the game (very useful).
https://www.lua.org/manual/5.1/The lua manual.
http://lua-users.org/wiki/Lua wiki - contains useful information about supplied libraries.
https://www.tutorialspoint.com/lua/Lua tutorial - others are available.

Back to top

Lua Data Types

Lua supports only eight data types, six of which are documented further down this page:

Data TypeDescription
nilThe absence of a value.
booleantrue/false values.
numberFloating-point numeric values.
stringText values.
functionExecutable chunks of script.
tableDynamically-sized key/value lists, may be used to build complex data structures.
threadRepresents independent threads of execution - not supported in Total War scripting.
userdataObjects provided by the host code to script, usually with an interface on which script may make function calls.

Back to top

Local and Global Variables

Back to top

if statements

An if statement may be used to perform a logical test and, based on the boolean result of that test, execute different blocks of instruction. An if statement will execute a block of script specified by a mandatory then operator if the logical test evaluates to true, or a second optional block specified by an else operator if it doesn't. Each if statement must be terminated by the keyword end.

An else operator following another if statement may be combined into an elseif operator. Converting nested if statements to elseif operators in this way saves on having to terminate each if statement with end - see the example below.

Example:

t = true
f = false

if t == true then
    print("t is true")
end

if f == true then
    print("f is true")
else
    print("f is false")
end

n = 28

if n < 5 then
    print("n is less than 5")
elseif n < 10 then
    print("n is less than 10")
elseif n < 15 then
    print("n is less than 15")
elseif n < 20 then
    print("n is less than 20")
else
    print("n is greater than or equal to 20")
end
t is true
f is false
n is greater than or equal to 20
Back to top

Conditional Operators

Conditional tests may be performed by if statements, while loops and repeat loops to make decisions about what scripts to execute. Any values can be evaluated in a conditional test - non-boolean values may be evaluated in a boolean manner as follows:

  • false boolean values, and nil values, evaluate to false.
  • Any other value evaluates to true (including the number 0, which evaluates to false in C).

The logical operator not may be used to negate the result of a boolean - if passed a true value it returns false, and if passed a false value it returns true. The value returned by the not operator is always boolean, even if the value supplied was not. The statement x = not not x converts x to a boolean value, therefore.

The logical operators and and or may be used to assess multiple boolean conditions together. The and operator returns true if both of the expressions passed to it evaluate to true themselves. The or operator returns the second value passed to it if the first evaluates to false, otherwise the first value is returned. Unlike and, not and other comparison operators, therefore, or can return something other than a boolean value. This can be useful for setting default values for a variable - see the example below.

The lua interpreter reads forward when performing conditional tests, and will not evaluate expressions that it doesn't need to. For example, if the first expression passed to an and operator evaluates to false then the second is never evaluated. Likewise, if the first expression passed to an or operator evaluates to true then the second expression is never evaluated (and the first is returned). These constructs can both be useful in different ways - see the examples below.

The not operator has precedence (meaning it gets evaluated first), followed by the and operator and finally the or operator. Parenthesis () can be used to override the natural order of precedence.

Example - Relying on conversion to boolean to test existence of value:

num_value = 10

-- A number of any value evaluates to true.
-- This is akin to saying "if num_value has been set.."
if num_value then
    print("num_value evaluates to true")
end
num_value evaluates to true

Example - Using 'not' to convert to boolean:

num_value = 10

print("not num_value: " .. not num_value)
print("not not num_value: " .. not not num_value)
not num_value: false
not not num_value: true

Example - and/or operator examples:

t = true
f = false

if t and f then
    print("this should never get printed")
end

if t and not f then            -- "not f" evaluates to true
    print("this should get printed")
end

if t or f then
    print("either t or f is true")
end
this should get printed
either t or f is true

Example - Compound logical test of greater length, with parenthesis:

t = true
f = false

if not (t and (not f or not t)) then
    print("???")
else
    print("wha?")
end
wha?

Example - Using 'or' to set a default value during an assignment operation:

function returns_nothing()
    -- do nothing
end

-- returns_nothing() evaluates to nil/false,
-- so 'or' will return the second value here
value = returns_nothing() or 1
print("value is " .. tostring(value))
value is 1

Example - Using 'and' to test existence or type before value of variable, to prevent errors :

This example shows how the 'and' operator can be used in a serial to guard operations on values that might otherwise fail and cause script errors. Performing a numeric comparison such as > on a non-numeric value is illegal and would cause a script failure. This is prevented by the first expression which tests whether value is a number. If value is not a number, and the type check returns false, lua will not proceed on to evaluate the second expression (containing the numeric comparison) as the interpreter is smart enough to realise that it can't affect the final result.
function test_value(value)
    if type(value) == "number" and value > 10 then
        print("value " .. tostring(value) .. " is a number > 10")
    else
        print("value " .. tostring(value) .. " is not a number or a number <= 10")
    end
end

test_value(20)
test_value("hello")
test_value(false)
value 20 is a number > 10
value hello is not a number or a number <= 10
value false is not a number or a number <= 10
Back to top

Standard Functions

print(... values to print)

Prints one or more supplied values to the standard output. In Total War games, the standard output is the console. Non-string values passed to the function are cast to string before printing.

Parameters:

1

...

values to print

Returns:

  1. nil

Example:

print("hello")        -- string
print(5, 3)        -- two numbers
print({})            -- a table
hello
5    3
table: 0xb805do

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 172

type(variable variable)

Returns the type of a specified value as a string.

Parameters:

1

variable

variable

Returns:

  1. string type

Example:

print(type(not_defined))
print(type("hello"))
print(type(5))
print(type({}))
nil
string
number
table

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 183

tostring(variable variable)

Returns the specified value cast to a string. The specified value is unaffected.

Parameters:

1

variable

variable

Returns:

  1. string variable cast to string

Example:

value = 6
value_as_string = tostring(value)
print(value, type(value))
print(value_as_string, type(value_as_string))
6    number
6    string

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 197

tonumber(variable variable)

Returns the specified string value cast to a number. This only works for string values that contain numeric characters (e.g. "65"). If the supplied value is a string that does not contain numeric characters, or is any other value other than a number then nil is returned.

Parameters:

1

variable

variable

Returns:

  1. number variable cast to number

Example:

numeric_str_value = "26"
non_numeric_str_value = "hello"
number_value = 18
boolean_value = true
table_value = {}
print(tonumber(numeric_str_value), tonumber(non_numeric_str_value), tonumber(number_value), tonumber(boolean_value), tonumber(table_value))
26    nil    18    nil    nil

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 209

loadstring(string lua string)

Returns an executable function created from a string. This string may be constructed manually, or generated by another function such as string.dump. When the returned function is executed the lua script contained within the specified string is run.
Use this function sparingly. See external documentation for more information.

Parameters:

1

string

lua string

Returns:

  1. function lua function

Example:

function test_func()
    print("hello");
end;

local str_a = string.dump(test_func);
local str_b = "print(\"123\")";

func_a = loadstring(str_a);
func_b = loadstring(str_b);

func_a()
func_b()
hello
123

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 222


Nil

The data type nil represents the absence of a value in lua. nil is both the name of the type and also the only value that a variable of that type can take. All variables contain the value nil, and are of type nil, before they are declared. Assigning nil to a variable is the same as deleting it.

nil values resolve to false when considered in a logical expression.

Example:

print("no_value has a value of " .. tostring(no_value) .. " and is of type " .. type(no_value))

some_value = 6
some_value = nil     -- deleting
if not some_value then
    print("some_value is false or nil")
end
no_value has a value of nil and is of type nil
some_value is false or nil

Booleans

Boolean values may be either true or false. Boolean values are of most use when evaluated by language structures such as if statements and while loops that perform logical tests and take action based on the result. The logical operators and, or and not can be used to evaluate booleans.

See the section on Conditional Operators for more information.

Example:

t = true

-- must use tostring as the .. concatenation operator wont work with booleans
print("t is " .. tostring(t) .. " and of type " .. type(t))

f = 6 > 7        -- logical expression evaluates to false

print("f is " .. tostring(f))
print("not f is " .. tostring(not f))
print("f and t is " .. tostring(f or t))
if f or t then
    print("f or t must be true!")
end
t is true and of type boolean
f is false
not f is true
f and t is true
f or t must be true!

Numbers

Numeric values in lua are real, so they may contain decimal places. There is no integer numeric type. The default lua language specification sets numbers to be stored as double-precision floats. At time of writing, however, numbers in Total War's implementation of lua are stored as single-precision floats, which offer only about 7 digits of precision. Scripters should be aware of this limitation when planning scripts that may potentially have to deal with very large or precise numbers.

Number values can be added, subtracted, multiplied and divided with the +, -, * and / operators respectively. Exponents may be expressed with the ^ operator.

Example:

a = 5
b = a + 10
c = b * 2
d = c / 10
e = a ^ d
print(a, b, c, d, e)
5    15    30    3.0    125.0

Strings

Strings are variables containing representations of text. A string may be specified by enclosing a value in matching single or double quotes. A string can be zero, one or more characters long, with no upper limit beyond the amount of memory available.

Strings may be joined together using the concatenation operator, ...

Example:

str_a = "hello"
str_b = "world"
print(str_a .. " " .. str_b)
hello world
Back to top

String Patterns

Some of the string functions described in the next section make use of string patterns, a method of matching sequences of characters akin to regular expressions. More information about lua string patterns may be found on lua-users.org here.

Back to top

String Library

Lua provides a number of operations that can be performed on strings, listed below. More detailed information about these functions may be found on the dedicated page on lua-users.org here.

The functions may be called in the form string.<function>(<string>, <arguments>), or <string>:<function>(<arguments>) where appropriate.

string.byte([number first char], [number last char])

Returns the numerical code corresponding to the characters of a specified portion of the string. The portion of the string is specified by index positions of the start and end characters.

Parameters:

1

number

optional, default value=1

Position of first character in the substring. If this is not a valid character index for this string then nil is returned.

2

number

optional, default value=1

Position of last character in the substring. If the first character position is specified and this is not, then this is set to the value of the first character position (so that only one character is returned).

Returns:

  1. ... number character value(s)

Example:

print(string.byte("hello"))        -- prints first character by default
print(string.byte("hello", 4))        -- print single character
print(string.byte("hello", 1, 3))    -- prints range of characters
104
108
104    101    108

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 355

string.char(... character values)

Returns a string constructed from the specified numeric character values. Number character values can be obtained with string.byte.

Parameters:

1

...

Vararg of number character values.

Returns:

  1. nil

Example:

print(string.char(104, 101, 108, 108, 111))
hello

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 368

string.dump(function function)

Returns a string representation of a supplied function, which can later be passed to the loadstring function to be reconstituted as an executable function.

Parameters:

1

function

function

Returns:

  1. string string representation

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 375

string.find(string string, string substring, [start index])

Returns the position of the first occurrence of a supplied substring in the subject string. If the supplied substring is found within the subject string then the start and end character positions of the substring are returned. nil is returned if the substring is not found.
Note that the standard lua version of this function supports pattern-matching. The implementation of this function in Total War does not, as it has been rewritten to be fully utf8-compliant. Use string.match to search by pattern.

Parameters:

1

string

Subject string.

2

string

String pattern to search for.

3

start

optional, default value=1

Position of character at which to start the search. Supply a negative number to specify a character from the end of the string, counting back.

Returns:

  1. nil

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 381

string.format(string container string, ... values to insert)

Returns a formatted string from the formatting string and then arguments provided, in a similar style to the C function printf. The formatting string may contain the following special characters:

CharacterData TypeDescription
%cnumber (character code)The supplied numerical character code (see string.byte) will be converted into its string representation.
%dnumber (integer)The supplied integer, to be preceded by up to up to seven leading zeroes, the number of which may optionally be specified alongside the special character e.g. %04d. If no number is specified then the integer is included in the returned string as it was given.
%enumberThe supplied number will be formatted as an exponent, with the output in lower-case.
%EnumberThe supplied number will be formatted as an exponent, with the output in upper-case.
%fnumberThe specified number will be formated as a floating-point value. A specific format for the number may optionally be specified alongside the special character e.g. %4.1f would specify that the floating point number should be formatted with four digits preceding the decimal point and one digit following it.
%gnumberThe specified number will be formated as a compact floating-point value, or as an exponent (if too many digits) in lower-case.
%GnumberThe specified number will be formated as a compact floating-point value, or as an exponent (if too many digits) in upper-case.
%inumber (integer)The supplied integer value will be formatted as a signed integer.
%onumber (integer)The supplied integer value will be formatted as an octal value.
%qstringThe supplied string will be enclosed in strings (as a quotation) when returned.
%sstringA string value.
%unumber (integer)The supplied value will be formatted as an unsigned integer.
%xnumber (integer)The supplied value will be formatted as a hexadecimal integer in lower-case.
%Xnumber (integer)The supplied value will be formatted as a hexadecimal integer in upper-case.
The function will throw an error if it's unable to convert the number specified into an integer value (should one be expected).

Parameters:

1

string

String containing special characters to insert values into.

2

...

One or more values to insert into the container string, in the order that the special characters are found.

Returns:

  1. string result

Example - Inserting character codes with %c:

local str = string.format("hello %c %c %c, pleased to meet you", 65, 66, 67)
print(str)
hello A B C, pleased to meet you

Example - Specifying the string length of an integer with %d:

local str = string.format("These integers will be displayed with at least 5 digits: %05d %05d %05d", 12, 1234, 123456)
print(str)
These integers will be displayed with at least 5 digits: 00012 01234 123456

Example - Lower/Upper-case exponents with %e and %E:

local str = string.format("Exponents: %e %E", 1234.56, 1234.56)
print(str)
Exponents: 1.234560e+03 1.234560E+03

Example - Floating point values with %f:

local str = string.format("Floating point values: %f %3.1f", 123456.78, 123456.78)
print(str)
Floating point values: 123456.780000 123456.8

Example - Compact floating point values with %g and %G:

local str = string.format("Compact floating point values: %g %g %G", 123456, 12345678, 12345678)
print(str)
Compact floating point values: 123456 1.23457e+07 1.23457E+07

Example - Signed, Unsigned, Octal and Hexadecimal integers:

local str = string.format("Signed: %i, Unsigned: %u, Octal: %o, Hex: %x", -100, -100, -100, -100)
print(str)
Signed: -100, Unsigned: 4294967196, Octal: 37777777634, Hex: ffffff9c

Example - Strings:

local str = string.format("Unquoted: %s, quoted: %q", "test", "test")
print(str)
Unquoted: test, quoted: "test"

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 389

string.gmatch(string subject string, string pattern)

Returns a pattern-finding iterator. More information about iterators and lua string patterns may be found externally - see String Patterns.

Parameters:

1

string

subject string

2

string

pattern

Returns:

  1. iterator

Example:

local str = "This is a test string"
local wordcount = 0
for word in string.gmatch(str, "%a+") do
wordcount = wordcount + 1
end
print(string.format("%q contains %d words", str, wordcount))
"This is a test string" contains 5 words

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 440

string.gsub(string subject, string pattern, string replacement, [number count])

This function takes a subject string, a pattern string and a replacement string, and performs a search based on the pattern string within the subject string. Should any parts of the pattern match, those parts of the subject string are replaced with the replacement string. The resulting string is then returned. An optional count argument may also be specified to limit the number of pattern replacements that may be performed.

Parameters:

1

string

Subject string.

2

string

Pattern string. More information about lua patterns may be found here: String Patterns

3

string

Replacement string.

4

number

optional, default value=nil

Maximum number of times the replacement can be performed. If left unset, then no maximum is applied.

Returns:

  1. string result

Example:

-- replace all spaces with underscores
result = string.gsub("this is a test string", " ", "_")
print(result)
this_is_a_test_string

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 454

string.len(string input)

Returns the number of characters in the supplied string.

Parameters:

1

string

input

Returns:

  1. number length

Example:

str = "hello"
print(str:len())
5

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 467

string.lower(string input)

Returns the supplied string, converted to lowercase.

Parameters:

1

string

input

Returns:

  1. string converted string

Example:

str = "A Test String"
print(string.lower(str))
a test string

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 476

string.match(string subject, string pattern, [number start character])

Returns a substring of the supplied string, by a supplied pattern. An optional index may also be used to specify a character at which the search should be started.
More information about patterns may be found here: String Patterns.

Parameters:

1

string

Subject string to search.

2

string

Search pattern.

3

number

optional, default value=1

Start character within the subject string.

Returns:

  1. string matching string

Example:

str = "THIS WORD here IS LOWERCASE"
print(string.match(str, "%l+"))
here

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 485

string.rep(string source, number count)

Generates and returns a string which is a supplied number of copies of the supplied string, all concatenated together.

Parameters:

1

string

source

2

number

count

Returns:

  1. string result

Example:

print(string.rep("test", 3))
testtesttest

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 497

string.reverse(string input)

Returns the supplied string with the character order reversed.

Parameters:

1

string

input

Returns:

  1. string reversed string

Example:

print(string.reverse("forward"))
drawrof

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 506

string.sub(string input, number start index, [number end index])

Returns a section of the supplied string, specified by start and (optionally) end character positions. The substring will include the characters specified by the start and end positions.

Parameters:

1

string

Subject string.

2

number

Position of the starting character of the substring. If a negative number is specified then the function counts back from the end of the string.

3

number

optional, default value=nil

Position of the end character of the desired substring. If omitted, then the end of the supplied string is used as the end of the substring. If a negative number is specified then the function counts back from the end of the string to find this character.

Returns:

  1. nil

Example - From character 11 until the end:

str = "this is a test string"
print(string.sub(str, 11))
test string

Example - From characters 11 through to 14 :

str = "this is a test string"
print(string.sub(str, 11, 14))
test

Example - From 13 characters from the end, onwards:

str = "this is a test string"
print(string.sub(str, -13))
a test string

Example - From 13 characters from the end until 9 from the start:

str = "this is a test string"
print(string.sub(str, -13, 9))
a

Example - From 13 characters from the end until 8 from the end:

str = "this is a test string"
print(string.sub(str, -13, -8))
a test

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 514

string.upper(string input)

Returns the supplied string, converted to uppercase.

Parameters:

1

string

input

Returns:

  1. string converted string

Example:

str = "A Test String"
print(string.upper(str))
A TEST STRING

defined in ../working_data/script/_lib/lib_lua_extensions.lua, line 541


Functions

Blurb about functions


Tables

Blurb about tables


Userdata

Blurb about userdata

Last updated 25/08/2021 12:07:50