xiao.workspace New
xiao.workspace keeps a Lua table across runs and game restarts, as a JSON file per name.
load returns the table of a name, you change it like any table, and it is written to C:\xiaohook\lua\workspace\<name>.json when you call save and automatically when the VM is cleared. The disk is only touched by load (the first time for a name), save and the automatic save: changing the table costs nothing. Do not call save every frame. For free form files, use xiao.fs.
At a glance
Serialization follows the conversion rules of xiao.json: values must be booleans, numbers, strings, tables or xiao.json.null. Use xiao.json.array() for a list that can be empty, and expect arrays read back to carry the xiao.json.array mark.
Packet hooks and cmd hooks
load and save raise xiao.workspace is not available inside a packet hook or a cmd hook: they read and write the disk. A table loaded before can still be read and changed in a hook, and saved later from a timer. See Execution contexts.
Functions
xiao.workspace.load(name): table
xiao.workspace.load(name?: string): table
Returns the persistent table of name. The first call of a VM reads the file, or returns a new empty table when the file does not exist; later calls return the same table without touching the disk.
Returns: the table (an object or an array, as stored). Errors:
invalid workspace name 'my save': 1 to 64 letters, digits, '_' or '-'invalid workspace name 'con': reserved Windows device namexiao.workspace: no script file to name the workspace after, pass a name: the caller is code without a file, such as aloadstringchunk run from a timerworkspace 'x' is not valid JSON: parse error at line 1, column 2: ...: the file is broken. It is left untouched and is never overwritten by the automatic saveworkspace 'x' does not hold a JSON object or arrayworkspace 'x' is 2000000 bytes, the limit is 1048576workspace 'x' cannot be readworkspace 'x' cannot be moved from lua/storage to lua/workspace: seeMoving older files xiao.workspace: file system unavailable: no workspace: noC:\xiaohookfolderxiao.workspace is not available inside a packet hook or a cmd hook
local settings = xiao.workspace.load()
settings.runs = (settings.runs or 0) + 1
print("run number", settings.runs)
xiao.workspace.save(name, t)
xiao.workspace.save(name?: string, t?: table)
Writes the table of name now. With t, t becomes the table of name first, and the next load(name) returns it. The file is replaced atomically: a crash during the write keeps the previous file.
Returns: nothing. Errors:
- the naming errors of
load, andxiao.workspace is not available inside a packet hook or a cmd hook bad argument #2 to 'save' (table expected, got number)workspace 'x' is not loaded: call xiao.workspace.load first or pass a tableworkspace 'x' not saved: cannot encode a function at $.callbackand the other encode errors, without thejson encode:prefixworkspace 'x' not saved: 1100017 bytes, the limit is 1048576workspace 'x' not saved: cannot write the file,workspace 'x' not saved: cannot replace the file
xiao.workspace.save("waypoints", {home = {x = 10, y = 64, z = -20}})
Automatic save
Every time the VM is cleared, every table loaded or saved in the VM is written, after on_unload and the unload signal, so they can still change it. A table that cannot be written prints workspace 'x' not saved: ... in the console and the others are still saved. Files that failed to load are not part of it. The automatic save has its own 100 ms budget: keep tables small.
Moving older files
Earlier builds kept these files in C:\xiaohook\lua\storage. The first load or save of a name moves the file over, once:
C:\xiaohook\lua\storage\<name>.jsonis moved toC:\xiaohook\lua\workspace\<name>.jsonwhen the new file does not exist yet, with its content unchanged- when
C:\xiaohook\lua\workspace\<name>.jsonalready exists, it wins and the older file is left untouched - once the older folder is empty, it is removed; any other file keeps it in place
- when the move fails, for example because the file is open in another program, the call raises
workspace 'x' cannot be moved from lua/storage to lua/workspaceand both files stay as they are
Complete example
Waypoints that survive restarts, shared by every script that uses the name waypoints.
local workspace = xiao.workspace
local points = workspace.load("waypoints")
local function add_here(label)
local me = xiao.game.player()
if me == nil then return false end
points[label] = {x = math.floor(me.x), y = math.floor(me.y), z = math.floor(me.z), at = os.date("%Y-%m-%d")}
workspace.save("waypoints")
xiao.notify("Waypoint", label .. " saved", "success")
return true
end
xiao.signal.add("chat", "waypoints", function(message)
local label = message:match("^!wp (%w+)$")
if label ~= nil then add_here(label) end
end)
for label, point in pairs(points) do
print(label, point.x, point.y, point.z, point.at)
end