Bevy All-in-One Documentation

A powerful 3D/2.5D game controller plugin for Bevy Engine.


Project maintained by yaskhan Hosted on GitHub Pages — Theme by mattgraham

AI System - Comprehensive Documentation

Table of Contents

  1. Overview
  2. Core Components
  3. System Architecture
  4. Behavior System
  5. Perception System
  6. Faction System
  7. Movement System
  8. Advanced Features
  9. Visualization
  10. Setup and Usage
  11. Performance Considerations
  12. Customization Guide

Overview

The AI System in Bevy All-in-One Controller provides a comprehensive framework for creating intelligent non-player characters (NPCs) with advanced behaviors, perception, and decision-making capabilities. The system is designed to be modular, extensible, and performance-oriented.

Core Components

AiController

The main AI component that controls behavior and state:

#[derive(Component, Debug, Reflect)]
pub struct AiController {
    pub state: AiBehaviorState,              // Current AI state
    pub target: Option<Entity>,              // Current target entity
    pub patrol_path: Vec<Vec3>,              // Patrol waypoints
    pub current_waypoint_index: usize,       // Current patrol index
    pub detection_range: f32,                // Detection range (default: 15.0)
    pub attack_range: f32,                   // Attack range (default: 2.5)
    pub patrol_speed_mult: f32,              // Patrol speed multiplier (default: 0.5)
    pub chase_speed_mult: f32,               // Chase speed multiplier (default: 1.0)
    pub wait_timer: f32,                     // Current wait timer
    pub wait_time_between_waypoints: f32,    // Waypoint wait time (default: 2.0)
    pub suspicion_timer: f32,                // Suspicion timer
    pub max_suspicion_time: f32,             // Max suspicion time (default: 5.0)
    pub wander_radius: f32,                  // Wander radius (default: 10.0)
    pub wander_center: Vec3,                 // Wander center point
    pub target_last_position: Option<Vec3>,   // Last known target position
}

AiMovement

Controls AI movement parameters:

#[derive(Component, Debug, Reflect, Default)]
pub struct AiMovement {
    pub destination: Option<Vec3>,           // Current destination
    pub speed: f32,                          // Movement speed
    pub acceleration: f32,                   // Movement acceleration
    pub stop_distance: f32,                  // Stop distance from target
    pub move_type: AiMovementType,           // Movement type
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, Default)]
pub enum AiMovementType {
    #[default]
    Walk,
    Run,
    Sprint,
    Crouch,
}

AiPerception

Handles AI sensory capabilities:

#[derive(Component, Debug, Reflect)]
pub struct AiPerception {
    pub fov: f32,                            // Field of view in degrees
    pub vision_range: f32,                   // Vision range
    pub visible_targets: Vec<Entity>,        // Currently visible targets
}

AiBehaviorState

Defines all possible AI states:

#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)]
pub enum AiBehaviorState {
    Idle,       // No activity
    Patrol,     // Following patrol path
    Chase,      // Pursuing target
    Attack,     // Attacking target
    Flee,       // Running away
    Follow,     // Following friendly entity
    Hide,       // Hiding from threats
    Combat,     // In combat mode
    Turret,     // Turret mode
    Dead,       // Dead/incapacitated
    Wander,     // Random wandering
    Suspect,    // Suspicious state
}

System Architecture

The AI system uses a multi-system approach with proper execution order:

Update Systems

Behavior System

State Machine

The AI uses a finite state machine with the following states:

Passive States:

Alert States:

Special States:

State Transitions

The AI transitions between states based on perception and environmental factors:

graph TD
    Idle -->|Detects enemy| Chase
    Idle -->|Hears noise| Suspect
    Idle -->|Patrol path set| Patrol
    Idle -->|Follow command| Follow
    
    Patrol -->|Detects enemy| Chase
    Patrol -->|Reaches waypoint| Patrol
    
    Chase -->|Target in range| Attack
    Chase -->|Loses target| Suspect
    Chase -->|Target lost| Idle
    
    Attack -->|Target out of range| Chase
    Attack -->|Target defeated| Idle
    
    Suspect -->|Timer expires| Idle
    Suspect -->|Confirms target| Chase
    
    Follow -->|Detects enemy| Chase
    Follow -->|Loses leader| Idle

