Companion AI
Three competing goals with priority + interruption. Demonstrates Family 1 goal momentum and Family 2 Schmitt latches on HP thresholds.
[ Example ]
Companion AI — follow, help, retreat
A companion who follows the player, helps in combat, and retreats when low on HP. Companion AI is the genre most punished by flap — a wounded companion flickering between Help and Retreat every half-second breaks immersion in a way no other AI shape does. This page is the showcase for using the anti-flap stack in combination.
Behaviour matrix
| Condition | Goal | Action | Why |
|---|---|---|---|
| Player nearby, no enemies | Follow | MoveToPlayer | Default state, low priority |
| Enemy in player's combat | Help | AttackEnemy | Higher priority than Follow when scored |
| Self HP < 30% | Retreat | FleeToSafeDistance | Critical interruption — overrides any plan |
Anatomy
Schema — DA_Schema_Companion
Five facts. Two are derived (filtered + latched); three feed direct from sensors.
PlayerDistanceScalar- Source
- Sensor
- Filter
- EMA α=0.3
PlayerNearBool (latched)- Source
- PlayerDistance
- Band
- 400 / 600
EnemyInCombatBool- Source
- Sensor
- Triggers Replan
- true
SelfHPScalar- Source
- Sensor
- Triggers Replan
- true
IsLowHPBool (latched)- Source
- SelfHP
- Band
- 0.25 / 0.40
Goals
DA_Goal_FollowIntentGoal- Priority
- 0.5
- Scored by
- PlayerNear
DA_Goal_HelpIntentGoal- Priority
- 1.0
- Scored by
- EnemyInCombat
DA_Goal_RetreatIntentGoal- Priority
- 2.0
- Interruption
- Critical
- Scored by
- IsLowHP
Actions
MoveToPlayerIntentAction- Effect
- PlayerNear = true
- Executor
- Move
AttackEnemyIntentAction- Precondition
- EnemyInCombat
- Effect
- enemy dispatched
- Executor
- Custom
FleeToSafeDistanceIntentAction- Effect
- IsLowHP = false (via distance)
- Executor
- Move
Why this example is here
Three layers of the anti-flap toolkit working together:
- Family 4 (EMA filter) on
PlayerDistance— smooths per-frame distance jitter that would otherwise causePlayerNearto flicker. - Family 2 (Schmitt latch) on
IsLowHP— when HP hovers near 30% (combat damage + healing tick), the 25%/40% band prevents Retreat / Help oscillation. - Family 1 (goal momentum bonus) — once Help is chosen, it scores +0.15 against Follow on subsequent ticks, preventing thrash when the player runs back behind cover momentarily.
- Critical interruption on Retreat — bypasses the momentum bonus when actually necessary (HP threshold crossed in the dangerous direction).
How to build it
Pending the marketplace sample pack (Linear: INT-13). In the meantime, the schema/goals/actions above are enough to scaffold this yourself in any project using built-in executors plus a custom Attack executor.
Acceptance test
SpawnDefault stateFollower's Inspector shows goal Follow.
Player engages enemyHelp firesGoal switches to Help within one replan tick.
HP oscillates near bandSchmitt holdsPlayer takes damage then heals across the IsLowHP threshold range — goal stays Help (Schmitt band absorbs the oscillation).
HP < 25%Critical interruptGoal immediately switches to Retreat. Critical interruption bypasses momentum.
HP > 40%Re-evaluateFollower retreats until HP rises back above the upper band edge, then re-evaluates between Follow and Help.
At no point should you see the goal flicker between Help and Retreat multiple times per second.