Skip to content

✍️ 필사 모드: Bevy Game Engine — A Hands-On Rust ECS Tour of Modern Game Development (Deep Dive, 2026)

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

Prologue — Why Rust and ECS Fit Game Development

The history of game engines compresses into two lines.

  1. The inheritance era (1995–2015) — Unity's MonoBehaviour, Unreal's UObject, Godot's Node. Every game object descended from a class hierarchy, and "GameObject is a Component" built deep trees. C++ and C# fit naturally.
  2. The data-oriented era (2015–) — Naughty Dog, Insomniac, and Epic's Mass system in Unreal 5 conceded that "a cache miss is a frame drop." Data-Oriented Design rose, and Entity-Component-System emerged as the textbook answer.

ECS in one paragraph.

  • Entity = just an ID, a 64-bit integer. No data, no behavior.
  • Component = pure data (Position, Velocity, Sprite). No methods.
  • System = a function that runs over "every entity that has this set of components."

No inheritance tree. Player extends Character extends Pawn vanishes. A "player" is an entity that happens to carry Player, Position, Velocity, and Health components.

Layer Rust on top of ECS and two old weaknesses dissolve at once. First, concurrency. The borrow checker proves at compile time that two systems cannot mutate the same component simultaneously, and Bevy's scheduler exploits that to parallelize automatically. Second, stability. Game code historically bruises against pointer, null, and out-of-bounds bugs — Rust removes the whole category.

Now the honest part. In May 2026, Unity still leads on mobile, indie, and VR. Unreal leads AAA and cinematics. Godot owns a strong slice of indie 2D. Bevy is the open-source star but counts shipped commercial titles on two hands. So this piece will not chant "Year of Bevy." It will answer instead — what does Bevy do well, how far has it come, where is it still stuck?

The plan.

  1. Understanding the ECS paradigm — how it differs from MonoBehaviour
  2. Bevy's anatomy — App, Schedule, Plugin
  3. The plugin architecture — everything is a plugin
  4. Rendering through wgpu — browser, desktop, and mobile from one codebase
  5. Your first Bevy game in thirty minutes — a circle that moves with arrow keys
  6. Honest comparison against Godot, Unity, Unreal, Macroquad
  7. Games actually shipped on Bevy — Foresight, Tunnet, and the truth about Tiny Glade
  8. Where Bevy still is not ready

The keeper sentence: "An engine is a tool, not a faith. But ECS is a paradigm before it is a tool, and Bevy is the most honest implementation of that paradigm — on top of Rust."


1. The ECS Paradigm — How It Differs From Unity and Unreal

1.1 The inheritance model in practice

An enemy in Unity usually looks like this.

// Unity / MonoBehaviour style
public class Enemy : MonoBehaviour {
    public int health = 100;
    public float speed = 2.0f;
    private Transform target;

    void Start() { target = GameObject.FindWithTag("Player").transform; }
    void Update() {
        transform.position = Vector3.MoveTowards(
            transform.position, target.position, speed * Time.deltaTime);
        if (health <= 0) Destroy(gameObject);
    }
}

Enemy inherits from MonoBehaviour, holds state (health, speed), and the behavior (Update) all in one class. A hundred enemies mean Update is dispatched a hundred times — virtual calls, cache misses, and branch mispredictions accumulate.

Unreal's AActor + UCharacterMovementComponent combination is structurally identical: a deep inheritance chain like AEnemy : public ACharacter : public APawn : public AActor, and each component holds a pointer back to its actor.

1.2 The ECS model in practice

The same enemy in Bevy.

// Bevy / ECS style
use bevy::prelude::*;

#[derive(Component)]
struct Enemy;

#[derive(Component)]
struct Health(i32);

#[derive(Component)]
struct Speed(f32);

#[derive(Component)]
struct Target(Entity);

