Migrating from Lune
LuneBlox was forked from Lune 0.10.5. Scripts written for Lune run unchanged; what changes is the command you type, where the tool keeps its own files, and a few behaviours that now match Roblox.
What does not change
Section titled “What does not change”- The library names.
require("@lune/fs")and every other@lune/*library keep their names and their interface. - The script folders. Scripts are still found in
luneand.lune, in the current directory and in your home directory. - The script comment for descriptions. A leading
-->comment still describes a script in the script list. - The subcommands.
run,list,setup,buildandrepltake the same arguments.
LuneBlox installs beside Lune, so you can keep both and move one project at a time.
What changes
Section titled “What changes”The command
Section titled “The command”The binary is luneblox:
luneblox run script.luauIn rokit.toml, add it with:
rokit add XopoIII/LuneBlox lunebloxReplace lune with luneblox in CI workflows, git hooks, package.json scripts and anywhere else
the command is spelled out.
The directories
Section titled “The directories”| What | LuneBlox |
|---|---|
| Type definitions | ~/.luneblox/.typedefs/<version>/ |
Base executables for build --target |
$XDG_CACHE_HOME/luneblox/target on XDG systems |
| REPL history | $XDG_STATE_HOME/luneblox/.luneblox_history on XDG systems |
LUNEBLOX_CACHE and LUNEBLOX_STATE override the last two. Directories
has the full rules.
The typedefs alias
Section titled “The typedefs alias”The lune alias in .luaurc must point at LuneBlox’s typedefs. Run this once in each project:
luneblox setupIt rewrites aliases.lune to ~/.luneblox/.typedefs/<version>/. The alias name stays lune, so no
require changes.
_VERSION
Section titled “_VERSION”--!strictprint(_VERSION) --> LuneBlox 0.11.3+740Lune 0.10.5 prints Lune 0.10.5+709. Code that parses _VERSION and expects it to start with Lune
needs to accept LuneBlox too.
The Luau underneath
Section titled “The Luau underneath”Luau moves from 0.709 to 0.740, runs with the fast flags of the live Roblox client, and is built at
-O3. Timings change, so benchmarks recorded on Lune need to be taken again. See
Why LuneBlox.
build --target downloads from LuneBlox
Section titled “build --target downloads from LuneBlox”Base executables for cross-compilation come from LuneBlox’s GitHub releases, not Lune’s, so a standalone binary built for another target carries the same Luau and flags.
Behaviour changes
Section titled “Behaviour changes”Coroutine errors arrive unchanged
Section titled “Coroutine errors arrive unchanged”Since 0.10.11, coroutine.resume returns the value a coroutine threw exactly as thrown, as on Roblox.
There is no runtime error: prefix and no traceback appended.
--!strictlocal thread = coroutine.create(function() error({ code = 404 })end)
local ok, err = coroutine.resume(thread)print(ok) --> falseprint(type(err)) --> tableprint(err.code) --> 404The same holds for the related functions:
coroutine.wrappropagates the same value.coroutine.closeon a coroutine that errored returnsfalseand that value, not the thread.
task.spawn and task.defer on a resuming thread
Section titled “task.spawn and task.defer on a resuming thread”task.spawn and task.defer no longer drop a thread that is itself resuming another coroutine. This
was a regression from moving to mlua 0.12 and is fixed since 0.10.6.
Roblox datatypes
Section titled “Roblox datatypes”Fixed since 0.10.7:
CFrame.lookAt,CFrame.lookAlongandCFrame.new(pos, lookAt)produced incorrect rotations when not rotating purely around the Y axis.Color3:ToHex()did not match Roblox’s rounding and casing.
Attributes whose names start with RBX can now be read and written through @lune/roblox.
@lune/serde uses a different YAML library since 0.10.7. YAML scalars that were decoded with the
wrong types are now decoded correctly. If a script worked around a wrongly typed value, check it.
Web sockets
Section titled “Web sockets”The close method on a web socket closes the socket. In Lune 0.10.5 it always errored with
Socket has been closed.
New in LuneBlox
Section titled “New in LuneBlox”The Enum global
Section titled “The Enum global”Since 0.11.0 every script has Roblox’s Enum, as a Roblox client has it, with no require:
--!strictprint(Enum.KeyCode.ButtonA.Name) --> ButtonAprint(Enum.KeyCode.ButtonA.EnumType == Enum.KeyCode) --> trueprint(#Enum.UserInputState:GetEnumItems()) --> 5It is the same value as require("@lune/roblox").Enum, so an item read through either is the same
item, and code that compares Enum items behaves as it does in a game. Run luneblox setup again so
that luau-lsp knows the global. A script that defined its own Enum global keeps it: a global
assigned by a script hides the built-in one.
luau.collect
Section titled “luau.collect”Scripts run sandboxed, where collectgarbage accepts only "count", as on Roblox. luau.collect()
runs a full garbage collection cycle, so a benchmark can start each measurement from the same heap:
--!strictlocal luau = require("@lune/luau")
luau.collect()local before = collectgarbage("count")See luau.
base64 and hex in serde
Section titled “base64 and hex in serde”serde.encode and serde.decode accept "base64" and "hex" as formats. Both take strings and
buffers:
--!strictlocal serde = require("@lune/serde")
local encoded = serde.encode("base64", "hello")print(encoded) --> aGVsbG8=print(serde.decode("base64", encoded)) --> helloprint(serde.encode("hex", "hello")) --> 68656c6c6fSee serde.
XDG directories and overrides
Section titled “XDG directories and overrides”The build cache and the REPL history follow the XDG Base Directory variables, and LUNEBLOX_CACHE and
LUNEBLOX_STATE set them outright. See
Environment variables.
LUNE_ROBLOX_FFLAGS
Section titled “LUNE_ROBLOX_FFLAGS”LUNE_ROBLOX_FFLAGS=0 runs with Luau’s default fast flags. See Fast flags.
Checklist
Section titled “Checklist”- Install
lunebloxnext tolune. - Run
luneblox setupin the project. - Replace
lunewithlunebloxin scripts, hooks and CI. - Run your tests. Look first at code that inspects coroutine error values or
_VERSION.
The changelog has every release in full.
