# 🍸 Moonshine Core
Unconventional cocktail of libraries to make ECS-driven development easier and safer in [Bevy](https://bevyengine.org/).
See individual crates for detailed documentation and examples.
### 🍎 Moonshine Kind
[](https://crates.io/crates/moonshine-kind)
[](https://crates.io/crates/moonshine-kind)
[](https://docs.rs/moonshine-kind)
[](https://github.com/Zeenobit/moonshine_kind/blob/main/LICENSE)
[](https://github.com/Zeenobit/moonshine_kind)
Type safety solution for Bevy entities:
```rust
use bevy::prelude::*;
use moonshine_core::prelude::*;
#[derive(Component)]
struct Fruit;
#[derive(Component)]
struct FruitBasket {
fruits: Vec<Instance<Fruit>>
}
```
### 🌴 Moonshine Object
[](https://crates.io/crates/moonshine-object)
[](https://crates.io/crates/moonshine-object)
[](https://docs.rs/moonshine-object)
[](https://github.com/Zeenobit/moonshine_object/blob/main/LICENSE)
[](https://github.com/Zeenobit/moonshine_object)
Ergonomic wrapper for managing complex enttiy hierarchies:
```rust
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
[](https://crates.io/crates/moonshine-save)
[](https://crates.io/crates/moonshine-save)
[](https://docs.rs/moonshine-save)
[](https://github.com/Zeenobit/moonshine_save/blob/main/LICENSE)
[](https://github.com/Zeenobit/moonshine_save)
Save/Load framework for managing persistent game state:
```rust
use bevy::prelude::*;
use moonshine_core::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins((SavePlugin, LoadPlugin))
.add_systems(PreUpdate, save_default().into(static_file("world.ron")).run_if(should_save))
.add_systems(PreUpdate, load(static_file("world.ron")).run_if(should_load))
.run();
}
fn should_save(key: Res<ButtonInput<KeyCode>>) -> bool {
key.just_pressed(KeyCode::KeyS)
}
fn should_load(key: Res<ButtonInput<KeyCode>>) -> bool {
key.just_pressed(KeyCode::KeyL)
}
```
### 🏷️ Moonshine Tag
[](https://crates.io/crates/moonshine-tag)
[](https://crates.io/crates/moonshine-tag)
[](https://docs.rs/moonshine-tag)
[](https://github.com/Zeenobit/moonshine_tag/blob/main/LICENSE)
[](https://github.com/Zeenobit/moonshine_tag)
Cheap, fast, mostly unique identifiers designed for Bevy:
```rust
use bevy::prelude::*;
use moonshine_tag::{prelude::*, filter, Filter};
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: Filter = filter!([APPLE, CRUNCHY]) & filter!(![POISONED]);
for fruit in &fruits {
if filter.allows(fruit) {
world.spawn(fruit.clone());
}
}
# assert!(filter.allows(&fruits[0]));
```
### 🛠️ Moonshine Utilities
Collection of generic utilities for improved safety, diagnostics, and ergonomics.
[](https://crates.io/crates/moonshine-util)
[](https://crates.io/crates/moonshine-util)
[](https://docs.rs/moonshine-util)
[](https://github.com/Zeenobit/moonshine_util/blob/main/LICENSE)
[](https://github.com/Zeenobit/moonshine_util)
## Support
Please [post an issue](https://github.com/Zeenobit/moonshine_core/issues/new) for any bugs, questions, or suggestions.
You may also contact me on the official [Bevy Discord](https://discord.gg/bevy) server as **@Zeenobit**.