This Week in Bevy

What happened this week in the Bevy Engine ecosystem

Links

Custom Cursors, Picking, and Space games

2024-08-19

A PR for an implementation of Required Components went up this week. If you have crates that will be affected and are interested in the ongoing Next Generation Scene/UI work then this is an important PR to check out.

This week we see a number of quality-of-life improvements as well as great new lands like custom cursors. Other work merged this week feels like groundswell work than will make for a great 0.15 release.

We also see some interesting crates this week such as bevy_transform_interpolation which aid the use of FixedTimesteps as well as some crates that slipped from last week's issue like leafwing-input-manger 0.15.

Custom Cursors

custom cursors

#14284 added custom cursors! In the updated window_settings example you can see a number of different cursors including the Bevy Logo as a cursor, which you can tell is a cursor in this image as it extends over the edge of the application.

try_insert

Inserting components gets a boost this week with #14646 and #14787 which added panicking and non-panicking variants of insert_if_new.

insert_if_new will attempt to insert a component, and fail if the component already exists on the Entity. This is particularly interesting when Bundles have duplicate components like inserting a PbrBundle onto an entity with a SpatialBundle.

EntityCommands.trigger

#14752 adds a function to EntityCommands to trigger observer events for the particular entity you're working with.

Mesh2d Improvements

mesh2d

Last week we saw an opaque pass with a depth texture get added to the 2d render pipelines. This week that work was optimized by moving from SortedRenderPhase to BinnedRenderPhase in #13091 and extended with a new alpha mask phase to support transparency in #14724. More Mesh2d improvements are being tracked in #13265.

Working Groups Documentation

A new post in the Bevy Discord #working-groups channel now gives a small explanation and routes people to more information.

Working groups are the primary way that Bevy collaborates on complex changes or large tasks, and one of the best ways to get started as a Bevy contributor. These are scoped, informal groups that design, implement and review a set of changes, or help out with things like preparing releases or running jams.

Curve Crew Working Group

#14700 continues last week's work from the Curve Crew and adds a Curve trait for general interoperation. This continues work described in the Curve RFC.

bevy_mod_picking upstreaming

The newly merged picking is made usable for UI elements in #14695. This enables Entitys with the Pickable component to trigger observers that can respond to pointer events like Click for these entities.

Check out the new simple_picking example to see how its used.

.observe(
    |_click: Trigger<Pointer<Click>>,
        mut commands: Commands,
        mut meshes: ResMut<Assets<Mesh>>,
        mut materials: ResMut<Assets<StandardMaterial>>,
        mut num: Local<usize>| {
        commands.spawn(PbrBundle {
            mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
            material: materials.add(Color::srgb_u8(124, 144, 255)),
            transform: Transform::from_xyz(0.0, 0.5 + 1.1 * *num as f32, 0.0),
            ..default()
        });
        *num += 1;
    },
)

Showcase

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

primes

Prime Visualizations

showcase

Plotting prime numbers in polar coordinates. With visually pleasing twinkling animations. Inspired by this video by 3Blue1Brown.

space game

Space Game Structures

showcase

Progress on an internal grid system for structures integrated with avian2d

rubiks cube

Rubik's cube

showcase

A visualization of a rotating rubik's cube, with some additional spinny components.

space travelstar system map

Astray

showcase

Astray is a space strategy game, inspired by Sterllaris and Aurora X4 rendered in a terminal.

aggressive ai

Path of Exile style ARPG

showcase

A major refactor resulted in this Path of Exile style ARPG supporting animation. Enjoy the hyper aggressive fireball-shooting enemies.

panoplypanoply placedpanoply buildings

Panoply

showcase

Progress on Panoply: an editor built with Quill.

Panoply allows for the speed of editing of a tile game, but allows greater flexibility in tile design and placement.

