Skip to content

Commit 3f96343

Browse files
committedNov 26, 2024··
wip new tutorial
1 parent db1509d commit 3f96343

File tree

5 files changed

+168
-119
lines changed

5 files changed

+168
-119
lines changed
 

‎src/_topic/mod.rs

Whitespace-only changes.

‎src/_tutorial/chapter_0.rs

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//! # Chapter 0 - Overview
2+
//!
3+
//! Big Brain is a highliy-concurrent [Utility
4+
//! AI](https://en.wikipedia.org/wiki/Utility_system) library for games, built
5+
//! for the [Bevy Game Engine](https://bevyengine.org/). The building blocks
6+
//! for Big Brain can be highly-generic and highly-composable, letting you
7+
//! reuse logic across your game by defining them in small pieces and then
8+
//! just putting them all together in a declarative way.
9+
//!
10+
//! ### High-level Overview
11+
//!
12+
//! As a developer, you write application-dependent code to define [`Scorer`]s
13+
//! and [`Action`]s, and then put it all together like building blocks, using
14+
//! [`Thinker`]s that will define the actual behavior.
15+
//!
16+
//! We'll go over each of these at a high-level, and cover them in more
17+
//! details later.
18+
//!
19+
//! #### Scorers
20+
//!
21+
//! [`Scorer`]s are entities that look at the world and evaluate into
22+
//! [`Score`] values. You can think of them as the "eyes" of the AI system.
23+
//! They're a highly-parallel way of being able to look at the `World` and use
24+
//! it to make some decisions later.
25+
//!
26+
//! They are constructed using [`ScorerBuilder`]s, for which there's a handy
27+
//! shortcut `derive` macro.
28+
//!
29+
//! ```rust
30+
//! use bevy::prelude::*;
31+
//! use big_brain::prelude::*;
32+
//! # #[derive(Component, Debug)]
33+
//! # struct Thirst { thirst: f32 }
34+
//!
35+
//! #[derive(Debug, Clone, Component, ScorerBuilder)]
36+
//! pub struct Thirsty;
37+
//!
38+
//! pub fn thirsty_scorer_system(
39+
//! thirsts: Query<&Thirst>,
40+
//! mut query: Query<(&Actor, &mut Score), With<Thirsty>>,
41+
//! ) {
42+
//! for (Actor(actor), mut score) in query.iter_mut() {
43+
//! if let Ok(thirst) = thirsts.get(*actor) {
44+
//! score.set(thirst.thirst);
45+
//! }
46+
//! }
47+
//! }
48+
//! ```
49+
//!
50+
//! #### Actions
51+
//!
52+
//! [`Action`]s are the actual things your entities will _do_. They are
53+
//! connected to [`ActionState`]s that represent the current execution state
54+
//! of the state machine. You can think of them as deconstructed async
55+
//! functions.
56+
//!
57+
//! They are constructed using [`ActionBuilder`]s, for which there's a handy
58+
//! shortcut `derive` macro.
59+
//!
60+
//! ```rust
61+
//! use bevy::prelude::*;
62+
//! use big_brain::prelude::*;
63+
//! # #[derive(Component, Debug)]
64+
//! # struct Thirst { thirst: f32 }
65+
//!
66+
//! #[derive(Debug, Clone, Component, ActionBuilder)]
67+
//! pub struct Drink;
68+
//!
69+
//! fn drink_action_system(
70+
//! mut thirsts: Query<&mut Thirst>,
71+
//! mut query: Query<(&Actor, &mut ActionState), With<Drink>>,
72+
//! ) {
73+
//! for (Actor(actor), mut state) in query.iter_mut() {
74+
//! if let Ok(mut thirst) = thirsts.get_mut(*actor) {
75+
//! match *state {
76+
//! ActionState::Requested => {
77+
//! thirst.thirst = 10.0;
78+
//! *state = ActionState::Success;
79+
//! }
80+
//! ActionState::Cancelled => {
81+
//! *state = ActionState::Failure;
82+
//! }
83+
//! _ => {}
84+
//! }
85+
//! }
86+
//! }
87+
//! }
88+
//! ```
89+
//!
90+
//! #### Thinkers
91+
//!
92+
//! Finally, you can use it when define the [`Thinker`], which you can attach
93+
//! as a regular [`Component`]:
94+
//!
95+
//! ```rust
96+
//! # use bevy::prelude::*;
97+
//! # use big_brain::prelude::*;
98+
//! # #[derive(Debug, Component)]
99+
//! # struct Thirst(f32, f32);
100+
//! # #[derive(Debug, Clone, Component, ScorerBuilder)]
101+
//! # struct Thirsty;
102+
//! # #[derive(Debug, Clone, Component, ActionBuilder)]
103+
//! # struct Drink;
104+
//! fn spawn_entity(cmd: &mut Commands) {
105+
//! cmd.spawn((
106+
//! Thirst(70.0, 2.0),
107+
//! Thinker::build()
108+
//! .picker(FirstToScore { threshold: 0.8 })
109+
//! .when(Thirsty, Drink),
110+
//! ));
111+
//! }
112+
//! ```
113+
//!
114+
//! #### App
115+
//!
116+
//! Once all that's done, we just add our systems and off we go!
117+
//!
118+
//! ```no_run
119+
//! # use bevy::prelude::*;
120+
//! # use big_brain::prelude::*;
121+
//! # fn init_entities() {}
122+
//! # fn thirst_system() {}
123+
//! # fn drink_action_system() {}
124+
//! # fn thirsty_scorer_system() {}
125+
//! fn main() {
126+
//! App::new()
127+
//! .add_plugins(DefaultPlugins)
128+
//! .add_plugins(BigBrainPlugin::new(PreUpdate))
129+
//! .add_systems(Startup, init_entities)
130+
//! .add_systems(Update, thirst_system)
131+
//! .add_systems(PreUpdate, drink_action_system.in_set(BigBrainSet::Actions))
132+
//! .add_systems(PreUpdate, thirsty_scorer_system.in_set(BigBrainSet::Scorers))
133+
//! .run();
134+
//! }
135+
//! ```
136+
//!
137+
//! #### What's next?
138+
//!
139+
//! You can read the general [crate docs][crate], or continue with the [next
140+
//! chapter of the tutorial][_tutorial::chapter_1] for an expanded guide on
141+
//! how to build out and organize the AI for your game using Big Brain!.
142+
#[allow(unused_imports)]
143+
use bevy::prelude::*;
144+
145+
#[allow(unused_imports)]
146+
use crate::prelude::{Action, ActionBuilder, ActionState, Score, Scorer, ScorerBuilder, Thinker};
147+
148+
pub use super::chapter_1 as next;
149+
pub use crate::_tutorial as table_of_contents;

