Azalea is an EXPERIMENTAL software suite designed to manipulate Roblox model files for use within sandboxed Roblox environments, such as OpenSB.
Azalea is freely available to you under the Apache 2.0 license. All code generated by tools, scripts, or code in this repository should be considered as files under the Apache 2.0 license.
cargo install --locked --git https://github.com/techs-sus/azalea.git --features="base122 cli"
# ^^^ azalea is now in your shell as `azalea`
# You can also install or run with Nix:
# nix shell github:techs-sus/azalea
# -s is optional: you can specify a location for a specialized decoder to be generated
# if using -s: this command is limiting, you should migrate to other commands such as generate-full-script.
azalea encode -i input.rbxm -o output.bin -s specializedDecoder.luau -m
# All examples below:
# -i = --input (can be multiple files, or one file, REQUIRED)
# -o = --output (either a file, or a directory (then multiple inputs must be present), REQUIRED)
# -f = --format (with stylua, optional)
# -m = --minify (with darklua, optional)
# -c = --compat (makes code generated Lua 5.1 compatible; done via darklua, optional)
# generates a full decoder: can decode any file under azalea's format
azalea generate-full-decoder -o output.luau -f
# Examples which generate tailored code for a model:
# --novel: Must be used with --legacy flag, inlines ModuleScript sources and completely avoids loadstring.
# --legacy: Enables any environment with NewScript and NewLocalScript to run. Shims require and NewModuleScript using loadstring.
# --opensb: Enables OpenSB or any environment with NewScript, NewLocalScript, and NewModuleScript to run.
# --studio: Enables Studio or any environment with Source access support to run.
# generates a full script: input.rbxm must have a root ModuleScript (such as a MainModule)
azalea generate-full-script -i input.rbxm -o output.luau -m
# generates an embeddable script, useful for embedding assets; script returns model root
azalea generate-embeddable-script -i input.rbxm -o output.luau -mWe supply a configurable alphabet base122 encoder in Rust and a decoder in Luau. (src/base122.rs, src/luau/base122.luau)
We use Base123 (base122 + ampersands) to embed binary data into the output scripts. We chose Base122 encoded data as it is ~14% smaller than Base64 encoded data.
A flake.nix is provided at flake.nix. It provides:
- a formatter usable with
nix flake fmt(formats the entire flake) - a devshell usable with
nix develop - a package usable in your flake via
azalea.packages.${system}.default(whereazaleais an input) - if nix-direnv installed, you can run
direnv allowto automatically enter a devshell when cd'ing into the project directory
We use bun for:
- generating files required for tests via
bun run generate - running tests via
bun run tests; you need eitherrun-in-roblox(preferred) orrun-in-cloudin yourPATH - comparing format efficency via
bun run compareExamples - little shell scripts as bash & powershell are weird and cross platform support is nice
Format details:
- ULEB128 is used for referents and other things
- completely chunkless, roblox uses chunks
- roblox uses lz4 and zstd, we only use zstd
- can change at any time, not formalized or standardized
Platform support:
- Legacy is any compliant Luau implementation (NewScript and NewLocalScript but no NewModuleScript)
- OpenSB is any compliant OpenSB implementation (Luau + NewModuleScript), usually https://github.com/Open-SB/OpenSB.
- Studio is the environment in which plugins run or the command bar runs. It uses
Script.Source(and other alike properties) to createLuaSourceContainer's.
Output of bun run compareExamples (format efficency, +'s added for color):
+ win! examples\attributes-and-tags.bin.zst (via Azalea) is smaller than examples\attributes-and-tags.rbxm (via Roblox) by 5.8 KiB
+ win! examples\fusion-0.3-release.bin.zst (via Azalea) is smaller than examples\fusion-0.3-release.rbxm (via Roblox) by 21.15 KiB
+ win! examples\graphql-3.10.0-release.bin.zst (via Azalea) is smaller than examples\graphql-3.10.0-release.rbxm (via Roblox) by 169.8 KiB
+ win! examples\luau-regexp-0.2.1-release.bin.zst (via Azalea) is smaller than examples\luau-regexp-0.2.1-release.rbxm (via Roblox) by 11.86 KiB
+ win! examples\matter-0.8.5-release.bin.zst (via Azalea) is smaller than examples\matter-0.8.5-release.rbxm (via Roblox) by 30.36 KiB
+ win! examples\matter-hooks-0.2.1-release.bin.zst (via Azalea) is smaller than examples\matter-hooks-0.2.1-release.rbxm (via Roblox) by 3.85 KiB
+ win! examples\plasma-0.4.4-release.bin.zst (via Azalea) is smaller than examples\plasma-0.4.4-release.rbxm (via Roblox) by 9.98 KiB
+ win! examples\react-lua-17-release.bin.zst (via Azalea) is smaller than examples\react-lua-17-release.rbxm (via Roblox) by 293.26 KiB
+ win! examples\test.bin.zst (via Azalea) is smaller than examples\test.rbxm (via Roblox) by 828 bytes