๐Ÿ“ฆ Zeenobit / moonshine_core

Unconventional framework for making games in Bevy

โ˜… 25 stars โ‘‚ 0 forks ๐Ÿ‘ 25 watching โš–๏ธ MIT License
๐Ÿ“ฅ Clone https://github.com/Zeenobit/moonshine_core.git
HTTPS git clone https://github.com/Zeenobit/moonshine_core.git
SSH git clone git@github.com:Zeenobit/moonshine_core.git
CLI gh repo clone Zeenobit/moonshine_core
Zeenobit Zeenobit Remove `check` from submodules 8dff722 3 months ago ๐Ÿ“ History
๐Ÿ“‚ main View all commits โ†’
๐Ÿ“ crates
๐Ÿ“ src
๐Ÿ“„ .gitattributes
๐Ÿ“„ .gitignore
๐Ÿ“„ .gitmodules
๐Ÿ“„ Cargo.toml
๐Ÿ“„ LICENSE
๐Ÿ“„ README.md
๐Ÿ“„ README.md

๐Ÿธ 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

crates.io downloads docs.rs license stars

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

crates.io downloads docs.rs license stars

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

crates.io downloads docs.rs license stars

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

crates.io downloads docs.rs license stars

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());
    }
}

# assert!(fruits[0].matches(&filter));
# assert!(!fruits[1].matches(&filter));
# assert!(!fruits[2].matches(&filter));

๐Ÿ› ๏ธ Moonshine Utilities

Collection of generic utilities for improved safety, diagnostics, and ergonomics.

crates.io downloads docs.rs license stars

Support

Please post an issue for any bugs, questions, or suggestions.

You may also contact me on the official Bevy Discord server as @Zeenobit.