diff --git a/content/learn/book/welcome/_index.md b/content/learn/book/welcome/_index.md index 33726b27b9..5dbfcd2682 100644 --- a/content/learn/book/welcome/_index.md +++ b/content/learn/book/welcome/_index.md @@ -1,9 +1,50 @@ +++ -title = "Welcome to Bevy" +title = "Welcome" weight = 1 sort_by = "weight" template = "book-section.html" page_template = "book-section.html" +++ -TODO: Briefly discuss what Bevy is. +Welcome to the Bevy game engine! A bevy may be a group of birds, but our engine offers a fresh new experience that's: + +- **Rust-first:** all the safety, tooling and power that come with a modern systems language +- **Completely free:** [free-of-charge](https://github.com/sponsors/cart), [open source](https://github.com/bevyengine/bevy/blob/main/LICENSE), and fully customizable with an architecture designed for modularity +- **Hardware-aware:** a data-oriented design and automatic parallel scheduler provide a high-performance foundation for your game +- **Powered by an innovative ECS:** our ergonomic, type-safe, full-native entity-component-system architecture that makes writing clear, scalable gameplay and engine logic a joy +- **Cross-platform:** support Windows, MacOS, Linux, web*, Android*, iOS and more** with a single code base + +This book is designed for new and experienced users looking for a thoughtful, [explanation-first](https://diataxis.fr/explanation/) guide to the engine's essential features. +If you just want to try it out hands-on, jump into one of our [quick-start guides](TODO: add link) instead! + +*: support for these platforms is still limited; you may encounter some missing features or a [more involved setup process](https://bevy-cheatbook.github.io/platforms/wasm.html) + +**: virtual, mixed and augmented reality (aka XR) compatibility is [in development](https://github.com/bevyengine/bevy/pull/2319) + +## Stability warning + +Bevy aims to be a general-purpose game engine capable of handling arbitrary 2D or 3D games. +However, Bevy is not yet production-ready, and there are very good reasons not to choose it for your next project. +No mature solutions currently exist for: + +- animation +- networking +- console support + +The following areas are part of the engine itself, but are very immature: + +- audio +- user interfaces + +Solid third-party solutions currently exist for: + +- [advanced audio](https://crates.io/crates/bevy_kira_audio) +- [realistic physics](https://github.com/dimforge/bevy_rapier) + +While Bevy's [modular architecture](plugins/_index.md) makes it relatively easy to integrate your own (or third-party) solutions, be mindful that Bevy does not provide a complete game solution out of the box *yet*. +[Contributions to the engine](https://github.com/bevyengine/bevy/) are extremely welcome, but if you want something fully-featured to make your dream game *today*, check out [Godot](https://godotengine.org/) instead! + +Unsurprisingly, Bevy's rapid pace of development means that our APIs will break, repeatedly, in both deep and pervasive ways. +This allows us to get user feedback and refine the engine now, adding new features and fixing problems fast, rather than being tied to our first attempt. +That said, updating versions of Bevy is surprisingly painless; we provide migration guides and Rust's excellent tooling will guide you. +Chase the errors until everything compiles again and you should be basically done. diff --git a/content/learn/book/welcome/apps/_index.md b/content/learn/book/welcome/apps/_index.md new file mode 100644 index 0000000000..0b6dad0bd6 --- /dev/null +++ b/content/learn/book/welcome/apps/_index.md @@ -0,0 +1,70 @@ ++++ +title = "Apps" +weight = 2 +template = "book-section.html" +page_template = "book-section.html" ++++ + +Bevy programs store and execute all of their game logic and data with a single {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}} data structure. + +Let's make a trivial Hello World app to demonstrate how that works in practice. +The process is straightforward: we first create a new {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}}. +Then, we add a simple system, which prints "Hello, Bevy!" when it is run. +Finally once we're done configuring the app, we call {{rust_type(type="struct" crate="bevy" mod = "app" name="App" method="run" no_mod = "true")}} to actually make our app *do things*. + +```rust +use bevy::prelude::*; + +fn main(){ + App::new() + .add_system(hello) + .run(); +} + +fn hello(){ + println!("Hello, Bevy!") +} +``` + +## What makes an App? + +So, what sort of data does our {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}} really store? +Looking at the docs linked, we find three fields: `world`, `schedule` and `runner`. +The `world` field stores all of our game's data, the `schedule` holds the systems that operate on this data (and the order in which they do so) and the `runner` interprets the schedule to control the broad execution strategy. +You can read more about these by exploring the reference documentation linked just above. + +Generally, you'll be operating at a more granular level than these basic primitives: controlling data in terms of specific resources or components and adding systems to an existing schedule. +To do so, customize your own {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}} by chaining its methods with the [builder pattern](https://doc.rust-lang.org/1.0.0/style/ownership/builders.html). +The most basic tools are: + + 1. Initializing resources in the {{rust_type(type="struct" crate="bevy" mod = "ecs/world" name="World" no_mod = "true")}} to store globally available data that we only need a single copy of. + 2. Adding systems to our {{rust_type(type="struct" crate="bevy" mod = "ecs/schedule" name="Schedule" no_mod = "true")}}, which can read and modify resources and our entities' components, according to our game logic. + 3. Importing other blocks of {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}}-modifying code using plugins. +Let's write a very simple demo that shows how those work. + +```rust +use bevy::prelude::*; + +fn main() { + App::new() + // Plugins are App code that was written elsewhere, + // imported as a single unit for organization and clarity + .add_plugins(MinimalPlugins) + // Resources are global singleton data stored in the `World` + .insert_resource(Message {string: "Welcome to Bevy!"}) + // Systems run every pass of the game loop and perform logic + .add_system(print_message_system) + .run(); +} + +// This resource can store a string +struct Message { + string: String, +} + +// This system reads our Message resource, +// so we add `Res` to its function parameters +fn read_message(message: Res) { + println!(message.string); +} +``` diff --git a/content/learn/book/welcome/community/_index.md b/content/learn/book/welcome/community/_index.md deleted file mode 100644 index ce256cf037..0000000000 --- a/content/learn/book/welcome/community/_index.md +++ /dev/null @@ -1,13 +0,0 @@ -+++ -title = "The Bevy community" -weight = 5 -template = "book-section.html" -page_template = "book-section.html" -+++ - -TODO: List places where the community congregates, and differentiate - -TODO: link to awesome-bevy and discuss crate ecosystem - -TODO: link to CONTRIBUTING.md and talk about how Bevy is maintained by Cart plus a broad community of volunteers. -Link to Cart's donation page diff --git a/content/learn/book/welcome/hello-world/_index.md b/content/learn/book/welcome/hello-world/_index.md deleted file mode 100644 index f96b20ee3a..0000000000 --- a/content/learn/book/welcome/hello-world/_index.md +++ /dev/null @@ -1,12 +0,0 @@ -+++ -title = "Hello World" -weight = 3 -template = "book-section.html" -page_template = "book-section.html" -+++ - -TODO: explain basic model of how Bevy apps are structured - -TODO: demonstrate `App::new().build().run()` - -TODO: make one system that says "Hello, World!" diff --git a/content/learn/book/welcome/plugins/_index.md b/content/learn/book/welcome/plugins/_index.md index b0e526ae07..2f555e480e 100644 --- a/content/learn/book/welcome/plugins/_index.md +++ b/content/learn/book/welcome/plugins/_index.md @@ -1,16 +1,102 @@ +++ -title = "Modularity through plugins" -weight = 4 +title = "Plugins" +weight = 3 template = "book-section.html" page_template = "book-section.html" +++ -TODO: Explain how plugins work +One of Bevy's core principles is modularity. In Bevy, all functionality is implemented via {{rust_type(type="trait" crate="bevy_app" name="Plugin" plural=true)}}, which are added to an {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}}. Game logic like player movement, core engine logic like rendering and sound, and third party extensions like tile maps are all implemented the same way using {{rust_type(type="trait" crate="bevy_app" name="Plugin" plural=true)}}. -## `MinimalPlugins` - -## `DefaultPlugins` +This empowers Bevy developers to modularly "build their own engine" using official, third party, and custom {{rust_type(type="trait" crate="bevy_app" name="Plugin" plural=true)}}. Bevy intentionally blurs the lines between engine developers and app developers. ## Writing your own plugins +Plugins are collections of code that modify {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}}. +Any code in a plugin could be directly applied to the base {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}}. +There's no magic to be found here; they're just a straightforward tool for code organization. + +Plugins are types that implement the {{rust_type(type="trait" crate="bevy_app" name="Plugin")}} trait: + +```rust +use bevy::prelude::*; + +fn main(){ + App::build() + // Adds the "default" Bevy Engine plugins. + // We'll cover this in the next section. + .add_plugins(DefaultPlugins) + // Adds our new `Plugin` to the `App` + .add_plugin(ScorePlugin) + .run(); +} + +struct ScorePlugin; + +impl Plugin for ScorePlugin { + fn build(&self, app: &mut App) { + app + // The Score struct is added as a resource (global singleton) to the world, + // beginning at the default value of 0 + .init_resource::() + // Increments the score by 1 every pass of the game loop + .add_system(increment_score.system()) + // Prints the current value of the score + .add_system(report_score.system()); + } +} + +#[derive(Default, Debug)] +struct Score(u8); + +fn increment_score(score: ResMut){ + score.0 += 1; +} + +fn report_score(score: Res){ + info!(score); +} +``` + +## Plugin groups + +Bevy's {{rust_type(type="struct" crate="bevy" name="DefaultPlugins")}} is a {{rust_type(type="trait" crate="bevy_app" name="PluginGroup")}} that adds the "core engine features" like rendering, windowing, and sound that most developers want when building an app. + +You can add {{rust_type(type="struct" crate="bevy" name="DefaultPlugins")}} to your app like this: + +```rust +App::new().add_plugins(DefaultPlugins) +``` + +Take a look at the [source](https://github.com/bevyengine/bevy/blob/latest/crates/bevy_internal/src/default_plugins.rs) to see a full list of what's included. + +If you're looking to structure your Bevy app in an unusual way (for example, if you want to run it in a [headless fashion](https://github.com/bevyengine/bevy/blob/latest/examples/app/headless.rs)) and don't want to use most of the functionality provided by the engine, you can choose to use Bevy's {{rust_type(type="struct" crate="bevy" name="MinimalPlugins")}} instead. + ## Third-party plugins + +Importing 3rd-party plugins is easy; they're just ordinary Rust code that can be managed with `cargo`. +Bevy's modular nature tends to result in simple plug-and-play interoperability and easy extensibility, so don't be afraid to try out plugins that seem interesting or useful for your game. + +1. Find a Bevy plugin (such as from our [collection of assets](https://bevyengine.org/assets/)). +2. Add it to your `Cargo.toml` as a crate under `[dependencies]`. +3. Import the code definitions from the crate (i.e. `using bevy_third_party::prelude::*`) to add the appropriate items to your workspace. +4. Add the plugin to your app (i.e. `app.add_plugin(bevy_third_party_plugin)`)! + +Follow the documentation and examples from the crates you're importing to make sure you have everything configured properly. + +If you plan on releasing a plugin yourself, please refer to [Bevy's Plugin Guidelines](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md), [release a crate](https://doc.rust-lang.org/cargo/reference/publishing.html), and then [add it to Bevy Assets](https://github.com/bevyengine/bevy-assets/) to share it with the community! + +## Pick-and-choose features + +Some apps won't need all of the features provided by {{rust_type(type="struct" crate="bevy" name="DefaultPlugins")}}. Other features must be opted into. We can use [cargo features](https://doc.rust-lang.org/cargo/reference/features.html) to enable and disable what features are compiled into our game. + +In your `Cargo.toml` file, you can disable default features and opt-in to the [features you want](https://github.com/bevyengine/bevy/blob/main/docs/cargo_features.md): + +```toml +[dependencies] +bevy = { version = "0.5", default-features = false, features = ["feature_name"] } +``` + +As shown in the [`plugin_group.rs`](https://github.com/bevyengine/bevy/blob/latest/examples/app/plugin_group.rs) example, you can also configure plugin groups from within Bevy itself. + +Many of Bevy's subcrates can also be used directly on their own and integrated with other engines or your own framework. +[`bevy_ecs`](https://crates.io/crates/bevy_ecs) is a particularly popular choice for this, allowing you to use our fast, featureful ECS in more unusual projects. diff --git a/content/learn/book/welcome/installation/_index.md b/content/learn/book/welcome/setup/_index.md similarity index 50% rename from content/learn/book/welcome/installation/_index.md rename to content/learn/book/welcome/setup/_index.md index e34b5a04ee..e1a4704827 100644 --- a/content/learn/book/welcome/installation/_index.md +++ b/content/learn/book/welcome/setup/_index.md @@ -1,6 +1,6 @@ +++ -title = "Installing Rust and Bevy" -weight = 2 +title = "Setup" +weight = 1 template = "book-section.html" page_template = "book-section.html" +++ @@ -15,13 +15,13 @@ All Bevy app and engine code is written in Rust. This means that before we begin Install Rust by following the [Rust Getting Started Guide](https://www.rust-lang.org/learn/get-started). -Once this is done, you should have the ```rustc``` compiler and the ```cargo``` build system installed in your path. +Once this is done, you should have the `rustc` compiler and the `cargo` build system installed in your path. ### Install OS dependencies * [Linux](https://github.com/bevyengine/bevy/blob/main/docs/linux_dependencies.md) * Windows: Make sure to install [VS2019 build tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16) -* MacOS: No dependencies here +* MacOS: No dependencies here! ### Code Editor / IDE @@ -45,13 +45,15 @@ Now we are ready to set up a Bevy project! Bevy is just a normal Rust dependency ### Create a new Rust 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: +First, navigate to a folder where you want to create your new project. Then, run the following command to create (and then navigate to) a new folder containing our rust executable project: ```sh cargo new my_bevy_game cd my_bevy_game ``` +If you already have a folder that you'd like to use, use `cargo init` from within that folder instead. + 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: @@ -95,6 +97,81 @@ Now run `cargo run` again. The Bevy dependencies should start building. This wil Now that we have our Bevy project set up, we're ready to start making our first Bevy app! +### Checking that it works + +Within `main.rs`, let's create our first app and check that all the dependencies are working correctly! + +```rust +use bevy::prelude::*; + +fn main(){ + App::build().add_plugins(DefaultPlugins).run(); +} +``` + +Use `cargo run` to test it out. +This will just show an empty window, and includes all of the standard functionality needed to make Bevy games. + +### Performance by default + +Rust's compiler supports several levels of performance optimization, with fairly dramatic effects on Bevy's performance. +For a more pleasant and realistic development experience, we recommend enabling optimized compilation by default by adding the following lines to your `Cargo.toml`. + +```toml +[profile.dev] +opt-level = 3 +``` + +### Faster compiling + +* **Bevy's Dynamic Linking Feature**: This is the most impactful iterative compilation time decrease! It requires no special setup except on Windows, where you also have to follow the three numbered steps below for it to work. If `bevy` is a dependency you can compile the binary with the `dynamic` feature flag (enables dynamic linking): + + ```sh + cargo run --features bevy/dynamic + ``` + + If you don't want to add the `--features bevy/dynamic` to each run, this flag can permanently be set via `Cargo.toml`: + + ```toml + [dependencies] + bevy = { version = "0.5.0", features = ["dynamic"] } + ``` + + NOTE: Remember to revert this before releasing your game! Otherwise you will need to include `libbevy_dylib` alongside your game if you want it to run. If you remove the `dynamic` feature, your game executable can run standalone. + +For the fastest iterative compile times, we recommend the following configuration as well. You need to follow all three steps for any effect: + +1. **LLD linker**: The Rust compiler spends a lot of time in the "link" step. LLD is _much faster_ at linking than the default Rust linker. To install LLD, find your OS below and run the given command: + * **Ubuntu**: `sudo apt-get install lld clang` + * **Arch**: `sudo pacman -S lld` + * **Windows**: Ensure you have the latest [cargo-binutils](https://github.com/rust-embedded/cargo-binutils) + + ```sh + cargo install -f cargo-binutils + rustup component add llvm-tools-preview + ``` + + * **MacOS**: Modern LLD does not yet support MacOS, but we can use zld instead: `brew install michaeleisel/zld/zld` +2. **Nightly Rust Compiler**: This gives access to the latest performance improvements and "unstable" optimizations + + ```sh + # Install the nightly toolchain + rustup toolchain install nightly + # EITHER configure your current project to use nightly (run this command within the project) + rustup override set nightly + # OR configure cargo to use nightly for all projects -- switch back with `rustup default stable` + rustup default nightly + ``` + + You can use `cargo +nightly ...` if you don't want to change the default to nightly, but just want to use it once for the current command. + +3. **Configure cargo**: With the linker installed and nightly rust activated, all we need to do now is put them to proper use. Copy [this file](https://github.com/bevyengine/bevy/blob/main/.cargo/config_fast_builds) to `YOUR_WORKSPACE/.cargo/config.toml`. For the project in this guide, that would be `my_bevy_game/.cargo/config.toml`. + + Beyond enabling the LLD linker, this configuration file also activates **Generic Sharing** (unless you use Windows), which 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 only available on nightly Rust. + +4. **Hot reloading**: Sometimes, the fastest compilation is no compilation. +For instant, compile-free simple changes, the excellent community-run [`bevy-inspector-egui`](https://crates.io/crates/bevy-inspector-egui) crate allows you to visually edit the values of your structs, and see the effect on your game in real time. + ## Troubleshooting Having trouble getting Bevy running? diff --git a/content/learn/book/welcome/why-bevy/_index.md b/content/learn/book/welcome/why-bevy/_index.md deleted file mode 100644 index 5134f6ac56..0000000000 --- a/content/learn/book/welcome/why-bevy/_index.md +++ /dev/null @@ -1,12 +0,0 @@ -+++ -title = "Why Bevy?" -weight = 1 -template = "book-section.html" -page_template = "book-section.html" -+++ - -TODO: discuss the cool features and design philosophy - -## Why not Bevy? - -TODO: discuss current limitations