Bevy 0.19 发布,BSN 场景系统让游戏代码从 100 行缩到 10 行
- 免费干货
- 13小时前
- 15热度
- 0评论
261 位贡献者,1185 个 PR,一个小版本迭代。
这是 Bevy 0.19 交出来的成绩单。这个 Rust 游戏引擎在 GitHub 上已经快 4 万 Star 了,在开源游戏引擎圈子里,妥妥算是最活跃的那一档。
不过说实话,这次更新最让我震惊的,还真不是渲染性能又翻了多少倍,也不是阴影效果有多逼真——而是一套全新的场景系统:BSN(Bevy Scene Notation)。
你猜怎么着?以前在 Bevy 里搞一个 UI 面板,加上按钮,再来几个子组件,代码动不动就 50-80 行,中间还得手动处理 AssetServer 传参、Bundle 组合、children 嵌套……现在呢?BSN 直接 10 行搞定。
我第一反应就是:没搞错吧?

BSN 是啥?一句话说清楚
BSN 的全称是 Bevy Scene Notation——听起来挺高大上的哈,说白了就是一套用来描述"场景里都有什么"的语法。
你写一个 bsn! 宏,在里面声明你的游戏对象和组件,它自己就把 ECS(Entity Component System,实体组件系统)注册、依赖注入、子实体生成这些杂活全干了。
来,看个对比感受一下。
用以前 Bundle 的方式写:
fn player(asset_server: &AssetServer) -> impl Bundle {
(
Player { score: 10, ..default() },
children! [
Sprite {
image: asset_server.load("player.png"),
..default()
}
]
)
}
fn setup(mut commands: Commands, asset_server: Res) {
commands.spawn(player(&asset_server));
}
用 BSN 写:
fn player() -> impl Scene {
bsn! {
Player { score: 10 }
Children [
Sprite { image: "player.png" }
]
}
}
fn setup(mut commands: Commands) {
commands.spawn_scene(player());
}
你看,前面那个得把 AssetServer 当参数一层层传进去,对吧?后面这个直接写个路径字符串就完事了。
区别在哪呢——BSN 内部搞了个 Template 机制。它能自动拿 "player.png" 这个字符串去加载资源、生成 Handle,根本不用你手动调用 asset_server.load()。
说实话,底层具体怎么实现的我也没完全吃透……但用起来是真的爽。
一个游戏场景的代码量从 100 行降到 10 行
再丢一个例子,这个比较猛。
假设你有个 UI 按钮,点了打印日志。旧版 Bevy 写法有多啰嗦呢——我老觉得 Bevy 的 UI 代码跟写配置文件似的,太折磨了。
旧方式——手动传参 + Bundle + 事件监听:
fn spawn_button(commands: &mut Commands, asset_server: &AssetServer) {
commands.spawn((
Button,
Node {
width: Val::Px(100.),
height: Val::Px(50.),
..default()
},
children! [
Text(TextStyle {
font: asset_server.load("fonts/Noto.ttf"),
font_size: 16.,
..default()
})
],
On::<Pointer>::run(|_| {
info!("button pressed!");
}),
));
}
BSN 写法:
fn button() -> impl Scene {
bsn! {
Button
Node { width: px(100), height: px(50) }
Children [
Text("Click Me")
]
on(|_: On<Pointer>| info!("button pressed!"))
}
}
你看,一个是手动一个个管依赖,一个直接声明式标记就完事了。这差别就好比你之前得自己劈柴生火,现在啪一下打开燃气灶。
而且 BSN 还支持一种叫可组合补丁场景(Composable Patches)的东西。简单说就是写个基础按钮,后面直接在它上面覆盖改:
fn base_button() -> impl Scene {
bsn! { Button Node { width: px(100), height: px(50) } }
}
fn red_button() -> impl Scene {
bsn! {
base_button()
Node { background_color: RED }
}
}
说实话,一开始我没搞懂作者为啥要这么设计。后来我猜啊,八成是为了配合他们马上要出的 Bevy Editor——到时候你在编辑器里拖拖拽拽搞场景,底层导出就是 BSN 文件,然后代码里直接 patch 一下就覆盖掉了。这个思路,有点东西。
BSN能干的事可不止这些
说实话,这个系统还有几个功能挺让我意外的:
- 实体引用语法——用类似
#Player1这种名字给实体打标记,场景里随便哪个地方都能直接引用它,还能定义图结构 - 自动缓存:给场景路径加个
:前缀,多实例化同一个场景的时候只解析一次,后面都走缓存 - 事件观察器——直接在
bsn!里面绑on()回调就行,不用额外写一个系统去处理,省事 - 内联资源:像
asset_value(Cuboid::new(1., 1., 1.))这样直接在场景里塞资源,不用先往 Assets 里塞再拿 Handle 去取,你说方便不方便
让我觉得最离谱的就是那个缓存机制。
你想啊,做一个 MMORPG,要刷 1000 个 NPC。每个 NPC 的场景里还套着武器、装备、AI 行为树什么的。以前的做法是什么?遍历 1000 次,每次都从头解析一遍,性能直接爆炸。现在呢?场景路径前面加个 :,完事。后续再实例化同样的场景,它自动走缓存,只 patch 覆盖差异化那一部分。
压缩率这块——算了,光说没用,你上手跑一跑就知道了。真的,跑起来帧率曲线就说明一切。

