moo is a deterministic, fixed-point fork of Luau.
- Home: https://github.com/mas-bandwidth/moo
- Forked from: Luau 0.741 (upstream tag
0.741, commit2d88f9b5facaa9e4ec91247b39ae8251bd49a244). The upstream source archive for that tag was checked against sha256deee653d0f5971b809ef67f50dbe8109ad369d7575e344cfe2013774fed2f4c6, and the tree this repository starts from is identical to it. Full upstream history is kept.
moo makes one promise Luau does not: the same program with the same inputs gives bit-identical results, and the same sequence of observable effects, on every platform and compiler, for every construct. To keep it, moo will:
- remove every non-deterministic source in the VM and standard library (object hashing by
address, GC pacing by clock,
osand time, address-revealingtostring, platform libm); - make
numbera Q48.16 fixed-point value, so floating point never enters the VM.
Everything else stays as close to Luau as possible: syntax, tools and the C API.
Layers 1-5 are built. The conformance record is the program-by-program matrix in docs/DETERMINISM.md, "Status"; the other promises are docs/DESIGN.md, "Layers". Every source of non-determinism found so far, with its fix, is in docs/DETERMINISM.md.
The rename is kept minimal so upstream merges stay clean.
| Luau | moo |
|---|---|
luau (REPL / runner) |
moo |
luau-analyze |
moo-analyze |
luau-compile |
moo-compile |
luau-ast, luau-reduce, luau-bytecode |
moo-ast, moo-reduce, moo-bytecode |
source extension .luau |
.moo (.luau and .lua are still read) |
require resolution, the CLI's file lookup and directory traversal try .moo first, then
.luau, then .lua (and init.moo before init.luau). Two candidates for one module path
are reported as ambiguous, as upstream already does for .luau/.lua.
What is not renamed: the C API keeps Luau's lua_/luaL_ names, the CMake targets keep
their Luau.* names, the C++ namespace stays Luau, and the configuration file stays
.config.luau. Source is not mass-renamed.
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build -j
build/moo tests/conformance/assert.luau
Supported for moo: Linux (gcc and clang), macOS arm64 and Windows (MSVC and clang-cl),
64-bit only; Windows is nightly-only. moo compiles
everything with -ffp-contract=off, so the C++ compiler never fuses a multiply and an add
into one FMA (which rounds differently). The upstream Makefile is kept and builds the same
moo* binaries with the same flag.
Luau's own suites run unmodified:
Luau.Conformance(thetests/conformancescripts),Luau.UnitTest(the compiler, analyzer and codegen unit tests),Luau.CLI.Test(the REPL andrequiretests; run it from the repository root).
moo's own tests are Moo.Test: the determinism cases and the fixed-point operators,
literals and formatting in tests/Moo.test.cpp, tests/MooNumber.test.cpp and
tests/Determinism.test.cpp.
CI (.github/workflows/):
ci.ymlpush-gate, required on every push and pull request: Linux clang. It builds onlyMoo.TestandLuau.VM, runsMoo.Test, checksextern/fixedagainst its pin, and checks that the VM archive reads no clock. With the compiler cache a warm run is under a minute; a change that touches a VM header rebuilds the VM and nothing else.ci.ymlfull, on pull requests, not required: Linux clang. It builds and runsLuau.Conformance,Luau.UnitTestandLuau.CLI.Test, smoke-runsmoo,moo-analyzeandmoo-compile, and checks that native codegen is refused.nightly.yml, nightly and on demand: the matrix on Linux gcc, Linux clang and macOS arm64 runsMoo.Test,Luau.Conformance(also at-O2),Luau.UnitTestandLuau.CLI.Test, the no-clock check and the smoke runs; Windows MSVC, nightly-only, runsMoo.Test,Luau.ConformanceandLuau.UnitTest; a separate job model-checks thetlacases with TLC 1.8.0.
Upstream's own workflows (build.yml, release.yml, new-release.yml, benchmark.yml)
are removed in moo; they target Luau's release process and runners.
The upstream remote is Luau:
git remote add upstream https://github.com/luau-lang/luau.git
git fetch upstream --tags
Upstream is taken once per upstream release, never commit by commit:
- Merge the release tag (for example
git merge 0.742) into a branch. Keep the merge commit, sogit log --first-parentshows exactly which Luau release moo is on. - Rebase moo's patches on top as needed, resolving conflicts in moo's favour only where moo deliberately differs (the rename, the removed workflows, and later the fixed-point VM).
- Rerun the full conformance suite (and, from layer 5, the determinism suite) on every platform. The merge lands only when it is green.
- Update the "Forked from" line above.
moo keeps its patches small and in few files for exactly this reason; see docs/DESIGN.md, "Upstream merges".
moo is MIT licensed, the same as Luau.
- LICENSE.txt is Luau's MIT license and copyright notice, kept intact.
- lua_LICENSE.txt is Lua's, kept intact.
- LICENSE-moo.txt covers moo's own changes, also MIT.