For more advice on writing examples, see the relevant section of CONTRIBUTING.md.
- Examples should live in an appropriate subfolder of
/examples
. - Examples should be a single file if possible.
- Assets live in
./assets
. Try to avoid adding new assets unless strictly necessary to keep the repo small. Don't add "large" asset files. - Each example should try to follow this order:
- Imports
- A
fn main()
block - Example logic
- Try to structure app / plugin construction in the same fashion as the actual code.
- Examples should typically not have tests, as they are not directly reusable by the Bevy user.
- Use simple, descriptive variable names.
- Avoid names like
MyComponent
in favor of more descriptive terms likeEvents
. - Prefer single letter differentiators like
EventsA
andEventsB
to nonsense words likeEventsFoo
andEventsBar
. - Avoid repeating the type of variables in their name where possible. For example,
Color
should be preferred toColorComponent
.
- Avoid names like
- Prefer glob imports of
bevy::prelude::*
andbevy::sub_crate::*
over granular imports (for terseness). - Use a consistent comment style:
///
doc comments belong above#[derive(Trait)]
invocations.//
comments should generally go above the line in question, rather than in-line.- Avoid
/* */
block comments, even when writing long comments. - Use `variable_name` code blocks in comments to signify that you're referring to specific types and variables.
- Start comments with capital letters; end them with a period if they are sentence-like.
- Use comments to organize long and complex stretches of code that can't sensibly be refactored into separate functions.
- Avoid making variables
pub
unless it is needed for your example.
- Refactor configurable values ("magic numbers") out into constants with clear names.
- Prefer
for
loops over.for_each
. The latter is faster (for now), but it is less clear for beginners, less idiomatic, and less flexible. - Use
.single
and.single_mut
where appropriate. - In Queries, prefer
With<T>
filters over actually fetching unused data with&T
. - Prefer disjoint queries using
With
andWithout
over param sets when you need more than one query in a single system. - Prefer structs with named fields over tuple structs except in the case of single-field wrapper types.
- Use enum-labels over string-labels for system / stage / etc. labels.
These examples demonstrate the usage of specific engine features in clear, minimal ways.
- Focus on demonstrating exactly one feature in an example
- Try to keep your names divorced from the context of a specific game, and focused on the feature you are demonstrating.
- Where they exist, show good alternative approaches to accomplish the same task and explain why you may prefer one over the other.
- Examples should have a visible effect when run, either in the command line or a graphical window.
These examples show how to build simple games in Bevy in a cohesive way.
- Each of these examples lives in the [/examples/games] folder.
- Aim for minimum but viable status: the game should be playable and not obviously buggy but does not need to be polished, featureful, or terribly fun.
- Focus on code quality and demonstrating good, extensible patterns for users.
- Make good use of enums and states to organize your game logic.
- Keep components as small as possible but no smaller: all of the data on a component should generally be accessed at once.
- Keep systems small: they should have a clear single purpose.
- Avoid duplicating logic across similar entities whenever possible by sharing systems and components.
- Use
///
doc comments to explain what each function / struct does as if the example were part of a polished production codebase. - Arrange your code into modules within the same file to allow for simple code folding / organization.