Lua Style in Roblox — Format Before Review

(Updated: July 16, 2026 ) Lua Roblox formatter

Decompiled or copy-pasted Lua often arrives as a single horizontal smear: every statement on one line, end keywords stacked without structure, and a PR description that says “small fix.” Reviewers bounce it not because they hate Lua, but because they cannot see control flow. Formatting is not fashion — it is how you make if / for / function boundaries visible before someone ships a logic error wrapped in noise.

What “style” means for Lua specifically

Lua (and Luau in Roblox) is whitespace-insensitive for semantics. That freedom is exactly why teams need a written convention:

  • Indent width (2 or 4 spaces, or tabs — one choice)
  • Where then / do sit relative to the condition
  • How long lines wrap (operators at end vs start of line)
  • Table layout: one entry per line past a size threshold
  • Blank lines between top-level functions

Without agreement, every contributor reformats the lines they touch and diffs become unreadable.

Bugs that formatting surfaces

Mismatched end — Dense code hides an extra or missing end. Once indented, the cliff of nesting makes the mistake obvious.

Accidental global assignmentsfoo = 1 vs local foo = 1 is easier to spot when declarations line up at the left of a scope.

Table comma mistakes — Trailing commas and missing commas in large tables stand out when each field owns a line.

Copy-paste block scope — An if that was supposed to wrap three statements only wraps one; indentation shows the real structure immediately.

None of these require a type system. They require a human-readable tree.

A lightweight team guide that sticks

Keep the doc short enough that people read it:

  1. Always local unless the symbol must be global (and comment why).
  2. Prefer early returns over deep nesting.
  3. Name Instances and remotes clearly; formatters will not fix thing1.
  4. Run the formatter before opening the PR, not after the first review comment.
  5. Do not hand-align columns with extra spaces; let the tool own layout.

Roblox-specific note: ModuleScripts and server/client boundaries matter more than brace style. Formatting should not obscure RemoteEvent names or WaitForChild chains — keep those strings untouched.

How to use a formatter without fear

  1. Format a single ModuleScript first and playtest that system.
  2. Diff only whitespace + your intentional edits in source control.
  3. If Studio or a linter complains, fix the rule config — do not disable formatting forever.
  4. Roll out folder-by-folder for large places so bisecting regressions stays possible.

Paste gnarly snippets into lua-formatter when you are cleaning a gist, a DevForum paste, or a decompiled fragment before you drop it into Studio. Use it as a readability pass, then paste back and let Rojo/Studio own the file on disk.

What not to argue about in review

  • Tabs vs spaces after the decision is recorded
  • Whether and / or chains wrap at column 80 vs 100
  • Alphabetical order of requires unless the team already automated it

Spend review time on replication, security (who can fire the remote), and performance of hot paths in Heartbeat. Spend formatter time making those discussions possible.

Before you merge messy Lua

Ask: can a teammate see every end that closes every block in under ten seconds? If not, format first. Readable Lua is not “enterprise theater” — it is how Roblox teams avoid shipping silent control-flow bugs that only appear under a specific player state. Format for humans, playtest in Studio, and keep the indent rule boring and consistent.