Skip to content

First module

Four steps from an empty file to a working module, then editor setup and shared code.

Declare a module

Create my-module.lua in <config>/aesthetic/scripts/. The game can stay running.

my-module.lualua
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.

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.

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.

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:

Install the Lua extension (sumneko), then open the scripts folder. .luarc.json is picked up automatically.

Install the SumnekoLua plugin and open the scripts folder as a project.

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
aesthetic.log(msg) Game log, prefixed with the script file name

Shared code

require resolves relative to the scripts folder. Only top-level .lua files load as scripts, so shared code goes in a subfolder:

Navigation

Type to search…

↑↓ navigate↵ selectEsc close