Bevy is a free and open-source data-driven game engine built in Rust. It's designed to be simple, modular, and performant, leveraging Rust's safety and concurrency features. At its core, Bevy is built around an Entity-Component-System (ECS) architecture, which provides a highly flexible and efficient way to organize game logic and data.
Key Concepts of Bevy:
1. Entity-Component-System (ECS):
* Entities: Unique identifiers (IDs) that represent "things" in your game (e.g., a player, a tree, a bullet). They are pure identifiers and hold no data themselves.
* Components: Raw data that can be attached to entities. Components define the properties of an entity (e.g., `Position`, `Velocity`, `Health`, `Mesh`, `Camera`). An entity can have multiple components, and multiple entities can share the same component type.
* Systems: Functions that run on a schedule, querying for entities that have specific combinations of components and performing logic on them. Systems are the core of game logic and transformation (e.g., a `MovementSystem` might query for entities with `Position` and `Velocity` components and update their positions).
2. App: The `App` struct is the entry point for a Bevy application. It manages the ECS world, registers systems, adds plugins, and ultimately runs the game loop.
3. Plugins: Bevy applications are built using a modular plugin architecture. A plugin is a collection of systems, resources, components, and other configurations bundled together. `DefaultPlugins` is a common plugin that provides essential functionality like window management, input handling, rendering, and asset loading.
4. Resources: Global, unique data accessible by any system. Unlike components (which are tied to specific entities), resources store singletons of data (e.g., `Time`, `Input`, `AssetServer`).
5. Queries: Systems use `Query` objects to efficiently select entities based on their attached components. Queries allow systems to access and mutate component data for relevant entities.
6. Commands: Systems can use `Commands` to modify the ECS world (e.g., spawning new entities, despawning entities, adding/removing components) in a safe and queued manner, preventing conflicts during system execution.
Why Bevy?
* Rust-Native: Benefits from Rust's performance, memory safety, and concurrency features.
* Data-Driven: Encourages declarative programming and makes game logic easier to reason about and modify.
* Modular: Highly extensible through its plugin system, allowing developers to pick and choose features or integrate their own.
* Performance: The ECS design leads to highly optimized data layouts and parallel processing.
* Ergonomics: Provides a developer-friendly API and aims for fast iteration times with features like hot-reloading.
* Open Source: Backed by a growing community, ensuring active development and a collaborative environment.
Bevy is suitable for developing a wide range of applications, from 2D and 3D games to simulations and interactive tools.
Example Code
```rust
// Cargo.toml setup:
// [dependencies]
// bevy = "0.13"
use bevy::prelude::*;
// The main function where the Bevy application is created and run.
fn main() {
App::new()
// Add Bevy's default plugins, which provide essential features like
// window creation, input handling, rendering, asset management, etc.
.add_plugins(DefaultPlugins)
// Add a system that runs once at the start of the application.
.add_systems(Startup, setup_camera_and_text)
// Add a system that runs every frame to rotate our cube.
.add_systems(Update, rotate_cube)
// Run the Bevy application.
.run();
}
// This system runs once at startup to set up our 3D scene.
fn setup_camera_and_text(mut commands: Commands, asset_server: Res<AssetServer>) {
// Spawn a 3D camera entity.
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// Spawn a simple 3D cube.
// We'll give it a unique component 'Rotatable' so our rotate_cube system can find it.
commands.spawn((PbrBundle {
mesh: commands.asset_server.load("models/cube/cube.gltf#Mesh0/Primitive0"), // Example: load a cube from a glTF file
material: commands.asset_server.load("materials/red.mat.ron"), // Example: load a red material
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
},
Rotatable, // Custom component to mark this entity as rotatable
));
// You might also want to add a light source
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
// And some ground plane for the cube to sit on
commands.spawn(PbrBundle {
mesh: commands.asset_server.load("models/plane/plane.gltf#Mesh0/Primitive0"),
material: commands.asset_server.load("materials/green.mat.ron"),
transform: Transform::from_scale(Vec3::new(10.0, 1.0, 10.0)),
..default()
});
// Spawn a UI Text element
commands.spawn(
TextBundle::from_section(
"Hello, Bevy!
(Cube by Bevy)",
TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"), // Load a font
font_size: 40.0,
color: Color::rgb(0.9, 0.9, 0.9),
},
)
.with_style(Style {
position_type: PositionType::Absolute, // Position text absolutely on the screen
top: Val::Px(10.0),
left: Val::Px(10.0),
..default()
}),
);
}
// Define a simple marker component for entities that should rotate.
// This struct doesn't need any data, it just marks an entity.
#[derive(Component)]
struct Rotatable;
// This system runs every frame to rotate any entity with a `Rotatable` component.
// It queries for `Transform` components of entities that also have `Rotatable`.
fn rotate_cube(mut query: Query<&mut Transform, With<Rotatable>>, time: Res<Time>) {
for mut transform in &mut query {
transform.rotate_y(time.delta_seconds() * 0.5);
}
}
// Note: For this example to run, you'll need some assets:
// 1. A `fonts` directory with `FiraSans-Bold.ttf` (e.g., from Bevy's examples or google fonts).
// 2. A `models` directory with a `cube` sub-directory containing `cube.gltf`.
// 3. A `materials` directory with `red.mat.ron` and `green.mat.ron` (simple PBR material definitions).
// Example red.mat.ron content:
// ( material: PbrBundle {
// base_color: Some(Color::rgb(0.8, 0.1, 0.1)),
// ..Default::default()
// } )
// These assets should be placed in a `assets` directory at the root of your project.
```








Bevy