A simple type safety solution for Bevy ECS.

Overview

🍎 Moonshine Kind

A simple type safety solution for Bevy ECS.

Overview

An Entity is a generic way to reference entities within Bevy ECS:

#[derive(Component)]
struct FruitBasket {
    fruits: Vec<Entity>
}

A problem with using entities in this way is that there is no information about the "kind" of the entity. This can result in code that is error prone, hard to debug, and hard to read.

This crate attempts to solve the problem by introducing a new type Instance<T> which functions like an entity, but also contains information about the "kind" of the entity:

#[derive(Component)]
struct FruitBasket {
    fruits: Vec<Instance<Fruit>>
}

Features

  • Improved type safety and readability for entities
  • Custom entity kinds
  • Kind-specific commands and queries
  • Zero or minimal boilerplate for defining entity kinds

Usage

Kind and Instance

By definition, an entity is of kind T if it matches the query Query<(), <T as Kind>::Filter>.

By default, all Bevy components automatically implement the Kind trait:

impl<T: Component> Kind for T {
    type Filter = With<T>;
}

This means you can use any component as an argument to Instance<T>. For example:

#[derive(Component)]
struct Apple;

#[derive(Component)]
struct Orange;

fn count_apples(apples: Query<Instance<Apple>>) {
    println!("Apples: {}", apples.iter().count());
}

Alternatively, you can define your own kinds by implementing the Kind trait:

struct Fruit;

impl Kind for Fruit {
    type Filter = Or<With<Apple>, With<Orange>>;
}

fn count_fruits(fruits: Query<Instance<Fruit>>) {
    println!("Fruits: {}", fruits.iter().count());
}

InstanceRef and InstanceMut

If a kind is also a component (such as Apple or Orange in examples above), you may use InstanceRef<T> and InstanceMut<T> to access the instance and component data:

impl Apple {
    fn is_fresh(&self) -> bool {
        ...
    }
}

fn fresh_apples(apples: Query<InstanceRef<Apple>>) -> Vec<Instance<Apple>> {
    let mut fresh_apples = Vec::new();
    for apple in apples.iter() {
        if apple.is_fresh() {
            fresh_apples.push(apple.instance());
        }
    }
    fresh_apples
}

InstanceCommands

You may also extend the InstanceCommands<T> type to define kind-specific commands:

#[derive(Component)]
struct Human;

trait Eat {
    fn eat(&mut self, fruit: Instance<Fruit>);
}

impl Eat for InstanceCommands<'_, '_, '_, Human> {
    fn eat(&mut self, fruit: Instance<Fruit>) {
        ...
    }
}

fn eat(human: Query<Instance<Human>>, fruits: Query<Instance<Fruit>>, mut commands: Commands) {
    let human = human.single();
    if let Some(fruit) = fruits.iter().next() {
        commands.instance(human).eat(fruit);
    }
}

Instance<Any>

When writing generic code, it may be desirable to have an instance that can be of any kind:

use moonshine_kind::Any;

struct Container<T: Kind = Any> {
    items: Vec<Instance<T>>
}

Note that Instance<Any> is functionally equivalent to Entity.

Examples

See examples for more complete examples.

Limitations

Instance Invalidation

This crate does not monitor instances for invalidation. This means that if an entity is modified in such a way that it no longer matches a given kind T (such as removing component T), all instances which reference it would become invalid.

If necessary, you must manually check instances for validity prior to usage:

fn prune_fruits(
    In(fruits): In<Vec<Instance<Fruit>>>,
    query: Query<Instance<Fruit>>) -> Vec<Instance<Fruit>> {
    fruits.retain(|fruit| {
        // Is the Fruit still a Fruit?
        query.get(fruit.entity()).is_ok()
    })
}
You might also like...
A simple extension for `bevy-editor-pls` to support tilemap editing right inside the bevy app.

What is this This is a simple tilemap editor plugin, that hooks right into bevy_editor_pls to work with bevy_ecs_tilemap. It works completely within i

Bevy Simple Portals is a Bevy game engine plugin aimed to create portals.
Bevy Simple Portals is a Bevy game engine plugin aimed to create portals.

