A preview that renders the wrong thing rarely tells you why. The tree is a WASM layout result
painted into a DOM that does not resemble it. A browser inspector shows divs and CSS transforms
rather than a Frame with a Size. Every gallery carries a panel that reports the scene in its own
terms.
Opening it
Three ways, all equivalent:
- the
debugbutton in the sidebar header, - Ctrl+Alt+D,
?debug=1on any gallery URL.
It is off by default, and while closed nothing it does runs at all — no observers, no timers, no tree walks. Everything it reads is outside the render path, so a scene behaves the same either way.
A bare ?debug is on. 0, false, off, no and none are off, and anything else present is
on. A host page can template a boolean straight through.
The gallery takes a full reload on every edit, so the state is remembered for the tab. An embed (chrome=none) deliberately does not remember it — a debug panel on somebody’s docs page should only ever be one the URL asked for.
What it reports
Each section folds away and keeps reporting its one headline number while folded.
target — the target’s path and title, how long its import() took, and how long from mount to
first frame. The ↻ button re-mounts the active target, which is how you take those timings for one
that was already up.
viewport — the stage in real pixels, the logical viewport the scene laid out against,
Workspace.CurrentCamera.ViewportSize, and the scale factor, plus device pixel ratio and theme. All
four agree unless the page asked for ?base=. Together they tell a scene that laid out small from
one that was painted small. See Previews on a phone.
scene — live instances, how many are GuiObjects, and how many of those are invisible, usually
the answer when a scene looks empty. Then tree depth, the DOM nodes it became, a count per class,
and each layer with its DisplayOrder and size.
fonts — every typeface the scene’s text resolved to, the weights asked for, and whether the browser really loaded it. A family that never arrived still paints, at the wrong metrics, so this is the row that explains a layout differing on one machine. See Fonts and text metrics.
frame — frame rate, DOM patches committed since the panel opened, and a count of what loom logged. Its warnings usually explain a scene, and nobody reads the console.
inspect — covered below.
Inspecting the stage
Hover the stage and the panel names the GuiObject under the pointer, outlines it, and lists its
ancestry, absolute geometry, UI* modifiers, resolved typeface and properties.
- Alt+click pins the selection so it stops following the pointer. Escape releases it.
- The ancestry trail and the under rows are clickable, so the tree can be walked from the panel. The under rows are everything else the pointer is over.
- The hit test is the scene’s own
PlayerGui:GetGuiObjectsAtPosition, not the browser’s. A click-through frame that no browser inspector can reach is still inspectable here.
Taking a snapshot out
copy puts the readout on the clipboard as text. json downloads every section as data, plus the
complete instance tree with each object’s absolute position and size. That is what a bug report
wants instead of a screenshot. The same object is available as loomDebug.snapshot() while the
panel is open:
copy(loomDebug.snapshot());See also
- Gallery targets — what the panel’s target section is reporting on.
- Mobile previews — the logical viewport and
?base=. - Troubleshooting — symptom-first, and most entries have a row in this panel.