diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b5cf34..64feea9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,7 +70,7 @@ jobs: rustup override set nightly cargo miri setup - name: Test with Miri - run: cargo miri test --all-features + run: cargo miri test env: # -Zrandomize-layout makes sure we dont rely on the layout of anything that might change RUSTFLAGS: -Zrandomize-layout @@ -102,4 +102,4 @@ jobs: run: rustup update ${{ env.MSRV }} --no-self-update && rustup default ${{ env.MSRV }} - name: Run cargo check id: check - run: cargo check --all-features + run: cargo check diff --git a/Cargo.toml b/Cargo.toml index 6bf9e8d..dc887cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,10 @@ rust-version = "1.70.0" default = ["serialize", "thread_local_entropy"] thread_local_entropy = ["dep:rand_chacha"] serialize = ["dep:serde", "rand_core/serde1"] +rand_chacha = ["bevy_prng/rand_chacha"] +rand_pcg = ["bevy_prng/rand_pcg"] +rand_xoshiro = ["bevy_prng/rand_xoshiro"] +wyrand = ["bevy_prng/wyrand"] [workspace] members = ["bevy_prng"] @@ -51,3 +55,8 @@ getrandom = { version = "0.2", features = ["js"] } [[example]] name = "turn_based_game" path = "examples/turn_based_game.rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/README.md b/README.md index 32fe4ed..a64505a 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,19 @@ Bevy Rand provides forking via `ForkableRng`/`ForkableAsRng`/`ForkableInnerRng` ## Using 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`,`bevy_prng`, 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_prng`, enable the feature representing the newtypes from the `rand_*` crate you want to use. +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. The examples below use `bevy_prng` directly for purposes of clarity. +#### `bevy_rand` feature activation ```toml rand_core = "0.6" -bevy_rand = "0.3" -bevy_prng = { version = "0.1", features = ["rand_chacha"] } +bevy_rand = { version = "0.4", features = ["rand_chacha"] } +``` + +#### `bevy_prng` feature activation +```toml +rand_core = "0.6" +bevy_rand = "0.4" +bevy_prng = { version = "0.2", features = ["rand_chacha"] } ``` ### Registering a PRNG for use with Bevy Rand @@ -153,12 +160,20 @@ The examples provided as integration tests in this repo demonstrate the two diff ## Selecting and using PRNG Algorithms -All supported PRNGs and compatible structs are provided by `bevy_prng`, so the easiest way to work with `bevy_rand` is to import the necessary algorithm from `bevy_prng`. Simply activate the relevant features in `bevy_prng` to pull in the PRNG algorithm you want to use, and then import them like so: +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: ```toml -bevy_prng = { version = "0.1", features = ["rand_chacha", "wyrand"] } +bevy_rand = { version = "0.4", features = ["rand_chacha", "wyrand"] } +``` +```rust ignore +use bevy::prelude::*; +use bevy_rand::prelude::{ChaCha8Rng, WyRand}; +``` +or +```toml +bevy_rand = "0.4" +bevy_prng = { version = "0.2", features = ["rand_chacha", "wyrand"] } ``` - ```rust ignore use bevy::prelude::*; use bevy_rand::prelude::*; @@ -169,12 +184,16 @@ Using PRNGs directly from the `rand_*` crates is not possible without newtyping, As a whole, which algorithm should be used/selected is dependent on a range of factors. Cryptographically Secure PRNGs (CSPRNGs) produce very hard to predict output (very high quality entropy), but in general are slow. The ChaCha algorithm can be sped up by using versions with less rounds (iterations of the algorithm), but this in turn reduces the quality of the output (making it easier to predict). However, `ChaCha8Rng` is still far stronger than what is feasible to be attacked, and is considerably faster as a source of entropy than the full `ChaCha20Rng`. `rand` uses `ChaCha12Rng` as a balance between security/quality of output and speed for its `StdRng`. CSPRNGs are important for cases when you _really_ don't want your output to be predictable and you need that extra level of assurance, such as doing any cryptography/authentication/security tasks. -If that extra level of security is not necessary, but there is still need for extra speed while maintaining good enough randomness, other PRNG algorithms exist for this purpose. These algorithms still try to output as high quality entropy as possible, but the level of entropy is not enough for cryptographic purposes. These algorithms should **never be used in situations that demand security**. Algorithms like `WyRand` and `Xoshiro256StarStar` are tuned for maximum throughput, while still possessing _good enough_ entropy for use as a source of randomness for non-security purposes. It still matters that the output is not predictable, but not to the same extent as CSPRNGs are required to be. +If that extra level of security is not necessary, but there is still need for extra speed while maintaining good enough randomness, other PRNG algorithms exist for this purpose. These algorithms still try to output as high quality entropy as possible, but the level of entropy is not enough for cryptographic purposes. These algorithms should **never be used in situations that demand security**. Algorithms like `WyRand` and `Xoshiro256StarStar` are tuned for maximum throughput, while still possessing _good enough_ entropy for use as a source of randomness for non-security purposes. It still matters that the output is not predictable, but not to the same extent as CSPRNGs are required to be. PRNGs like `WyRand` also have small state sizes, which makes them take less memory per instance compared to CSPRNGs like `ChaCha8Rng`. ## Features - **`thread_local_entropy`** - Enables `ThreadLocalEntropy`, overriding `SeedableRng::from_entropy` implementations to make use of thread local entropy sources for faster PRNG initialisation. Enabled by default. - **`serialize`** - Enables `Serialize` and `Deserialize` derives. Enabled by default. +- **`rand_chacha`** - This enables the exporting of newtyped `ChaCha*Rng` structs, for those that want/need to use a CSPRNG level source. +- **`rand_pcg`** - This enables the exporting of newtyped `Pcg*` structs from `rand_pcg`. +- **`rand_xoshiro`** - This enables the exporting of newtyped `Xoshiro*` structs from `rand_xoshiro`. It also reexports `Seed512` so to allow setting up `Xoshiro512StarStar` and so forth without the need to pull in `rand_xoshiro` explicitly. +- **`wyrand`** - This enables the exporting of newtyped `WyRand` from `wyrand`, the same algorithm in use within `fastrand`/`turborand`. ## Supported Versions & MSRV diff --git a/bevy_prng/Cargo.toml b/bevy_prng/Cargo.toml index 1d985cb..6b37fdb 100644 --- a/bevy_prng/Cargo.toml +++ b/bevy_prng/Cargo.toml @@ -31,3 +31,8 @@ rand_chacha = { version = "0.3", optional = true } wyrand = { version = "0.1", optional = true } rand_pcg = { version = "0.3", optional = true } rand_xoshiro = { version = "0.6", optional = true } + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/src/prelude.rs b/src/prelude.rs index 4482719..58a9c7f 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -2,3 +2,22 @@ pub use crate::component::EntropyComponent; pub use crate::plugin::EntropyPlugin; pub use crate::resource::GlobalEntropy; pub use crate::traits::{ForkableAsRng, ForkableInnerRng, ForkableRng}; +#[cfg(feature = "wyrand")] +#[cfg_attr(docsrs, doc(cfg(feature = "wyrand")))] +pub use bevy_prng::WyRand; + +#[cfg(feature = "rand_chacha")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_chacha")))] +pub use bevy_prng::{ChaCha12Rng, ChaCha20Rng, ChaCha8Rng}; + +#[cfg(feature = "rand_pcg")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_pcg")))] +pub use bevy_prng::{Pcg32, Pcg64, Pcg64Mcg}; + +#[cfg(feature = "rand_xoshiro")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_xoshiro")))] +pub use bevy_prng::{ + Xoroshiro128Plus, Xoroshiro128PlusPlus, Xoroshiro128StarStar, Xoroshiro64Star, + Xoroshiro64StarStar, Xoshiro128Plus, Xoshiro128PlusPlus, Xoshiro128StarStar, Xoshiro256Plus, + Xoshiro256PlusPlus, Xoshiro256StarStar, Xoshiro512Plus, Xoshiro512PlusPlus, Xoshiro512StarStar, +};