../
Bevy Jam #1 data exploration
Published: , updated:
Intro
The first Bevy Jam offers an opportunity to look at how different people use Bevy (at least in the context of a game jam) - which features they use, which crates they use to augment Bevy, and also which asset types they use. This can help highlight commonly used features or dependencies that might encourage further development, or infrequently used or avoided features that may need better documentation, examples, or improvements.
Some summary highlights
Dependencies
These are the direct expressed dependencies of the game project, representing what the game developer directly interacted with. I somewhat-arbitrarily decided what were “game development-related” vs. general Rust or infrastructural crates.
Bevy-specific dependencies
These are 38 unique dependencies built to work directly with Bevy. Debugging (perhaps unsurprisingly?) was the most common category, and egui was a clear favourite. bevy_kira_audio was used for 9 of the 11 entries in the top 25 entries that had audio assets, showing a clear preference for skipping the built-in audio capabilities.
Rank | Dependency | All entries | Top 25 entries | Category | Description |
---|---|---|---|---|---|
1 | bevy-inspector-egui | 18 | 7 | Debugging | Provide ECS inspection via egui. |
2 | bevy_kira_audio | 17 | 9 | Audio | Plugin to use Kira, providing sound mixing and other features not available in the base audio plugin. |
3 | heron | 15 | 5 | Physics | Ergonomic 2d/3d physics API using Rapier. |
4 | bevy_asset_loader | 10 | 6 | Assets | Plugin to reduce boilerplate around asset loading, especially around game states transitions. |
5 | bevy_egui | 10 | 5 | Debugging / UI | Plugin to set up and manage egui usage |
6 | bevy_prototype_lyon | 9 | 3 | 2D graphics | Plugin to use Lyon, a 2D graphics library in Rust using path tessellation. |
6 | bevy_tweening | 9 | 3 | Animation | Tweening animation plugin. |
8 | benimator | 7 | 3 | Animation | Plugin for sprite sheet animation |
8 | bevy_rapier2d | 7 | 3 | Physics | Plugin to use Rapier’s 2D physics engine |
10 | bevy_ecs_tilemap | 6 | 1 | 2D Games / Tilemaps | Plugin for tilemap rendering |
11 | bevy_prototype_debug_lines | 5 | 0 | Debugging | Plugin providing a simple line drawing API |
12 | bevy_embedded_assets | 3 | 2 | Assets | Embeds assets into the binary for easier releases. |
13 | bevy_ecs_ldtk | 3 | 1 | 2D Games / Tilemaps | Plugin to integrate with the LDtk 2D level editor |
13 | bevy-web-resizer | 3 | 1 | Rendering | Automatically resizes app on the web to the size of the window |
15 | bevy_framepace | 3 | 0 | Rendering | Plugin to provide frame pacing and framelimiting |
16 | bevy_console | 2 | 1 | Debugging | Plugin to support an on-screen debugging console |
16 | bevy_loading | 2 | 1 | Assets | Asset loading progress tracking library |
16 | bevy_mod_raycast | 2 | 1 | 3D Games | Allows easy 3D ray casting against meshes |
16 | bevy_ninepatch | 2 | 1 | UI | Support 9-patch images - let you have a UI that scales only the right parts of your images |
16 | leafwing-input-manager | 2 | 1 | Input | An input manager providing an ergonomic interface over the lower-level input system in Bevy |
21 | bevy_rapier3d | 2 | 0 | Physics | Plugin to use Rapier’s 3D physics engine |
21 | bevy_asset_ron | 2 | 0 | Assets | Register arbitrary custom data to be loaded as an Asset, from files using the RON format. |
23 | bevy-ui-build-macros | 1 | 1 | UI | Macros to speed up the process of defining UIs |
23 | bevy-debug-text-overlay | 1 | 1 | Debugging | Convenient debug text overlay plugin. |
23 | bevy_mod_picking | 1 | 1 | 3D Games | Plugin for 3D mouse picking |
23 | bevy-ui-navigation | 1 | 1 | UI | UI navigation algorithm for the default UI library |
23 | bevy-scene-hook | 1 | 1 | ? | Scene manager proof-of-concept |
23 | bevy_easings | 1 | 1 | Animations | Easings on components using interpolation. |
23 | bevy_system_graph | 1 | 1 | ? | Utilities for creating strictly ordered execution graphs of systems |
23 | bevy-egui-kbgp | 1 | 1 | Debugging / UI | Improved keyboard and gamepad navigation and usage for egui |
23 | bevy_polyline | 1 | 1 | Rendering | Plugin that adds instanced rendering of Polylines |
23 | bevy_ggrs | 1 | 1 | Networking | Plugin for the GGRS P2P rollback networking library |
33 | iyes_bevy_util | 1 | 0 | Miscellaneous | Miscellaneous utilities from IyesGames |
33 | bevy_ase | 1 | 0 | Assets | Asset loader for Asesprite files |
33 | smooth-bevy-cameras | 1 | 0 | Rendering | Collection of exponentially-smoothed camera controllers |
33 | bevy_networking_turbulence | 1 | 0 | Networking | Networking plugin using on naia-socket and turbulence libraries. |
33 | bevy_editor_pls | 1 | 0 | Debugging / Creation | WIP editor-use-case tooling |
33 | bevy_atmosphere | 1 | 0 | Rendering | Procedural sky rendering plugin |
Game development related dependencies
Unsurprisingly, most entries used randomness, and most (43/55) used the rand crate. Perhaps surprisingly, many entries had no non-Bevy dependencies beyond that crate.
Rank | Dependency | All entries | Top 25 entries | Category | Description |
---|---|---|---|---|---|
1 | rand | 45 | 19 | Randomness | Random number generation with multiple generators across multiple generation types |
2 | noise | 2 | 1 | Noise | Procedural noise generation library covering gradient, fBm, and Worley noise |
2 | pathfinding | 2 | 1 | Pathfinding | Implementations of several pathfinding, flow, and graph algorithms |
2 | fastrand | 2 | 1 | Randomness | PRNG using Wyrand |
2 | big-brain | 2 | 1 | AI | Utility AI library for games |
2 | rand_chacha | 2 | 1 | Randomness | Cryptographically secure random number generation using ChaCha |
7 | spirv-std | 2 | 0 | Rendering | The rust-gpu ecosystem, allowing Rust as a language for GPU graphics and compute shaders. (Also spirv-builder, spirv-std-macros) |
8 | alea | 1 | 1 | Randomness | PRNG using Wyrand |
8 | splines | 1 | 1 | ? | Spline interpolation |
8 | tiled | 1 | 1 | Levels | Managing maps build with the Tiled map editor (or something else that supports that format) |
8 | ggrs | 1 | 1 | Networking | P2P rollback networking library |
8 | impacted | 1 | 1 | Physics | 2D collision testing (has Bevy interop through optional features) |
8 | interpolation | 1 | 1 | Animation+ | Interpolating between two numbers (finding points between on some non-uniform scale, often curves) |
8 | getrandom | 1 | 1 | Randomness | Use operating system-sourced random data |
8 | matchbox_socket | 1 | 1 | Networking | P2P WebRTC networking for rust wasm applications |
15 | names | 1 | 0 | Randomness | Random name generation |
Bevy feature usage
Plugins and features
Plugin | All entries | Top 25 entries | Description |
---|---|---|---|
DefaultPlugins | 56 | 22 | The default set of commonly used built-in plugins |
NodeBundle | 33 | 15 | Bevy UI’s node-based UI element |
FrameTimeDiagnosticsPlugin | 10 | 5 | A plugin that populates diagnostics about frame time and fps |
LogDiagnosticsPlugin | 8 | 4 | A plugin that outputs diagnostics to logs |
FixedTimestep | 8 | 1 | Used for attaching actions at a fixed time step, rather than time taken for frames. |
MaterialMesh2dBundle | 3 | 1 | Custom 2D material (custom shaders) |
MaterialPlugin | 2 | 1 | Custom material (3D) |
Cameras
This one is a bit of a stretch - just looked at whether PerspectiveCameraBundle
or OrthographicCameraBundle
were present (preferring perspective), and if ::new_2d()
or ::new_3d()
were used (preferring the latter).
Camera | All entries | Top 25 entries |
---|---|---|
Orthographic (2D) | 43 | 17 |
Perspective (3D) | 10 | 4 |
Orthographic (3D) | 1 | 0 |
Assets
Asset Categories
Unsurprisingly, most entries used fonts and images. Fewer than half of games used audio. Using external level editors was infrequent, as well as imported shaders.
Asset Category | All entries | Top 25 entries |
---|---|---|
Font | 47 | 19 |
Image | 44 | 18 |
Audio | 25 | 11 |
Model | 9 | 5 |
Level | 4 | 2 |
Shader | 4 | 2 |
Data | 3 | 1 |
Font asset formats
Fonts were the most frequently used asset category, and roughly 50 unique font faces were used over all entries, while the top 25 entries used roughly 25 different font faces. Fira Sans (13) and Fira Mono (9) were the only faces used by more than 2 entries.
Asset Format | All entries | Top 25 entries |
---|---|---|
TrueType (ttf) | 44 | 17 |
OpenType | 7 | 4 |
Image asset formats
PNG dominates for plain images/textures, while Aseprite is the infrequently used sprite format.
Asset Format | All entries | Top 25 entries |
---|---|---|
PNG | 42 | 17 |
Aseprite | 5 | 1 |
JPEG | 2 | 2 |
Gimp (xcf) | 1 | 0 |
.ico | 1 | 0 |
Audio asset formats
Asset Format | All entries | Top 25 entries |
---|---|---|
Ogg | 18 | 9 |
Wav | 11 | 3 |
Mp3 | 1 |
Model asset formats
The binary GLTF variant is preferred, although not many entries used 3D model assets
Asset Format | All entries | Top 25 entries |
---|---|---|
GLTF Binary (glb) | 9 | 5 |
GLTF JSON (gltf) | 3 | 2 |
Blender | 1 | 1 |
Level asset formats
Not many projects used level assets authored externally, but LDtk was slightly preferred over Tiled.
Asset Format | All entries | Top 25 entries |
---|---|---|
LDtk | 3 | 1 |
Tiled | 1 | 1 |
Shader asset formats
Asset format | All entries | Top 25 entries |
---|---|---|
WGSL | 2 | 2 |
SPIR-V | 2 | 0 |
Game dependency and asset data
Methodology
This ended up being a single Rust binary that does all the work, with caching of external data to both be a good citizen and to speed up iteration. There are two main phases of collection - fetching information from itch.io, and then looking at the source code - and then reporting.
itch.io data
Itch.io was the platform used to host the jam, and while it doesn’t have official APIs for getting jam data. Luckily, the entries page is actually built client-side, and fetches the data for the entries via JSON - https://itch.io/jam/316945/entries.json. Note that this URL has the jam ID in it (316945
, not the vanity name (bevy-jam-1
). This entries page (and the data that backs it) doesn’t include rankings, which is on the results page. The results page renders server-side, but there happens to be an easily-guessed JSON file with the data - https://itch.io/jam/316945/results.json. Both of these could be fetched without authentication, so they could be fetched from code, and deserialized using serde_json
. For all URL retrieval, reqwest
was used, with a simple on-disk cache to prevent fetching the same resource more than once, and a sleep between fetches (both of which are probably easy to do with middleware).
The Bevy Jam encouraged, but did not require, source code to be provided for the software. Unfortunately, Itch.io doesn’t appear to provide a way to structurally denote things like a link to the source code, and so none of the internal APIs provide any such thing. There are two URLs available from here per entry - the entry page specific to this jam, and the general game page. The entry page doesn’t appear to have any useful information on it, but the general game page has freeform information from the game’s developers, as well as potentially download links. Using the scraper
crate, all the links in the downloaded game pages could be examined for potentially being a link to a code hosting platform. GitHub appeared to be the only platform used for the jam. (It’s possible some entries used download links, but a spot-check showed these were largely used for binaries.)
Source data
With homogenous usage of Git repositories for code, the git2
crate could be used to fetch the repositories (with a simple on-disk cache). The cargo-metadata
crate could be used to extract the dependencies from the Cargo.toml
files (with a simple fix-up for one case where the file was named the lower case cargo.toml
). Asset data could be found using the walkdir
crate to traverse the source code, focusing on any assets
folders. Finally, the grep
crate from ripgrep could be used to find simple regex patterns in files to discover use of particular cameras, plugins, and so forth.
Reporting
This was largely done with plain text, although for the main table, the comrak
crate was used to generate the Markdown table in Markdown.
Further work
In an ideal world, something like Tree Sitter could be used to examine the source code to be able to answer questions like “what are all the structs used from bevy modules by this repository”, or look at initialization for particular structs to tell if they’re configured for 2D or 3D usage.
There was another Rust game jam using the Itch.io platform, the Rusty Game Jam, which could probably be evaluated using very similar approaches. Trying to do this for something like Ludum Dare would require a different approach - besides being a different platform, only a small subset of entries use Rust, and it may be hard to discover this. Perhaps this could be attempted by using a compiled list of Rust games from a source like Reddit or Twitter.