currently lua is not complete, and not yet usable in keeperfx, wip code for it in this PR https://github.com/dkfans/keeperfx/pull/2043 the documentation itself is also wip and bound to change
the lua version keeperfx uses is 5.1 for the base language see the lua documentation, this page will only go over the keeperfx specific implementation https://www.lua.org/manual/5.1/
lua is used in a lot of places, documentation of those games could also prove useful an example would be Warcraft III reforged, ofcource the Warcraft specific stuff won't apply to Dungeon keeper, but might still prove usefull https://www.hiveworkshop.com/threads/a-comprehensive-guide-to-mapping-in-lua.341880/
vscode extention, point workspace to correct folder,
the game has multiple entrypoints from where it runs lua code
-
function GameStart()
runs once at the start of the game -
function GameLoop()
runs every gametick (20 times per second) -
function ChatMsg(plrIdx, msg)
runs when a player sends a chat message, the player and the message text are available as parameters
all native functions can be found in this file, https://github.com/dkfans/keeperfx/blob/d3c1fb33bd25dd01eac76385a07ae99b6040eb0f/lua/native.lua the file makes the IDE aware of the functions DK provides, and doubles as documentation if you want to find something
the lua has support for most of the commands in the DKscript language, while also repeated in the native.lua file, the dkscript documentation could also be referenced for the overlapping ones, some commands might be changed, and not all lua commands will exist in dkscript New-and-Modified-Level-Script-Commands
the flow control is also different
NEXT_COMMAND_REUSABLE
is not a thing in lua, all commands are always reusable in lua
you have to control flow in other ways, GameStart for example will generally only be run once, so all initialization code goes there
the special IF's in dkscript are also replaced with different syntax you just compare variables which you can fetch like this
- PLAYER0.MONEY
- IF_ACTION_POINT todo
- IF_AVAILABLE
PLAYER0.AVAILABLE.WORKSHOP
- IF_CONTROLS
PLAYER0.CONTROLS.IMP
- IF_SLAB_OWNER and IF_SLAB_TYPE
slb = GET_SLAB(x,y) slb.owner slb.type slb.style
- IF_ALLIED PLAYER0:ALLIED_WITH(PLAYER2)
the commands related to flags are removed to assign to a flag simply assign
PLAYER0.FLAG0 = 1
calculations can also be done in lua, so no need for COMPUTE_FLAG either
PLAYER0.CAMPAIGN_FLAG2 = PLAYER0.MONEY + 75 * PLAYER0.IMP
the assignable variables, are regular flags
eg. PLAYER0.FLAG0 = 1
campaign flags
eg. PLAYER0.CAMPAIGN_FLAG2 = 1
´
sacrificed creatures
eg. PLAYER0.SACRIFICED.IMP = 1
and temple rewarded creatures
eg. PLAYER0.REWARDED.IMP = 1
attempting to assign to a variable that's not assignable will throw an error
local variables inside of functions are fine to use without worrying, variables that have a scope that outlasts single function, for other stuff that needs to stay after saving/loading use flags