This crate provides a way to interactively create, edit, save, and load Bevy data in 3D.
Caution
This is in early development and you will likely encounter bugs
- Rust 1.75 or later
- Bevy 0.18.1 (see Compatibility)
- A Windows, macOS, or Linux system with graphics support
Add meshflow_vibe to your project's Cargo.toml:
[dependencies]
bevy = "0.18.1"
meshflow_vibe = { git = "https://github.com/Meshflow3D/Meshflow_vibe", branch = "main" }
serde = "*"This crate supports three optional feature sets:
| Feature | Description | Includes |
|---|---|---|
gizmos |
Visual debugging tools and entity manipulation | Core functionality |
core |
Bare serialization/deserialization with macros & logging | None (base) |
editor |
Full in-game editor with UI components | Core + Gizmos |
default |
All features enabled | Core + Editor + Gizmos |
Example: Core only (no editor or gizmos)
[dependencies]
meshflow_vibe = { git = "https://github.com/Meshflow3D/Meshflow_vibe", branch = "main", default-features = false, features = ["core"] }Example: Gizmos only
[dependencies]
meshflow_vibe = { git = "https://github.com/Meshflow3D/Meshflow_vibe", branch = "main", default-features = false, features = ["gizmos"] }- Navigate to your project's
Cargo.tomland add the dependency - Register editor components in your
main()function - Add the
MeshflowVibeplugin group to your Bevy app
use bevy::prelude::*;
use meshflow_vibe::prelude::*;
const STARTING_WORLD: &str = "scenes/starting.scene";
fn main() {
let mut app = App::new();
register_editor_components!();
app.add_plugins(DefaultPlugins)
.add_plugins(MeshflowVibe {
default_world: STARTING_WORLD.to_string(),
..Default::default()
})
.run();
}Check out the examples which showcase how to set up a project.
The dungeon example provides a simple entry point file with code ready to start editing. Make sure to copy over the relevant assets subfolder or you will get errors.
# If you clone this repo directly, you can use the example argument
cargo run --release --example dungeonThis project uses Rust's built-in test infrastructure. To run all tests locally:
cargo test --workspace --all-targetsThe test suite includes unit tests, integration tests, and headless Bevy tests that run without requiring a display. These tests are automatically run in CI on every push and pull request to main.
| Bevy Version | meshflow_vibe Version |
|---|---|
| 0.18 | 0.3.1 |
| 0.17 | 0.3.0 |
| 0.16 | 0.2.0 - 0.2.2 |
| 0.14 | 0.1.0 |
| Feature | Core | Gizmos | Editor | Default |
|---|---|---|---|---|
| Logging System | ✅ | ✅ | ✅ | ✅ |
| Serialization Macros | ✅ | ✅ | ✅ | ✅ |
| Scene Serialization | ✅ | ✅ | ✅ | ✅ |
| Visual Debugging | ✅ | ✅ | ✅ | |
| Entity Manipulation | ✅ | ✅ | ✅ | |
| In-Game Editor UI | ✅ | ✅ | ||
| Entity Management | ✅ | ✅ | ||
| World Save/Load | ✅ | ✅ | ✅ | ✅ |
Full API documentation is available at:
- API Docs - Crates.io documentation
- GitHub Repository - Source code and examples
Generate local documentation with:
cargo doc --no-deps --openAn entity is stored as three main parts:
- Identity: Contains the entity's name, uuid, and type/class (such as Camera, Light, OBJ). This class data contains everything necessary to rebuild this bundle and any other adjacently relevant data. Not everything is currently available in classes.
- Transform: Describes the entity's position, rotation, and scale. This determines where the entity is located and how it is oriented in the world.
- Components: (Optional) Holds additional data or behaviors attached to the entity. This is where you extend the entity's functionality via the
#[granite_component]macro.
A scene file contains metadata and a list of serializable entity data. Check out the assets/scenes for scene examples.
While comprehensive documentation is currently unavailable, here are some helpful events you can use to interact with the editor:
RequestEditorToggle- Toggle the editor UI on/offRequestToggleCameraSync- Toggle camera synchronization between editor and main camera
RequestSelectEntityEvent- Select an entity (additive for multi-selection)RequestDeselectEntityEvent- Deselect a specific entityRequestDeselectAllEntitiesEvent- Clear all entity selectionsRequestCameraEntityFrame- Frame the UI camera to focus on active entity
RequestDuplicateEntityEvent- Duplicate a specific entityRequestDuplicateAllSelectionEvent- Duplicate all currently selected entities
RequestNewParent- Request to set active as parent for selected entitiesRequestRemoveParents- Remove parent relationships from selected entitiesRequestRemoveChildren- Remove child relationships from selected entities
RequestSaveEvent- Save the specific worldRequestLoadEvent- Load a world from specified pathRequestReloadEvent- Reload a world from specified pathWorldLoadSuccessEvent- Event sent when world loading completes successfullyWorldSaveSuccessEvent- Event sent when world saving completes successfullyRequestDespawnSerializableEntities- Event to despawn all serializable entitiesRequestDespawnBySource- Event to despawn a specific source that is loaded
Only Bevy Event unit structs are supported for UI button rendering.
With version 0.2.x, there is a new window that renders users buttons that are clickable. Create a struct that holds your events, and add #[ui_callable_events]. This will add all the events to the events window as clickable, and will dispatch said event in your struct.
Make sure to call UI registration before the plugin gets initialized in your app if your using this. DebugEvents::register_ui();.
Example:
use bevy::prelude::*;
use meshflow_vibe::prelude::*;
#[derive(Event, Default)]
pub struct DebugRequestPlayer;
#[derive(Event, Default)]
pub struct DebugRequestRemovePlayer;
#[ui_callable_events]
pub struct DebugEvents {
pub spawn_player: DebugRequestPlayer,
pub remove_player: DebugRequestRemovePlayer,
}
pub fn debug_callable_watcher(
mut despawn: MessageReader<DebugRequestRemovePlayer>,
mut spawn: MessageReader<DebugRequestPlayer>,
mut commands: Commands,
mut player_start: Query<(&GlobalTransform, &mut PlayerSpawner)>,
mut world_state: ResMut<WorldState>,
) {
for _ in despawn.read() {
commands.send_event(RequestDespawnBySource(PLAYER_PREFAB.to_string()));
}
for _ in spawn.read() {
spawn_player(&mut commands, &mut world_state, &mut player_start);
}
}Meshflow Vibe is free and open source. Except when noted, all assets are licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
Any contributions by you, shall be dual licensed as above, without any additional terms or conditions.
If you have any feedback or questions, please reach out via:
- GitHub Issues - Bug reports and feature requests
- GitHub Discussions - Questions and general discussion
- Noah
- Silas
- Ethan
- Max
@BlakeDarrow on YouTube