Perception System

Vision

The vision system uses:

Vision Process:

  1. Check if target is within range
  2. Check if target is within FOV angle
  3. Perform raycast to verify line of sight
  4. Check faction relations
  5. Add to visible targets list

Hearing

The hearing system responds to noise events:

Hearing Process:

  1. Check if noise is within hearing range
  2. Apply volume attenuation based on distance
  3. If audible, set AI to Suspect state
  4. Store noise position as investigation target

Field of View

The FOV system uses:

Faction System

Faction Relations

The faction system manages relationships between different groups:

#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, Default)]
pub enum FactionRelation {
    #[default]
    Neutral,   // No special relationship
    Friend,    // Friendly relationship
    Enemy,     // Hostile relationship
}

#[derive(Resource, Debug, Reflect, Default)]
pub struct FactionSystem {
    pub factions: Vec<FactionInfo>,
    pub relations: Vec<FactionRelationInfo>,
}

Friend/Foe Detection

The system automatically determines relationships:

Faction Detection Process:

  1. Get AI’s faction
  2. Get target’s faction
  3. Check if same faction → Friendly
  4. Look up in relations table
  5. Return appropriate relation

Movement System

The movement system provides:

Path Following

The patrol system includes:

Advanced Features

Patrol System

The patrol system allows AI to follow predefined paths:

#[derive(Component, Debug, Reflect, Default)]
pub struct PatrolPath {
    pub waypoints: Vec<Vec3>,   // List of waypoints
    pub loop_path: bool,        // Whether to loop the path
}

Patrol Behavior:

  1. Move to current waypoint
  2. Wait at waypoint for configured time
  3. Move to next waypoint
  4. Loop or reverse if path ends

Turret System

Specialized AI for stationary turrets:

Combat System

The combat system handles:

Hiding System

The hiding system allows AI to:

Visualization

Vision Cones

The system provides debug visualization:

#[derive(Component, Debug, Reflect)]
pub struct AiVisionVisualizer {
    pub active: bool,               // Enable/disable visualization
    pub normal_color: Color,        // Normal state color
    pub alert_color: Color,         // Alert state color
}

State Icons

Visual indicators for AI state:

Setup and Usage

Basic AI Setup

use bevy::prelude::*;
use bevy_allinone::prelude::*;

fn spawn_basic_ai(commands: &mut Commands, position: Vec3) -> Entity {
    commands.spawn((
        Name::new("Basic AI"),
        AiController {
            state: AiBehaviorState::Idle,
            detection_range: 15.0,
            attack_range: 2.5,
            ..default()
        },
        AiMovement::default(),
        AiPerception {
            fov: 90.0,
            vision_range: 20.0,
            ..default()
        },
        AiVisionVisualizer::default(),
        CharacterFaction {
            name: "Enemy".to_string(),
        },
        Transform::from_translation(position),
        GlobalTransform::default(),
    ))
    .insert((
        // Add character controller components
        CharacterController::default(),
        CharacterMovementState::default(),
        InputState::default(),
        
        // Add physics components
        RigidBody::Dynamic,
        Collider::capsule(0.4, 1.0),
        LockedAxes::ROTATION_LOCKED,
        GravityScale(1.0),
        Friction::new(0.0),
        Restitution::new(0.0),
        LinearVelocity::default(),
        AngularVelocity::default(),
    ))
    .id()
}

Patrol AI Setup

fn spawn_patrol_ai(commands: &mut Commands) -> Entity {
    let patrol_path = vec![
        Vec3::new(0.0, 0.0, 0.0),
        Vec3::new(5.0, 0.0, 0.0),
        Vec3::new(5.0, 0.0, 5.0),
        Vec3::new(0.0, 0.0, 5.0),
    ];
    
    commands.spawn((
        Name::new("Patrol AI"),
        AiController {
            state: AiBehaviorState::Patrol,
            patrol_path: patrol_path,
            wait_time_between_waypoints: 3.0,
            patrol_speed_mult: 0.7,
            ..default()
        },
        // ... other components
    ))
    .id()
}

Faction Setup

