Skip to content

Commit

Permalink
feat: Simplified dependency/feature options
Browse files Browse the repository at this point in the history
  • Loading branch information
Bluefinger committed Oct 21, 2023
1 parent 73ba917 commit 7e7f13d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 9 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down Expand Up @@ -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"]
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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::*;
Expand All @@ -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

Expand Down
5 changes: 5 additions & 0 deletions bevy_prng/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
19 changes: 19 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

0 comments on commit 7e7f13d

Please sign in to comment.