The Variables collapsible section shows three roots:
Globals resolves against _G first and then against the paused
frame’s _ENV upvalue. The _ENV fallback matters for scripts
loaded with a file environment (for example via dofile) — a
top-level my_proto = Proto.new(…) in such a script lands in the
file’s _ENV rather than _G, and the debugger still lists it
under Globals.
The tree is populated lazily: a row is only inspected when you expand it. Sub-trees stop at the same path-depth cap as Watch (see Section 14.6.2, “Path-watch syntax”).
The tree has two columns, Name and Value; the underlying
type is folded into the row tooltip rather than shown in its own
column. For userdata values (Wireshark class instances such as
Pinfo, Tvb, ProtoField), the tooltip reads userdata
(ClassName) when the instance metatable exposes a __name,
otherwise just userdata.
Functions are listed alongside other values (rendered as
function: 0xADDR, the standard Lua tostring shape) so callbacks,
locally-bound helpers, methods on userdata, and stdlib namespaces
like string and table all show up in their respective scopes.
Function rows are not expandable; to inspect what a function does,
view its source via Stack Trace once it is on the call stack.
Selecting a different frame in Stack Trace rebuilds the Variables tree for that frame.
A context menu on any row offers Copy Name, Copy Value (the
full, untruncated value — the tree itself truncates long values for
display), Copy Name & Value (name = value), Copy Path
(the canonical Variables-tree path, ready to paste into the Watch
panel or the Evaluate panel), and Add Watch (prefilled with
the row’s variable path; the menu label includes the path so you
can see exactly what would be added).
Both the Variables tree and the Watch tree highlight values that changed since the previous pause: the row is drawn in a bold accent foreground from the current theme and briefly flashes a softer highlight tint. New rows (a local that did not exist last pause, a key added to a table, a freshly appearing Watch child) receive the same treatment. Watch roots deliberately do not flash on first sighting — a new root is usually a spec you just typed.
The cue is anchored to the stack frame that was active when the pause started, because "the value changed" only makes sense against a comparable earlier reading:
The change baseline is cleared, so the next pause shows no cue, after editing a watch’s spec, removing watches, reloading Lua plugins, or disabling the debugger. A failed watch lookup invalidates that one watch’s baseline only.
Empty strings count as real values for the comparison: a variable
whose value was "" last pause and is still "" now does not
flash. Single-stepping never flickers the Watch Value column
through its not-paused em-dash placeholder, even though a step
technically resumes and re-pauses; the tree repaints straight from
the new pause’s values.