How to use this cheat sheet#

Identify the language first. XPath, MD and Lua express similar intentions differently. This is a selection useful for reading these examples and project code, not a statistical ranking or complete language reference. Start with how X4 code works if the terms are unfamiliar. New snippets are learning examples, not claimed in-game tests.

Four basic concepts#

A variable stores a value. A condition chooses whether to do something. A function receives arguments and performs work, sometimes returning a result. An event handler is a function or MD node run for a particular event. Distinguish defining getName, calling getName() and storing its returned value.

XML elements, attributes and selectors#

Form Meaning
<hull max="1800" /> An element with an attribute and no child content
<actions> ... </actions> A container's start and end
<!-- comment --> XML comment
replace, add, remove Diff operations to replace, add or remove selected content
/properties/hull/@max XPath to an attribute
[@name='example'] XPath attribute filter

Inside an XML attribute, escape ampersands as &amp; and less-than as &lt;. XML is parsed before MD expressions, which is why lt/le/gt/ge are convenient comparisons. A diff selector and a do_if expression use different grammars.

MD: one small action at a time#

Construct Purpose
set_value Assign or update a value
do_if, do_elseif, do_else Select a branch
do_for_each Process list elements
append_to_list Append an element
remove_value Remove a variable or record
debug_text Write diagnostics
run_actions Run an appropriate action library
event_ui_triggered Receive a UI event in cue conditions
raise_lua_event Send an event to Lua

These are MD element names, not standard XML functions. The engine defines attributes and valid context. The actions example below creates its own list and ends with Count equal to 2. operation=add exact=1 increments it; Item denotes the current element.

XML
<set_value name="$Items" exact="['Корпус', 'Двигатель']" />
<set_value name="$Count" exact="0" />
<do_for_each name="$Item" in="$Items">
  <set_value name="$Count" operation="add" exact="1" />
</do_for_each>
<do_if value="$Count == 2">
  <debug_text text="'Обработано два элемента'" />
</do_if>

MD expressions#

Form Meaning
$Count, Init.$States A variable, or a variable in an explicit cue context
==, != Equal, not equal
lt, le, gt, ge Less, less-or-equal, greater, greater-or-equal
and, or, not Logical operations
+, -, *, /, % Arithmetic; percent is remainder
'Name: ' + $Label String concatenation
$Value?, $Object.exists Variable/property resolution versus object existence
typeof $D == datatype.list Value type test
$D.{1}, $D.count First list element and element count
table[], [] Empty table and empty list
if $Ready then 'yes' else 'no' A conditional value expression

The shown MD lists start at 1. A resolvable variable may contain false; existence and truth are different. See variable context, especially with instantiated cues.

Lua: reading a regular function#

The standalone example below uses no X4 functions. Its result is 8, assuming every item has a numeric amount field. {} creates a table, used for both sequences and named records. item.amount means item["amount"]. In for _, item, the first variable receives the index; underscore is an ordinary name conventionally marking an unused value.

LUA
local function total(items)
    if type(items) ~= "table" then
        return 0
    end
    local result = 0
    for _, item in ipairs(items) do
        result = result + item.amount
    end
    return result
end

local amount = total({{amount = 3}, {amount = 5}})

Lua operators#

Form Meaning
= Assignment
==, ~= Equal, not equal
<, <=, >, >= Comparisons
and, or, not Logical operations
+, -, *, /, % Arithmetic
.. String concatenation
#value String byte length or sequence boundary
object.field Table field access
object:method(x) Equivalent to object.method(object, x)

#table is not a count of arbitrary keys. Holes and string keys do not form a dense sequence. String lengths count bytes, which matters for UTF-8. Only false and nil are false in Lua; 0 and an empty string are true. value or fallback also replaces false. Logical and/or return a selected value, not necessarily a boolean.

Standard Lua functions#

type reports a value type; tostring formats a value; tonumber attempts conversion and may return nil. ipairs walks dense indices from 1 until a missing item; pairs has no order guarantee. table.insert, table.remove and table.concat manipulate sequences. string.format builds formatted text; match/gsub use Lua patterns. math.min and math.max select numeric bounds. pcall catches Lua errors; require loads modules under environment rules.

Not every module is available in game UI. Do not assume debug or file access. Check the pcall flag and error rather than silently hiding a failure. A protected Lua call does not make an invalid native call safe. See the Lua 5.1 and LuaJIT primary references below.

X4 functions versus mod functions#

Resolve object IDs in the correct representation. A random number, ship name, network ID, UI handle and UniverseID are not interchangeable: ID precision.

Five mistakes you can spot while reading#

  1. Lua uses ~=, while MD uses != for inequality.
  2. Lua joins strings with ..; MD uses + in the shown forms.
  3. Lua assignment is =, comparison is ==.
  4. Changing window text does not prove changing the world object.
  5. A handler definition still needs a loaded file, a received event and validated input.

Read Lua ↔ MD and explain each line before installing the example in a test profile.