Opens an external site in a new window
Mental Health Awareness Month
“Community”
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links
  • Profile
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links

Using egui for Bevy ECS Introspection with Macroquad Rendering 🧐 # Using egui for Bevy ECS Introspection with Macroquad Rendering 🧐 #

blurry low resolution placeholder image Using egui for Bevy ECS Introspection
  1. Home Rodney Lab Home
  2. Blog Posts Rodney Lab Blog Posts
  3. Gaming Gaming Blog Posts
<PREVIOUS POST
NEXT POST >
LATEST POST >>

Using egui for Bevy ECS Introspection with Macroquad Rendering 🧐 #

Updated 2 months ago
6 minute read
Gunning Fog Index: 6.6
Content by Rodney
blurry low resolution placeholder image Author Image: Rodney from Rodney Lab
SHARE:

👀 Using egui for Bevy ECS Introspection #

In this post, we look at using egui for Bevy Introspection with Macroquad rendering. This continues the series of recent posts, which started with adding egui DevTools to Macroquad, then added Rapier physics, units of measurement and an Entity Component system (ECS).

Here, we bring everything together, adding DevTools-like introspection to the Bevy ECS demo from the previous post. As before, the complete project code is on GitHub (link further down).

🧱 What are we Building Here? #

blurry low resolution placeholder image Using egui for Bevy ECS Introspection: A number of blue, yellow and orange bubbles are trapped at the top of the screen.  The Developer tools panel appears to contain details for all of them, with the details for just 2 or 3 scrolled into view.  The headings Entity Generation:ID 1:8 and Entity Generation:ID 1:9 are visible.  These top sections with Position, Velocity, Colour, and Radius data for their respective bubble.
Using egui for Bevy ECS Introspection: DevTools

The demo simulation, built in Rust, shows a series of coloured, floating bubbles release and float to top of the window. The bubbles subsequently get trapped at the top of the screen; filling the window, from the top down.

I employed the following tools to build the demo:

  • Macroquad — a fast, quick-to-get going on Rust tool built with game prototyping in mind;
  • Rapier — mature, pure Rust physics engine for game dev;
  • uom — a crate with applications in Aerospace for maintaining consistency in physical quantity units and helping to avoid unit errors;
  • Bevy ECS — ECS implementation from the Bevy game engine, added to this project as the stand-alone bevy_ecs crate; and
  • egui — an immediate Graphics User Interface (GUI) library for Rust (inspired, in fact, by the C++ Dear ImGui library ).

I focus on the egui integration in this post, so feel free to jump back through the series to learn more about how I put the other elements together.

⚙️ Crate Setup #

You might need to use slightly older (than the latest) versions of some crates to get everything working together. Here is my Cargo.toml, which you can use as a starting point for finding compatible versions of egui, egui-macroquad and macroquad:

Cargo.toml
toml
    
1 [package]
2 name = "macroquad-bevy-ecs-introspection"
3 version = "0.1.0"
4 edition = "2021"
5 license = "BSD-3-Clause"
6 repository = "https://github.com/rapier-example"
7 # bevy_ecs 0.15 requires MSRV 1.83
8 rust-version = "1.83"
9 description = "Macroquad Rapier ECS 🦀 Rust game dev — using bevy's 🧩 Entity Component System in a Macroquad game with Rapier physics."
10
11 [dependencies]
12 bevy_ecs = "0.15.3"
13 crossbeam = "0.8.4"
14 egui = "0.21.0"
15 egui-macroquad = "0.15"
16 macroquad = { version = "0.3.26", default-features = false }
17 rand = "0.9.0"
18 rand_distr = "0.5.1"
19 rapier2d = { version = "0.24.0", features = ["simd-stable"] }
20 uom = "0.36.0"

🔄 Update egui Introspection System #

I introduced Bevy ECS to the project in a previous Macroquad Rapier ECS post. Continuing, we need to add a couple of ECS systems for updating and rendering the egui DevTools. First up is the update_dev_tools_system in src/systems.rs:

src/systems.rs
rust
    
