bevy_map_runtime
Runtime map loading and rendering for Bevy 0.18 using bevy_ecs_tilemap.
Part of bevy_map_editor.
Features
- Efficient tilemap rendering via bevy_ecs_tilemap 0.18
- Asset-based map loading with hot reload support
- Custom entity spawning with
#[derive(MapEntity)]
- Autoloading for animations and dialogues
- Collision integration with Avian2D physics (optional
physics feature)
- Runtime tile modification
Quick Start
use bevy::prelude::*;
use bevy_map::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MapRuntimePlugin)
.add_systems(Startup, load_map)
.run();
}
fn load_map(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2d);
commands.spawn(MapHandle(asset_server.load("maps/level.map.json")));
}
Custom Entities
Register entity types to spawn game objects from map data:
use bevy::prelude::*;
use bevy_map::prelude::*;
#[derive(Component, MapEntity)]
#[map_entity(type_name = "Chest")]
pub struct Chest {
#[map_prop]
pub loot_table: String,
#[map_prop(default = false)]
pub locked: bool,
}
App::new()
.add_plugins(MapRuntimePlugin)
.register_map_entity::<Chest>()
Auto-Loading Animations
Use AnimatedSpriteHandle to autoload sprite animations from a map project:
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::AnimatedSpriteHandle;
fn spawn_player(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
AnimatedSpriteHandle::new(
asset_server.load("maps/game.map.json"),
"player_sprite",
"idle", ),
Transform::default(),
));
}
Autoloading Dialogues
Use DialogueTreeHandle to auto-load dialogues:
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::DialogueTreeHandle;
fn spawn_npc(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(DialogueTreeHandle::new(
asset_server.load("maps/game.map.json"),
"merchant_greeting", ));
}
Manual Animation Control
For direct control over sprites, use #[map_sprite]:
#[derive(Component, MapEntity)]
#[map_entity(type_name = "Player")]
pub struct Player {
#[map_prop]
pub speed: f32,
#[map_sprite("player_sprite")]
pub sprite: Option<Handle<Image>>,
}
Collision Integration (Avian2D)
Enable the physics feature to automatically spawn colliders from tile collision data:
bevy_map = { version = "0.1", features = ["physics"] }
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::MapCollisionPlugin;
use avian2d::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MapRuntimePlugin)
.add_plugins(MapCollisionPlugin) .add_plugins(PhysicsPlugins::default())
.add_systems(Startup, load_map)
.run();
}
fn load_map(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2d);
commands.spawn(MapHandle(asset_server.load("maps/level.map.json")));
}
The MapCollisionPlugin reads collision shapes defined in the tileset editor and spawns corresponding Avian2D Collider components. Query MapCollider to access original collision data.
Entity Type Components (Zero-Code Physics & Input)
Configure physics, input, and sprites at the entity type level in the editor - no Rust code needed!
Automatic Physics
With MapEntityPhysicsPlugin, entities spawn with physics components based on their type configuration:
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::{MapEntityPhysicsPlugin, MapCollisionPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MapRuntimePlugin)
.add_plugins(MapCollisionPlugin) .add_plugins(MapEntityPhysicsPlugin) .add_systems(Startup, load_map)
.run();
}
In the Schema Editor, go to the "Components" tab and configure:
- Body Type: Dynamic, Kinematic, or Static
- Collider: Box, Capsule, or Circle with custom dimensions
- Physics properties: Gravity scale, friction, restitution, etc.
Automatic Input
With MapEntityInputPlugin, entities respond to input based on their type configuration:
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::{MapEntityInputPlugin, MapEntityPhysicsPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MapRuntimePlugin)
.add_plugins(MapEntityPhysicsPlugin) .add_plugins(MapEntityInputPlugin) .add_systems(Startup, load_map)
.run();
}
Built-in input profiles:
- Platformer: A/D movement, Space to jump
- Top-Down: WASD 8-directional movement
- Twin-Stick: WASD move, mouse aim (marker only)
- Custom: Add your own systems that query the marker component
Automatic Sprites
With MapEntitySpritePlugin, entities spawn with sprites from type configuration:
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::MapEntitySpritePlugin;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MapRuntimePlugin)
.add_plugins(MapEntitySpritePlugin) .add_systems(Startup, load_map)
.run();
}
In the Schema Editor Components tab, select a sprite sheet and default animation.
Full Zero-Code Setup
For a complete platformer with no entity code:
use bevy::prelude::*;
use bevy_map::prelude::*;
use bevy_map::runtime::{MapCollisionPlugin, MapEntityPhysicsPlugin, MapEntityInputPlugin, MapEntitySpritePlugin};
use avian2d::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MapRuntimePlugin)
.add_plugins(MapCollisionPlugin) .add_plugins(MapEntityPhysicsPlugin) .add_plugins(MapEntityInputPlugin) .add_plugins(MapEntitySpritePlugin) .insert_resource(Gravity(Vec2::new(0.0, -800.0)))
.add_systems(Startup, load_map)
.run();
}
fn load_map(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2d);
commands.spawn(MapHandle(asset_server.load("maps/level.map.json")));
}
Re-exported Types
For convenience, use bevy_map::prelude::* which includes all commonly used types:
use bevy_map::prelude::*;
License
MIT OR Apache-2.0