fn move_enemies(
    time: Res<Time>,
    mut enemies: Query<(&mut Transform, &Speed, &Target), With<Enemy>>,
    targets: Query<&Transform, Without<Enemy>>,
) {
    for (mut tf, speed, target) in &mut enemies {
        if let Ok(target_tf) = targets.get(target.0) {
            let dir = (target_tf.translation - tf.translation).normalize_or_zero();
            tf.translation += dir * speed.0 * time.delta_secs();
        }
    }
}

fn kill_dead_enemies(mut commands: Commands, q: Query<(Entity, &Health), With<Enemy>>) {
    for (e, hp) in &q {
        if hp.0 <= 0 { commands.entity(e).despawn(); }
    }
}

The differences are sharp.

  • Enemy is a marker component — an empty struct. No data, no behavior.
  • Health(i32) and Speed(f32) are pure data. No methods.
  • move_enemies is a system that processes only entities carrying the Enemy marker, in bulk.
  • The Position, Speed, and Target of a hundred enemies are laid out contiguously in memory under archetype-based storage, so cache hit rates are high.
  • move_enemies and kill_dead_enemies touch different components, so Bevy runs them in parallel automatically.

1.3 Archetypes and memory layout

Bevy (and Flecs, Unity DOTS, Unreal Mass) is an archetype-based ECS. It groups entities into chunks by "which components they have."

Archetype A: [Position, Velocity, Sprite] — a thousand entities laid out with Position contiguous, then Velocity contiguous, then Sprite contiguous. Archetype B: [Position, Velocity, Sprite, Health, Enemy] — a separate chunk.

A Query of Position plus Velocity walks chunks from both A and B, and inside each chunk it is just an array walk. No virtual dispatch, almost no cache miss. That is why ECS is fast.

1.4 The honest downsides of ECS

ECS is not a silver bullet.

  • State machines and complex behavior trees explode when you model each state as a component. Idle, Walking, Attacking, Hurt, Dead as separate components forces every system to know every combination. Putting an enum inside a single component is usually saner.
  • Parent-child relationships are not native to vanilla ECS. Bevy fakes a tree with Parent and Children components, but the grain is different.
  • The learning curve is steep. "Why can't I just call a method?" and "How does this query split the borrow?" eat hours.

The keeper sentence: "OOP cages verbs inside nouns. ECS keeps nouns (data) and verbs (systems) separated all the way down."


2. Bevy's Anatomy — App, Schedule, System

2.1 App

Every Bevy program starts at an App. The main function usually looks like this.

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, spawn_camera)
        .add_systems(Update, (move_player, count_fps).chain())
        .run();
}
  • App::new() creates an empty ECS world and scheduler.
  • .add_plugins(DefaultPlugins) pulls in the standard bundle — windowing, input, rendering, time, asset loading.
  • .add_systems(Startup, ...) registers systems that run once at game start.
  • .add_systems(Update, ...) registers systems that run every frame.
  • .run() enters the main loop.

The crucial absence is the absence of a manager. There is no class GameManager : MonoBehaviour { void Awake() }. The App is the manager, and the game logic is free functions.

2.2 Schedule — When systems run

Bevy 0.10 retired stages and introduced schedules. As of 0.15 the main ones are.

  • Startup — once at app start.
  • PreUpdate — every frame, after input is gathered.
  • Update — every frame, main game logic.
  • PostUpdate — every frame, after transform propagation and physics.
  • FixedUpdate — fixed timestep (default 64 Hz). Physics and lockstep networking.
  • Last — end of frame.

Ordering between systems is controlled with .before(), .after(), .chain(), and named SystemSet groupings.

app.add_systems(
    Update,
    (
        input_system,
        movement_system.after(input_system),
        collision_system.after(movement_system),
    ),
);

2.3 Component, Resource, Event

Three ways to put data into the ECS world.

  • Component — data attached to an entity. #[derive(Component)].
  • Resource — a single global per world. Score, settings, asset handles. #[derive(Resource)].
  • Event — frame-scoped messages between systems. #[derive(Event)].
