Development Workflow
The typical workflow once everything is set up: write code, build, inject, test, repeat. This page covers how to make that loop as fast as possible and what tools help along the way.
Dev mode vs release mode
There are two build modes:
Dev mode (--dev)
rb build --dev
Produces build/script.dev.lua. Includes the dev overlay — a floating panel injected into your game that shows:
- Live log output (
Pulse.Logcalls) - All active signal values
- Feature toggle panel
- Draggable, toggleable with the Insert key
Use dev mode while actively building and testing. The overlay gives you real-time visibility into what's happening inside the script without needing print() statements everywhere.
Release mode
rb build
Produces build/script.obf.lua (obfuscated) and build/script.lua (plain). No dev overlay. Smaller output. Use this when you're done with a feature and want to distribute or use the final version.
The watch loop
The fastest development cycle:
Terminal 1:
rb watch --dev (or just rb watch)
Watches src/ for file changes. Every time you save a .ts or .lua file, it rebuilds automatically and prints success or error.
VS Code:
Make changes, save (Ctrl+S). With autoSave enabled at 500ms delay, you don't even need to press save.
Roblox + executor: After the rebuild completes, re-execute the updated script in your executor. If the game supports re-injection without rejoining, this takes about 3 seconds per iteration.
With this setup: change code → see rebuild in terminal → re-execute → test immediately.
Common build commands
rb build --no-obfuscate # skip obfuscation — much faster, use during dev
rb build --dev # dev build with overlay
rb build # full build with obfuscation — for release
rb copy # build + copy to clipboard — paste directly into executor
rb watch # continuous rebuild on save
During development, --no-obfuscate is significantly faster since IronBrew2 takes time to run. Only obfuscate when you're ready to test the release version or distribute.
Reading errors
When a build fails, rb prints the error with file name and line number:
[ERROR] src/combat/SpeedHack.ts:14
Type 'string' is not assignable to type 'boolean'
Open the file at that line, fix the issue, save — watch rebuilds automatically.
Common sources of errors:
- TypeScript type errors (check the TSTL output for line numbers)
- Missing
endin raw.luafiles - Signal name typo in an
on.*handler
Dev overlay
When running a dev build, the overlay appears in-game. Controls:
- Insert key — toggle the overlay open/closed
- Click the floating ◉ pill (bottom-right) — same as Insert
- Drag the pill — move it anywhere on screen
- Inside the overlay: view logs, toggle features, inspect signal values
The overlay is only in script.dev.lua. The release build has no overlay and no overhead from it.
Testing with an alt
Always test on your alt account (see Environment Setup). Typical session:
- Open VS Code with your project
- Start
rb watchin terminal - Open Roblox on alt, join target game
- Inject
build/script.lua(dev:script.dev.lua) - Press Insert to open the overlay
- Make code changes in VS Code — auto-saves trigger a rebuild
- Re-inject in executor after each rebuild
Keep the terminal visible so you see build errors immediately.
Saving your work
rb wraps git with shortcuts:
rb save "added speed hack" # git add -A && git commit
rb history # recent commits
rb restore abc1234 # check out previous commit
Commit frequently. When something breaks, rb history and rb restore get you back quickly.
Compat builds
Not all executors support the full UNC standard. Some APIs — readfile, writefile, getgc, Drawing — are only available on more advanced executors. The compat build is a second output that strips those modules so your script still works on lower-end executors.
rb build always produces both versions:
| File | Description |
|---|---|
build/script.obf.lua | Full build — requires full UNC support |
build/script.compat.obf.lua | Compat build — works on limited executors |
rb build --no-compat # skip compat build if you don't need it
Defining what gets excluded
You control the compat exclude list from src/layout.ts:
export default {
// ...
compatExclude: [
'player/UNC.ts',
'visuals/Drawing.ts',
],
} satisfies LayoutConfig
Any module listed there is compiled normally into script.obf.lua but dropped from script.compat.obf.lua. If the list is empty (or omitted), both builds are identical.
Project status
rb status
Shows: project root, installed rb version, git branch, uncommitted changes, and whether build output exists. Useful sanity check when switching between projects.