Skip to content

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 UpdateInterval reasonable? (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 IsSearchComplete guard to preserve investigation sweep progress across re-entries.
  • Add a targetRelocated check that only restarts investigation on genuine context changes.
  • Increase the investigation SearchRadius to 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 .meta file
  • 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 (not GetComponent)
  • [ ] OnStart is safe for re-entry (checks completion + context change)
  • [ ] Any null GetCapability<T>() result emits an actionable LogWarning
  • [ ] OnStop cleans up regardless of success/failure/preemption
  • [ ] NavMeshAgent arrival uses remainingDistance, not euclidean distance
  • [ ] All Debug.Log/LogWarning calls gated behind debug flags

Before Shipping a Sensor

  • [ ] GetOutputs() declares all outputs with correct GoapKeyType
  • [ ] 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()
  • [ ] OverrideSettingsType returns 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

Still Stuck?

  • Check the GOAP Console (Tools > RGS GOAP > Console) for framework-specific messages.
  • Enable Debug Plan Search on the agent to see planner activity.
  • Join the Discord for community support.