#[derive(Resource)]
struct Score(u32);

#[derive(Event)]
struct EnemyKilled { entity: Entity, by: Entity }

fn award_score(mut score: ResMut<Score>, mut events: EventReader<EnemyKilled>) {
    for _ in events.read() {
        score.0 += 100;
    }
}

Res is read-only access, ResMut is mutable. Two systems that both want ResMut of the same resource serialize automatically; a Res reader runs in parallel with another Res reader.

2.4 Query — How a system asks for data

fn move_player(
    time: Res<Time>,
    mut q: Query<(&mut Transform, &Speed), With<Player>>,
) {
    for (mut tf, speed) in &mut q {
        tf.translation.x += speed.0 * time.delta_secs();
    }
}

The Query signature is the system's data manifest. With<Player> is a filter — it does not pull the marker into the iteration, but it requires the entity to carry it. If two systems hold non-overlapping queries, Bevy can run them simultaneously.

The keeper sentence: "Reading Bevy code = the system signature already tells you what that system reads and what it writes."


3. Plugin Architecture — Everything Is a Plugin

Bevy's biggest aesthetic decision is that "the engine itself is a collection of plugins."

Unpack DefaultPlugins and roughly twenty plugins fall out.

  • WindowPlugin — window creation
  • InputPlugin — keyboard, mouse, gamepad
  • RenderPlugin — wgpu-backed rendering
  • SpritePlugin — 2D sprites
  • PbrPlugin — physically based 3D rendering
  • UiPlugin — bevy_ui
  • AudioPlugin — kira-backed audio
  • AssetPlugin — asynchronous asset loading
  • TimePlugin, TransformPlugin, LogPlugin, and so on.

Anything you do not want, you can drop.

// Headless server — ECS only, no window or renderer
App::new()
    .add_plugins(MinimalPlugins)
    .add_plugins(LogPlugin::default())
    .add_systems(Update, game_logic)
    .run();

3.1 Writing your own plugin

Bundling your own code into a plugin keeps modules clean.

use bevy::prelude::*;

pub struct PlayerPlugin;

impl Plugin for PlayerPlugin {
    fn build(&self, app: &mut App) {
        app
            .add_event::<PlayerHurt>()
            .add_systems(Startup, spawn_player)
            .add_systems(Update, (
                player_input,
                player_movement.after(player_input),
                player_animation,
            ));
    }
}

#[derive(Event)]
pub struct PlayerHurt { pub amount: i32 }

#[derive(Component)]
pub struct Player;

fn spawn_player(mut commands: Commands) {
    commands.spawn((
        Player,
        Transform::default(),
        // sprite, collider, etc.
    ));
}

fn player_input(/* ... */) {}
fn player_movement(/* ... */) {}
fn player_animation(/* ... */) {}

Then main becomes tiny.

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins((PlayerPlugin, EnemyPlugin, AudioPlugin, UiPlugin))
        .run();
}

3.2 The ecosystem (as of May 2026)

  • Avian — 2D and 3D physics. The successor to bevy_xpbd. Position-based dynamics, compatible with 0.15.
  • bevy_egui — Drops egui into Bevy for debug UI. The de facto standard for inspectors and tooling.
  • bevy-inspector-egui — Live-edit components and resources in the running world.
  • Lightyear — Client-server networking with replication, prediction, and rollback.
  • bevy_rapier — Rapier physics bindings (alternative to Avian).
  • bevy_tweening and bevy_easings — Animation interpolation.
  • bevy_kira_audio — Richer audio control.
  • Big Brain — Utility AI decision trees.

The bevy_assets repository on GitHub curates the canonical list.

The keeper sentence: "A plugin is not just a module — it is Bevy's philosophy. There is no border between engine and game code."


4. wgpu Rendering — One Codebase for Browser, Desktop, and Mobile

