Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Welcome chapter #176

Merged
merged 44 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f734bc5
Welcome blurb
alice-i-cecile Jun 14, 2021
528a91f
Community blurb
alice-i-cecile Jun 14, 2021
b35d0b8
Why not Bevy
alice-i-cecile Jun 14, 2021
8e7794c
Hello World
alice-i-cecile Jun 14, 2021
b0a7a0b
Quick draft on plugins
alice-i-cecile Jun 14, 2021
d82ee9b
Explain MinimalPlugins
alice-i-cecile Jun 14, 2021
9896278
Disabling plugins
alice-i-cecile Jun 14, 2021
1c28e56
Third-party plugins
alice-i-cecile Jun 14, 2021
62b998a
Removed Community page
alice-i-cecile Jun 16, 2021
07f4528
Content polish
alice-i-cecile Jun 16, 2021
50dbe1c
Link to documentation strategies
alice-i-cecile Jun 16, 2021
bef720e
Typo
alice-i-cecile Jun 16, 2021
a4ef5f8
Typo fix
alice-i-cecile Jun 16, 2021
a0b0363
Use link over embedding default plugins code
alice-i-cecile Jun 19, 2021
ab2410c
Better explained how plugins work
alice-i-cecile Jun 19, 2021
b6b0de4
Concrete example of a plugin before jumping to DefaultPlugins
alice-i-cecile Jun 19, 2021
0e9677d
Added page on App and AppBuilder
alice-i-cecile Jun 19, 2021
0b38fba
Fix hello_world code
alice-i-cecile Jun 19, 2021
138fa48
Swapped out Hello World example in Installation
alice-i-cecile Jun 19, 2021
70fbcb1
Condensed section on MinimalPlugins to link to code
alice-i-cecile Jun 19, 2021
c2f9070
Added advice on publishing 3rd party plugins
alice-i-cecile Jul 31, 2021
b2f30c1
Removed references to AppBuilder
alice-i-cecile Jul 31, 2021
a3a00ad
Encourage the reader to explore the reference docs more
alice-i-cecile Jul 31, 2021
3e370de
Introduction page optimism and clarity
alice-i-cecile Aug 1, 2021
190c6a2
Cleaned up game terminology
alice-i-cecile Aug 1, 2021
ec50cff
dbg -> info
alice-i-cecile Aug 1, 2021
f2799f5
Clarity improvements for Plugin page
alice-i-cecile Aug 2, 2021
fc9a7ad
Clarity improvements for `App` page
alice-i-cecile Aug 2, 2021
d8ebee3
Clarified that Bevy is both free and libre
alice-i-cecile Aug 2, 2021
4f169ab
Clarity improvements to Welcome page
alice-i-cecile Aug 2, 2021
ee2bfc3
Removed .system() call
alice-i-cecile Aug 6, 2021
4bd12cc
Typo fix
alice-i-cecile Aug 6, 2021
ce83f85
Style and phrasing tweaks
cart Aug 6, 2021
97a6f91
Mention efforts towards XR support
alice-i-cecile Aug 9, 2021
2f0c543
Removed code blocks from headings
alice-i-cecile Aug 9, 2021
331e951
Use shortcodes
alice-i-cecile Aug 9, 2021
c289603
Tiny cleanup
alice-i-cecile Aug 13, 2021
7042901
Swapped out Fibonacci example
alice-i-cecile Aug 13, 2021
c7aa36b
Misc cleanup; credit to @djeedai
alice-i-cecile Oct 13, 2021
b8a794f
Introductory text polish
alice-i-cecile Oct 13, 2021
662380b
Better setup page, including @lukors work in #137
alice-i-cecile Oct 13, 2021
2ae0898
More review in App page
alice-i-cecile Oct 13, 2021
5faa8fa
Cut detail about minimal plugins
alice-i-cecile Oct 13, 2021
0386180
Slightly better cargo new directions
alice-i-cecile Oct 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions content/learn/book/welcome/_index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,49 @@
+++
title = "Welcome to Bevy"
title = "Welcome"
weight = 1
sort_by = "weight"
template = "book-section.html"
page_template = "book-section.html"
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
+++

TODO: Briefly discuss what Bevy is.
Welcome to the Bevy game engine! A bevy may be a group of birds, but our engine is:

- **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 hackable with an architecture designed for modularity
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
- **Innovative ECS:** powered by an ergonomic, full-native entity-component-system architecture that makes writing clear, performant gameplay and engine logic a joy
- **Cross-platform:** support Windows, MacOS, Linux, web*, Android*, iOS and more** with a single code base
- **Effortless parallelism:** a data-oriented design and automatic parallel scheduler provide a high-performance foundation for your game

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
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
**: virtual and augmented reality (aka XR) compatability 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 still in its infancy, and there are very good reasons not to choose it for your next project.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
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 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*.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
[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.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to consider: Rust is often considered to be in line with "if it compiles, it works" - however, I think bevy is not matured there yet. Maybe a good to mention in docs?

(920+ unwrap() or panic!'s in code currently - I've personally been caught by a surprise few times to runtime crashes)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably a good caveat. Compared to other game engines, it's surprisingly "if it compiles it works". But much less so for people coming to games from the Rust ecosystem!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "if it compiles, it works" is an unrealistic goal because Rust's static guarantees are just a subset of its capabilities. I also don't think that "number of unwraps" is a particularly good measure of code maturity. There are plenty of cases where the only real option is an internal unwrap.

That being said, except in a few specific cases, Bevy internals shouldn't crash from normal "userspace" code (and they do currently in a number of cases).

Its worth calling out that Bevy currently has more rough edges / bugs / crashes than a stable product would. However this page is also the first thing Bevy users will see and I consider it a key part of "Bevy marketing". We should do it in a way that doesn't (1) scare people away or (2) give the wrong impression about our goals and priorities. Feel free to add a line here, but (as I've already warned @alice-i-cecile) I have a lot of very specific goals for this page and I'll probably follow this pr up with a lot of changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except in a few specific cases