Overlays and grids are reactive gizmo-like drawing primitives from quill_overlay. Tiles can be placed in the world using a series of thumbnails. The thumbnails are generated in a large scene with a single camera and a dedicated render target. Boolean operations are also supported.

sword swipe

Healing Spirit

showcase

Upgrades to animations in Healing Spirit

bot game

Bot programming game

showcase

A bot programming game after a few days of development and in a state where there's some gameplay (harvest magically regenerating rocks).

Uses:

  • Egui for UI
  • Rhai (https://rhai.rs/) as a scripting language, which is how players play
  • bevy_ecs_ldtk for tile map
hitscanweapon switching

Source inspired FPS

showcase

This Source-inspired FPS introduced a number of new features and mechanics.

  • Sprinting
  • Inventory system
  • Switchable weapon attachments
  • Hit scan firing with bullet tracers
  • Recoil (going to change the algorithm later)
  • Aim down sights
  • Aimed reloads, like in the newer Call of Duty games
moon

Space Mining Game

showcase

What is supposed to be a mining game with an excavator and destructible mountain. turned into more detailed space exploration this week, inspired by the big_space crate.

bevy_plotting

bevy_plotting

showcase

A demo of some gizmo plotting code extracted into a repo for general use. Its not available on crates.io, so either use it as inspiration or a git dependency.

// Data
let points = [
    Vec2::new(0., 0.),
    Vec2::new(1., 1.),
    Vec2::new(2., 0.5)
];
// Position & size of plot
let bounds = Rect::from_center_size(
    Vec2::ZERO,
    Vec2::splat(100.)
);

draw_gizmo_line_plot_2d_raw(
    points.iter(),
    &mut gizmos,
    bounds,
    Vec2::ZERO,
    Vec2::new(2., 1.),
    Color::WHITE,
);
mesh based rich text

Mesh based rich text

showcase

Mesh based rich text in 3d, powered by cosmic_text, with dynamic data fetching.

springspring filled

Spring: Spherical Interpolation using Numerical Gradient descent

showcase

Implementation of "Spherical Interpolation using Numerical Gradient descent" aka spring, a method of creating smooth splines between quaternions.

This starts with 8 keyframe quaternions that form a closed loop. The gradient descent doesn't work well when given too many values at once, so the authors of spring recommend gradually increasing the number of interpolation frames.

Algorithm reference (PDF)

transform interpolation

bevy_transform_interpolation

showcase

An experiment in ergonomic general-purpose Transform interpolation. Add some marker components to granularly enable interpolation for the properties you need:

use bevy::prelude::*;
use bevy_transform_interpolation::*;

// Note: Interpolation can also be enabled globally.
fn setup(mut commands: Commands) {
    // Only interpolate translation.
    commands.spawn((TransformBundle::default(), TranslationInterpolation));
    
    // Interpolate the entire transform: translation, rotation, and scale.
    commands.spawn((
        TransformBundle::default(),
        TransformInterpolationBundle::default(),
    ));
}

Now, all changes that happen to the Transform in FixedUpdate or other fixed timestep schedules will automatically be smoothed. Transform can be still be modified in any schedule like normal, no separate "gameplay transforms" needed.

This approach makes the interpolation automatically compatible with physics engines and the majority of other ecosystem libraries without any modifications.

kiwibert

kiwibert

showcase

Kiwibert is a Q*bert-inspired game built on bevy_ecs_tilemap and some leafwing-input-manager goodness for controls. Development is streamed on Twitch

sword animation

Chess animations

showcase

The author of this in-progress chess game found Bevy's 0.14 animation support to be a good fit for their project.

Crates

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

bevy_djqf

crate_release

bevy disjoint query filters (djqf) crate provides macros and a trait to generate disjoint query filters for Bevy queries. In a somewhat extreme example the following:

fn complex_system(
    a_query: Query<&mut Transform, (With<A>, Without<B>, Without<C>, Without<D>, Without<E>, Without<F>, Without<G>, ..., Without<Z>)>,
    b_query: Query<&mut Transform, (Without<A>, With<B>, Without<C>, Without<D>, Without<E>, Without<F>, Without<G>, ..., Without<Z>)>,
    ...,
    z_query: Query<&mut Transform, (Without<A>, Without<B>, Without<C>, Without<D>, Without<E>, Without<F>, Without<G>, ..., With<Z>)>,
) {
    // ...
}

can be reduced to

fn complex_system(
    a_query: Query<&mut Transform, <A as Disjoint>::Only>,
    b_query: Query<&mut Transform, <B as Disjoint>::Only>,
    ...,
    z_query: Query<&mut Transform, <Z as Disjoint>::Only>,
) {
    // ...
}

bevy_bsml

crate_release

bevy_bsml is a markup language & implementation inspired by svelte and tailwindcss.

Create your own reusable components, and handle reactivity using BsmlClasses component in systems to add/remove classes. It's built on top of bevy_ui, so you can still use bevy_ui to manually interact with the ui node or styles.

(node) {
    (text) { "hello world" }
}

bevy_serialization_extras

crate_release

A library that allows the editing of non-reflect components via wrapper components, and serialization of these components via moonshine-save

leafwing-input-manager 0.15

crate_release

A straightforward but robust input-action manager for Bevy. You can read the full release notes, but the highlights are:

  • clear separation of buttonlike, axislike and dual-axislike inputs and actions. No more wondering what it means for an analog stick to be pressed!
  • fully extensible trait-based definition of user input kinds. Ever wanted to add VR support? Touch? Electric guitar? Now you can!
  • powerful axis / dual axis processors: invert controls, scale axes, create deadzones and more!
  • fixed time step support: safely and reliably check the action values in FixedUpdate.
  • better action disabling: bug-free* support for 4 disabling actions at 4 different levels of granularity.

bevy_mod_lookat

crate_release

Rotate entities even through hierarchies:

bevy_htnp

crate_release

bevy_htnp provides Hierarchical Task Network Planning.

Hierarchical Task Networks are characterized by having a concrete set of specific primitive tasks that can be compounded into a sequence that affects the world around them. Because of bevy using ECS, individual task primitives can be modeled with a simple, and standard, bevy system. This plugin handles the heavy lifting of organizing those task primitives, loading and unloading specific components associated with those primitives, and cleaning up if something goes wrong.

bevy_gizmo_log

crate_release

bevy_gizmo_log lets you render gizmos through logging:

debug!(gizmo = arrow(Vec3::ZERO, Vec3::ONE, RED));
dogoap

Dogoap Initial Release - Data-Oriented GOAP for Bevy

crate_release

Dogoap is Data-oriented, Goal-oriented Action Planning for Bevy. The crate sits somewhere between "utility AI" and "Hierarchical Task Networks".

The project has two crates:

  1. dogoap: a data-oriented GOAP planning library
  2. bevy_dogoap: Bevy library that integrates dogoap with Bevy

Why would you use dogoap?

  • If you have NPCs that have to perform tasks that depend on each other
    1. Move to A
    2. pickup item X
    3. move to B
    4. drop item X
  • If you want NPCs to be able to improvise themselves to how to reach a goal (aka "emergent behavior"), after you setup the actions

Live demonstration can be found here: https://victorb.github.io/dogoap/

The first release is an MVP, so if you try it out be sure to share feedback with the crate author.

bevy_simple_text_input 0.9

crate_release

bevy_simple_text_input gains a few features in 0.9 including integration with Observers, new navigation shortcuts, and improvements to multiple active input support.

csgcsg

brusher v0.1.0

crate_release

Brusher is a engine-agnostic Constructive Solid Geometry crate with a game dev focus.

Brusher started as a port of csg.js and the API is heavily inspired by Hammer, Trenchboom, GTK Radiant, etc. Eventually, it will be a full backend API that you could use to build a level editor. And if you understand those editors you should be able to grasp this API pretty easily.

Features

  • Boolean Operations: union, intersect, subtract
  • Knife Operation: slice solids with planes, good for bevels
lightyear

lightyear 0.17.0

crate_release

Lightyear is a full-featured client-server networking library. 0.17 introduces:

Added rollback for non-networked components Previously, only components that were networked could be affected by rollback. However there's plenty of cases where you might want to rollback non-networked client components: for example animations or sounds. You can now call app.add_rollback::<C>() to enable rollback for a non-networked component.

Seamless entity mapping Previously, entity-mapping was only done on the receiver. (i.e. server spawns E1, sends it to the client who spawns E2 and maintains a mapping from E1 to E2). The mapping wasn't applied on the send-side, which meant that the client had to map the entity manually from E2 to E1 if they wanted to send a message about E2. Entity mapping is now correctly applied in all directions, so you don't need to worry about it anymore.

Introducing authority transfer Lightyear now has the concept of Authority: the peer (client or server) that is simulating the entity and sending replication updates for it. Only one peer can have authority over an entity at any given time.

The server can freely transfer authority over an entity to other peers with the EntityCommands::transfer_authority(new_owner) command. The Replicate bundles automatically provide you with authority over the entity you spawn; make sure to remember to update them if you're just adding Replicate on the server to re-broadcast a client-authoritative entity to other clients.

In the demo video, the authority that simulates the ball keeps getting swapped as the ball gets close to players.

tiny_bail 0.2

crate_release

"Bailing" is defined by this tiny_bail as an error-handling pattern that takes the middle path between unwrap and ?:

  • Compared to unwrap: Bail will return, continue, or break instead of panicking.
  • Compared to ?: Bail will log or ignore the error instead of propagating it.

tiny_bail tries to optimize the act of writing let-else conditions like this:

let Ok(x) = query.get_single() else {
    warn!("query requires exactly one result");
    return;
}

using macros

*or_return!(list.last_mut()) += 1;

tiny_bail 0.2 adds support for break variation macros.

bevy_mod_reqwest

crate_release

bevy_mod_reqwest helps when trying to use reqwest with bevy, without having to deal with async stuff, and it works on both web and and native.

It now allows reacting to errors of the http requests using observer-style callback patterns

    client
        // Sends the created http request
        .send(reqwest_request)
        // The response from the http request can be reached using an observersystem
        .on_response(|trigger: Trigger<ReqwestResponseEvent>| {
            let response = trigger.event();
            let data = response.as_str();
            let status = response.status();
            // let headers = req.response_headers();
            bevy::log::info!("code: {status}, data: {data:?}");
        })
        // In case of request error, it can be reached using an observersystem
        .on_error(|trigger: Trigger<ReqwestErrorEvent>| {
            let e = &trigger.event().0;
            bevy::log::info!("error: {e:?}");
        });

Devlogs

vlog style updates from long-term projects

bd103 - Bevy 4th Birthday

devlog

bd103 does amazing work on Bevy's CI systems, including benchmarks and automated feature flag testing.

Their post reflects on their journey in the Bevy developer community.

ThierryBerger - Bevy's 4th Birthday

devlog

Thierry is a Bevy contributor with a Unity and mobile development background. They maintain bevy_awesome_prod which is a curated list of production Bevy projects.

Their Bevy 4th Birthday post addresses the future, the community, and the Bevy project.

Educational

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

corCTF 2024 cybersecurity capture-the-flag with Bevy

educational

The recent corCTF 2024 cybersecurity capture-the-flag competition had a reverse-engineering challenge featuring a Bevy game called corMine. This post dives into reverse-engineering Bevy including how Bevy programs get optimized by the Rust compiler.

Detects default Handle in Bevy

educational

An article about how you can detect not-initialized assets in Bevy like TextureAtlas::default() or Texture::default()

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