Bevy's renderer sits on wgpu, the Rust-side implementation of WebGPU. One codebase targets Vulkan, Metal, DirectX 12, WebGPU, and OpenGL ES.

4.1 What it gets right

  • Cross-platform is real. Metal on macOS, Vulkan on Linux, DX12 on Windows, Vulkan/Metal on mobile, WebGPU on the web. Shaders go through WGSL once and run everywhere.
  • WebGPU is a first-class target. cargo build --target wasm32-unknown-unknown plus wasm-bindgen produces a browser build. As of 0.15 it is good enough to ship on itch.io.
  • Modern shaders. WGSL is safer than GLSL (typed, bounds-checked) and simpler than HLSL.

4.2 What it does not get right

  • Browser support is still narrow. As of May 2026, WebGPU is stable in Chrome and Edge, supported in Safari 18, and only on nightly Firefox on some platforms. You still need a fallback plan for web shipping.
  • Shader compile times and driver compatibility sit with wgpu, and the tooling is not yet as smooth as Vulkan SDK natively gives you.
  • The PBR pipeline is modern but not UE5-rich. No Lumen, no Nanite. If you need those, Bevy is not the engine.

4.3 Custom shaders

Write WGSL, then implement the Material trait to register it as a Bevy material.

use bevy::{
    prelude::*,
    render::render_resource::{AsBindGroup, ShaderRef},
    sprite::Material2d,
};

#[derive(Asset, TypePath, AsBindGroup, Clone, Debug)]
struct WaveMaterial {
    #[uniform(0)] time: f32,
    #[uniform(0)] color: LinearRgba,
}

impl Material2d for WaveMaterial {
    fn fragment_shader() -> ShaderRef { "shaders/wave.wgsl".into() }
}

And the shader file.

struct Uniforms {
    time: f32,
    color: vec4<f32>,
};

@group(2) @binding(0) var<uniform> u: Uniforms;

@fragment
fn fragment(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
    let wave = sin(uv.x * 10.0 + u.time) * 0.5 + 0.5;
    return vec4<f32>(u.color.rgb * wave, 1.0);
}

The keeper sentence: "wgpu gave Bevy a 'one codebase, every platform' renderer almost for free — though 'every' does not yet mean 'optimal'."


5. Your First Bevy Game in Thirty Minutes — A Circle That Moves

Time to actually write code. "A circle on screen that moves with arrow keys." Done in thirty minutes.

5.1 Project setup

# If you do not have Rust, install via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# New project
cargo new moving_circle && cd moving_circle

Open Cargo.toml.

[package]
name = "moving_circle"
version = "0.1.0"
edition = "2021"

[dependencies]
bevy = "0.15"

# Faster dev compile — recommended
[profile.dev]
opt-level = 1

[profile.dev.package."*"]
opt-level = 3

5.2 First code — empty window

src/main.rs.

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d);
}
cargo run

A black window appears. The first build takes two to three minutes (dependency compile). Incremental builds afterward take seconds.

5.3 Draw a circle

use bevy::prelude::*;

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Speed(f32);

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    commands.spawn(Camera2d);

    commands.spawn((
        Player,
        Speed(300.0),
        Mesh2d(meshes.add(Circle::new(40.0))),
        MeshMaterial2d(materials.add(Color::srgb(0.2, 0.7, 1.0))),
        Transform::from_xyz(0.0, 0.0, 0.0),
    ));
}

cargo run again. A blue circle sits in the middle of the window.

The shape of the code.

  • commands.spawn((..., ..., ...)) attaches a tuple of components at once.
  • Mesh2d + MeshMaterial2d are Bevy 0.15's refreshed 2D material API. Mesh and material each become their own component.
  • Transform carries position, rotation, and scale.

5.4 Move with input

Add a system to the Update schedule.

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, move_player)
        .run();
}

