Skip to main content

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.Log calls)
  • 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 end in raw .lua files
  • 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:

  1. Open VS Code with your project
  2. Start rb watch in terminal
  3. Open Roblox on alt, join target game
  4. Inject build/script.lua (dev: script.dev.lua)
  5. Press Insert to open the overlay
  6. Make code changes in VS Code — auto-saves trigger a rebuild
  7. 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:

FileDescription
build/script.obf.luaFull build — requires full UNC support
build/script.compat.obf.luaCompat 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.