When a native layer is needed#
Ordinary XML changes and UI windows usually do not need one. Use FFI or a custom DLL when available MD and Lua UI cannot express the task. Built-in Lua functions, FFI exports and custom Lua C modules are different interfaces with different contracts.
Declaring the ABI#
The example below illustrates declarations used with the corresponding game build. Successful cdef does not prove export availability. pcall does not make a wrong signature safe. Verify types, calling convention and support in your own X4 version.
local ffi = require("ffi")
if ffi.cdef then
pcall(ffi.cdef, [[
bool IsGamePaused(void);
bool IsStartmenu(void);
]])
endThird-party components#
X4Native is a separate library with its own loader and ABI, not a required dependency for every Lua mod. Declare and verify it only when used. UI protected mode also affects loading mechanisms; disabling it is not the first step for an ordinary data patch.
Value types#
A pointer, uint64_t and Lua number are not interchangeable. Read ID precision before serialization or crossing languages. Direct memory offsets depend even more strongly on the build. Establish safe readback and object identity before testing a mutation.