Debugging and diagnostics
HTN planning is deterministic symbolic solving, so “why did the AI pick this behavior” can always be replayed exactly. This chapter covers three tool sets—console commands, the ImGui live panel, and offline trace replay in Canvas—plus how to read the global statistics.
Debugging happens in two places: live monitoring in the game process (ImGui), and graph replay in HTN Canvas (offline traces).
Console commands
| Command | Purpose |
|---|---|
htn_dumpStats | Prints global statistics: active agents, per-frame/total decomposition steps, solve/replan counters, and call counts/timings per operator source (C++ / .htnnode / script) |
htn_setPlanningBudget <steps> | Sets the global per-frame planning step budget (shared by all agents, default 2048) |
htn_debugAgent <entityId> | Selects the trace recording target (omit the argument to clear); once selected, that agent records a decomposition trace on every solve |
htn_dumpTrace [N] | Exports the last N traces as .htntrace files (default 1, buffer of 8) into <project>/user/htn/traces/ |
htn_imguiPanel <true|false> | Toggles the ImGui debug panel (CVar; requires the ImGui Gem) |
ImGui live panel
Requires the ImGui Gem. Workflow:
- Enter game mode, press Home to open ImGui, then main menu HTN > Debug Panel (or console
htn_imguiPanel true). - Pick a Debug Agent from the dropdown (equivalent to
htn_debugAgent <entityId>)—once selected, that agent records a decomposition trace on every solve. - The panel shows live: the state machine state (Idle / Planning / Executing / Failed), the current plan (executing step highlighted), and the full WorldState key/value table.
- Bool / Int / Float / Vector3 values are editable in-panel for “what-if” analysis—edits go through the same replan evaluation as game-code writes, which makes it easy to verify how the Domain decides under different facts.
Offline trace replay in Canvas
Export the decomposition traces recorded in the game process and replay them event by event in HTN Canvas, answering precisely “why was this method chosen / why was that method skipped”. The Canvas Debug panel is strictly read-only and never connects to the runtime—traces cross processes as files.
- In the game process, click Dump traces in the ImGui panel (or console
htn_dumpTrace 3); traces are written to<project>/user/htn/traces/*.htntrace. - Open the matching Domain document in HTN Canvas, show the Debug panel from the
Viewmenu, and pick the exported file via Load Trace.. - The event list shows the full solve as a
TryMethod(with per-atom evaluation results) /PushTask/AddStep/Backtracksequence (green = passed/step emitted, red = condition failed/backtracked). Scrub the timeline to step through events; the current event’s task/method node is selected and centered in the graph.
Traces are also exposed to code via HtnAgentNotificationBus::OnTraceRecorded (debug agent only).
Reading the global statistics
htn_dumpStats reads HtnGlobalStats (public header HtnPlanner/HtnPlannerBus.h; frozen at zero when EnableStats=false):
| Field | Meaning |
|---|---|
m_activeAgentCount / m_agentsInBackoff | Active agents / agents in failure backoff |
m_decompositionStepsThisFrame / m_decompositionStepsTotal | Per-frame / cumulative decomposition steps (compare against the frame budget) |
m_solveCountByResult[3] | Solve counts bucketed by result (Success / NoPlan / StepLimit) |
m_replanCountByReason[6] | Replans bucketed by reason (HtnReplanReason) |
m_mtrPreemptCount / m_mtrDiscardCount | Opportunistic replans where a better MTR preempted / where the new plan was discarded |
m_operatorStatsBySource[3] | Call counts and total timings per operator source (C++ / .htnnode / script)—the entry point for spotting script-operator abuse |
Settings Registry keys for the stats toggle and the global budget are in Reference.
Common debugging paths
- Agent never acts: confirm the Domain asset compiled (no AssetProcessor errors),
Auto Startis on, and the Root Task name is correct. Check NoPlan counts withhtn_dumpStats—NoPlan usually means condition keys are never written (verify that Externally Written keys really have a sensor writing them). - Frequent replans / thrash: raise the agent’s
Replan Interval, or check whether a changing WorldState key is written every frame (opportunistic replan triggers on revision changes). - StepLimitExceeded: look at compile-time V15 complexity warnings and simplify the method tree first; raise
Max Decomposition Stepsonly if genuinely needed. - Script operator stuck: the script must call
HtnCompleteCurrentOperatorwith the token received inBegin; stale tokens (a replan happened in between) are ignored with a warning.
More troubleshooting in Reference.