107 pub fn update_dev_tools_system(query: Query<(Entity, &Position, &Velocity, &CircleMesh)>) {
108 egui_macroquad::ui(|egui_ctx| {
109 egui_ctx.set_pixels_per_point(4.0);
110 egui::Window::new("Developer Tools").show(egui_ctx, |ui| {
111 ScrollArea::vertical().show(ui, |ui| {
112 CollapsingHeader::new("Bubbles")
113 .default_open(false)
114 .show(ui, |ui| {
115 for (entity, position, bubble_velocity, circle_mesh) in &query {
116 draw_ball_ui_data(ui, entity, position, bubble_velocity, circle_mesh);
117 }
118 });
119 });
120 });
121 });
122 }

Bevy ECS Queries #

Typically, for Bevy ECS, this function takes a query over ECS components as its argument (line 107). Here, the query generates a collection of all ECS entities that have Position, Velocity and CircleMesh components (essentially the bubbles). Additionally:

  • In line 109, I call set_pixels_per_point this scales up the UI. 4.0 worked for screen captures, though for general use, you will probably want something a touch lower.
  • We need a ScrollArea in the UI (line 111) to make viewing data for the dozens of balls in the simulation more practical.
  • You can iterate over the ECS entities satisfying the initial query, with a simple for loop (line 115).

Next, we look at the draw_ball_ui_data function called within that last loop.

🫧 Individual Bubble Updates #

blurry low resolution placeholder image Using egui for Bevy ECS Introspection: An orange bubble is trapped in the top, right corner of the window.  Towards the left, is the Developer Tools Panel.  This show properties for the bubble, reading Entity Generation:ID 1:0, Position x: 26.26 m, y: -0.65m, Velocity x: -0.00 m/s, y: 0.00 m/s, Colour (orange dot is displayed), Radius 0.6m
Using egui for Bevy ECS Introspection: Bubble Properties

Another advantage of using the uom crate for handling physical quantities is formatting of those values for output, which we use in the draw_ball_ui_data function (src/systems):

src/systems.rs
rust
    
48 fn draw_ball_ui_data(
49 ui: &mut Ui,
50 entity: Entity,
51 position: &Position,
52 bubble_velocity: &Velocity,
53 circle_mesh: &CircleMesh,
54 ) {
55 let m = Length::format_args(length::meter, Abbreviation);
56 let m_s = VelocityUnit::format_args(velocity::meter_per_second, Abbreviation);
57 CollapsingHeader::new(format!(
58 "Entity Generation:ID {}:{}",
59 entity.generation(),
60 entity.index()
61 ))
62 .default_open(false)
63 .show(ui, |ui| {
64 ui.horizontal(|ui| {
65 ui.label("Position");
66 ui.label(format!(
67 "x: {:.2}, y: {:.2}",
68 m.with(position.0.x),
69 m.with(position.0.y)
70 ))
71 });
72 // TRUNCATED...
73 });
74 }

Quantity Formatting #

To select preferred formatting, in lines 55 and 56, we add unit formatting for metre and metre per second quantities. These uom format args incorporate type checking, so you would get a compile-time error if you tried to format a length quantity using metres per second, for example.

Notice, in for example, in lines 67 – 70 that we can use standard Rust formatting arguments with the uom format arg to specify the precision we want position output data with. Here, the {:.2} format specifiers indicates we want to round the position values to two decimal places.

ECS Entity Generations and IDs #

ECS entities are not a lot more than an integer ID and a generation. The generation provides a mechanism for reusing IDs. For example, the first bubble spawned might have ID 0 and generation 1. If we then despawned that bubble from the ECS, the next bubble can re-use ID 0, which is now free. However, the ECS would give it a generation of 2, so it can be distinguished from the earlier one.

We access, both generation an id from the Bevy ECS Entity struct calling .generation() and .index() in lines 59 and 60.

✍🏽 Draw UI System #

The system for actually drawing the DevTools panel, using egui is a little simpler — we just need to call egui_macroquad::draw:

src/systems.rs
rust
    
124 pub fn draw_dev_tools_system() {
125 egui_macroquad::draw();
126 }

📆 Bringing it all together: ECS Schedule #

I added the two new systems to the Bevy ECS schedule, to give us some control over the order Bevy ECS runs them in (src/main.rs):

src/main.rs
rust
    
