@gwigz/slua

Targets

Pairing projects with objects via link, source headers, and a config file

An object's UUID changes every time it is taken and rezzed again, so pinning a project to one is a losing game. Names and descriptions survive that round trip, which makes a description key the durable way to pair.

Precedence

A destination comes from command line flags, then slua.json, then the source header. The header is the default a script ships with, and config retargets a build for another environment without touching source.

link main stamps slua:main into the published object's description and records it in slua.json. From then on push --all finds the object by that key, however many times it has been rezzed.

slua-viewer link main --wait

The object has to be published first, and --wait holds the connection open so the viewer's button has somewhere to publish to, see Publishing an object. Name one with --object if several are published, --key to pair on something other than slua:<name>, and --file to record an output path other than dist/<name>.slua.

The key is appended to the object's existing description, matched on a word boundary so slua:main is not confused with slua:main-menu. Descriptions cap at 127 bytes of UTF-8, and a full one is reported rather than truncated. Linking warns, but still writes, when the object has no item of that name yet.

Source headers

A script can declare its own destination, so a small project needs no config:

/**
 * @slua-target desc:slua:my-project/Main
 * @slua-vm luau
 * @slua-save-back
 */
TagMeaning
@slua-target <object>/<item>Whole destination, <object>/<link>/<item> for a child prim
@slua-object <selector>Object only
@slua-item <name>Inventory item only
@slua-link <name>Child prim only
@slua-vm <vm>Compile target
@slua-save-backDerez back into the source prim after a successful push

@slua-save-back needs no value, but takes one, so @slua-save-back false turns it off where something else enabled it. An unknown tag is an error, which catches a typo before it deploys somewhere unintended.

For a compiled bundle the tags come from the source it was built from, found through the source map, and the entry point wins when several sources carry them, since TSTL emits it last. Unknown tags are tolerated during that sweep rather than failing the push, since those sources include vendored code you did not write. A hand-written .lsl or .luau file is its own source and carries its header directly.

Both comment syntaxes work (//, /* */, --, --[[ ]]), and tags are only honoured above the first line of code, so a @slua- string appearing later cannot silently retarget a deploy.

slua.json

Config is optional. It is looked up from the working directory upwards, and relative paths resolve against the directory holding it.

slua.json
{
  "targets": {
    "main": {
      "file": "dist/main.slua",
      "object": { "description": "slua:my-project" },
      "item": "Main",
      "saveBack": true
    }
  }
}
FieldMeaning
fileBuilt output to upload
object{ id }, { name } or { description }, or the string form
itemInventory item name
linkChild prim, when the item is not in the root
vmCompile target
saveBackDerez back into the source prim after a successful push
entrySource to read the header from, skipping the source map lookup

object also accepts the string form: "desc:slua:my-project", "4f2b...", "name:My Object".

Deploy one target with --target main, or all of them with --all:

slua-viewer push --all

With no --target, --all or config entry, push dist/main.slua uses the file's base name as the target name.

Saving back to a rezzer

saveBack derezzes the object into the prim it was rezzed from, which updates a rezzer's payload without the take-and-replace dance.

The viewer only offers it for an object rezzed out of another in-world prim's contents, decided when the object is published. One published by UUID alone reports canSaveBack: false, and the push reports the save-back as failed.

Inventory objects

An object sitting in your own inventory cannot be reached at all. It has to be rezzed.

On this page