15个版本 (8个破坏性更新)
0.9.0 | 2024年7月4日 |
---|---|
0.8.2 | 2024年2月24日 |
0.7.0 | 2023年11月4日 |
0.6.0 | 2023年7月10日 |
0.2.0 | 2022年7月30日 |
#172 in 游戏开发
每月650次下载
在 3 个crate 中使用
47KB
591 行
bevy_turborand
一个为Bevy游戏引擎启用随机数生成的插件,基于turborand
构建。实现了Bevy的确定性RNG RFC中的想法。
turborand
的内部实现使用Wyrand,这是一个简单快速的生成器,但不是加密安全的,以及ChaCha8,这是一个加密安全的生成器,经过调整以进行8轮ChaCha算法,以提高吞吐量而不牺牲太多安全性,如Too Much Crypto论文中所述。
示例
use bevy::prelude::*;
use bevy_turborand::prelude::*;
#[derive(Debug, Component)]
struct Player;
fn setup_player(mut commands: Commands, mut global_rng: ResMut<GlobalRng>) {
commands.spawn((
Player,
RngComponent::from(&mut global_rng)
));
}
fn do_damage(mut q_player: Query<&mut RngComponent, With<Player>>) {
let mut rng = q_player.single_mut();
println!("Player attacked for {} damage!", rng.u32(10..=20));
}
fn main() {
App::new()
.add_plugins(RngPlugin::default())
.add_systems(Startup, setup_player)
.add_systems(Update, do_damage)
.run();
}
确定性RNG
为了使您的游戏/应用程序具有确定性,必须对Rng
进行初始化。可以给GlobalRng
和RngPlugin
提供一个种子,然后设置内部PRNG以表现出确定性。无需手动初始化每个RngComponent
,只要初始化了GlobalRng
,就可以直接从全局实例创建RngComponent
,将内部Rng克隆到自身,这给它提供了一个随机但确定的种子。这允许在RngComponent
之间有更好的随机状态,同时仍然有一个确定性的应用程序。
系统还需要正确排序才能保证确定性。然而,系统并不需要像线性路径一样严格排序。只有访问特定集合的 RngComponent
的相关系统需要排序。那些无关的系统可以并行运行,仍然能得到确定性的结果。因此,选择带有 RngComponent
的 Player
实体的系统都应该相互排序,但选择带有 RngComponent
的 Item
实体且从不与 Player
交互的系统,无需与 Player
系统排序,只需它们自己之间排序。
要查看此示例,请查看项目的测试用例 链接,了解如何利用确定性进行随机系统的测试。
支持版本
bevy_turborand |
bevy |
---|---|
v0.9.0-rc.1 | v0.14.0-rc.4 |
v0.8 | v0.13 |
v0.7 | v0.12 |
v0.6 | v0.11 |
v0.5 | v0.10 |
v0.4 | v0.9 |
v0.2, v0.3 | v0.8 |
v0.1 | v0.7 |
bevy_turborand
的 MSRV 与 bevy
相同,因此始终使用最新的 Rust 编译器版本。
从 0.2 版本迁移到 0.3 版本的指南
由于 API 的重构,turborand 0.6 版本有很多破坏性更改。大部分是 turborand
和 bevy_turborand
的内部更改,而 bevy_turborand
默认公开了新特性,所以现有代码应该大致正常工作,除了以下内容:
RngComponent
上的from_global
已不存在。取而代之的是,在RngComponent
和ChaChaRngComponent
上有From
实现,覆盖了更多用例,其中可以使用引用、资源甚至另一个组件来初始化新的RngComponent
等。这使得它在源的选择上更加灵活。只需使用RngComponent::from
即可。- 不再接受 Option 参数的
new
函数。方法被分割在new
(用于不带种子初始化,因此获取随机种子)和with_seed
(用于带种子值初始化,适用于组件和资源)之间。 RngPlugin
现在采用构建器模式进行初始化。默认创建一个不带种子的默认状态,然后使用with_rng_seed
和with_chacha_seed
将种子值应用到插件上,然后使用这些种子值初始化全局 RNG 资源。请参阅文档以了解示例。bevy_turborand
现在有一些功能标志,除了始终提供的新特性之外,其他所有内容都位于功能标志之后。例如,基于wyrand
的结构(如RngComponent
等)位于wyrand
标志之后,该标志默认启用。为了获得更高质量的熵源(尽管它会更慢),chacha
标志提供 ChaCha8 算法提供的 RNG,例如ChaChaRngComponent
。当启用wyrand
或chacha
时,RngPlugin
可用。否则,现有的标志如rand
启用 rand crate 兼容层,而serialize
用于 serde derive。
从 0.3 版本迁移到 0.4 版本的指南
bevy_turborand
已升级到 turborand
0.8,带来了一些重大的 API 破坏性更改。某些特性不再公开,因为它们是内部实现细节。主要变化是,ChaChaRng
不再由 Vec
缓存熵,而是切换到对齐数组以提高生成吞吐量,这略微牺牲了初始化性能和结构体大小。这意味着当 RNG 首次生成数字时,不需要单次堆分配。这次重构还改变了 ChaChaRng
的序列化方式,因此 bevy_turborand
0.4 与先前序列化的数据不兼容。
此外,TurboCore
RNG 的旧 Clone
行为已更改,因此 .clone()
现在在原始实例和克隆实例之间保持状态。旧的行为现在作为 ForkableCore
特性存在,具有 .fork()
方法,该方法会修改原始实例的状态,以便为分叉实例推导新的随机状态。因此,RngComponent
和 ChaChaRngComponent
现在可以实现 Clone
。
从 0.4 迁移到 0.5 的指南
bevy_turborand
已升级到 turborand
0.10,引入了更多支持迭代器的样本/样本多次方法,partial_shuffle
,以及关于稳定索引的重大更改,样本/洗牌方法使用新的 index
方法。 index
允许样本在平台之间稳定,尽管它目前针对 64 位系统进行了优化。所有样本/洗牌方法现在都使用 index
,这意味着 bevy_turborand
在不同平台之间将是确定的,例如 wasm32
和 x86-64
有相同的输出。唯一不受此影响的方法是 usize
。
ChaChaRngComponent
也因内部 ChaChaRng
源代码的改变而具有不同的输出,这也改变了它的序列化方式。
许可证
根据您的要求,受以下任一许可证的许可:
- Apache License,版本 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
依赖项
~22MB
~408K SLoC