This Week in Bevy

What happened this week in the Bevy Engine ecosystem

Links

Spooky Jam, Game Boy Jam, and 501c3 status

2024-09-30

The Bevy Spooky Jam is an unofficial Bevy game jam for the spooky season! It starts on October 4th and runs until October 21st. Bevy Spooky Jam is a casual game jam that the creator would like to turn into a monthly game jam if there's enough interest.

We also see a number of game-boy game jam submissions this week and a release of a new navigation mesh crate.

The Bevy Foundation is now a 501(c)(3) Public Charity!

501c3

The Bevy Foundation's Federal 501(c)(3) status in the US was announced this week, which means donations are income-tax-exempt for the Foundation, tax-deductible for donators in the US, and employer donation-matching programs become applicable. Check to see if your employer will match your donation!

Bevy Remote Protocol

As part of the ongoing Editor work, the Bevy Remote Protocol landed for the first time in #14880. The Bevy Remote Protocol, or BRP, provides a JSON rpc-style interface for querying running games. This currently allows you to query for entities with specific components and more including:

  • querying components, returning entities and components that match
  • spawning new entities with components
  • destroying an entity
  • inserting or removing components from an entity
  • reparenting entities

Required Components

The Required Components feature enables requiring certain components to also be added when adding specific other components.

#14964 migrates bevy_transform while #15474 migrates Visibility.

This means that previously where you would spawn a Bundle:

commands.spawn(TransformBundle::IDENTITY)

You now only need to add the Transform component, and required components like GlobalTransform will be automatically added.

commands.spawn(Transform::IDENTITY)

There's a long list of Required Components refactors like this that are still being debated or implemented, so expect more of this kind of refactor when 0.15 comes around. Notably the concept of Bundles is not going away and these refactors are mostly about porting engine-level code.

Generic Animation

#15282 introduces the ability for AnimationClips to animate arbitrary properties.

An example AnimatableProperty implementation for the font size of a text section is included in the PR description:

 #[derive(Reflect)]
 struct FontSizeProperty;

 impl AnimatableProperty for FontSizeProperty {
     type Component = Text;
     type Property = f32;
     fn get_mut(component: &mut Self::Component) -> Option<&mut Self::Property> {
         Some(&mut component.sections.get_mut(0)?.style.font_size)
     }
 }

run_system

In #14920 a new run_system_cached API allows the running of systems (like one-shot systems) without first creating/saving the SystemId, providing some nice ergonomic improvements.

Function Reflection

While #13152 added function reflection, it didn't really make functions reflectable. Instead, it made it so that they can be called with reflected arguments and return reflected data. But functions themselves cannot be reflected.

#15205 enables DynamicFunction to actually be reflected.

disqualified

The disqualified was initiated by a community member and the crate was transferred into the Bevy maintainership this week. It was used in Bevy in #15372.

Lazily shortens a "fully qualified" type name to remove all module paths. The short name of a type is its full name as returned by [core::any::type_name], but with the prefix of all paths removed. For example, the short name of alloc::vec::Vec<core::option::Option<u32>> would be Vec<Option<u32>>. Shortening is performed lazily without allocation.

bevy_ui scrolling

#15291 implements scrolling for bevy_ui! The implementation uses a new ScrollPosition component.

System input references

#15184 introduces the ability to create systems that take references as input. This means that when piping or running systems, you can now use exclusive or shared references, as seen here.

let mut world = World::new();

let mut value = 2;

// Currently possible:
fn square(In(input): In<usize>) -> usize {
    input * input
}
value = world.run_system_once_with(value, square);

// Now possible:
fn square_mut(InMut(input): InMut<usize>) {
    *input *= *input;
}
world.run_system_once_with(&mut value, square_mut);

// Or:
fn square_ref(InRef(input): InRef<usize>) -> usize {
    *input * *input
}
value = world.run_system_once_with(&value, square_ref);

Non-consuming trigger functions on World

#14894 introduces the ability to trigger observers for a specific event while also reacting to the changes the observer makes to the event. This involves passing an exclusive reference to the Event as an argument in the new World::trigger_ref function, which will then run observers watching that event before returning to the code location that called trigger_ref and allowing it to use the modified event data.

This is an established pattern in applications like the Paper Minecraft server, where a listener can modify event data.

Notably this is a function on World, not Commands.

QuerySingle

#15476 adds a new SystemParam currently called Single (but called QuerySingle in this PR), which is valid if exactly 1 matching entity exists. A variant, written as Option<Single<D, F>>, is valid if 0 or 1 matching entities exists.

A new example, ecs/fallible_params, shows off the new functionality.

