Debug Overlay¶
the engine’s built-in on-screen diagnostic HUD.
▶ Run in browserTags: debug
Debug is the engine’s diagnostic switchboard and Debug.create_node() builds
the node that draws it. Add that node to any scene, last so it draws over
everything else, and the overlay is available in the running game:
self.add_child(Debug.create_node())
Debug.enabled = True # start with it on; it is off by default
F3 toggles the overlay (Debug.toggle() does the same from code) and F4 steps
through its feature presets. It opens on the profiler alone: frame rate,
per-phase timings, node and control counts and a frame-time graph. Each press
then adds to it: the bounding box of every control, coloured by state (red
disabled, blue focused, green hovered); the same boxes for interactive controls
only; all boxes again with a label on each control near the cursor; a rolling
log of input events and where they landed. One more press shows nothing, and
the next starts over. While it is off the overlay draws nothing.
The scene under it is an ordinary panel of buttons, a disabled button and a dropdown, which keep working normally beneath the overlay: click them with the event log showing to watch each press and the control it reached.
The labels read name (Type), and name is whatever the control was given
with name=. A control given none is named after its class, so every button
would read Button (Button); naming the controls is what makes the overlay
say which one is under the cursor:
Button("Click Me", name="ClickMe")
Source¶
1"""Debug Overlay: the engine's built-in on-screen diagnostic HUD.
2
3`Debug` is the engine's diagnostic switchboard and `Debug.create_node()` builds
4the node that draws it. Add that node to any scene, last so it draws over
5everything else, and the overlay is available in the running game:
6
7 self.add_child(Debug.create_node())
8 Debug.enabled = True # start with it on; it is off by default
9
10F3 toggles the overlay (`Debug.toggle()` does the same from code) and F4 steps
11through its feature presets. It opens on the profiler alone: frame rate,
12per-phase timings, node and control counts and a frame-time graph. Each press
13then adds to it: the bounding box of every control, coloured by state (red
14disabled, blue focused, green hovered); the same boxes for interactive controls
15only; all boxes again with a label on each control near the cursor; a rolling
16log of input events and where they landed. One more press shows nothing, and
17the next starts over. While it is off the overlay draws nothing.
18
19The scene under it is an ordinary panel of buttons, a disabled button and a
20dropdown, which keep working normally beneath the overlay: click them with
21the event log showing to watch each press and the control it reached.
22
23The labels read `name (Type)`, and `name` is whatever the control was given
24with `name=`. A control given none is named after its class, so every button
25would read `Button (Button)`; naming the controls is what makes the overlay
26say which one is under the cursor:
27
28 Button("Click Me", name="ClickMe")
29"""
30
31from simvx.core import Anchor, Button, Debug, DropDown, HBoxContainer, Label, Node, Panel, VBoxContainer
32from simvx.graphics import App
33
34
35class DebugDemo(Node):
36 def on_ready(self):
37 panel = self.add_child(Panel(name="RootPanel", anchor=Anchor.TOP_LEFT, inset=50, size=(400, 300)))
38 column = panel.add_child(VBoxContainer(name="Column", anchor=Anchor.FULL_RECT, inset=10))
39 column.add_child(Label("Debug Overlay Demo", name="Title", font_size=20))
40 self.status = column.add_child(Label("Click a button", name="Status"))
41 for text, name in (("Click Me", "ClickMe"), ("Another Button", "Another")):
42 column.add_child(Button(text, name=name, on_press=lambda text=text: self._clicked(text)))
43 disabled = column.add_child(Button("Disabled", name="DisabledBtn"))
44 disabled.disabled = True
45 column.add_child(DropDown(items=["Option A", "Option B", "Option C"], name="Choice"))
46 row = column.add_child(HBoxContainer(name="SmallButtons"))
47 for i in range(3):
48 row.add_child(Button(f"Btn {i}", name=f"SmallBtn{i}", on_press=lambda i=i: self._clicked(f"Btn {i}")))
49
50 # Example help overlay: not part of the technique shown.
51 help_row = self.add_child(HBoxContainer(name="Help", anchor=Anchor.BOTTOM_RIGHT, inset=16))
52 help_row.add_child(Button("F3: toggle overlay", name="ToggleOverlay", on_press=Debug.toggle))
53 help_row.add_child(Label("F4: cycle features", name="CycleHint"))
54 # An anchored container keeps its default 100-pixel width rather than its
55 # content's, which pushes a right-anchored row off the screen; fit it by hand.
56 help_row.autosize_to_content()
57
58 self.add_child(Debug.create_node())
59 Debug.enabled = True
60
61 def _clicked(self, text):
62 self.status.text = f"Clicked: {text}"
63
64
65if __name__ == "__main__":
66 App(title="Debug Overlay", width=1280, height=720).run(DebugDemo())