fn setup_factions(mut commands: Commands) {
    // Initialize faction system
    let mut faction_system = FactionSystem::default();
    
    // Add factions
    faction_system.factions.push(FactionInfo {
        name: "Player".to_string(),
        turn_to_enemy_if_attacked: true,
        turn_faction_to_enemy: false,
        friendly_fire_turn_into_enemies: false,
    });
    
    faction_system.factions.push(FactionInfo {
        name: "Enemy".to_string(),
        turn_to_enemy_if_attacked: true,
        turn_faction_to_enemy: false,
        friendly_fire_turn_into_enemies: true,
    });
    
    faction_system.factions.push(FactionInfo {
        name: "Neutral".to_string(),
        turn_to_enemy_if_attacked: true,
        turn_faction_to_enemy: false,
        friendly_fire_turn_into_enemies: false,
    });
    
    // Set faction relations
    faction_system.relations.push(FactionRelationInfo {
        faction_a: "Player".to_string(),
        faction_b: "Enemy".to_string(),
        relation: FactionRelation::Enemy,
    });
    
    faction_system.relations.push(FactionRelationInfo {
        faction_a: "Player".to_string(),
        faction_b: "Neutral".to_string(),
        relation: FactionRelation::Neutral,
    });
    
    commands.insert_resource(faction_system);
}

Performance Considerations

Optimization Techniques

  1. Spatial Partitioning: Uses Bevy’s spatial query system
  2. Early Exit: Skips processing for dead/fleeing AI
  3. Component Organization: Data organized for cache efficiency
  4. Batch Processing: Processes all AI in single systems
  5. Distance Culling: Only processes AI within relevant ranges

Performance Tips

Customization Guide

Creating Custom AI States

// Extend AiBehaviorState enum
#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)]
pub enum AiBehaviorState {
    // ... existing states ...
    CustomState,      // Your custom state
    SpecialAbility,   // Another custom state
}

// Add custom behavior logic
fn update_ai_behavior(
    time: Res<Time>,
    mut ai_query: Query<(&mut AiController, &mut InputState)>
) {
    for (mut ai, mut input) in ai_query.iter_mut() {
        match ai.state {
            AiBehaviorState::CustomState => {
                // Your custom behavior logic
                input.movement = Vec2::new(1.0, 0.0); // Example movement
                // Add your custom state transitions
            }
            AiBehaviorState::SpecialAbility => {
                // Special ability logic
                input.attack_pressed = true;
                // Handle ability cooldowns, etc.
            }
            // ... existing state handling ...
        }
    }
}

Extending Perception

// Add custom perception components
#[derive(Component, Debug, Reflect)]
pub struct CustomPerception {
    pub custom_detection_range: f32,
    pub custom_sense_type: CustomSenseType,
}

// Add custom perception system
fn update_custom_perception(
    mut ai_query: Query<(&GlobalTransform, &mut AiController, &CustomPerception)>
) {
    for (transform, mut ai, custom_perception) in ai_query.iter_mut() {
        // Your custom perception logic
        // Could detect special objects, environmental factors, etc.
        
        if detects_custom_condition(transform.translation(), custom_perception) {
            ai.state = AiBehaviorState::Chase; // Or custom state
            // Set target or other parameters
        }
    }
}

Custom Movement Patterns

// Extend AiMovementType
#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, Default)]
pub enum AiMovementType {
    // ... existing types ...
    CustomMovement,   // Your custom movement type
}

// Add custom movement system
fn update_custom_movement(
    time: Res<Time>,
    mut query: Query<(&mut AiMovement, &mut CharacterController, &mut InputState)>
) {
    for (mut movement, mut controller, mut input) in query.iter_mut() {
        if movement.move_type == AiMovementType::CustomMovement {
            // Your custom movement logic
            // Could implement formation movement, flocking, etc.
            
            input.movement = calculate_custom_movement_direction();
            controller.run_speed = calculate_custom_speed();
        }
    }
}

Best Practices

  1. State Management: Keep state transitions clear and predictable
  2. Component Organization: Group related data in components
  3. Performance: Optimize perception systems first
  4. Debugging: Use visualization tools during development
  5. Testing: Test AI in various scenarios
  6. Documentation: Document custom AI behaviors

Troubleshooting

Common Issues

AI doesn’t detect targets:

AI gets stuck:

AI doesn’t attack:

Performance issues:

Future Enhancements

Potential areas for expansion: