Build mob AI with goals
The goal system separates behavior into small stateful actions. A goal decides when it can begin, when it must stop, and what it does while active. GoalSelector schedules compatible goals and resolves priority conflicts.
Register goals on the mob
Section titled “Register goals on the mob”Mob.Initialize sets the world and calls RegisterGoals. Override that method in a Mob subclass and register each behavior with an integer priority; smaller numbers have higher priority.
protected override void RegisterGoals(){ GoalSelector.AddGoal(0, new FloatGoal(this)); GoalSelector.AddGoal(1, new PanicGoal(this, speedModifier: 1.35f)); GoalSelector.AddGoal(5, new WaterAvoidingRandomStrollGoal(this, speedModifier: 0.75f)); GoalSelector.AddGoal(6, new LookAtPlayerGoal(this, lookDistance: 6.0f));}This is the same composition pattern used by CowMob. Goals can be added to TargetSelector for target acquisition; keep target selection separate from actions that move toward or attack the selected target.
Implement one focused goal
Section titled “Implement one focused goal”The following example shows the lifecycle and control-flag pattern used by MeleeAttackGoal. Target is selected elsewhere; this goal only steers toward it.
public sealed class FollowTargetGoal : Goal{ private readonly Mob _mob;
public FollowTargetGoal(Mob mob) { _mob = mob; SetFlags(GoalFlag.Move); }
public override bool CanUse() => _mob.Target is { } target && target.IsInsideTree();
public override bool CanContinueToUse() => CanUse();
public override void Stop() => _mob.MoveControl.Stop();
public override void Tick() { if (_mob.Target is { } target) _mob.MoveControl.SetWantedPosition(target.GlobalPosition, 1.0f); }}Move prevents another active goal from controlling movement at the same time. Add Look only if this goal must also own look control. Stop should release any control or temporary state the goal acquired.
Keep each lifecycle hook precise
Section titled “Keep each lifecycle hook precise”CanUsechecks the initial precondition.Startinitializes timers or captures a target when the goal begins.CanContinueToUsechecks whether the active action remains valid.Tickrequests movement, looking, jumping, or a domain action.Stopclears requests and temporary flags.
Goals normally tick on the selector’s reduced schedule. Override RequiresUpdateEveryTick only when the behavior needs a per-game-tick update. Prefer controls such as MoveControl.SetWantedPosition over writing velocity from a goal; the control and travel layers own steering and movement physics.
Check which AI path the mob uses
Section titled “Check which AI path the mob uses”Not every mob is on the same path. ZombieMob creates a ZombieAi state machine and ticks it from its physics callback; it does not register its behavior through Mob.RegisterGoals. Before adding AI, follow the mob’s initialization and tick entry point. Do not install both schedulers for the same action by accident.
Aquatic movement: goal plus control
Section titled “Aquatic movement: goal plus control”DolphinMob shows how a goal can request travel while a specialized MoveControl owns the steering details. The goal picks a clear water corridor and starts a jump; the control handles yaw, pitch, and swimming speed during ordinary navigation.
MoveControl = new SmoothSwimmingMoveControl( this, IsInWater, maxTurnX: 85, maxTurnY: 10, inWaterSpeedModifier: 0.02f, outsideWaterSpeedModifier: 0.1f, applyGravity: true);
GoalSelector.AddGoal(5, new DolphinJumpGoal(this, interval: 10));The control turns toward the requested position and converts pitch into forward and vertical inputs. DolphinJumpGoal validates water and headroom before applying a launch impulse, then requests every-tick updates to animate the arc. Keep environment checks in the goal and repeated locomotion math in the control; this makes the control reusable and the goal’s start/stop conditions easy to inspect.
Keep sensing, navigation, and combat decisions in the AI or goal layer that owns them. Keep shared locomotion in movement controls, and shared target-selection behavior in target goals.
Related: entity simulation, adding an entity, physics validation, and build and validation.