Caution
This project is no longer developed on GitHub. All development has moved to big-brain on Codeberg. This repository exists only as a read-only archive and may be removed in the future.
big-brain is a Utility
AI library for games, built
for the Bevy Game Engine
It lets you define complex, intricate AI behaviors for your entities based on their perception of the world. Definitions are heavily data-driven, using plain Rust, and you only need to program Scorers (entities that look at your game world and come up with a Score), and Actions (entities that perform actual behaviors upon the world). No other code is needed for actual AI behavior.
See the documentation for more details.
- Highly concurrent/parallelizable evaluation.
- Integrates smoothly with Bevy.
- Proven game AI model.
- Highly composable and reusable.
- State machine-style continuous actions/behaviors.
- Action cancellation.
As a developer, you write application-dependent code to define
Scorers and Actions, and then put it all
together like building blocks, using Thinkers that will
define the actual behavior.
Scorers are entities that look at the world and evaluate into Score
values. You can think of them as the "eyes" of the AI system. They're a
highly-parallel way of being able to look at the World and use it to
make some decisions later.
use bevy::prelude::*;
use big_brain::prelude::*;
#[derive(Debug, Clone, Component, ScorerBuilder)]
pub struct Thirsty;
pub fn thirsty_scorer_system(
thirsts: Query<&Thirst>,
mut query: Query<(&Actor, &mut Score), With<Thirsty>>,
) {
for (Actor(actor), mut score) in query.iter_mut() {
if let Ok(thirst) = thirsts.get(*actor) {
score.set(thirst.thirst);
}
}
}Actions are the actual things your entities will do. They are
connected to ActionStates that represent the current execution state of
the state machine.
use bevy::prelude::*;
use big_brain::prelude::*;
#[derive(Debug, Clone, Component, ActionBuilder)]
pub struct Drink;
fn drink_action_system(
mut thirsts: Query<&mut Thirst>,
mut query: Query<(&Actor, &mut ActionState), With<Drink>>,
) {
for (Actor(actor), mut state) in query.iter_mut() {
if let Ok(mut thirst) = thirsts.get_mut(*actor) {
match *state {
ActionState::Requested => {
thirst.thirst = 10.0;
*state = ActionState::Success;
}
ActionState::Cancelled => {
*state = ActionState::Failure;
}
_ => {}
}
}
}
}Finally, you can use it when define the Thinker, which you can attach as
a regular Component:
fn spawn_entity(cmd: &mut Commands) {
cmd.spawn((
Thirst(70.0, 2.0),
Thinker::build()
.picker(FirstToScore { threshold: 0.8 })
.when(Thirsty, Drink),
));
}Once all that's done, we just add our systems and off we go!
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(BigBrainPlugin::new(PreUpdate))
.add_systems(Startup, init_entities)
.add_systems(Update, thirst_system)
.add_systems(PreUpdate, drink_action_system.in_set(BigBrainSet::Actions))
.add_systems(PreUpdate, thirsty_scorer_system.in_set(BigBrainSet::Scorers))
.run();
}The current version of big-brain is compatible with bevy@0.16.0.
The Minimum Supported Rust Version for big-brain should be considered to
be the same as bevy's, which as of the time of this writing was "the
latest stable release".
All relevant big-brain types implement the bevy Reflect trait, so you
should be able to get some useful display info while using things like
bevy_inspector_egui.
This implementation should not be considered stable, and individual fields made visible may change at any time and not be considered towards semver. Please use this feature only for debugging.
- Install the latest Rust toolchain (stable supported).
cargo run --example thirst- Happy hacking!
This project is licensed under the Apache-2.0 License.