126 let mut playing_schedule = Schedule::default();
127 playing_schedule
128 .configure_sets(
129 (
130 ScheduleSet::BeforeSimulation,
131 ScheduleSet::Simulation,
132 ScheduleSet::AfterSimulation,
133 )
134 .chain(),
135 )
136 .add_systems(
137 (
138 create_ball_physics_system,
139 (
140 update_dev_tools_system,
141 draw_balls_system,
142 draw_dev_tools_system,
143 )
144 .chain(),
145 )
146 .chain()
147 .in_set(ScheduleSet::BeforeSimulation),
148 )
149 .add_systems(step_physics_engine_system.in_set(ScheduleSet::Simulation))
150 .add_systems(
151 (
152 update_balls_system,
153 spawn_new_ball_system,
154 end_simulation_system,
155 )
156 .in_set(ScheduleSet::AfterSimulation),
157 );

With Bevy ECS, schedule systems grouped into a tuple will run in parallel. Tacking .chain() onto the end of the tuple tells the ECS that you want the systems to run in series, in the order of appearance.

Please enable JavaScript to watch the video 📼

Using egui for Bevy ECS Introspection: MVP Demo

🏁 What Next? #

I have the basic, minimal DevTools panel working now. In terms of extensions and where to go next, I am considering:

  • adding a wireframe view mode, with toggle, to show/hide the Rapier colliders;
  • buttons for pausing, stepping and restarting the simulation from the dev panel tool; and
  • adding the collider properties to the panel.

Interested to know if you have some ideas on and also, what else might be a good direction to take this in. Drop a comment below, or reach out on other channels .

🗳 Poll #

Primarily, how do you use Rust Game Dev tooling?
Voting reveals latest results.

🙌🏽 Using egui for Bevy ECS Introspection: Wrapping Up #

In this post on using egui for Bevy ECS introspection, we looked at displaying Rapier physical properties with egui and Macroquad rendering. In particular, we saw:

  • code for adding egui update and draw ECS systems;
  • how you can add an egui ScrollArea to display large data collections; and
  • how you can format uom quantities for display, including rounding to a fixed number of decimal places.

I hope you found this useful. As promised, you can get the full project code on the Rodney Lab GitHub repo . I would love to hear from you, if you are also new to Rust game development. Do you have alternative resources you found useful? How will you use this code in your own projects?

🙏🏽 Using egui for Bevy ECS Introspection: Feedback #

If you have found this post useful, see links below for further related content on this site. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on X, giving me a mention, so I can see what you did. Finally, be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please consider supporting me through Buy me a Coffee.

blurry low resolution placeholder image ask Rodney X (formerly Twitter) avatar

Rodney

@askRodney

Just dropped a new blog post on using Bevy ECS with Macroquad for introspection.

Including formatting ECS quantities using physical units of measurement.

Hope you find it useful!

https://t.co/bszngNnbd0

— Rodney (@askRodney) May 29, 2024

Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on X (previously Twitter) and also, join the #rodney  Element Matrix room. Also, see further ways to get in touch with Rodney Lab. I post regularly on Game Dev as well as Rust and C++ (among other topics). Also, subscribe to the newsletter to keep up-to-date with our latest projects.

Thanks for reading this post. I hope you found it valuable. Please get in touch with your feedback and suggestions for posts you would like to see. Read more about me …

blurry low resolution placeholder image Rodney from Rodney Lab
TAGS:
RUSTGAMING
<PREVIOUS POST
NEXT POST >
LATEST POST >>

Leave a comment …

Your information will be handled in line with our Privacy Policy .

Ask for more

1 Nov 2022 — Astro Server-Side Rendering: Edge Search Site
3 Oct 2022 — Svelte eCommerce Site: SvelteKit Snipcart Storefront
1 Sept 2022 — Get Started with SvelteKit Headless WordPress

Copyright © 2020 – 2025 Rodney Johnson. All Rights Reserved. Please read important copyright and intellectual property information.

  • Home
  • Profile
  • Plus +
  • Newsletter
  • Contact
  • Links
  • Terms of Use
  • Privacy Policy
We use cookies  to enhance visitors’ experience. Please click the “Options” button to make your choice.  Learn more here.