Tainted \\ Coders

Metadata Components

Last updated:

When spawning tuple bundles it can sometimes difficult to identify their purpose:

// What am I?
commands.spawn((
    Position::new(),
    Velocity::new()
))

If we used an inspector such as the bevy-inspector-egui then it would be hard to identify which component is what just by their component list.

Remember that even when we use a named bundle, the bundle itself is ephemeral and only the components will remain afterwards.

One common alternative is to create components such as Player that can make querying easier. But some components won’t be queried and many component types can clutter up our code base.

So it can be useful to create a Name component that makes this debugging much easier:

commands.spawn((
    Name::new("Player"),
    Position::new(),
    Velocity::new()
))

Another useful metadata component is to create components that tag entities to be cleaned up at specific points in our apps.

commands.spawn((
    Name::new("Player"),
    Position::new(),
    Velocity::new(),
    CleanupOnGameExit
))

This can be used in combination with generic systems to trigger a cleanup for multiple component types:

use bevy::{
    prelude::*,
    ecs::component::Component,
};

#[derive(Component)]
struct CleanupOnGameExit;

#[derive(Debug, Clone, Eq, PartialEq, Hash, Default, States)]
enum AppState {
    #[default]
    MainMenu,
    InGame,
    Paused,
}


impl AppState {
    fn next(&self) -> Self {
        match *self {
            AppState::MainMenu => AppState::InGame,
            AppState::InGame => AppState::Paused,
            AppState::Paused => AppState::InGame
        }
    }
}

fn cleanup_system<T: Component>(
    mut commands: Commands,
    q: Query<Entity, With<T>>,
) {
    for e in q.iter() {
        commands.entity(e).despawn_recursive();
    }
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<AppState>()
        .add_systems(
            OnExit(AppState::InGame),
            cleanup_system::<CleanupOnGameExit>
        );
}

Read more