14 releases (breaking)
Uses new Rust 2024
0.11.0 | May 7, 2025 |
---|---|
0.9.0 | Dec 31, 2024 |
0.8.0 | Nov 30, 2024 |
0.7.1 | Jul 5, 2024 |
0.1.0 | Apr 14, 2023 |
#42 in Game dev
1,443 downloads per month
Used in haalka
105KB
1.5K
SLoC
Bevy Rand
What is Bevy Rand?
Bevy Rand is a plugin to provide integration of rand
ecosystem PRNGs in an ECS friendly way. It provides a set of wrapper component and resource types that allow for safe access to a PRNG for generating random numbers, giving features like reflection, serialization for free. And with these types, it becomes possible to have determinism with the usage of these integrated PRNGs in ways that work with multi-threading and also avoid pitfalls such as unstable query iteration order.
Using Bevy Rand
There's now a tutorial, go to here if you want a more comprehensive rundown of how to use
bevy_rand
.
Usage of Bevy Rand can range from very simple to quite complex use-cases, all depending on whether one cares about deterministic output or not. First, add bevy_rand
, and either rand_core
or rand
to your Cargo.toml
to bring in both the components and the PRNGs you want to use, along with the various traits needed to use the RNGs. To select a given algorithm type with bevy_rand
, enable the feature representing the algorithm rand_*
crate you want to use. This will then give you access to the PRNG structs via the prelude. Alternatively, you can use bevy_prng
directly to get the newtyped structs with the same feature flags. However, using the algorithm crates like rand_chacha
directly will not work as these don't implement the necessary traits to support bevy's reflection.
All supported PRNGs and compatible structs are provided by the bevy_prng
crate. Simply activate the relevant features in bevy_rand
/bevy_prng
to pull in the PRNG algorithm you want to use, and then import them like so:
bevy_rand
feature activation
rand_core = "0.9"
bevy_rand = { version = "0.11", features = ["rand_chacha", "wyrand"] }
bevy_prng
feature activation
rand_core = "0.9"
bevy_rand = "0.11"
bevy_prng = { version = "0.11", features = ["rand_chacha", "wyrand"] }
The summary of what RNG algorithm to choose is: pick wyrand
for almost all cases as it is faster and more portable than other algorithms. For cases where you need the extra assurance of entropy quality (as in, better and much less predictable 'randomness', etc), then use rand_chacha
. For more information, go here.
DO NOT use bevy_rand
for actual security purposes, as this requires much more careful consideration and properly vetted crates designed for cryptography. A good starting point would be to look at RustCrypto and go from there.
no_std
support
bevy_rand
is no_std
compatible, but it requires disabling default features. It also assumes that alloc
is available, just the same as bevy
. Certain features like thread_local_entropy
are not available for no_std
due to requiring std
specific functionalities like thread locals.
bevy_rand = { version = "0.11", default-features = false, features = ["rand_chacha", "wyrand"] }
All PRNG backends should support no_std
environments. Furthermore, getrandom
needs to be configured to support the platform, so in the case of a no_std
environment such as an embedded board or console, you'll need to implement the custom backend for getrandom
to compile.
Usage within Web WASM environments
From v0.9
onwards, bevy_rand
no longer assumes that bevy
will be run in a web environment when compiled for WASM. To enable that in v0.11
, just paste the following into your Cargo.toml
for your binary crate:
[target.'cfg(all(target_family = "wasm", any(target_os = "unknown", target_os = "none")))'.dependencies]
bevy_rand = { version = "0.11", features = ["wasm_js"] }
This enables the wasm_js
backend to be made available for getrandom
, but it doesn't actually build. The next step is to either edit your .cargo/config.toml
with the below configuration:
# It's recommended to set the flag on a per-target basis:
[target.wasm32-unknown-unknown]
rustflags = ['--cfg', 'getrandom_backend="wasm_js"']
Or pass an environment variable: RUSTFLAGS='--cfg getrandom_backend="wasm_js"'
. This then enables the getrandom
WASM backend to get built correctly.
Registering a PRNG for use with Bevy Rand
Before a PRNG can be used via GlobalEntropy
or Entropy
, it must be registered via the plugin.
use bevy_ecs::prelude::*;
use bevy_app::App;
use bevy_prng::WyRand;
use bevy_rand::prelude::EntropyPlugin;
use rand_core::RngCore;
fn example_main() {
App::new()
.add_plugins(EntropyPlugin::<WyRand>::default())
.run();
}
Basic Usage
At the simplest case, using GlobalEntropy
directly for all random number generation, though this does limit how well systems using GlobalEntropy
can be parallelised. All systems that access GlobalEntropy
will run serially to each other.
use bevy_prng::WyRand;
use bevy_rand::prelude::GlobalEntropy;
use rand_core::RngCore;
fn print_random_value(mut rng: GlobalEntropy<WyRand>) {
println!("Random value: {}", rng.next_u32());
}
Forking RNGs
For seeding Entropy
s from a global source, it is best to make use of forking instead of generating the seed value directly. GlobalEntropy
can only exist as a singular instance, so when forking normally, it will always fork as Entropy
instances.
use bevy_ecs::prelude::*;
use bevy_prng::WyRand;
use bevy_rand::prelude::{GlobalEntropy, ForkableRng};
#[derive(Component)]
struct Source;
fn setup_source(mut commands: Commands, mut global: GlobalEntropy<WyRand>) {
commands
.spawn((
Source,
global.fork_rng(),
));
}
Entropy
s can be seeded/forked from other Entropy
s as well.
use bevy_ecs::prelude::*;
use bevy_prng::WyRand;
use bevy_rand::prelude::{Entropy, ForkableRng};
#[derive(Component)]
struct Npc;
#[derive(Component)]
struct Source;
fn setup_npc_from_source(
mut commands: Commands,
mut q_source: Single<&mut Entropy<WyRand>, (With<Source>, Without<Npc>)>,
) {
for _ in 0..2 {
commands
.spawn((
Npc,
q_source.fork_rng()
));
}
}
Features
bevy_reflect
- Enables reflection support for allbevy_rand
types. Enabled by default.std
- Enables support forstd
environment, allows enablingstd
specific optimisations forrand_chacha
and more. Enabled by default.thread_local_entropy
- EnablesThreadLocalEntropy
, overridingSeedableRng::from_entropy
implementations to make use of thread local entropy sources for faster PRNG initialisation. Requiresstd
environments so it enables thestd
feature. Enabled by default.serialize
- EnablesSerialize
andDeserialize
derives. Enabled by default.rand_chacha
- This enables the exporting of newtypedChaCha*Rng
structs, for those that want/need to use a CSPRNG level source.rand_pcg
- This enables the exporting of newtypedPcg*
structs fromrand_pcg
.rand_xoshiro
- This enables the exporting of newtypedXoshiro*
structs fromrand_xoshiro
. It also exports a remote-reflected version ofSeed512
so to allow setting upXoshiro512StarStar
and so forth.wyrand
- This enables the exporting of newtypedWyRand
fromwyrand
, the same algorithm in use withinfastrand
/turborand
.experimental
- This enables any unstable/experimental features forbevy_rand
. Currently, this does nothing at the moment.wasm_js
- This enables thegetrandom
WASM backend, though doesn't makegetrandom
use it. That requires extra steps outlined here.compat
- This enables the old v0.6RngCore
trait implementation on the RNGs, providing additional compatibility with other crates that haven't yet upgraded to the latestrand_core
/rand
versions. Currently enabled by default in order to supportbevy_math
, which is still usingrand
v0.8.
Supported Versions & MSRV
bevy_rand
uses the same MSRV policy as bevy
.
bevy |
bevy_rand |
---|---|
v0.16 | v0.10 - v0.11 |
v0.15 | v0.8 - v0.9 |
v0.14 | v0.7 |
v0.13 | v0.5 - v0.6 |
v0.12 | v0.4 |
v0.11 | v0.2 - v0.3 |
v0.10 | v0.1 |
The versions of rand_core
/rand
that bevy_rand
is compatible with is as follows:
bevy_rand |
rand_core |
rand |
getrandom |
compat feature |
---|---|---|---|---|
v0.10 -> v0.11 | v0.9 | v0.9 | v0.3 | ✅ (supports rand_core v0.6) |
v0.1 -> v0.9 | v0.6 | v0.8 | v0.2 | ❌ |
Migrations
Notes on migrating between versions can be found here.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Dependencies
~11–17MB
~233K SLoC