Troubleshooting¶
This page covers the most common issues and how to resolve them. Use the decision tree below for quick diagnosis, or jump to a specific symptom.
Quick Diagnosis¶
graph TD
A["Agent not working"] --> B{"Is the agent moving?"}
B -->|No| C{"Is a plan shown<br/>in GOAP Hub?"}
B -->|Yes| D{"Correct behavior?"}
C -->|No| E["<b>Check:</b><br/>Goal Priority > 0<br/>Missing Strategy<br/>Missing Components"]
C -->|Yes| F["<b>Check:</b><br/>NavMesh baked<br/>Strategy settings<br/>StoppingDistance"]
D -->|"Oscillating"| G["See: Investigate/Alert<br/>Oscillation"]
D -->|"Stuck after action"| H["See: PostProcess<br/>Timing"]
D -->|"Key never changes"| I["See: Key Value<br/>Never Changes"]
click E "#agent-stands-still-plan-failure-loop"
click F "#agent-stands-still-plan-failure-loop"
click G "#investigatealert-oscillation"
click H "#postprocess-runs-but-has-no-effect"
click I "#key-value-never-changes"
Jump to Symptom¶
| Symptom | Section |
|---|---|
| Agent stands still / plan keeps failing | Plan-Failure Loop |
| Blackboard key never updates | Key Value Never Changes |
| Agent oscillates between states | Investigate/Alert Oscillation |
| PostProcess runs but nothing happens | PostProcess Has No Effect |
| Timer resets don't stick | Timer Reset Race Condition |
| Goal preemption loops forever | Goal Preemption Loop |
| "Missing Script" on strategy asset | Missing Script |
Agent Stands Still / Plan-Failure Loop¶
The agent doesn't move or act. The planner keeps failing.
Check for Missing Strategy¶
Open all strategy .asset files in the Inspector. If any show a "Missing Script" badge, the planner silently skips that action.
Fix: The most common cause is a broken assembly reference. Ensure your .asmdef files reference RGS.GOAP.Core and that the strategy class exists and compiles.
Check Goal Priorities¶
Every state needs at least one goal with Priority > 0 that passes IsValid(). If all goals have zero or negative priority, the planner has nothing to work toward.
Fix: Open the GOAP Hub, select the state, and check each goal's priority. Ensure at least one is positive.
Check Missing Components¶
Look for GetCapability<T>() returning null in the Console. This means a strategy needs a component (like NavMeshAgent) that isn't on the agent's GameObject.
Fix: Read the warning message — it tells you exactly which component to add and where.
Run Validation¶
Click Validate in the GOAP Hub toolbar. It catches most configuration errors: unwired slots, missing beliefs, broken transitions.
Key Value Never Changes¶
Is It a ValidityKey?¶
If the key is a ValidityKeyId for a RecollectionSystem memory stream, the system overwrites it every frame.
Fix: Never write directly to a ValidityKey. Use ClearStream() to clear it.
Is the Sensor Running?¶
The sensor that writes to this key might not be firing. Check:
- Is the sensor added to the Brain's sensor list?
- Is its
UpdateIntervalreasonable? (Default: 0.5s) - Is
IsDrivingKeyById()blocking the write? (Temporal key routing)
Fix: Enable Debug Plan Search on the agent and check the Console for sensor activity.
Investigate/Alert Oscillation¶
The agent rapidly switches between Alert and Investigate states.
This is usually expected behavior: the agent investigates near the target's last-known position, the sight sensor fires CanSeeTarget = true, transition to Alert, the target moves, CanSeeTarget = false, back to Investigate.
Fix options:
- Add an
IsSearchCompleteguard to preserve investigation sweep progress across re-entries. - Add a
targetRelocatedcheck that only restarts investigation on genuine context changes. - Increase the investigation
SearchRadiusto spread sweep points away from the trigger zone.
PostProcess Runs But Has No Effect¶
Writing to a Temporal Key?¶
If you're writing directly to a key managed by the RecollectionSystem, your write is overwritten next frame.
Fix: Use ClearStream() instead of SetBool() for temporal keys.
Timing Issue?¶
Post-processes run before HandlePlanCompleted. The stored transition was determined at plan creation time — it is NOT re-evaluated after post-processes modify the blackboard.
Timer Reset Race Condition¶
A post-process resets a timer's timestamp key, but the timer sensor hasn't ticked yet (0.5s interval). The planner reads the stale elapsed time and immediately re-selects the same goal.
Fix: When resetting a timer, also write 0 to the sensor's output key on the same frame. Use SetBlackboardFloatPostProcess with AlsoZeroKeyId to reset both atomically.
Goal Preemption Infinite Loop¶
A higher-priority goal keeps winning because the timer/state driving its priority isn't reset on the same frame as action completion.
Fix: The post-process must zero both the reset key AND the output key atomically. See "Timer Reset Race Condition" above.
Missing Script on Strategy Asset¶
The Inspector shows "Missing Script" on a ScriptableObject asset.
Causes:
- The assembly definition (
.asmdef) reference is broken - The script file was renamed or moved without updating the
.metafile - The class name doesn't match the file name
Fix: Check that your .asmdef references RGS.GOAP.Core and that the strategy class compiles without errors.
Checklists¶
Before Shipping a Strategy or PostProcess¶
- [ ] No per-agent state on the SO (no fields storing runtime data, even
[NonSerialized]) - [ ] Uses
GetCapability<T>()for all component access (notGetComponent) - [ ]
OnStartis safe for re-entry (checks completion + context change) - [ ] Any null
GetCapability<T>()result emits an actionableLogWarning - [ ]
OnStopcleans up regardless of success/failure/preemption - [ ] NavMeshAgent arrival uses
remainingDistance, not euclidean distance - [ ] All
Debug.Log/LogWarningcalls gated behind debug flags
Before Shipping a Sensor¶
- [ ]
GetOutputs()declares all outputs with correctGoapKeyType - [ ] Uses typed write helpers (
WriteBool,WriteVector3, etc.) - [ ] Uses
WriteVector3(settings, bb, name, value, target)for entity tracking - [ ] No expensive work outside of
OnUpdate - [ ]
DrawGizmos()implemented for scene debugging
Before Shipping a Belief¶
- [ ]
Evaluate()is stateless — depends only on blackboard and settings - [ ] No physics, raycasts, or expensive operations in
Evaluate() - [ ]
OverrideSettingsTypereturns the correct settings type - [ ] Works with per-agent overrides
Before Shipping a Brain¶
- [ ] At least one state, one action, one goal with
Priority > 0 - [ ] All MonoBehaviours required by strategies are on the agent's GameObject
- [ ] Total unique beliefs across all states ≤ 128
- [ ] Temporal keys have
Brain.UsesSpatialMemory = true - [ ] At least one FSM transition path exists for each reachable state
- [ ] At least one goal per state passes
IsValid()under normal conditions - [ ] Validate button in GOAP Hub shows no errors
Log Level Guide¶
| Situation | Level | Gated? |
|---|---|---|
| Expected during normal operation | Log |
Yes (Debug Plan Search) |
| Broken invariant / should never happen | LogError |
No |
| Missing component (user fixable, init only) | LogWarning |
No |
| Per-frame diagnostic | Log |
Yes (DebugExecution) |
| Never in hot path | LogWarning |
— |
Danger
String interpolation + stack trace capture at 1000+ agents destroys performance. Gate all per-frame logs behind debug flags.
See Also
- Runtime Debugging — Using the GOAP Hub debugger and console
- Validation System — What the Validate button checks for
- Performance Tuning — Diagnosing performance-related issues
- Glossary — Quick definitions for ValidityKey, ContentRevision, and other terms
Still Stuck?¶
- Check the GOAP Console (
Tools > RGS GOAP > Console) for framework-specific messages. - Enable
Debug Plan Searchon the agent to see planner activity. - Join the Discord for community support.