Write TypeScript
Run SLua
A TypeScript-to-Lua plugin for Second Life with full type coverage, editor support, and compile-time safety.
$bunx @gwigz/slua-create
TypeScript in, Lua out
Every example is transpiled through the TSTL pipeline
TypeScript
let let owner: UUIDowner = ll.function ll.GetOwner(): UUIDReturns the object owner's UUID.
Returns the key for the owner of the object.GetOwner()
const LLEvents: LLEventsEvent registration and management class for Second Life events
Event registration and management singleton for Second Life events.LLEvents.LLEvents.on<"changed">(event: "changed", callback: (changed: number) => void): (changed: number) => voidRegisters a callback for an event. Returns the callback.on("changed", (changed: numberchanged) => {
if ((changed: numberchanged & const CHANGED_OWNER: 128The object has changed ownership.CHANGED_OWNER) !== 0) {
let owner: UUIDowner = ll.function ll.GetOwner(): UUIDReturns the object owner's UUID.
Returns the key for the owner of the object.GetOwner()
}
})
const LLEvents: LLEventsEvent registration and management class for Second Life events
Event registration and management singleton for Second Life events.LLEvents.LLEvents.on<"touch_start">(event: "touch_start", callback: (detected: DetectedEvent[]) => void): (detected: DetectedEvent[]) => voidRegisters a callback for an event. Returns the callback.on("touch_start", (events: DetectedEvent[]events) => {
for (const const event: DetectedEventevent of events: DetectedEvent[]events) {
if (const event: DetectedEventevent.DetectedEvent.getKey(): UUIDReturns the key of detected object or avatar number.
Returns NULL_KEY if Number is not a valid index.getKey() === let owner: UUIDowner) {
ll.function ll.Say(channel: number, text: string): voidSays Text on Channel.
This chat method has a range of 20m radius.
PUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts.Say(0, `${const event: DetectedEventevent.DetectedEvent.getName(): stringReturns the name of detected object or avatar number.
Returns the name of detected object number.
Returns empty string if Number is not a valid index.getName()} touched at ${const event: DetectedEventevent.DetectedEvent.getTouchPos(): VectorReturns the position, in region coordinates, where the object was touched in a triggered touch event.
Unless it is a HUD, in which case it returns the position relative to the attach point.getTouchPos()}`)
}
}
})SLua
local owner = ll.GetOwner()
LLEvents:on("changed", function(changed)
if bit32.btest(changed, CHANGED_OWNER) then
owner = ll.GetOwner()
end
end)
LLEvents:on("touch_start", function(events)
for ____, event in ipairs(events) do
if event:getKey() == owner then
ll.Say(0, (event:getName() .. " touched at ") .. tostring(event:getTouchPos()))
end
end
end)Powered by TypeScript-to-Lua
Everything You Need
Type Definitions
Full LSL and SLua API coverage with autocomplete and inline docs.
TSTL Plugin
Bitwise ops, self-calls, index correction, and dead code elimination.
Modules
Coroutine-based async, config loading, and yield wrappers.
Playground
Try ts-slua in the browser with Monaco editor.
Scaffolding
Bootstrap projects instantly with bunx @gwigz/slua-create.
Linting
oxlint config with SLua-specific rules for consistent code.
Resources
Tools, documentation, and community projects for SLua development
Official
Function descriptions and API data sourced from lsl-definitions by Linden Lab and its contributors