fn move_player(
    time: Res<Time>,
    keyboard: Res<ButtonInput<KeyCode>>,
    mut q: Query<(&mut Transform, &Speed), With<Player>>,
) {
    let dt = time.delta_secs();
    for (mut tf, speed) in &mut q {
        let mut dir = Vec2::ZERO;
        if keyboard.pressed(KeyCode::ArrowLeft)  { dir.x -= 1.0; }
        if keyboard.pressed(KeyCode::ArrowRight) { dir.x += 1.0; }
        if keyboard.pressed(KeyCode::ArrowUp)    { dir.y += 1.0; }
        if keyboard.pressed(KeyCode::ArrowDown)  { dir.y -= 1.0; }
        if dir != Vec2::ZERO {
            tf.translation += (dir.normalize() * speed.0 * dt).extend(0.0);
        }
    }
}

cargo run. Press arrow keys — the circle moves. Done.

The key patterns.

  • Res<Time> is the time resource Bevy provides automatically.
  • Res<ButtonInput<KeyCode>> is the keyboard state resource.
  • A Query of Transform and Speed, filtered with With<Player>, pulls only Player entities.
  • time.delta_secs() keeps movement frame-rate independent.

5.5 Add an enemy

#[derive(Component)]
struct Enemy;

fn setup(/* ... */) {
    // same as before

    commands.spawn((
        Enemy,
        Speed(150.0),
        Mesh2d(meshes.add(Circle::new(30.0))),
        MeshMaterial2d(materials.add(Color::srgb(1.0, 0.3, 0.3))),
        Transform::from_xyz(200.0, 200.0, 0.0),
    ));
}

fn chase_player(
    time: Res<Time>,
    player_q: Query<&Transform, With<Player>>,
    mut enemy_q: Query<(&mut Transform, &Speed), (With<Enemy>, Without<Player>)>,
) {
    let Ok(player_tf) = player_q.single() else { return };
    let dt = time.delta_secs();
    for (mut tf, speed) in &mut enemy_q {
        let dir = (player_tf.translation - tf.translation).normalize_or_zero();
        tf.translation += dir * speed.0 * dt;
    }
}

// in main: .add_systems(Update, (move_player, chase_player))

The red enemy chases the player. ECS shines here — no new class hierarchy, only a new component and a new system, and a new behavior appears.

The keeper sentence: "Reaching 'a circle that moves with arrow keys' in thirty minutes is the real first-impression test for an engine. Bevy passes."


6. Honest Comparison Against Godot, Unity, Unreal, Macroquad

An engine is not a religion. To the table.

