Skip to content
Snippets Groups Projects
README.md 3.58 KiB
Newer Older
Kat Marchán's avatar
Kat Marchán committed
`big-brain` is a [Utility AI](https://en.wikipedia.org/wiki/Utility_system)
library for games, built for the [Bevy Game Engine](https://bevyengine.org/)
Kat Marchán's avatar
Kat Marchán committed

It lets you define complex, intricate AI behaviors for your entities based on
Kat Marchán's avatar
Kat Marchán committed
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.
Kat Marchán's avatar
Kat Marchán committed

See [the documentation](https://docs.rs/big-brain) for more details.

## Example

Kat Marchán's avatar
Kat Marchán committed
First, you define actions and considerations, which are just plain old `Bevy`
Kat Marchán's avatar
Kat Marchán committed
`Component`s and `System`s.

Kat Marchán's avatar
Kat Marchán committed
### Scorers
Kat Marchán's avatar
Kat Marchán committed
`Scorers`s are entities that look at the world and evaluate into `Score` values.
Kat Marchán's avatar
Kat Marchán committed

```rust
use bevy::prelude::*;
Kat Marchán's avatar
Kat Marchán committed
use big_brain::prelude::*;
Kat Marchán's avatar
Kat Marchán committed
#[derive(Debug, Clone)]
Kat Marchán's avatar
Kat Marchán committed
pub struct Thirsty;
Kat Marchán's avatar
Kat Marchán committed
impl Thirsty {
    fn build() -> ThirstyBuilder {
        ThirstyBuilder
    }
}

#[derive(Debug, Clone)]
pub struct ThirstyBuilder;

impl ScorerBuilder for ThirstyBuilder {
    fn build(&self, cmd: &mut Commands, scorer: Entity, _actor: Entity) {
        cmd.entity(scorer).insert(Thirsty);
    }
}

pub fn thirsty_scorer_system(
    thirsts: Query<&Thirst>,
Kat Marchán's avatar
Kat Marchán committed
    mut query: Query<(&Actor, &mut Score), With<Thirsty>>,
Kat Marchán's avatar
Kat Marchán committed
    for (Actor(actor), mut score) in query.iter_mut() {
        if let Ok(thirst) = thirsts.get(*actor) {
Kat Marchán's avatar
Kat Marchán committed
        }
    }
}
```

### Actions

`Action`s are the actual things your entities will _do_.

```rust
Kat Marchán's avatar
Kat Marchán committed
use bevy::prelude::*;
Kat Marchán's avatar
Kat Marchán committed
use big_brain::prelude::*;
Kat Marchán's avatar
Kat Marchán committed

Kat Marchán's avatar
Kat Marchán committed
#[derive(Debug, Clone)]
Kat Marchán's avatar
Kat Marchán committed
pub struct Drink;
Kat Marchán's avatar
Kat Marchán committed
impl Drink {
    pub fn build() -> DrinkBuilder {
        DrinkBuilder
    }
}

#[derive(Debug, Clone)]
pub struct DrinkBuilder;

impl ActionBuilder for DrinkBuilder {
    fn build(&self, cmd: &mut Commands, action: Entity, _actor: Entity) {
        cmd.entity(action).insert(Drink);
    }
}

fn drink_action_system(
    mut thirsts: Query<&mut Thirst>,
Kat Marchán's avatar
Kat Marchán committed
    mut query: Query<(&Actor, &mut ActionState), With<Drink>>,
Kat Marchán's avatar
Kat Marchán committed
    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;
Kat Marchán's avatar
Kat Marchán committed
                }
                _ => {}
Kat Marchán's avatar
Kat Marchán committed
            }
        }
    }
}
```

### Thinker Definition

Finally, you can use it when define the `Thinker`, which you can attach as a
regular Component:
Kat Marchán's avatar
Kat Marchán committed
```rust
cmd.spawn().insert(Thirst::new(70.0, 2.0)).insert(
    Thinker::build()
        .picker(FirstToScore { threshold: 80.0 })
        .when(Thirsty::build(), Drink::build()),
Kat Marchán's avatar
Kat Marchán committed
```

## License

This project is licensed under [the Parity License](LICENSE.md). Third-party contributions are licensed under Apache-2.0 and belong to their respective authors.

The Parity License is a copyleft license that, unlike the GPL family, allows you to license derivative and connected works under permissive licenses like MIT or Apache-2.0. It's free to use provided the work you do is freely available!

For proprietary use, please [contact me](mailto:kzm@zkat.tech?subject=big-brain%20license), or just [sponsor me on GitHub](https://github.com/users/zkat/sponsorship) under the appropriate tier to [acquire a proprietary-use license](LICENSE-PATRON.md)! This funding model helps me make my work sustainable and compensates me for the work it took to write this crate!