fn move_pointer(
    // `Single` ensures the system runs ONLY when exactly one matching entity exists.
    mut player: Single<(&mut Transform, &Player)>,
    // `Option<Single>` ensures that the system runs ONLY when zero or one matching entity exists.
    enemy: Option<Single<&Transform, (With<Enemy>, Without<Player>)>>,
    time: Res<Time>,
) {
...

Alice's Merge Train is a maintainer-level view into active PRs, both those that are merging and those that need work.

Showcase

Bevy work from the #showcase channel in Discord and around the internet. Use hashtag #bevyengine.

building-building systembuilding-building system floors

Building building

showcase

A Building building system coming together, now complete with floors.

jarljarl ui

Jarl UI

showcase

Showing off some Jarl UI which was built with vanilla Bevy UI and some tweens

varg

Varg

showcase

Varg got game menus with localization support, various resolution and scaling options, as well as a tentative title/logo. In RTL languages the UI is reversed and so are the key bindings.

bevy no_std

bevy no_std

showcase

Bevy no_std is making progress and here we see bevy_app and bevy_ecs working on bare-metal. This example application is running at 2fps in qemu.

architect of ruin devtools

Architect of Ruin Character Editor

showcase

The developers of Architect of Ruin are using this egui-based character editor to bring all the spine skeleton, attachment sprites, equipment, and color palettes together to test random character generation. They've already used it to build some new races out, including Hobbits and Dwarves.

sweet escapesweet escapesweet escape

Sweet Escape

showcase

Sweet Escape is a GBJAM12 entry which means game-boy style graphics and an old-school vibe.

You can also view the game in a video on YouTube

ecs scripting language

Custom ECS scripting language

showcase

A custom ECS scripting language that can now run and modify bevy's game state to move a circle around.

redeathredeath

Redeath

showcase

Redeath is a platformer on the side of Celeste made for GBJam12. Its a game with an interesting mechanic and a great gameboy-like aesthetic.

stylized earthstylized earth

Stylized Earth

showcase

This stylized rendering of Earth is slowly being turned into a game in the Discord thread.

n-body space shootern-body space shooter

37 hours in

showcase

The developer of this game is challenging themselves to make & finish small games quickly (approximately monthly). In this one, you optimize your orbital trajectory to avoid running out of fuel while defending the planet from incoming enemy ships.

endeavorendeavor

Endeavor

showcase

Endeavor is a 3D Space Adventure where you can Explore, Gather, Build and Battle your way through the unknown frontiers of deep space. The first free playtest of Endeavor is scheduled for October 14, 2024! This game started life in Bevy 0.12 in 20213 before upgrading to 0.13 and 0.14.

mercatormercatormercator

Mercator early access

showcase

Mercator is a shopkeeping game where you craft items with workers, haggle for profit, and move goods via sail (and eventually wheel) across Asia (and eventually Africa and Europe) in the third century AD. The developer is looking for early access testers, so contact them in the Discord thread if you're interested.

vleue_navigator in a house

From oxidized_navigation to vleue_navigator

showcase

Project Harmonia migrated npc navigation from oxidized_navigation to vleue_navigator this week, which also means a switch from the classic A* to Polyanya

Crates

New releases to crates.io and substantial updates to existing projects

vleue_navigator

vleue_navigator

crate_release

vleue_navigator is a navmesh crate that can integrate with Bevy and/or Avian to produce dynamic navigation meshes.

Features

  • live navmesh updates with obstacles from Bevy's AABB, Bevy's primitive shapes, avian2d obstacles, avian3d obstacles
  • easy to add new obstacles types with a trait to implement
  • layers that are connected and can be updated independently
  • layers that can overlap
  • agent radius

bevy_submerge_ui 0.1.0

crate_release

bevy_submerge_ui is a ui plugin with tailwind like capabilities for bevy.

Features

  • Nested UI components: Create hierarchical UI layouts with ease by referencing components by ID, without the need for complex child nesting.
  • Tailwind-like styling: Apply styles directly in a familiar, space-separated format for quick UI customization.
  • Scalable design: Designed for both small and large projects, allowing for modular and customizable UI layouts.
  • Custom utilities: Submerge comes with some custom styling utilities like predefined colors, text sizes, border radius, all based on tailwind css presets.
No devlogs this week

Educational

Tutorials, deep dives, and other information on developing Bevy applications, games, and plugins

lowpoly terrain

Low poly "heightmap" based terrain generation

educational

Low poly "heightmap" based terrain generation from plane meshes. Covers using noise to modify vertex positions, vertex colors, and updating normals.

Pull Requests Merged This Week
Contributing

Want to contribute to Bevy?

Here you can find two types of potential contribution: Pull Requests that might need review and Issues that might need to be worked on.

How do I contribute?

Pull Requests Opened this week

Issues Opened this week