Darklua
Step-by-step setup guide for Darklua projects.
Darklua is a processor: it rewrites your code into a folder of its own before Rojo syncs it. That folder is the sync directory. Rogen detects Darklua when it finds a .darklua.json or .darklua.json5 file in the project root, and init asks about it.
Only Rojo syncs from the sync directory
Rogen reads your source folders to decide where each file goes. It never reads the sync directory: it only points Rojo's paths there.
Define the Sync Directory
Assume the Darklua configuration takes files from src and outputs files to dist. With roblox-ts, Darklua reads the compiled out folder instead.
Create the Config
Run rogen init and answer that Darklua processes your code. The setup differs by language:
init writes two configs. default.rogen.json holds the tree, with paths into src, and sync.rogen.json extends it and adds the sync directory:
{
"$schema": "https://ldgerrits.github.io/rogen/schema/2/rogen.json",
"rootDirs": ["src"],
"routes": {
"Server": "ServerScriptService",
"Client": "StarterPlayer/StarterPlayerScripts",
"Shared": "ReplicatedStorage/Shared",
"*": "ReplicatedStorage/Shared"
}
}{
"$schema": "https://ldgerrits.github.io/rogen/schema/2/rogen.json",
"extends": "./default.rogen.json",
"syncDir": "dist"
}The two configs are one tree rendered twice. default.project.json points into src. sync.project.json points into dist and is the file for rojo serve.
The source-rooted config is the default because luau-lsp generates its sourcemap from default.project.json without any settings, and Darklua's convert_require rule reads that same sourcemap.json. Your editor maps instances to the files you edit, and Darklua rewrites requires against your source, with nothing configured. It's also the parent, because a child can add a field but never remove one.
Run the Pipeline
init prints the commands to run. Run the processors and Rogen simultaneously.
Have Darklua process your code into the sync dir:
darklua process src distWith several root directories, each one lands at its own path under dist (darklua process lib dist/lib), and init prints one command per directory.
darklua process src dist --watchWatch both configs, so the project file for Darklua stays current too:
rogen watch default syncDarklua reads sourcemap.json, which luau-lsp keeps current from default.project.json while your editor is open. Without luau-lsp, keep it current yourself:
rojo sourcemap default.project.json --output sourcemap.json --watchThen serve the synced project:
rojo serve sync.project.jsonA bare rojo serve picks up default.project.json and syncs your unprocessed source. Always name sync.project.json.
rogen build and rogen watch print one line naming any *.rogen.json they weren't asked to build, so forgetting the synced config in a Darklua setup doesn't go unnoticed.