Expand description
ยง๐ธ Moonshine Core
Unconventional cocktail of libraries to make ECS-driven development easier and safer in Bevy.
See individual crates for detailed documentation and examples.
ยง๐ Moonshine Kind
Type safety solution for Bevy entities:
use bevy::prelude::*;
use moonshine_core::prelude::*;
#[derive(Component)]
struct Fruit;
#[derive(Component)]
struct FruitBasket {
fruits: Vec<Instance<Fruit>>
}ยง๐ด Moonshine Object
Ergonomic wrapper for managing complex enttiy hierarchies:
use bevy::prelude::*;
use moonshine_core::prelude::*;
#[derive(Component)]
struct Bird;
#[derive(Component)]
struct Flying;
fn setup_bird(birds: Objects<Bird, Added<Flying>>, mut commands: Commands) {
for bird in birds.iter() {
if let Some(wings) = bird.find_by_path("./Wings") {
for wing in wings.children() {
// TODO: Flap! Flap!
}
}
}
}ยง๐พ Moonshine Save
Save/Load framework for managing persistent game state:
use bevy::prelude::*;
use moonshine_core::prelude::*;
#[derive(Component, Reflect)]
#[reflect(Component)]
#[require(Save)]
struct Player { /* ... */ }
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins)
.register_type::<Player>()
.add_observer(save_on_default_event)
.add_observer(load_on_default_event)
.add_systems(Startup, spawn_player)
.add_systems(
Update,
(trigger_save, trigger_load)
);
// app.run();
}
fn spawn_player(mut commands: Commands) {
commands.spawn(Player { /* ... */ });
}
fn trigger_save(key: Res<ButtonInput<KeyCode>>, mut commands: Commands) {
if key.just_pressed(KeyCode::KeyS) {
commands.trigger_save(SaveWorld::default_into_file("world.ron"));
}
}
fn trigger_load(key: Res<ButtonInput<KeyCode>>, mut commands: Commands) {
if key.just_pressed(KeyCode::KeyL) {
commands.trigger_load(LoadWorld::default_from_file("world.ron"));
}
}ยง๐ท๏ธ Moonshine Tag
Cheap, fast, mostly unique identifiers designed for Bevy:
use bevy::prelude::*;
use moonshine_tag::prelude::*;
tags! { APPLE, ORANGE, JUICY, CRUNCHY, POISONED }
let mut world = World::new();
// Define some fruits!
let fruits = [
Tags::from([APPLE, CRUNCHY]),
Tags::from([ORANGE, JUICY]),
Tags::from([APPLE, CRUNCHY, POISONED])
];
// Only crunchy, edible apples, please! :)
let filter: TagFilter = tag_filter!([APPLE, CRUNCHY] & ![POISONED]);
for fruit in &fruits {
if filter.allows(fruit) {
world.spawn(fruit.clone());
}
}
ยง๐ ๏ธ Moonshine Utilities
Collection of generic utilities for improved safety, diagnostics, and ergonomics.
ยงSupport
Please post an issue for any bugs, questions, or suggestions.
You may also contact me on the official Bevy Discord server as @Zeenobit.
Modulesยง
Structsยง
- Moonshine
Core Plugins - A
PluginGroupwhich adds all the core plugins.