1
1
use bevy_ecs:: prelude:: * ;
2
- use rand:: Rng ;
2
+ use bevy_ecs:: schedule:: RunOnce ;
3
+ use bevy_entropy:: Entropy ;
4
+ use rand:: { rngs:: SmallRng , Rng , SeedableRng } ;
3
5
use std:: ops:: Deref ;
4
6
5
7
// In this example we will simulate a population of entities. In every tick we will:
6
- // 1. spawn a new entity with a certain possibility
8
+ // 1. spawn a new entity with a certain deterministic probability
7
9
// 2. age all entities
8
10
// 3. despawn entities with age > 2
9
11
//
@@ -13,17 +15,33 @@ fn main() {
13
15
// Create a new empty World to hold our Entities, Components and Resources
14
16
let mut world = World :: new ( ) ;
15
17
18
+ // Add the entropy resource for future random number generators to use.
19
+ // This makes execution deterministic.
20
+ let world_seed = [ 1 ; 32 ] ;
21
+ world. insert_resource ( Entropy :: from ( world_seed) ) ;
22
+
16
23
// Add the counter resource to remember how many entities where spawned
17
24
world. insert_resource ( EntityCounter { value : 0 } ) ;
18
25
19
- // Create a new Schedule, which defines an execution strategy for Systems
26
+ // Create a new Schedule, which defines an execution strategy for Systems.
20
27
let mut schedule = Schedule :: default ( ) ;
28
+
21
29
// Create a Stage to add to our Schedule. Each Stage in a schedule runs all of its systems
22
- // before moving on to the next Stage
23
- let mut update = SystemStage :: parallel ( ) ;
30
+ // before moving on to the next Stage.
31
+ // Here, we are creating a "startup" Stage with a schedule that runs once.
32
+ let mut startup = SystemStage :: parallel ( ) ;
33
+ startup. add_system ( create_rng. system ( ) ) ;
34
+ schedule. add_stage (
35
+ "startup" ,
36
+ Schedule :: default ( )
37
+ . with_run_criteria ( RunOnce :: default ( ) )
38
+ . with_stage ( "only_once" , startup) ,
39
+ ) ;
24
40
25
- // Add systems to the Stage to execute our app logic
41
+ // Add systems to another Stage to execute our app logic.
26
42
// We can label our systems to force a specific run-order between some of them
43
+ // within the Stage.
44
+ let mut update = SystemStage :: parallel ( ) ;
27
45
update. add_system ( spawn_entities. system ( ) . label ( SimulationSystem :: Spawn ) ) ;
28
46
update. add_system (
29
47
print_counter_when_changed
@@ -62,11 +80,23 @@ enum SimulationSystem {
62
80
Age ,
63
81
}
64
82
83
+ // This system creates a random number generator resource from [`Entropy`].
84
+ fn create_rng ( mut commands : Commands , mut entropy : ResMut < Entropy > ) {
85
+ let seed = entropy. get ( ) ;
86
+ println ! ( " seeding rng from entropy: {:?}" , seed) ;
87
+ let rng = SmallRng :: from_seed ( seed) ;
88
+ commands. insert_resource ( rng) ;
89
+ }
90
+
65
91
// This system randomly spawns a new entity in 60% of all frames
66
92
// The entity will start with an age of 0 frames
67
93
// If an entity gets spawned, we increase the counter in the EntityCounter resource
68
- fn spawn_entities ( mut commands : Commands , mut entity_counter : ResMut < EntityCounter > ) {
69
- if rand:: thread_rng ( ) . gen_bool ( 0.6 ) {
94
+ fn spawn_entities (
95
+ mut commands : Commands ,
96
+ mut entity_counter : ResMut < EntityCounter > ,
97
+ mut rng : ResMut < SmallRng > ,
98
+ ) {
99
+ if rng. gen_bool ( 0.6 ) {
70
100
let entity_id = commands. spawn ( ) . insert ( Age :: default ( ) ) . id ( ) ;
71
101
println ! ( " spawning {:?}" , entity_id) ;
72
102
entity_counter. value += 1 ;
0 commit comments