godot-debugging-profiling
Expert debugging and profiling for leaks, GPU/Visual Profiler, headless CI QA, orphan nodes, thread-safe logs, and custom Debugger monitors — not pr…
它会碰到什么
这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。
技能内容
NEVER Do
- NEVER use
print()without descriptive context —print(value)is useless. Useprint("Player health:", health)with labels. - NEVER leave debug prints in release builds — Wrap in
if OS.is_debug_build()or use custom DEBUG const. Prints slow down release. - NEVER ignore
push_warning()messages — Warnings indicate potential bugs (null refs, deprecated APIs). Fix them before they become errors. - NEVER use
assert()for runtime validation in release — Asserts are disabled in release builds. Useif not condition: push_error()for runtime checks. - NEVER profile in debug mode — Debug builds are 5-10x slower. Always profile with release exports or
--releaseflag. - NEVER assume
Engine.capture_script_backtraces(true)is cheap — Capturing locals allocates significant memory and can prevent objects from being deallocated, causing artificial leaks [19]. - NEVER call
push_error()orprint()inside a customLogger._log_messageoverride — This causes infinite recursion and crashes as the logger intercepts its own output [20]. - NEVER leave the Visual Profiler running during gameplay tests — Continuous polling degrades framerates significantly, invalidating actual performance metrics [21].
- NEVER rely on
OS.get_ticks_msec()for microbenchmarking — Milliseconds lack precision for logic timing; ALWAYS useTime.get_ticks_usec()for microsecond precision [22]. - NEVER assume
OBJECT_ORPHAN_NODE_COUNTworks in production — This monitor is strictly debug-only; it safely returns 0 in release builds, potentially hiding leaks [23]. - NEVER benchmark with V-Sync enabled — V-Sync throttles metrics to the monitor refresh rate, masking the true CPU/GPU processing overhead [24].
- NEVER leave
print_stack()orprint_debug()in release builds — These are often stripped or useless outside the debugger. Use structured logging for production [25]. - NEVER strip debugging symbols if using external C++ profilers — Stripping destroys call stack readability for external tools like Perfetto or VerySleepy [26].
- NEVER forget to unregister an
EditorDebuggerPluginin_exit_tree()— Failing to clean up leaves "ghost" connections in the engine's debugging loop [27]. - NEVER trust the Visual Profiler on macOS when using the Compatibility renderer — Platform-specific driver limitations severely restrict OpenGL profiling accuracy on macOS [28].
Symptom → Monitor → Script
> MANDATORY for the matching row. Do NOT Load every debug script for one bug.
| Symptom | Monitor / API | Script |
|---------|---------------|--------|
| Nodes removed but RAM climbs | OBJECT_ORPHAN_NODE_COUNT (debug) | MANDATORY [orphan_node_detector.gd](scripts/orphan_node_detector.gd) |
| ObjectDB / instance growth | custom monitors + dump | [memory_usage_threshold_alert.gd](scripts/memory_usage_threshold_alert.gd), [scene_tree_dump.gd](scripts/scene_tree_dump.gd) |
| GPU / overdraw mystery | Visual Profiler (briefly) | Pair with perf skill; use [performance_plotter.gd](scripts/performance_plotter.gd) for trends — do not leave Visual Profiler on |
| Flaky headless / CI exit | exit codes + asserts | MANDATORY [automated_qa_suite.gd](scripts/automated_qa_suite.gd), [push_error_safe_exit.gd](scripts/push_error_safe_exit.gd) |
| Microbenchmark lies | Time.get_ticks_usec | MANDATORY [high_precision_benchmarker.gd](scripts/high_precision_benchmarker.gd) |
| Crash needs locals | backtraces (debug only) | [advanced_backtrace_recorder.gd](scripts/advanced_backtrace_recorder.gd), [stack_trace_logger.gd](scripts/stack_trace_logger.gd) |
| Engine errors to backend | Logger intercept | [engine_error_interceptor.gd](scripts/engine_error_interceptor.gd) — never print inside Logger |
| Custom Debugger metrics | Monitors tab | [custom_editor_monitor.gd](scripts/custom_editor_monitor.gd), [debugger_tab_plugin.gd](scripts/debugger_tab_plugin.gd) |
| Mobile/console no stdout | in-game console | [remote_debug_console.gd](scripts/remote_debug_console.gd), [debug_overlay.gd](scripts/debug_overlay.gd) (debug builds only) |
| Thread races / log corruption | mutex logger / asserts | [thread_safe_logger.gd](scripts/thread_safe_logger.gd), [thread_safety_assert.gd](scripts/thread_safety_assert.gd) |
| Invisible logic (AI/physics) | debug draw / gizmos | [custom_debug_draw.gd](scripts/custom_debug_draw.gd), [property_watcher_gizmo.gd](scripts/property_watcher_gizmo.gd) |
| Conditional halt | hardcoded break | [break_on_condition.gd](scripts/break_on_condition.gd) |
| Editor vs runtime paths | Engine.is_editor_hint | [engine_editor_hint_logic.gd](scripts/engine_editor_hint_logic.gd) |
Available Scripts (full catalog)
Leaks & memory
- [orphan_node_detector.gd](scripts/orphan_node_detector.gd)
- [memory_usage_threshold_alert.gd](scripts/memory_usage_threshold_alert.gd)
- [scene_tree_dump.gd](scripts/scene_tree_dump.gd)
Timing & QA
- [high_precision_benchmarker.gd](scripts/high_precision_benchmarker.gd)
- [automated_qa_suite.gd](scripts/automated_qa_suite.gd)
- [push_error_safe_exit.gd](scripts/push_error_safe_exit.gd)
- [performance_plotter.gd](scripts/performance_plotter.gd)
Errors, stacks, threads
- [advanced_backtrace_recorder.gd](scripts/advanced_backtrace_recorder.gd)
- [stack_trace_logger.gd](scripts/stack_trace_logger.gd)
- [engine_error_interceptor.gd](scripts/engine_error_interceptor.gd)
- [thread_safe_logger.gd](scripts/thread_safe_logger.gd)
- [thread_safety_assert.gd](scripts/thread_safety_assert.gd)
Editor / remote / viz
- [custom_editor_monitor.gd](scripts/custom_editor_monitor.gd)
- [debugger_tab_plugin.gd](scripts/debugger_tab_plugin.gd) — unregister in
_exit_tree() - [remote_debug_console.gd](scripts/remote_debug_console.gd)
- [debug_overlay.gd](scripts/debug_overlay.gd) — debug builds only
- [custom_debug_draw.gd](scripts/custom_debug_draw.gd)
- [property_watcher_gizmo.gd](scripts/property_watcher_gizmo.gd)
- [break_on_condition.gd](scripts/break_on_condition.gd)
- [engine_editor_hint_logic.gd](scripts/engine_editor_hint_logic.gd)
Expert Pointers
- Profile release/
--releasewith V-Sync off; never trust Debug-build timings. - Prefer structured logs over
print_stack()in anything that might ship. - Escalate sustained FPS issues to
godot-performance-optimizationafter the symptom tree identifies the bottleneck class.
> MANDATORY for print/breakpoint workflow depth, profiler interpretation, and expert CI/GPU/thread patterns: [debug-workflows.md](references/debug-workflows.md). Do NOT Load when the symptom → script table above already routes you.
Reference
> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
Official Documentation
- Overview of debugging tools — Map of remote scene tree, breakpoints, Output, and profiler entry points before picking a deeper page.
- Debugger panel — Stack, variables, breakpoints, errors, and monitors used for live remote debug sessions.
- The profiler — Time and visual profilers: why you profile release-like builds and how frame charts isolate CPU/GPU spikes.
- Output panel — How
print/push_warning/push_errorsurface in the editor and why noisy release logs hide real faults. - ObjectDB profiler — Before/after ObjectDB snapshots for RefCounted cycles and leaked instances that orphan monitors miss.
- Custom performance monitors —
Performance.add_custom_monitorso game-specific metrics appear next to engine monitors. - Logging — Custom
Loggerregistration, file sinks, and recursion hazards when logging from inside log handlers. - Command line tutorial — Headless
--script/ export flags for automated QA and CI exit-code runners. - CPU optimization — Interpreting profiler hotspots into GDScript/server/thread fixes after measurement.
- Using multiple threads — Worker-thread rules that motivate thread-safety asserts and mutexed loggers.
- Thread-safe APIs — Which servers/APIs may be called off-main-thread without corrupting the SceneTree.
- Performance — Built-in monitors (
OBJECT_ORPHAN_NODE_COUNT, memory, render) used by overlays and leak detectors.
Related Skills
Prerequisites
- godot-project-foundations — Debug/release feature tags, project settings, and Autoload layout must exist before debugger plugins or global monitors.
- godot-gdscript-mastery — Typed Callables,
assert/push_error, andTimeAPIs underpin benchmarks, breakpoints, and stack helpers.
Complements
- godot-performance-optimization — After the profiler names a hotspot, apply pooling, culling, and MultiMesh fixes from that skill.
- godot-testing-patterns — GUT/assert/CI patterns pair with headless QA suites and deterministic
quitexit codes. - godot-export-builds — Profile and remote-debug against real export templates; debug symbols and strip settings matter for external profilers.
- godot-scene-management — Scene swap lifetime bugs show up as orphan-node growth; use tree dumps when loaders fail to free.
- godot-signal-architecture — Ghost listeners and deferred connects often explain “why is this still running?” stack traces.
- godot-autoload-architecture — Global loggers, monitors, and error interceptors belong in Autoloads with clear boot order.
- godot-server-architecture — When debug draw or metrics push into Rendering/Physics servers, keep server ownership separate from nodes.
Downstream / consumers
- godot-auditor — Consumes debugger/profiler evidence when enforcing never-lists and architectural integrity reviews.
- godot-platform-mobile — Device remote debug and on-screen consoles are required when desktop Output is unavailable.
- godot-monte-carlo-balancer — Headless microbenchmarks and CI QA feed balance sims that need stable timing and exit codes.
- godot-multiplayer-networking — Networked games need remote inspectors and structured logs across peers without flooding the Output panel.
Master
- godot-master — Library router and mirrored module entry; open when discovering which Domain Skill owns a cross-cutting debug or perf concern.
想直接用这个技能?
本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。
它属于哪个仓库
skills/godot-debugging-profiling/SKILL.md