‎src/_tutorial/chapter_1.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//! # Chapter 1
2+
//!
3+
//!
4+
5+
// pub use super::chapter_2 as next;
6+
pub use crate::_tutorial as table_of_contents;

‎src/_tutorial/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//! # Tutorial
2+
//!
3+
//! Table of Contents
4+
5+
pub mod chapter_0;
6+
pub mod chapter_1;

‎src/lib.rs

+7-119
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
//! perform actual behaviors upon the world). No other code is needed for
1515
//! actual AI behavior.
1616
//!
17-
//! See [the documentation](https://docs.rs/big-brain) for more details.
17+
//! See [the documentation](https://docs.rs/big-brain), alone with [the
18+
//! tutorial][_tutorial::chapter_0] for more details.
1819
//!
1920
//! ### Features
2021
//!
@@ -25,124 +26,6 @@
2526
//! * State machine-style continuous actions/behaviors.
2627
//! * Action cancellation.
2728
//!
28-
//! ### Example
29-
//!
30-
//! As a developer, you write application-dependent code to define
31-
//! [`Scorers`](#scorers) and [`Actions`](#actions), and then put it all
32-
//! together like building blocks, using [`Thinkers`](#thinkers) that will
33-
//! define the actual behavior.
34-
//!
35-
//! #### Scorers
36-
//!
37-
//! `Scorer`s are entities that look at the world and evaluate into `Score`
38-
//! values. You can think of them as the "eyes" of the AI system. They're a
39-
//! highly-parallel way of being able to look at the `World` and use it to
40-
//! make some decisions later.
41-
//!
42-
//! ```rust
43-
//! use bevy::prelude::*;
44-
//! use big_brain::prelude::*;
45-
//! # #[derive(Component, Debug)]
46-
//! # struct Thirst { thirst: f32 }
47-
//!
48-
//! #[derive(Debug, Clone, Component, ScorerBuilder)]
49-
//! pub struct Thirsty;
50-
//!
51-
//! pub fn thirsty_scorer_system(
52-
//! thirsts: Query<&Thirst>,
53-
//! mut query: Query<(&Actor, &mut Score), With<Thirsty>>,
54-
//! ) {
55-
//! for (Actor(actor), mut score) in query.iter_mut() {
56-
//! if let Ok(thirst) = thirsts.get(*actor) {
57-
//! score.set(thirst.thirst);
58-
//! }
59-
//! }
60-
//! }
61-
//! ```
62-
//!
63-
//! #### Actions
64-
//!
65-
//! `Action`s are the actual things your entities will _do_. They are
66-
//! connected to `ActionState`s that represent the current execution state of
67-
//! the state machine.
68-
//!
69-
//! ```rust
70-
//! use bevy::prelude::*;
71-
//! use big_brain::prelude::*;
72-
//! # #[derive(Component, Debug)]
73-
//! # struct Thirst { thirst: f32 }
74-
//!
75-
//! #[derive(Debug, Clone, Component, ActionBuilder)]
76-
//! pub struct Drink;
77-
//!
78-
//! fn drink_action_system(
79-
//! mut thirsts: Query<&mut Thirst>,
80-
//! mut query: Query<(&Actor, &mut ActionState), With<Drink>>,
81-
//! ) {
82-
//! for (Actor(actor), mut state) in query.iter_mut() {
83-
//! if let Ok(mut thirst) = thirsts.get_mut(*actor) {
84-
//! match *state {
85-
//! ActionState::Requested => {
86-
//! thirst.thirst = 10.0;
87-
//! *state = ActionState::Success;
88-
//! }
89-
//! ActionState::Cancelled => {
90-
//! *state = ActionState::Failure;
91-
//! }
92-
//! _ => {}
93-
//! }
94-
//! }
95-
//! }
96-
//! }
97-
//! ```
98-
//!
99-
//! #### Thinkers
100-
//!
101-
//! Finally, you can use it when define the `Thinker`, which you can attach as
102-
//! a regular Component:
103-
//!
104-
//! ```rust
105-
//! # use bevy::prelude::*;
106-
//! # use big_brain::prelude::*;
107-
//! # #[derive(Debug, Component)]
108-
//! # struct Thirst(f32, f32);
109-
//! # #[derive(Debug, Clone, Component, ScorerBuilder)]
110-
//! # struct Thirsty;
111-
//! # #[derive(Debug, Clone, Component, ActionBuilder)]
112-
//! # struct Drink;
113-
//! fn spawn_entity(cmd: &mut Commands) {
114-
//! cmd.spawn((
115-
//! Thirst(70.0, 2.0),
116-
//! Thinker::build()
117-
//! .picker(FirstToScore { threshold: 0.8 })
118-
//! .when(Thirsty, Drink),
119-
//! ));
120-
//! }
121-
//! ```
122-
//!
123-
//! #### App
124-
//!
125-
//! Once all that's done, we just add our systems and off we go!
126-
//!
127-
//! ```no_run
128-
//! # use bevy::prelude::*;
129-
//! # use big_brain::prelude::*;
130-
//! # fn init_entities() {}
131-
//! # fn thirst_system() {}
132-
//! # fn drink_action_system() {}
133-
//! # fn thirsty_scorer_system() {}
134-
//! fn main() {
135-
//! App::new()
136-
//! .add_plugins(DefaultPlugins)
137-
//! .add_plugins(BigBrainPlugin::new(PreUpdate))
138-
//! .add_systems(Startup, init_entities)
139-
//! .add_systems(Update, thirst_system)
140-
//! .add_systems(PreUpdate, drink_action_system.in_set(BigBrainSet::Actions))
141-
//! .add_systems(PreUpdate, thirsty_scorer_system.in_set(BigBrainSet::Scorers))
142-
//! .run();
143-
//! }
144-
//! ```
145-
//!
14629
//! ### bevy version and MSRV
14730
//!
14831
//! The current version of `big-brain` is compatible with `bevy` 0.12.1.
@@ -180,6 +63,11 @@ pub mod measures;
18063
pub mod scorers;
18164
pub mod thinker;
18265

66+
//#[cfg(feature = "documentation")]
67+
pub mod _topic;
68+
//#[cfg(feature = "documentation")]
69+
pub mod _tutorial;
70+
18371
pub mod prelude {
18472
/*!
18573
Convenience module with the core types you're most likely to use when working with Big Brain. Mean to be used like `use big_brain::prelude::*;`

0 commit comments

Comments
 (0)
Please sign in to comment.