不只是 BSN:0.19 版本还有哪些硬货
BSN 确实是最抢眼的,不过话说回来,这个版本其他更新也挺能打的:
Contact Shadows(接触阴影) 以前 Bevy 自带的阴影嘛……能用,但也就是能用的水平,谈不上多好看。0.19 加入了 Contact Shadows,物体接触的边缘会多出很细腻的暗部细节。关键是不需要开光线追踪,帧率基本没啥损耗。我拿开关对比了一下,观感差距……怎么说呢,大概就是"手机随手拍 vs 单反认真拍"的感觉。
Text Input(文本输入) Bevy UI 终于有了原生的文本输入组件 EditableText。你想想看,之前想在 UI 里搞个输入框,要么自己造轮子写插件,要么去绑系统级输入,折腾得够呛。现在官方直接支持了,是不是省心多了?
Rectangular Area Lights(矩形面光源) 做室内场景或者产品展示的朋友看过来。普通点光源打出来的光太"硬"太假,面光源就不一样了,出来的效果更接近真实世界那种柔和的光线过渡。老实讲,想用 Bevy 做建筑可视化的,这个功能真的可以吹爆。
Post-Processing 效果 内置了暗角(Vignette)和镜头畸变(Lens Distortion)两种后处理特效。以前想要这些效果?自己写 shader 吧。现在直接开箱即用,对吧。
Renderer 性能优化 大量渲染工作从 CPU 搬到了 GPU,GPU Driven 管线的趋势越来越明显了。大场景下帧率提升很可观,你猜怎么着?有些场景直接翻倍了都。
同类工具怎么选?
如果你在 Rust 生态里挑游戏引擎,老实讲就两个选项:Bevy 和 Fyrox。
Fyrox 最大的卖点是自带可视化编辑器,你要是看见一堆 YAML 配置文件就头大,那它可能更对你胃口。不过 Bevy 的社区活跃度和生态广度确实碾压 Fyrox——近 4 万 Star,3500+ Fork,Crates.io 上的依赖量级完全不是一个级别的。
再说说跨引擎对比——Bevy vs Godot vs Unity:
- Unity:C# 生态,商业引擎,最近收费政策闹得沸沸扬扬的,对吧
- Godot:原生场景系统做得挺成熟,GDScript 配上可视化编辑器,2D 小项目搞起来很快
- Bevy:纯 Rust 写的,ECS 架构,天生高性能,但目前没有编辑器(官方 Editor 还在开发中)
选哪个?看你到底想干嘛。快速搞个 2D 小游戏的话,Godot 上手确实快。但如果你打算用 Rust 写一个高性能、多线程、数据驱动的 3D 游戏,Bevy 基本是唯一解——而且 0.19 版本带来的 BSN 让代码量直接腰斩再腰斩,这谁顶得住啊。
Bevy 0.19 的 BSN 是什么?
BSN,全称 Bevy Scene Notation,是 0.19 版本新加的一套声明式场景描述语法。简单说就是靠 bsn! 这个宏,帮你自动搞定 ECS 实体注册、资源加载、子实体嵌套这些繁琐操作,样板代码大幅减少。
BSN 能替代旧的 Bundle 写法吗?
大部分场景下可以,特别是 UI 和场景组合这块。但底层还是 ECS 那一套,复杂的自定义系统逻辑你老老实实用传统方式写吧。
Bevy 0.19 适合新手入门 Rust 游戏开发吗?
我觉得如果你已经有点 Rust 基础,BSN 确实把门槛拉下来不少。但纯新手的话,建议先过一遍 Rust 所有权和生命周期,不然 ECS 的查询语法还是会卡得你怀疑人生……
Bevy 官网:https://bevy.org/
项目地址:https://github.com/bevyengine/bevy
写在最后
说实话,Bevy 0.19 这套 BSN 场景系统,让我对 ECS 架构"开发体验"这个方向有了不一样的看法。
之前大家聊 ECS 都在比性能——多核并行、缓存友好、数据驱动嘛。性能再猛又怎样?写代码比传统 OOP 痛苦三倍,该劝退还是劝退。不过 BSN 出现之后,感觉 ECS 的开发体验终于能跟声明式 UI 掰掰手腕了。
261 个人、1185 个 PR,这个版本真是一点点磨出来的。你猜怎么着?我可以拍胸脯讲一句:Bevy 0.19,值得你花一个下午把你的游戏场景逻辑重写一遍。
转自:https://mp.weixin.qq.com/s/E-IADd9xVDER_-Tr2mNN6g