Are these cases outlined elsewhere? While I agree that they shouldn't be listed on the first welcome page, perhaps a link to the "rough edges" would be appropriate.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was good discussion in Discord about the unwrap's as well yesterday. I agree that there will be unwraps, and some of them are totally okay as well (e.g. when starting app, during development work). Also, of the 920+ quite many seemed to be in the tests code, which I did not consider when grepping.

Good point about the marketing, maybe the extra warning should not be yet - the section header "Stability warning" already gives a hint about it.

Also, over time the runtime panic's will get lower and lower. However, I would still be very mindful of this, since an unanticipated runtime panic at wrong point (e.g. demo time, or in production) will quickly turn new adopters away.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these cases outlined elsewhere? While I agree that they shouldn't be listed on the first welcome page, perhaps a link to the "rough edges" would be appropriate.

They are not. It will be hard to maintain the list unless it integrates directly with the issue tracker. Maybe we should have a label for "UX speedbumps". We can link to that specific label. And that way whenever we resolve an issue, the list is automatically updated.

This allows us to refine the engine now, adding new features and fixing problems fast, rather than being tied to a 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.
81 changes: 81 additions & 0 deletions content/learn/book/welcome/apps/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
+++
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" no_mod = "true")}} to actually make our app *do things*.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved

```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.
Copy link
Contributor

@IceSentry IceSentry Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not immediately obvious to me which documentation link this is referencing. I think adding an actual link here would be better.


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 global data.
2. Adding systems to our {{rust_type(type="struct" crate="bevy" mod = "ecs/schedule" name="Schedule" no_mod = "true")}} to perform logic.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
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(DefaultPlugins)
// Resources are global singleton data stored in the `World`
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
.insert_resource(Fibonacci { a: 1, b: 1 })
// Systems run every pass of the game loop and perform logic
.add_system(fibonacci_sum.system())
.add_system(report_fibonacci.system())
.run();
}

// A simple data structure to store the two current fibonacci numbers
struct Fibonacci {
a: u64,
b: u64,
}

// This system requires mutable access to our Fibonacci resource,
// so we add `ResMut` to its function parameters
fn fibonacci_sum(mut fibonacci: ResMut<Fibonacci>) {
// This crashes fairly quickly, as we overflow our u64 data storage
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
let new_sum = fibonacci.a + fibonacci.b;
fibonacci.a = fibonacci.b;
fibonacci.b = new_sum;
}

// This system only reads the value of our Fibonacci resource,
// so we only need `Res`
fn report_fibonacci(fibonacci: Res<Fibonacci>) {
info!(fibonacci.a, fibonacci.b);
}
```
13 changes: 0 additions & 13 deletions content/learn/book/welcome/community/_index.md

This file was deleted.

12 changes: 0 additions & 12 deletions content/learn/book/welcome/hello-world/_index.md

This file was deleted.

21 changes: 18 additions & 3 deletions content/learn/book/welcome/installation/_index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
+++
title = "Installing Rust and Bevy"
weight = 2
title = "Setup"
weight = 1
template = "book-section.html"
page_template = "book-section.html"
+++
Expand All @@ -15,7 +15,7 @@ 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

Expand Down Expand Up @@ -95,6 +95,21 @@ 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.

## Troubleshooting

Having trouble getting Bevy running?
Expand Down
100 changes: 94 additions & 6 deletions content/learn/book/welcome/plugins/_index.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,104 @@
+++
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 substituted directly on the base {{rust_type(type="struct" crate="bevy" mod = "app" name="App" no_mod = "true")}}.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
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::<Score>()
// 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>){
score.0 += 1;
}

fn report_score(score: Res<Score>){
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 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.

We can click through to the [source]((https://github.com/bevyengine/bevy/blob/latest/crates/bevy_internal/src/default_plugins.rs)) for the `impl PluginGroup for MinimalPlugins` to see that this adds {{rust_type(type="struct" crate="bevy_core" name="CorePlugin")}} and {{rust_type(type="struct" crate="bevy_app" name="ScheduleRunnerPlugin")}}.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved

The {{rust_type(type="struct" crate="bevy_core" name="CorePlugin")}} handles low-level fundamentals such as updating app time, while the {{rust_type(type="struct" crate="bevy_app" name="ScheduleRunnerPlugin")}} sets up the main game loop to run repeatedly over time.
This functionality is essential: starting with these plugins is virtually always going to be a safe bet.

## 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.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved

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.
12 changes: 0 additions & 12 deletions content/learn/book/welcome/why-bevy/_index.md

This file was deleted.