Setup
I know you are itching to start making games, but we need to do a small amount of setup first.
Rust Setup #
All Bevy app and engine code is written in Rust. This means that before we begin, we need to set up our Rust development environment.
Installing Rust #
Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is "the latest stable release" of Rust.
Install Rust by following the Rust Getting Started Guide.
Once this is done, you should have the rustc
compiler and the cargo
build system installed in your path.
Installing OS Dependencies #
Linux #
Follow the instructions at Linux Dependencies
Windows #
- Run the Visual Studio 2019 build tools installer
- For easy setup, select the
Desktop development with C++
workload in the installer. - For a minimal setup, follow these steps:
- In the installer, navigate to
Individual components
- Select the latest
MSVC
for your architecture and version of Windows - Select the latest
Windows SDK
for your version of Windows - Select the
C++ CMake tools
for Windows component - Install the components
- In the installer, navigate to
Code Editor / IDE #
You can use any code editor you want, but we highly recommend one that has a rust-analyzer plugin. It's still in development, but it already provides top-tier autocomplete and code intelligence. Visual Studio Code has an officially supported rust-analyzer extension.
Rust Learning Resources #
The goal of this guide is to get started learning Bevy quickly, so it won't serve as a full Rust education. If you would like to learn more about the Rust language, check out the following resources:
- The Rust Book: the best place to learn Rust from scratch
- Rust by Example: learn Rust by working through live coding examples
- Rustlings: learn Rust through a series of fun and interactive exercises
Create a new Bevy Project #
Now we are ready to set up a Bevy project! Bevy is just a normal Rust dependency. You can either add it to an existing Rust project or create a new one. For completeness we will assume you are starting from scratch.
Create a new Rust executable project #
First, navigate to a folder where you want to create your new project. Then, run the following command to create a new folder containing our rust executable project:
cargo new my_bevy_game
cd my_bevy_game
Now run cargo run
to build and run your project. You should see Hello, world!
printed to your terminal. Open the my_bevy_game
folder in your code editor of choice and take some time to look through the files.
main.rs
is the entry point of your program:
fn main() {
println!("Hello, world!");
}
Cargo.toml
is your "project file". It contains metadata about your project such as its name, dependencies, and build configuration.
[package]
name = "my_bevy_game"
version = "0.1.0"
edition = "2021"
[dependencies]
Add Bevy as a dependency #
Bevy is available as a library on crates.io, the official Rust package repository.
The easiest way to add it to your project is to use cargo add
:
cargo add bevy
Alternate - Manually Add Bevy to Cargo.toml
You can also manually add it to your project's Cargo.toml like this:[package]
name = "my_bevy_game"
version = "0.1.0"
edition = "2021" # this needs to be 2021, or you need to set "resolver=2"
[dependencies]
bevy = "0.14" # make sure this is the latest version
Make sure to use the latest If you are using Cargo Workspaces, you will also need to add the resolver to your Cargo.toml file in the root directory:bevy
crate version ().Cargo Workspaces #
[workspace]
resolver = "2" # Important! wgpu/Bevy needs this!
Compile with Performance Optimizations #
While it may not be an issue for simple projects, debug builds in Rust can be very slow - especially when you start using Bevy to make real games.
It's not uncommon for debug builds using the default configuration to take multiple minutes to load large 3D models, or for the framerate for simple scenes to drop to near-unplayable levels.
Fortunately, there is a simple fix, and we don't have to give up our fast iterative compiles! Add the following to your Cargo.toml
:
# Enable a small amount of optimization in the dev profile.
[profile.dev]
opt-level = 1
# Enable a large amount of optimization in the dev profile for dependencies.
[profile.dev.package."*"]
opt-level = 3
You might think to simply develop in release mode instead, but we recommend against this as it can worsen the development experience by slowing down recompiles and disabling helpful debug symbols and assertions. In fact, you may want to trade even more compile time for performance in release mode by adding the following to your Release Mode Optimizations (Optional)
Cargo.toml
:# Enable more optimization in the release profile at the cost of compile time.
[profile.release]
# Compile the entire crate as one unit.
# Slows compile times, marginal improvements.
codegen-units = 1
# Do a second optimization pass over the entire program, including dependencies.
# Slows compile times, marginal improvements.
lto = "thin"
# Optimize for size in the wasm-release profile to reduce load times and bandwidth usage on web.
[profile.wasm-release]
# Default to release profile values.
inherits = "release"
# Optimize with size in mind (also try "z", sometimes it is better).
# Slightly slows compile times, great improvements to file size and runtime performance.
opt-level = "s"
# Strip all debugging information from the binary to slightly reduce file size.
strip = "debuginfo"
When releasing for web, you can pass Binaryen is a Wasm compiler toolchain that provides a Note that See the following for more information on optimizing Wasm:--profile wasm-release
to cargo
instead of --release
.Advanced Wasm optimizations (Optional) #
wasm-opt
CLI tool for making .wasm
files smaller and faster:wasm-opt -Os --output output.wasm input.wasm
wasm-opt
runs very slowly, but it can make a big difference, especially in combination with the optimizations from the previous section.
Enable Fast Compiles (Optional) #
Bevy can be built just fine using default configuration on stable Rust. Unfortunately, the compile times are rather long. This section explains how to speed up iterative compiles: the amount of time it takes to rebuild your project after changing a single file. This is the most impactful compilation time decrease! You can compile If you don't want to add the The Rust compiler spends a lot of time in the final "link" step, especially with a massive library like Bevy. Ubuntu: Fedora: Arch: Windows: Ensure you have the latest cargo-binutils as this lets commands like MacOS: On MacOS, the default system linker Then, add one of the following to your Cargo config at Mold is up to 5× (five times!) faster than LLD, but with a few caveats like limited platform support and occasional stability issues. To install mold, find your OS below and run the given command: You will also need to add the following to your Cargo config at This gives access to the latest performance improvements and "unstable" optimizations, including generic sharing below. Create a For more information, see The rustup book: Overrides. This uses a new nightly-only codegen that is about 30% faster at compiling than LLVM. It currently works best on Linux. To install cranelift, run the following. To activate it for your project, add the following to your This enables faster compiles for your binary, but builds Bevy and other dependencies with the more-optimized LLVM backend. See the cranelift setup guide for details on other ways in which cranelift can be enabled. The installation process for Windows is a bit more involved. Consult the linked documentation for help. MacOS builds can currently crash on Bevy applications, so you should still wait a bit before using cranelift on that system. While cranelift is very fast to compile, the generated binaries are not optimized for speed. Additionally, it is generally still immature, so you may run into issues with it. Notably, Wasm builds do not work yet. When shipping your game, you should still compile it with LLVM. Allows crates to share monomorphized generic code instead of duplicating it. In some cases this allows us to "precompile" generic code so it doesn't affect iterative compiles. This is currently only available on nightly Rust (see above). See this file for a more comprehensive, cross-platform example. Bevy's dependencies do a lot of trace logging that is not relevant for an end user. To improve your runtime performance, you can add the following to the Dynamic Linking #
bevy
as dynamic library, preventing it from having to be statically linked each time you rebuild your project. You can enable this with the dynamic_linking
feature flag.cargo run --features bevy/dynamic_linking
--features bevy/dynamic_linking
to each run, this flag can permanently be set with this command (edits Cargo.toml
for you):cargo add bevy -F dynamic_linking
Alternative Linkers #
lld
is much faster at linking than the default Rust linker. To install LLD, find your OS below and run the given command.LLD Installation
sudo apt-get install lld clang
sudo dnf install lld clang
sudo pacman -S lld clang
cargo run
use the LLD linker automatically.cargo install -f cargo-binutils
rustup component add llvm-tools-preview
ld-prime
is faster than LLD./path/to/project/.cargo/config.toml
(where /path/to/project
is the directory which contains Cargo.toml
) depending on your OS:# for Linux
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
# for Windows
[target.x86_64-pc-windows-msvc]
linker = "rust-lld.exe"
Alternative - Mold
sudo apt-get install mold clang
sudo dnf install mold clang
sudo pacman -S mold clang
/path/to/project/.cargo/config.toml
:[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold"]
Nightly Rust Compiler #
rust-toolchain.toml
file in the root of your project, next to Cargo.toml
.[toolchain]
channel = "nightly"
Cranelift #
rustup component add rustc-codegen-cranelift-preview --toolchain nightly
.cargo/config.toml
.[unstable]
codegen-backend = true
[profile.dev]
codegen-backend = "cranelift"
[profile.dev.package."*"]
codegen-backend = "llvm"
Generic Sharing #
Generic sharing setup #
# /path/to/project/.cargo/config.toml
[target.x86_64-unknown-linux-gnu]
rustflags = [
# (Nightly) Make the current crate share its generic instantiations
"-Zshare-generics=y",
]
Improve Runtime Performance (Optional) #
[dependencies]
section of your Cargo.toml. It will disable detailed log levels on compile time so that they do not need to be filtered out while your app is running.log = { version = "*", features = ["max_level_debug", "release_max_level_warn"] }
Build Bevy #
Now run cargo run
again. The Bevy dependencies should start building. This will take some time as you are essentially building an engine from scratch. You will only need to do a full rebuild once. Every build after this one will be fast!
Now that we have our Bevy project set up, we're ready to start making our first Bevy app!