Portals for Bevy Bevy Simple Portals is a Bevy game engine plugin aimed to create portals. Those portals are (for now) purely visual and can be used t

Minecraft-esque voxel engine prototype made with the bevy game engine. Pending bevy 0.6 release to undergo a full rewrite.
Minecraft-esque voxel engine prototype made with the bevy game engine. Pending bevy 0.6 release to undergo a full rewrite.

vx_bevy A voxel engine prototype made using the Bevy game engine. Goals and features Very basic worldgen Animated chunk loading (ala cube world) Optim

bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy
bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy

Bevy Voxel Cone Tracing bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy. Bevy Version

Minecraft using Bevy and Bevy-Meshem

minecraft_bevy Minecraft_bevy was built to showcase bevy_meshem. After a week of developing it has: Chunk loading / unloading each chunk's mesh is bei

Experimental type-safe geometric algebra for Rust

Projective Geometric Algebra This library is a Rust code generator, generating the mathematics you need for a geometric algebra library. I made it mos

Chess implemented entirely in the Rust and TS type systems.
Chess implemented entirely in the Rust and TS type systems.

Type System Chess This repo contains chess implemented entirely in the (stable) Rust and Typescript type systems. Both languages feature turing comple

A prototype plugin providing a simple line drawing api for bevy.
A prototype plugin providing a simple line drawing api for bevy.

bevy_debug_lines A prototype plugin providing a simple line drawing api for bevy. See docs.rs for documentation. Expect breakage on master. Click on t

Simple RUST game with the Bevy Engine

Simple RUST Game using the Bevy Engine YouTube videos for this code base: Episode 1 - Rust Game Development tutorial from Scratch with Bevy Engine Epi

Owner
Professional Logical Operator
null
A tilemap rendering crate for bevy which is more ECS friendly.

bevy_ecs_tilemap A tilemap rendering plugin for bevy which is more ECS friendly by having an entity per tile. Features A tile per entity Fast renderin

John 414 Dec 30, 2022
🏷️ Markers for Bevy ECS Entities

Bevy ECS Markers Adds the support for marking entites and fetching them in queries Example View the whole example here #[derive(EntityMarker)] enum Pl

Chopped Studio 2 Dec 23, 2022
Minimalistic implementation of entity kinds for Bevy ECS.

Bevy ?? Kindly This crate is a minimalistic implementation of Kinded Entities for Bevy game engine. In summary, it allows the user to define, construc

null 10 Jan 26, 2023
Bring Bevy's ECS to Godot4

bevy_godot4 Bring the design power of Bevy's ECS to the mature engine capabilities of Godot 4. WARNING: This crate is very early in development, and i

JR 4 May 8, 2023
Specs - Parallel ECS

Specs Specs Parallel ECS Specs is an Entity-Component System written in Rust. Unlike most other ECS libraries out there, it provides easy parallelism

Amethyst Engine 2.2k Jan 8, 2023
High performance Rust ECS library

Legion aims to be a feature rich high performance Entity component system (ECS) library for Rust game projects with minimal boilerplate. Getting Start

Amethyst Engine 1.4k Jan 5, 2023
Creative Coding Framework based on Entity Component System (ECS) written in Rust

creativity creativity is Creative Coding Framework based on Entity Component System (ECS) written in Rust. Key Features TBA Quick Start TBA How To Con

Chris Ohk 9 Nov 6, 2021
🤹‍ 2D sprite rendering extension for the specs ECS system

specs-blit 2D sprite rendering extension for the Specs ECS system. All sprites are loaded onto a big array on the heap. Example // Setup the specs wor

Thomas Versteeg 8 Aug 14, 2022
A direct ecs to low-level server implementation for Godot 4.1

godot_ecs What if Godot 4.1 and Bevy got married? Well, you'd get one interesting duo of data driven goodness. In Development This crate is not produc

null 5 Oct 6, 2023
A quick and dirty Space Invaders type game in Bevy, with attached tutorial.

This article is in-development and will be released in full form soon. It'll appear on Medium (my publisher likes that), with this as a the accompanyi

Herbert 17 Oct 18, 2022