6.1 One-line summary

  • Unity (C#) — Industry standard. Dominant for 2D indie, mobile, VR, and lightweight 3D. Editor and Asset Store are the moat.
  • Unreal Engine (C++/Blueprint) — King of AAA, cinematics, and high-end 3D. Nanite, Lumen, MetaHuman, plus enterprise-grade solutions.
  • Godot (GDScript/C#) — Indie 2D and lightweight 3D. Open source, MIT, around 50 MB editor. 3D improved a lot in the 4.x line.
  • Bevy (Rust) — ECS-first, open source, MIT/Apache. No editor (BSN proposal in progress). Closer to a library than a traditional engine.
  • Macroquad (Rust) — A minimal Rust game library that answers "I just want to start a 2D game quickly." No ECS.

6.2 Side-by-side

Language and paradigm

  • Unity: C# with OOP and component composition.
  • Unreal: C++ plus Blueprint visual scripting.
  • Godot: GDScript (Python-ish) with optional C#.
  • Bevy: Rust with ECS.
  • Macroquad: Rust, immediate-mode procedural.

Editor

  • Unity, Unreal, Godot: rich built-in GUI editors.
  • Bevy: no official editor. As of 0.15, the BSN (Bevy Scene Notation) RFC is open, and an editor will follow on top of it. Until then, runtime inspection through bevy-inspector-egui is the substitute.
  • Macroquad: no editor.

Compile speed

  • Unity, Unreal: C++/C# builds with hot-reload options.
  • Godot: GDScript runs instantly; C# compiles.
  • Bevy: Rust compiles slowly. Dev-build tweaks (opt-level=1), cargo watch -x run, and the dynamic_linking feature (on 0.x.x) bring iteration to seconds or low tens of seconds.

Runtime performance

  • Unreal: proven AAA performance, but heavy builds.
  • Unity DOTS: introduces ECS, but at the cost of a steeper curve and a split ecosystem.
  • Bevy: ECS plus Rust delivers solid multithreaded performance with safety, on relatively little code.
  • Godot: fast enough, not AAA territory.

Mobile/console builds

  • Unity, Unreal: first-class, console SDK licenses in place.
  • Godot: iOS and Android supported, consoles via third-party ports.
  • Bevy: desktop and web are smooth. iOS is possible but rough. Android is mostly nightly work. Consoles are practically impossible (licensing).

Open-source posture

  • Unity, Unreal: licensing or royalties above revenue thresholds.
  • Godot, Bevy, Macroquad: MIT/Apache, fully free.

6.3 When to choose what

  • Mobile indie 2D, simple 3D — Unity.
  • AAA graphics, cinematics — Unreal.
  • Indie 2D, GDScript-friendly team — Godot.
  • Rust lover, want ECS, building tools or simulations — Bevy.
  • "2D game jam in five hours" — Macroquad.

The keeper sentence: "Bevy is not a 'Unity replacement.' It is a different tool — correct only when you want Rust, ECS, open source, and modularity at the same time."


7. Games Actually Shipped on Bevy — What Is True

This is where honesty matters. Lists of "games made with Bevy" circulating on the internet sometimes lie.

7.1 Commercial games genuinely built on Bevy

  • Foresight — an indie RTS from Captured by Aliens. The studio publicly states they use Bevy.
  • Roll It Up — an indie casual title.
  • Tunnet — a network-simulation game developed against Bevy from early 0.x and shipped.
  • Jarl — a grid-based RTS released on Steam, Bevy-based.
  • Many itch.io jam entries — outputs of Bevy Jam (held one to two times a year). Searching bevyengine.org or itch.io/jam/bevy-jam surfaces hundreds.

7.2 The common misunderstanding — Tiny Glade

Pounce Light's Tiny Glade topped Steam Popular New Releases shortly after its September 2024 launch and became a celebrated indie simulator. It does not use Bevy — the studio built its own Rust engine. Some Rust ecosystem libraries (wgpu and others) are reused, but it is wrong to file Tiny Glade under "Bevy games." The developers have stated this in multiple interviews and GDC talks.

Ignore posts that claim "Tiny Glade was made with Bevy." The Bevy community welcomed Tiny Glade's success as evidence that "Rust games can ship," but the engine is distinct.

7.3 Non-game uses

The ECS plus wgpu combination is also used outside games.

  • Foresight Mining Software — mining simulation tooling.
  • Komodo — interactive visualization built partly on Bevy.
  • Many data-visualization, robotics-simulation, and educational demos.

The fact that the engine can be imported like a library is a real differentiator — Unity and Unreal cannot do this in practice.

The keeper sentence: "Bevy does not lie about making 'a Tiny Glade.' It tells the truth — it shipped Foresight, Jarl, and Tunnet, and it is used in data visualization and simulation as well."


8. Where Bevy Is Not Ready — Honest Limits

"Year of Bevy" has been declared in 2024, in 2025, and again in 2026. Let us split what is actually mature from what remains rough.

8.1 What matured

  • 2D rendering and basic UI — 0.15 consolidated the API around Mesh2d and MeshMaterial2d.
  • Physics — Avian is stable, covers 2D and 3D, constraints, and CCD.
  • Audiobevy_audio (basic) plus bevy_kira_audio (richer).
  • WebGPU builds — smooth enough for demos.
  • Plugin ecosystem — hundreds of entries in bevy_assets. The popular ones track each release.

8.2 What is still rough

  • No official editor. As of 0.15 the BSN (Bevy Scene Notation) RFC is in flight. It proposes a data format for scene hierarchies, assets, and materials, and an editor would follow. Adoption likely lands in 2026 to 2027.
  • Hot reload. Asset watching works; code hot reload via dynamic_linking is partial. JIT-level hot reload is still future.
  • Breaking changes across versions. Migration between 0.10 to 0.11 to 0.12 to 0.13 to 0.14 to 0.15 has been non-trivial every time. Reading the 0.15 migration guide is mandatory. This will continue until 1.0.
  • Console builds. Switch, PS5, and Xbox are practically unreachable due to licensing and closed SDKs.
  • Mobile builds. iOS works but tooling is rough; Android is nightly and experimental. Not in the same league as Unity or Unreal.
  • No GUI designer. bevy_ui is code-only; a designer-driven workflow is the BSN goal.
  • Steep learning curve. Rust plus ECS plus the Bevy API. Time-to-first-game is longer than other engines.

8.3 The road from 0.15 to 1.0

The official Bevy roadmap (as of May 2026) holds these items before 1.0.

  1. BSN landing and a minimum viable official editor.
  2. A stable ABI for dynamic plugin loading.
  3. A grounded story for hot reload.
  4. Desktop polish — multiple windows, high-DPI, drag-and-drop.
  5. Visual scripting (likely as a plugin, if at all).

Do not ask when 1.0 ships. The answer is always "when it is ready." But 0.15 is stable enough to start a small indie game today.

The keeper sentence: "Do not wait for Bevy 1.0. Build the game 0.15 lets you build now. Migrate at 1.0."


Epilogue — Guidance for People Starting Out

Thirty-minute hands-on checklist

  • Install Rust 1.81+ via rustup
  • cargo new and add bevy = "0.15" to Cargo.toml
  • Spawn Camera2d — confirm the empty window
  • Draw a circle with Mesh2d(Circle::new(40.0)) and MeshMaterial2d
  • Add a move_player system on Update reading Res<ButtonInput<KeyCode>>
  • Add an Enemy marker component plus a chase_player system
  • Run cargo run --release for an optimized build at least once
  • Try cargo build --target wasm32-unknown-unknown and wasm-bindgen for a web build
  • Attach bevy-inspector-egui to surface a runtime inspector
  • Add Avian, give the two circles colliders, and feel the collision

Seven Bevy anti-patterns

  1. Carrying a Vec<Entity> through systems and doing lookups every frame — a well-shaped query removes the need.
  2. Modeling everything as a component — state machines and small enums often belong inside a single component.
  3. Using Commands everywhere for mutation — fine, but the effect lands next frame. Use an exclusive system with &mut World when you need immediate effect.
  4. Unwrapping Query::single() with a panic — prefer let Ok(...) = q.single() else { return };.
  5. Event overflow — if no EventReader runs in a frame, the events vanish. Two systems reading the same event need consistent ordering plus an add_event registration.
  6. Putting render systems on Update — render systems are mostly internal. Your code should only write data.
  7. Ignoring 0.x migrations — each minor bump costs four to twelve hours. Bake a migration buffer into the schedule until 1.0 lands.

What is next

  • Build a 2D platformer with Avian — jumping, coyote time, gravity tuning, continuous collision detection.
  • Multiplayer shooter on Lightyear — replication, prediction, and rollback in the client-server model.
  • Bevy plus wasm plus itch.io shipping — web builds, key capture, mobile touch mapping.
  • Read the BSN RFC end to end — the shape Bevy 1.0 is aiming for and how it reshapes game code.

The keeper sentence: "Rust plus ECS is the most honest answer to the game-engine-paradigm question. Bevy is the quickest path to writing that answer with your own hands."


References

현재 단락 (1/446)

The history of game engines compresses into two lines.

작성 글자: 0원문 글자: 23,981작성 단락: 0/446