From 56f519a8aad5574561901b75dbadb3dc3baff62e Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Mon, 24 May 2021 17:50:33 -0400 Subject: [PATCH 01/24] Add user-facing explanation to CONTRIBUTING.md Copied verbatim from https://github.com/bevyengine/rfcs/blob/main/rfcs/22-quick-start-book.md --- CONTRIBUTING.md | 147 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..e72cde671d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,147 @@ +So, you want to help write some learning material for the [Bevy website](https://bevyengine.org/)? + +As you probably noticed, our introductory learning material is split into two main sections: + +1. **Bevy Quick Start:** "Get started making your first game now!" +2. **Bevy Book:** "Understand how Bevy works, and how you can use it" + +This is intended to cater to two different types of learners, without compromising the experience for either: + +- **Example-first:** These users want to dive right in, see everything in action and get a working game as quickly as possible. +These users often have an idea in their mind that they want to start prototyping as quickly as possible. +- **Definition-first:** These users want to carefully build up a mental model of Bevy, thoroughly understanding each new concept before moving on. +These users tend to be driven by curiosity, or are aiming to carefully develop a new skill. + +Crucially, these paths are independent of the experience levels of the learner! +Bevy intentionally aims to be inclusive of both complete beginners who have never programmed before, and professionals coming from other engines. + +| | **Beginner** | **Professional** | +| -------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------- | +| **Example-first** | Enthusiastic, wants to create a new version of the game they love. | Exploratory, wants to dive in and see how Bevy holds up in practice. | +| **Definition-first** | Curious, wants to understand how making games works. | Critical, wants to understand Bevy's unique design choices. | + +Each of these requires their own complementary learning paths that branch as soon as they get to the [Learn page](https://bevyengine.org/learn/) to ensure that the first experience that they have with Bevy matches what they need. + +Once users have completed the introductory learning materials in their path of choice, they can begin creating their own games or move on to our advanced examples to see how everything comes together in a realistic way. + +### Bevy Quick Start: the example-first path + +Users following the example-first path will tend to take the following route: + +1. Encounter the Bevy homepage due to social media or word of mouth. +2. Navigate to the Learn page. +3. Choose one of the most relevant **quick start games**. +4. Complete that tutorial. +5. Dive into making the game they have in mind, accessing the following resources as needed when they encounter road-blocks: + 1. Official Examples. + 2. The Bevy book. + 3. Community tutorials and template games. + 4. Various community support forums. + 5. Streams, YouTube channels and blogs. + 6. Advanced examples. + +Each quick start game should: + +1. Assume zero existing knowledge of Bevy. +2. Begin with a initial high-level explanation of what we're trying to build. +3. Introduce commented code first, then explain what each of the critical terms means as they come up. +4. Be broken into compilable, playable sections: one per page of the guide. +5. Gradually refactor the code to add more functionality. +6. End with a list of suggestions (with appropriate links) on how you could extend the game in interesting ways. + +This path should prioritize: + +1. Rapid time-to-fun. +2. Functional, good-enough explanations that are tied to the code in front of them. +3. Relevance of quick-start game to the genre of game they want to make. +4. High asset quality. +5. Ease of extending the quick-start game with their own tweaks. +6. Explaining how to get unstuck, through documentation, community help and filing issues. + +### The Bevy Book: the definition-first path + +Users following the definition-first path will tend to take the following route: + +1. Encounter the Bevy homepage due to social media or word of mouth. +2. Navigate to the Learn page. +3. Select the **Bevy book**. +4. Read through the book, largely in order. +5. Once they feel they have a good enough understanding of the engine, they will begin to make their own games, typically by jumping over onto the example-first path. +6. As they explore, they will also browse: + 1. The source code. + 2. [docs.rs](https://docs.rs/bevy/) + 3. CONTRIBUTING.md, GitHub issues and pull requests. + 4. Release notes. + 5. The engine development channels on Discord. + 6. Advanced examples to see how everything comes together. + +Each chapter of the Bevy Book should: + +1. Have a clear topic, and give a high-level overview of the subtopics it is going to cover and how they fit together. +2. Be broken down into several sections / pages to focus on detailed topics. + 1. These should have simple, minimal examples explaining how that functionality works. +3. Link to appropriate sections of quick start guides that demonstrate the ideas being taught in a more coherent way. + +This path should prioritize: + +1. Clear, thorough explanations. +2. Carefully introducing one concept at a time in an organized fashion. +3. Connecting concepts to each other in context. +4. Explaining the technical details of how things work, but only in clearly marked asides. +5. Communicating all of the supporting development practices that make Bevy productive: + 1. How to set up your dev environment. + 2. Code organization. + 3. Design patterns and best practices. + 4. Testing, benchmarking and debugging. + 5. Contributing to Bevy itself. +6. Linking to further reading: official examples, `docs.rs` and (very sparingly) source code links. + +### Contributor's style guide + +When writing and reviewing learning material for the Bevy Book and Quick Start Games, please try to follow these guidelines: + +#### Writing + +1. Use clear, simple language. +2. Prefer short sentences. Remove extra words. +3. **Bold** new vocabulary words where they are defined. + 1. Define them as soon as is reasonable after they are introduced. +4. Make sure your grammar and spelling are correct. +5. Avoid idioms and slang. +6. Speak directly to the reader in an approachable tone. Use "we" and "you" pronouns. +7. It can be useful to create specific, named characters to demonstrate a point. + 1. If you do, pick a pronoun set for them and stick to it. + 2. Otherwise, use "they/them" third-person pronouns to refer to the reader or others. +8. Keep humor light. + 1. Avoid off-color or offensive humor. + 2. Be mindful not to overuse in-jokes or cultural references. + 3. Don't drag your jokes out: that's not what the audience is here to read. + +#### Organizational + +1. Carefully organize your work into separate pages, headings, paragraphs and code blocks. +2. Clearly signal when you are explaining a concept in technical depth so it can be skipped. +3. Use lists, numbered lists and sub-lists to present information in bite-sized ways. + 1. Refer back to these items by number! +4. Provide plenty of links, but be sure that what you are linking to is obvious by context. + 1. Link to other sections of the book / example / web page when you mention them. + 2. Always link to the most specific location you can, whether that's a section on a page or a method on a struct. + 3. Use the `latest` tag when linking to Bevy docs and source code so it won't go stale every time the version is updated. + 4. When linking to detailed explanations or discussions, summarize the most important points in addition to providing a link. + +#### Technical + +1. All examples must be able to be compiled and run. +2. Prefer game-relevant, descriptive examples and variable names over generic ones like `MyEvent`. Avoid meaningless names like `foo` at all times. +3. It's good practice to break your code into blocks with comments or explanatory text, but you need to link to a cohesive, copy-able whole at the end. +4. Examples must pass Bevy's standard `clippy` lints. +5. The polish level of your examples should correspond to the point you're trying to make. + 1. If you're demonstrating a new feature, show only the most basic syntax as locally as possible. + 2. When trying to explain how a game can be made, organize and polish your code to showcase best practices. + 3. Lack of polish should serve an end: don't show bad or sloppy practices without a good reason. + 4. Showing how (and why!) to refactor your code is a very powerful teaching tool. +6. Stick to a consistent style (e.g. for loops vs map) within each example. +7. If you need to give advice that will only matter to some of your audience (e.g. how to handle an edge case, or support a specific platform), do so in a clearly marked aside or list. +8. Examples should not use or rely on third-party plugins. +These may be appropriate to link in "next steps" however at the end of the examples. + 1. Third-party crates should be limited to the most essential, such as `rand`. From fd6e055fcb2b31fb5101096fbeeac4dd5873793d Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Mon, 24 May 2021 18:04:50 -0400 Subject: [PATCH 02/24] Revised guidance on state of docs --- content/news/2020-08-10-introducing-bevy/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/news/2020-08-10-introducing-bevy/index.md b/content/news/2020-08-10-introducing-bevy/index.md index e70d8999cb..ef3a0c3fe6 100644 --- a/content/news/2020-08-10-introducing-bevy/index.md +++ b/content/news/2020-08-10-introducing-bevy/index.md @@ -1129,7 +1129,7 @@ There are plenty of areas that need more design work or features. For example, I ### Documentation -Bevy's APIs are still very unstable, so I haven't spent much time documenting anything yet. [The Bevy Book](https://bevyengine.org/learn/book/introduction/) is still small and the [Rust API Docs](https://docs.rs/bevy) have plenty of gaps. In general I subscribe to the idea of "documentation proportional to stability". As features stabilize and design patterns emerge, we will increase efforts in both of those areas. +Bevy's APIs are still quite unstable, so documentation is spotty. [The Bevy Book](https://bevyengine.org/learn/book/welcome/) only covers relatively mature areas of the engine and the [Rust API Docs](https://docs.rs/bevy) have plenty of gaps. In general I subscribe to the idea of "documentation proportional to stability". As features stabilize and design patterns emerge, we will increase efforts in both of those areas. ## Join the Bevy! From 6efe94bf804e57934e0349807ac96c8fccb18533 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Mon, 24 May 2021 18:05:11 -0400 Subject: [PATCH 03/24] Removed old book content --- content/learn/book/_index.md | 2 +- content/learn/book/contributing/_index.md | 16 - .../learn/book/contributing/code/_index.md | 32 -- .../learn/book/contributing/docs/_index.md | 59 ---- content/learn/book/faq/_index.md | 28 -- content/learn/book/getting-started/_index.md | 66 ---- .../learn/book/getting-started/apps/_index.md | 25 -- .../learn/book/getting-started/ecs/_index.md | 137 -------- .../book/getting-started/plugins/_index.md | 97 ------ .../book/getting-started/resources/_index.md | 63 ---- .../book/getting-started/setup/_index.md | 130 -------- content/learn/book/introduction/_index.md | 39 --- .../book/migration-guides/0.4-0.5/_index.md | 298 ------------------ content/learn/book/migration-guides/_index.md | 9 - content/learn/book/next-steps/_index.md | 17 - content/learn/book/troubleshooting/_index.md | 18 -- content/learn/book/welcome/_index.md | 7 + templates/index.html | 39 ++- 18 files changed, 30 insertions(+), 1052 deletions(-) delete mode 100644 content/learn/book/contributing/_index.md delete mode 100644 content/learn/book/contributing/code/_index.md delete mode 100644 content/learn/book/contributing/docs/_index.md delete mode 100644 content/learn/book/faq/_index.md delete mode 100644 content/learn/book/getting-started/_index.md delete mode 100644 content/learn/book/getting-started/apps/_index.md delete mode 100644 content/learn/book/getting-started/ecs/_index.md delete mode 100644 content/learn/book/getting-started/plugins/_index.md delete mode 100644 content/learn/book/getting-started/resources/_index.md delete mode 100644 content/learn/book/getting-started/setup/_index.md delete mode 100644 content/learn/book/introduction/_index.md delete mode 100644 content/learn/book/migration-guides/0.4-0.5/_index.md delete mode 100644 content/learn/book/migration-guides/_index.md delete mode 100644 content/learn/book/next-steps/_index.md delete mode 100644 content/learn/book/troubleshooting/_index.md create mode 100644 content/learn/book/welcome/_index.md diff --git a/content/learn/book/_index.md b/content/learn/book/_index.md index 31fe29f7bb..55709a1563 100644 --- a/content/learn/book/_index.md +++ b/content/learn/book/_index.md @@ -3,5 +3,5 @@ title = "Book" sort_by = "weight" template = "book-section.html" page_template = "book-section.html" -redirect_to = "learn/book/introduction" +redirect_to = "learn/book/welcome" +++ \ No newline at end of file diff --git a/content/learn/book/contributing/_index.md b/content/learn/book/contributing/_index.md deleted file mode 100644 index 8546049d34..0000000000 --- a/content/learn/book/contributing/_index.md +++ /dev/null @@ -1,16 +0,0 @@ -+++ -title = "Contributing" -weight = 4 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -[extra] -subtitle = "join the bevy" -+++ - -Bevy is built by volunteers. If you want to help us build the next great game engine, [please reach out](/community)! We need all the help we can get: - -* If you are a software developer and you want to help out, check out the [Contributing Code](/learn/book/contributing/code) section. -* If you are good at teaching or writing, consider [contributing to our docs](/learn/book/contributing/docs). - -We want Bevy to be a vibrant developer community ... thats actually why we chose the name! A Bevy is a group of birds, just like we are a group of game developers. Join the Bevy! diff --git a/content/learn/book/contributing/code/_index.md b/content/learn/book/contributing/code/_index.md deleted file mode 100644 index 165ddb765d..0000000000 --- a/content/learn/book/contributing/code/_index.md +++ /dev/null @@ -1,32 +0,0 @@ -+++ -title = "Code" -weight = 1 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -[extra] -long_title = "Contributing Code" -+++ - -Would you like to contribute code to Bevy? Here's how! - -# How to Contribute - -1. Fork the [`bevyengine/bevy` repository on GitHub][bevy], you'll need to create a GitHub account if you don't have one already.* -2. Make your changes in a local clone of your fork -3. For a higher chance of CI passing the first time, consider locally running `cargo run -p ci`. You can run the commands manually: - 1. `cargo fmt --all -- --check` (remove `--check` to let the command fix found problems) - 2. `cargo clippy --workspace --all-targets --all-features -- -D warnings -A clippy::type_complexity -A clippy::manual-strip` - 3. `cargo test --all-targets --workspace` -4. Push your changes to your fork and open a [Pull Request][pull] -5. Respond to any CI failures or review feedback. - -Remember to follow Bevy's [Code of Conduct][coc], and thanks for contributing! - -*The same steps apply for any other repository in the [Bevy organization][bevyorg] that you would like to contribute to. - - -[bevy]: https://github.com/bevyengine/bevy -[bevyorg]: https://github.com/bevyengine -[coc]: https://github.com/bevyengine/bevy/blob/main/CODE_OF_CONDUCT.md -[pull]: https://github.com/bevyengine/bevy/compare diff --git a/content/learn/book/contributing/docs/_index.md b/content/learn/book/contributing/docs/_index.md deleted file mode 100644 index 8e2570c281..0000000000 --- a/content/learn/book/contributing/docs/_index.md +++ /dev/null @@ -1,59 +0,0 @@ -+++ -title = "Docs" -weight = 2 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -[extra] -long_title = "Contributing Docs" -+++ - -## The Bevy Book - -The Bevy Book is open source, along with the rest of this website. Check out the [Bevy Website repository on GitHub](https://github.com/bevyengine/bevy-website). The Bevy Book content is written in Markdown. - -### Building the Website - -The website is built using the [Zola static site generator](https://www.getzola.org/). Download Zola, then do the following: - -1. Clone the Bevy Website git repo and move to that directory: - ```sh - git clone https://github.com/bevyengine/bevy-website.git - cd bevy-website - ``` -2. Start the Zola server - ```sh - zola serve - ``` - -A local server should start and you should be able to access a local version of the website from there. - -### Rust API Doc Syntax - -We made an extension to the markdown syntax that makes linking to Rust API docs nicer. It also gives the links special formatting. Here are some examples: - -* Full Type Path: {{rust_type(type="struct" crate="std", mod="collections", name="HashMap")}} - - ```{{curly_open()}}{rust_type(type="struct" crate="std" mod="collections" name="HashMap")}{{curly_close()}}``` -* Short Type: {{rust_type(type="struct", crate="std" mod="collections", name="HashMap", no_mod=true)}} - - ```{{curly_open()}}{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true)}{{curly_close()}}``` -* Plural Type: {{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true plural=true)}} - - ```{{curly_open()}}{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true, plural=true)}{{curly_close()}}``` -* Function: {{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true method="insert")}} - - ```{{curly_open()}}{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true method="insert")}{{curly_close()}}``` -* Module: {{rust_mod(crate="std" mod="collections")}} - - ```{{curly_open()}}{rust_mod(crate="std" mod="collections")}{{curly_close()}}``` - -Modules from {{rust_mod(crate="std")}} will link to [https://doc.rust-lang.org](https://doc.rust-lang.org/std/index.html). Other modules (like {{rust_mod(crate="bevy_render" mod="render_graph")}} ) will link to [https://docs.rs](https://docs.rs). - -## Rust API Docs - -Bevy's Rust API Docs are automatically generated from the latest Bevy source code. If you add [Rust documentation comments](https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments) to the Bevy codebase, the API docs will be automatically updated. - -## Bevy Markdown Docs - -Bevy's CI will check markdown files like Readmes using [markdownlint](https://github.com/DavidAnson/markdownlint). If you contribute to markdown files consider installing [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli) to locally lint your changes. Running `markdownlint -f -c .github/linters/.markdown-lint.yml .` in the root directory of the Bevy project will apply the same linting rules to your changes as the CI workflow. diff --git a/content/learn/book/faq/_index.md b/content/learn/book/faq/_index.md deleted file mode 100644 index f89045ffd0..0000000000 --- a/content/learn/book/faq/_index.md +++ /dev/null @@ -1,28 +0,0 @@ -+++ -title = "Faq" -weight = 6 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -[extra] -long_title = "Frequently Asked Questions" -+++ - -### Why create Bevy when INSERT-GAME-ENGINE-HERE exists? - -There are plenty of fantastic engines out there ... why build another one? Especially when there are already so many in the Rust ecosystem? - -First a bit about me: I decided to build Bevy after years of contributing code to other engines (ex: Godot). I spent over four years [building a game in Godot](https://www.youtube.com/c/cartdev) and I also have experience with Unity, Unreal, and a number of other frameworks like SDL and Three.js. I have built multiple custom engines in the past using Rust, Go, HTML5, and Java. I have also used and/or closely followed most of the current players in the Rust gamedev ecosystem. I recently quit my job as Senior Software Engineer at Microsoft and my experience there deeply affected my opinions of software and what it should be. - -These experiences led me to want the following from a game engine: - -* **Free and Open Source**: It needs to be free and open source with _no strings attached_. Games are a huge part of our culture and humanity is investing _millions_ of hours into the development of games. Why are we (as game developers / engine developers) continuing to build up the ecosystems of closed-source monopolies that take cuts of our sales and deny us visibility into the tech we use daily? As a community I believe we can do so much better. This criteria eliminates Unreal and Unity, despite their huge feature sets. -* **Productive**: It needs to have fast build/run/test loops, which translates to either scripting languages or fast compile times in native languages. But scripting languages introduce runtime overhead, cognitive load, and a barrier between me and the actual engine, so my preference here is a native language with fast compile times. Sadly compile times are a huge problem in the Rust ecosystem and many Rust engines have prohibitively long iterative compiles. Fortunately Rust game engines like Macroquad and coffee prove that productive iterative compile times are possible. -* **Turtles All The Way Down**: Ideally the engine is written in the same language that games are. Being able to run an IDE "go to definition" command on a symbol in your game and hop directly into the engine source is an extremely powerful concept. You also don't need to worry about heavy language translation layers or lossy abstractions. If an engine's community builds games in the same language as the engine, they are more likely (and able) to contribute back to the engine. -* **Simple**: It needs to be easy to use for common tasks, but it also can't hide the details from you. Many engines are either "easy to use but too high level" or "very low level but difficult to do common tasks in". Additionally, many engines in Rust are littered with lifetimes and generics. Both are powerful tools to be sure, but they also introduce cognitive load and reduce ergonomics. Generics can also have a huge impact on compile times if you aren't careful. -* **Editor**: It needs to have an (optional) graphical editor. Scene creation is a large part of game development and in many cases visual editors beat code. As a bonus, the editor should be built _in the engine_. Godot uses this approach and it is _so smart_. Doing so [dogfoods](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) the engine's UI system and creates positive feedback loops. Improvements to the editor are also often improvements to the core engine. It also makes sure your engine is flexible enough to build tooling (and not just games). I personally consider building an engine's editor in another stack to be a missed opportunity (ex: the web, QT, native widgets). -* **Data Driven**: It needs to be data-driven/data-oriented/data-first. ECS is a common way of doing this, but it definitely isn't the only way. These paradigms can make your game faster (cache friendly, easier to parallelize), but they also make common tasks like game state serialization and synchronization delightfully straightforward. - -None of the engines on the market _quite_ line up with what I'm looking for. And the changes required to make them meet my requirements are either massive in scope, impossible (closed source), or unwelcome (the things I want aren't what the developers or customers want). On top of that, making new game engines is fun! - -Bevy is not trying to out-compete other open-source game engines. As much as possible we should be collaborating and building common foundations. If you are an open source game engine developer and you think a Bevy component would make your engine better, one of your engine's components could make Bevy better, or both, please reach out! Bevy is already benefitting massively from the efforts of the Rust gamedev ecosystem and we would love to pay it forward in whatever way we can. \ No newline at end of file diff --git a/content/learn/book/getting-started/_index.md b/content/learn/book/getting-started/_index.md deleted file mode 100644 index fce931c41d..0000000000 --- a/content/learn/book/getting-started/_index.md +++ /dev/null @@ -1,66 +0,0 @@ -+++ -title = "Getting Started" -weight = 2 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -+++ - -This section will help you get started on your Bevy journey as quickly as possible. It will walk you through setting up your development environment and writing a simple Bevy app. - -## Quick Start - -If you want to dive in immediately and you already have a working Rust setup, feel free to follow this "quick start" guide. Otherwise, move on to the next page. - -Note: the "fast compiles" setup is on the next page, so you might want to read that section first. - -### Try the Examples - -1. Clone the [Bevy repo](https://github.com/bevyengine/bevy): - ```sh - git clone https://github.com/bevyengine/bevy - ``` -2. Navigate to the new "bevy" folder - ```sh - cd bevy - ``` -3. Switch to the correct Bevy version (as the default is the git main development branch) - ```sh - # use the latest Bevy release - git checkout latest - # or a specific version - git checkout v0.4.0 - ``` -4. Try the examples in the [examples folder](https://github.com/bevyengine/bevy/tree/latest/examples#examples) - ```sh - cargo run --example breakout - ``` - -### Add Bevy as a Dependency - -Bevy is [available as a library on crates.io](https://crates.io/crates/bevy). - - -Add the bevy crate to your project's Cargo.toml like this: - -```toml -[dependencies] -bevy = "0.5" # make sure this is the latest version -``` - -This is the current `bevy` crate version: - - - -**_NOTE:_** Bevy is currently being updated at a rapid pace. Taking a dependency on the git repo instead of the cargo crate will allow you to receive the latest updates as fast as possible. *However*, **there are often breaking changes made to APIs and behavior**. This means that it will be important to keep up with the latest developments with bevy. **This is not recommended for people who are just getting started with bevy.** -```toml -[dependencies] -bevy = { git = "https://github.com/bevyengine/bevy" } -``` - -In general it's a good idea to lock in to a specific commit hash, which gives you control over when you take updates. You can find the [latest commit hash here](https://github.com/bevyengine/bevy/commits/main) (to the right of each commit). - -```toml -[dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", rev = "25f62f7250a0d750068dc32533b9433f7985af98" } -``` diff --git a/content/learn/book/getting-started/apps/_index.md b/content/learn/book/getting-started/apps/_index.md deleted file mode 100644 index 6f0b290fd3..0000000000 --- a/content/learn/book/getting-started/apps/_index.md +++ /dev/null @@ -1,25 +0,0 @@ -+++ -title = "Apps" -weight = 2 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -+++ - -Bevy programs are referred to as {{rust_type(type="struct", crate="bevy_app", name="App", no_mod=true, plural=true)}}. The simplest Bevy app looks like this: - -```rs -use bevy::prelude::*; - -fn main() { - App::build().run(); -} -``` - -Nice and simple right? Copy the code above into your ```main.rs``` file, then run: - -```sh -cargo run -``` - -in your project folder. You will notice that ... nothing happens. This is because we haven't told our app to do anything yet! Apps are just empty shells capable of running our application logic. Let's add some logic to our App using Bevy ECS. diff --git a/content/learn/book/getting-started/ecs/_index.md b/content/learn/book/getting-started/ecs/_index.md deleted file mode 100644 index 9a5df83218..0000000000 --- a/content/learn/book/getting-started/ecs/_index.md +++ /dev/null @@ -1,137 +0,0 @@ -+++ -title = "ECS" -weight = 3 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -+++ - -All app logic in Bevy uses the Entity Component System paradigm, which is often shortened to ECS. ECS is a software pattern that involves breaking your program up into **Entities**, **Components**, and **Systems**. **Entities** are unique "things" that are assigned groups of **Components**, which are then processed using **Systems**. - -For example, one entity might have a `Position` and `Velocity` component, whereas another entity might have a `Position` and `UI` component. Systems are logic that runs on a specific set of component types. You might have a `movement` system that runs on all entities with a `Position` and `Velocity` component. - -The ECS pattern encourages clean, decoupled designs by forcing you to break up your app data and logic into its core components. It also helps make your code faster by optimizing memory access patterns and making parallelism easier. - -## Bevy ECS - -Bevy ECS is Bevy's implementation of the ECS pattern. Unlike other Rust ECS implementations, which often require complex lifetimes, traits, builder patterns, or macros, Bevy ECS uses normal Rust datatypes for all of these concepts: -* **Components**: normal Rust structs - ```rs - struct Position { x: f32, y: f32 } - ``` -* **Systems**: normal Rust functions - ```rs - fn print_position_system(query: Query<&Transform>) { - for transform in query.iter() { - println!("position: {:?}", transform.translation); - } - } - ``` -* **Entities**: a simple type containing a unique integer - ```rs - struct Entity(u64); - ``` - -Now let's see how this works in practice! - -## Your First System - -Paste the following function into your `main.rs` file: - -```rs -fn hello_world() { - println!("hello world!"); -} -``` - -This will be our first system. The only remaining step is to add it to our App! - -```rs -fn main() { - App::build() - .add_system(hello_world.system()) - .run(); -} -``` - -Note the `hello_world.system()` function call. This is a "trait extension method" that converts the `hello_world` function into the {{rust_type(type="trait" crate="bevy_ecs" mod="system" no_mod=true name="System")}} type. - -The {{rust_type(type="struct" crate="bevy_app", name="AppBuilder" method="add_system" no_struct=true)}} function adds the system to your App's {{rust_type(type="struct", crate="bevy_ecs", mod="schedule" no_mod=true name="Schedule")}}, but we'll cover that more later. - -Now run your App again using `cargo run`. You should see `hello world!` printed once in your terminal. - -## Your First Components - -Greeting the whole world is great, but what if we want to greet specific people? In ECS, you would generally model people as entities with a set of components that define them. Let's start simple with a `Person` component. - -Add this struct to `main.rs`: - -```rs -struct Person; -``` - -But what if we want our people to have a name? In a more traditional design, we might just tack on a `name: String` field to `Person`. But other entities might have names too! For example, dogs should probably also have a name. It often makes sense to break datatypes up in to small pieces to encourage code reuse. So let's make `Name` its own component: - -```rs -struct Name(String); -``` - -We can then add `People` to our {{rust_type(type="struct" crate="bevy_ecs" mod="world" no_mod=true name="World")}} using a "startup system". Startup systems are just like normal systems, but they run exactly once, before all other systems, right when our app starts. Let's use {{rust_type(type="struct" crate="bevy_ecs" mod="system" no_mod=true name="Commands")}} to spawn some entities into our {{rust_type(type="struct" crate="bevy_ecs" mod="world" no_mod=true name="World")}}: - -```rs -fn add_people(mut commands: Commands) { - commands.spawn().insert(Person).insert(Name("Elaina Proctor".to_string())); - commands.spawn().insert(Person).insert(Name("Renzo Hume".to_string())); - commands.spawn().insert(Person).insert(Name("Zayna Nieves".to_string())); -} -``` - -Now register the startup system like this: - -```rs -fn main() { - App::build() - .add_startup_system(add_people.system()) - .add_system(hello_world.system()) - .run(); -} -``` - -We could run this App now and the `add_people` system would run first, followed by `hello_world`. But our new people don't have anything to do yet! Let's make a system that properly greets the new citizens of our {{rust_type(type="struct" crate="bevy_ecs" mod="world" no_mod=true name="World")}}: - -```rs -fn greet_people(query: Query<&Name, With>) { - for name in query.iter() { - println!("hello {}!", name.0); - } -} -``` - -The parameters we pass in to a "system function" define what data the system runs on. In this case, `greet_people` will run on all entities with the `Person` and `Name` component. - -You can interpret the Query above as: "iterate over every Name component for entities that also have a Person component" - -Now we just register the system in our App: - -```rs -fn main() { - App::build() - .add_startup_system(add_people.system()) - .add_system(hello_world.system()) - .add_system(greet_people.system()) - .run(); -} -``` - -Running our app will result in the following output: - -``` -hello world! -hello Elaina Proctor! -hello Renzo Hume! -hello Zayna Nieves! -``` - -Marvelous! - -**Quick Note**: "hello world!" might show up in a different order than it does above. This is because systems run in parallel by default whenever possible. diff --git a/content/learn/book/getting-started/plugins/_index.md b/content/learn/book/getting-started/plugins/_index.md deleted file mode 100644 index f69b6c4a53..0000000000 --- a/content/learn/book/getting-started/plugins/_index.md +++ /dev/null @@ -1,97 +0,0 @@ -+++ -title = "Plugins" -weight = 4 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -+++ - -One of Bevy's core principles is modularity. All Bevy engine features are implemented as plugins. This includes internal features like the renderer, but games themselves are also implemented as plugins! This empowers developers to pick and choose which features they want. Don't need a UI? Don't register the {{rust_type(type="struct" crate="bevy_ui", name="UiPlugin")}}. Want to build a headless server? Don't register the {{rust_type(type="struct" crate="bevy_render" name="RenderPlugin")}}. - -This also means you are free to replace any components you don't like. If you feel the need, you are welcome to build your own {{rust_type(type="struct" crate="bevy_ui" name="UiPlugin")}}, but consider [contributing it back to Bevy](/learn/book/contributing) if you think it would be useful! - -However, most developers don't need a custom experience and just want the "full engine" experience with no hassle. For this, Bevy provides a set of "default plugins". - -## Bevy's Default Plugins - -Let's make our app more interesting by adding the "default Bevy plugins". -`add_plugins(DefaultPlugins)` adds the features most people expect from an engine, such as a 2D / 3D renderer, asset loading, a UI system, windows, and input. - -```rs -fn main() { - App::build() - .add_plugins(DefaultPlugins) - .add_startup_system(add_people.system()) - .add_system(hello_world.system()) - .add_system(greet_people.system()) - .run(); -} -``` - -Once again run `cargo run`. - -You should hopefully notice two things: -* **A window should pop up**. This is because we now have {{rust_type(type="struct" crate="bevy_window" name="WindowPlugin")}}, which defines the window interface (but doesn't actually know how to make windows), and {{rust_type(type="struct" crate="bevy_winit" name="WinitPlugin")}} which uses the [winit library](https://github.com/rust-windowing/winit) to create a window using your OS's native window api. -* **Your console is now full of "hello" messages**: This is because {{rust_type(type="struct" crate="bevy" name="DefaultPlugins")}} adds an "event loop" to our application. Our App's ECS Schedule now runs in a loop once per "frame". We will resolve the console spam in a moment. - -Note that `add_plugins(DefaultPlugins)` is equivalent to the following: -```rs -fn main() { - App::build() - .add_plugin(CorePlugin::default()) - .add_plugin(InputPlugin::default()) - .add_plugin(WindowPlugin::default()) - /* more plugins omitted for brevity */ - .run(); -} -``` - -You are free to use whatever approach suits you! - -## Creating your first plugin - -For better organization, let's move all of our "hello" logic to a plugin. To create a plugin we just need to implement the {{rust_type(type="trait" name="Plugin" crate="bevy_app" no_mod=true)}} interface. Add the following code to your `main.rs` file: - -```rs -pub struct HelloPlugin; - -impl Plugin for HelloPlugin { - fn build(&self, app: &mut AppBuilder) { - // add things to your app here - } -} -``` - -Then register the plugin in your App like this: -```rs -fn main() { - App::build() - .add_plugins(DefaultPlugins) - .add_plugin(HelloPlugin) - .add_startup_system(add_people.system()) - .add_system(hello_world.system()) - .add_system(greet_people.system()) - .run(); -} -``` - -Now all thats left is to move our systems into `HelloPlugin`, which is just a matter of cut and paste. The `app` variable in our plugin's `build()` function is the same builder type we use in our `main()` function: - -```rs -impl Plugin for HelloPlugin { - fn build(&self, app: &mut AppBuilder) { - app.add_startup_system(add_people.system()) - .add_system(hello_world.system()) - .add_system(greet_people.system()); - } -} - -fn main() { - App::build() - .add_plugins(DefaultPlugins) - .add_plugin(HelloPlugin) - .run(); -} -``` - -Try running the app again. It should do exactly what it did before. In the next section, we'll fix the "hello" spam using Resources. diff --git a/content/learn/book/getting-started/resources/_index.md b/content/learn/book/getting-started/resources/_index.md deleted file mode 100644 index 4e3ec86903..0000000000 --- a/content/learn/book/getting-started/resources/_index.md +++ /dev/null @@ -1,63 +0,0 @@ -+++ -title = "Resources" -weight = 5 -sort_by = "weight" -template = "book-section.html" -page_template = "book-section.html" -+++ - -**Entities** and **Components** are great for representing complex, query-able groups of data. But most Apps will also require "globally unique" data of some kind. In Bevy ECS, we represent globally unique data using **Resources**. - -Here are some examples of data that could be encoded as **Resources**: -* Elapsed Time -* Asset Collections (sounds, textures, meshes) -* Renderers - -## Tracking Time with Resources - -Let's solve our App's "hello spam" problem by only printing "hello" once every two seconds. We'll do this by using the {{rust_type(type="struct" crate="bevy_core" name="Time")}} resource, which is automatically added to our App via `add_plugins(DefaultPlugins)`. - -For simplicity, remove the `hello_world` system from your App. This way we only need to adapt the `greet_people` system. - -Resources are accessed in much the same way that we access components. You can access the `Time` resource in your system like this: - -```rs -fn greet_people(time: Res