Context
The server runtime architecture spec (section 7) defines an AI system based on priority goal lists, matching the vanilla Minecraft MobGoal pattern. The ECS foundation is in place (basalt-ecs with system scheduler, phase ordering, component access declarations), and the physics plugin demonstrates the pattern. The AI system is the next simulation layer needed to enable mob behavior.
Spec reference: docs/superpowers/specs/2026-04-15-server-runtime-architecture-design.md sections 7.1 and 7.2.
Problem
- There is no AI system — entities (mobs, NPCs) have no autonomous behavior.
- No
Goal trait exists for defining reusable behavior primitives (wander, look at player, flee, attack).
- No
GoalScheduler exists to evaluate and switch between goals by priority each AI tick.
- No core components (
AiGoals, Health, EntityType) are registered for AI-driven entities.
Proposed approach
7.1 — Goal trait
Define a Goal trait in basalt-ecs (or a new basalt-ai crate if preferred):
trait Goal: Send + Sync {
fn can_start(&self, entity: EntityId, ecs: &Ecs) -> bool;
fn start(&mut self, entity: EntityId, ecs: &mut Ecs);
fn tick(&mut self, entity: EntityId, ecs: &mut Ecs);
fn can_continue(&self, entity: EntityId, ecs: &Ecs) -> bool;
fn stop(&mut self, entity: EntityId, ecs: &mut Ecs);
}
7.2 — GoalScheduler
An ECS system running in the Simulate phase at every(5) (4 effective TPS at 20 TPS global):
- For each entity with
AiGoals, iterate goals from highest to lowest priority.
- If a higher-priority goal can start, interrupt the current goal (
stop()) and start the new one.
- If the current goal can no longer continue, stop it and evaluate the next candidate.
- Call
tick() on the active goal.
Core goals (provided by basalt)
RandomWalkGoal — picks a random nearby position and walks toward it.
LookAtPlayerGoal — rotates to face the nearest player within range.
PanicGoal — runs in a random direction when damaged.
FloatGoal — prevents drowning by swimming to the surface.
Core components to add
AiGoals — goals: Vec<PrioritizedGoal> (priority + boxed goal)
Health — current: f32, max: f32
EntityType — type_id: u32 (Minecraft entity type ID)
Plugin extensibility
Plugins add custom goals and reorder goal lists per mob type via registrar.system(). Survival plugins add combat, farming, breeding, etc.
Scope
crates/basalt-ecs/ — new components (AiGoals, Health, EntityType), Goal trait, GoalScheduler system
crates/basalt-server/src/game/tick.rs — register AI system in game loop
- Possibly a new
basalt-ai plugin under plugins/ for the core goals
Benefits
- Enables autonomous mob behavior (zombies, animals, villagers)
- Provides the foundation for all PvE gameplay
- Plugin-extensible: server operators can customize mob AI per server type
- Matches vanilla Minecraft patterns — familiar to plugin developers
Non-goals
- Mob spawning rules and spawn rate configuration (separate feature)
- Entity rendering/model system (client-side concern)
- Combat mechanics (PvP, damage, knockback) — separate issue
- Pathfinding algorithm itself — covered by a dedicated issue
Context
The server runtime architecture spec (section 7) defines an AI system based on priority goal lists, matching the vanilla Minecraft MobGoal pattern. The ECS foundation is in place (basalt-ecs with system scheduler, phase ordering, component access declarations), and the physics plugin demonstrates the pattern. The AI system is the next simulation layer needed to enable mob behavior.
Spec reference:
docs/superpowers/specs/2026-04-15-server-runtime-architecture-design.mdsections 7.1 and 7.2.Problem
Goaltrait exists for defining reusable behavior primitives (wander, look at player, flee, attack).GoalSchedulerexists to evaluate and switch between goals by priority each AI tick.AiGoals,Health,EntityType) are registered for AI-driven entities.Proposed approach
7.1 — Goal trait
Define a
Goaltrait inbasalt-ecs(or a newbasalt-aicrate if preferred):7.2 — GoalScheduler
An ECS system running in the Simulate phase at
every(5)(4 effective TPS at 20 TPS global):AiGoals, iterate goals from highest to lowest priority.stop()) and start the new one.tick()on the active goal.Core goals (provided by basalt)
RandomWalkGoal— picks a random nearby position and walks toward it.LookAtPlayerGoal— rotates to face the nearest player within range.PanicGoal— runs in a random direction when damaged.FloatGoal— prevents drowning by swimming to the surface.Core components to add
AiGoals—goals: Vec<PrioritizedGoal>(priority + boxed goal)Health—current: f32, max: f32EntityType—type_id: u32(Minecraft entity type ID)Plugin extensibility
Plugins add custom goals and reorder goal lists per mob type via
registrar.system(). Survival plugins add combat, farming, breeding, etc.Scope
crates/basalt-ecs/— new components (AiGoals,Health,EntityType),Goaltrait,GoalSchedulersystemcrates/basalt-server/src/game/tick.rs— register AI system in game loopbasalt-aiplugin underplugins/for the core goalsBenefits
Non-goals