First module
1. Declare a module
Create my-module.lua in <config>/kawaki/scripts/. The game can stay running.
local module = ui.create("code", "My Module")
ui.create(icon, name[, description]) takes an icon glyph ("code", "bolt", "eye", …)
and a name unique among modules. The module lands in the Scripts tab.
2. Add settings
local delay = module:slider("Delay", 1, 100, 20, 1, "t")
local text = module:input("Text", "hello")
local on = module:switch("Enabled part", true)
Each call adds one row to the panel, top to bottom in declaration order. Read a value with
:get(). Every control type is on Settings.
3. Handle events
local ticks = 0
module:event("enable", function()
ticks = 0
end)
module:event("tick", function()
ticks = ticks + 1
if on:get() and ticks % delay:get() == 0 then
print(text:get())
end
end)
Names are exact snake_case strings: "enable" and "disable" fire on toggle, the rest come
from the game. See Events.
4. Save
Chat shows lua » Loaded my-module.lua and the module appears in the GUI. Enable it and keep
editing: each save reloads the script, keeping setting values and the enabled state.
Editor support
Every launch writes language-server files next to your scripts:
| Path | Contents |
|---|---|
scripts/library/*.lua |
LuaCATS stubs for the whole API |
scripts/docs/*.md |
Offline copy of this reference |
scripts/.luarc.json |
Points lua-language-server at the stubs |
library/ and docs/ are overwritten on every launch, so edits there are lost. .luarc.json
is only written when missing.
Open the scripts folder in an editor running lua-language-server for completion, hovers,
signature help and typed event callbacks:
tab: VS Code
Install the Lua extension (sumneko), then open the scripts folder. .luarc.json is
picked up automatically.
tab: IntelliJ
Install the SumnekoLua plugin and open the scripts folder as a project.
tab: Neovim
Enable lua_ls (for example through nvim-lspconfig) and start Neovim inside the scripts
folder, so the server finds .luarc.json at the workspace root.
Debug output
| Call | Goes to |
|---|---|
print("a", value) |
Chat, with a lua » prefix |
kawaki.log(msg) |
Game log, prefixed with the script file name |
Shared code
dofile resolves relative to the scripts folder. Only top-level .lua files load as
scripts, so shared code goes in a subfolder. require is not available:
tab: my-module.lua
local util = dofile "lib/util.lua" -- <scripts>/lib/util.lua
module:event("enable", function()
util.greet()
end)
tab: lib/util.lua
local M = {}
function M.greet()
print("hello from lib")
end
return M