Skip to content

Commit 2d02728

Browse files
committed
Add a page on custom performance monitors
1 parent d84c5ae commit 2d02728

5 files changed

+127
-1
lines changed

about/list_of_features.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ Editor
5151
- No support for debugging in threads yet.
5252
- Visual profiler with CPU and GPU time indications for each step of the
5353
rendering pipeline.
54-
- Performance monitoring tools.
54+
- Performance monitoring tools, including
55+
:ref:`custom performance monitors <doc_custom_performance_monitors>`.
5556
- Live script reloading.
5657
- Live scene editing.
5758

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
.. _doc_custom_performance_monitors:
2+
3+
Custom performance monitors
4+
===========================
5+
6+
Introduction
7+
------------
8+
9+
As explained in the :ref:`doc_debugger_panel` documentation, Godot features a
10+
**Debugger > Monitor** bottom panel that allows tracking various values with
11+
graphs showing their evolution over time. The data for those graphs is sourced
12+
from the engine's :ref:`class_Performance` singleton.
13+
14+
Since Godot 4.0, you can declare custom values to be displayed in this Monitor
15+
tab. Example use cases for custom performance monitors include:
16+
17+
- Displaying performance metrics that are specific to your project. For
18+
instance, in a voxel game, you could create a performance monitor to track the
19+
number of chunks that are loaded every second.
20+
- Displaying in-game metrics that are not strictly related to performance, but
21+
are still useful to graph for debugging purposes. For instance, you could
22+
track the number of enemies present in the game to make sure your spawning
23+
mechanic works as intended.
24+
25+
Creating a custom performance monitor
26+
-------------------------------------
27+
28+
In this example, we'll create a custom performance monitor to track how many
29+
enemies are present in the currently running project.
30+
31+
The main scene features a :ref:`class_Timer` node with the following script attached:
32+
33+
::
34+
35+
extends Timer
36+
37+
38+
func _ready():
39+
# The slash delimiter is used to determine the category of the monitor.
40+
# If there is no slash in the monitor name, a generic "Custom" category
41+
# will be used instead.
42+
Performance.add_custom_monitor("game/enemies", get_enemy_count)
43+
timeout.connect(_on_timeout)
44+
# Spawn 20 enemies per second.
45+
wait_time = 0.05
46+
start()
47+
48+
49+
func _on_timeout():
50+
var enemy = preload("res://enemy.tscn").instantiate()
51+
get_parent().add_child(enemy)
52+
53+
54+
# This function is called every time the performance monitor is queried
55+
# (this occurs once per second in the editor, more if called manually).
56+
# The function must return a number greater than or equal to 0 (int or float).
57+
func get_enemy_count():
58+
return get_tree().get_nodes_in_group("enemies").size()
59+
60+
61+
The second parameter of
62+
ref:`Performance.add_custom_monitor<class_Performance_method_add_custom_monitor>`
63+
is a :ref:`class_Callable`.
64+
65+
``enemy.tscn`` is a scene with a Node2D root node and Timer child node. The
66+
Node2D has the following script attached:
67+
68+
::
69+
70+
extends Node2D
71+
72+
73+
func _ready():
74+
add_to_group("enemies")
75+
$Timer.timeout.connect(_on_timer_timeout)
76+
# Despawn enemies 2.5 seconds after they spawn.
77+
$Timer.wait_time = 2.5
78+
$Timer.start()
79+
80+
81+
func _on_timer_timeout():
82+
queue_free()
83+
84+
In this example, since we spawn 20 enemies per second, and each enemy despawns
85+
2.5 seconds after they spawn, we expect the number of enemies present in the
86+
scene to stabilize to 50. We can make sure about this by looking at the graph.
87+
88+
To visualize the graph created from this custom performance monitor, run the
89+
project, switch to the editor while the project is running and open **Debugger >
90+
Monitors** at the bottom of the editor window. Scroll down to the newly
91+
available **Game** section and check **Enemies**. You should see a graph
92+
appearing as follows:
93+
94+
.. :figure: img/custom_performance_monitors_graph_example.webp
95+
:align: center
96+
:alt: Example editor graph from a custom performance monitor
97+
98+
Example editor graph from a custom performance monitor
99+
100+
.. note::
101+
102+
The performance monitor handling code doesn't have to live in the same
103+
script as the nodes themselves. You may choose to move the performance
104+
monitor registration and getter function to an :ref:`autoload
105+
<doc_singletons_autoload>` instead.
106+
107+
Querying a performance monitor in a project
108+
-------------------------------------------
109+
110+
If you wish to display the value of the performance monitor in the running
111+
project's window (rather than the editor), use
112+
``Performance.get_custom_monitor("category/name")`` to fetch the value of the
113+
custom monitor. You can display the value using a :ref:`class_Label`,
114+
:ref:`class_RichTextLabel`, :ref:`doc_custom_drawing_in_2d`, :ref:`doc_3d_text`,
115+
etc.
116+
117+
This method can be used in exported projects as well (debug and release mode),
118+
which allows you to create visualizations outside the editor.

tutorials/scripting/debug/debugger_panel.rst

+6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ FPS, memory usage, how many nodes are in a scene and more. All monitors keep
6868
track of stats automatically, so even if one monitor isn't open while the game
6969
is running, you can open it later and see how the values changed.
7070

71+
.. seealso::
72+
73+
In addition to the default performance monitors, you can also create
74+
:ref:`custom performance monitors <doc_custom_performance_monitors>`
75+
to track arbitrary values in your project.
76+
7177
Video RAM
7278
+++++++++
7379

Binary file not shown.

tutorials/scripting/debug/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Debug
88
overview_of_debugging_tools
99
debugger_panel
1010
the_profiler
11+
custom_performance_monitors

0 commit comments

Comments
 (0)