mirror of
https://github.com/bevyengine/bevy
synced 2024-11-26 14:40:19 +00:00
a7f2120c9e
# Objective Add a section to the example's README on how to reduce generated wasm executable size. Add a `wasm-release` profile to bevy's `Cargo.toml` in order to use it when building bevy-website. Notes: - We do not recommend `strip = "symbols"` since it breaks bindgen - see https://github.com/bevyengine/bevy-website/pull/402
314 lines
9.5 KiB
Smarty
314 lines
9.5 KiB
Smarty
<!-- MD024 - The Headers from the Platform-Specific Examples should be identical -->
|
|
<!-- markdownlint-disable-file MD024 -->
|
|
|
|
# Examples
|
|
|
|
These examples demonstrate the main features of Bevy and how to use them.
|
|
To run an example, use the command `cargo run --example <Example>`, and add the option `--features x11` or `--features wayland` to force the example to run on a specific window compositor, e.g.
|
|
|
|
```sh
|
|
cargo run --features wayland --example hello_world
|
|
```
|
|
|
|
**⚠️ Note: for users of releases on crates.io!**
|
|
|
|
There are often large differences and incompatible API changes between the latest [crates.io](https://crates.io/crates/bevy) release and the development version of Bevy in the git main branch!
|
|
|
|
If you are using a released version of bevy, you need to make sure you are viewing the correct version of the examples!
|
|
|
|
- Latest release: [https://github.com/bevyengine/bevy/tree/latest/examples](https://github.com/bevyengine/bevy/tree/latest/examples)
|
|
- Specific version, such as `0.4`: [https://github.com/bevyengine/bevy/tree/v0.4.0/examples](https://github.com/bevyengine/bevy/tree/v0.4.0/examples)
|
|
|
|
When you clone the repo locally to run the examples, use `git checkout` to get the correct version:
|
|
|
|
```bash
|
|
# `latest` always points to the newest release
|
|
git checkout latest
|
|
# or use a specific version
|
|
git checkout v0.4.0
|
|
```
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
- [Examples](#examples)
|
|
- [Table of Contents](#table-of-contents)
|
|
- [The Bare Minimum](#the-bare-minimum)
|
|
- [Hello, World!](#hello-world)
|
|
- [Cross-Platform Examples](#cross-platform-examples)
|
|
{% for category, _ in all_examples %} - [{{ category }}](#{{ category | slugify }})
|
|
{% endfor %}
|
|
- [Tests](#tests)
|
|
- [Platform-Specific Examples](#platform-specific-examples)
|
|
- [Android](#android)
|
|
- [Setup](#setup)
|
|
- [Build & Run](#build--run)
|
|
- [Old phones](#old-phones)
|
|
- [iOS](#ios)
|
|
- [Setup](#setup-1)
|
|
- [Build & Run](#build--run-1)
|
|
- [WASM](#wasm)
|
|
- [Setup](#setup-2)
|
|
- [Build & Run](#build--run-2)
|
|
- [Loading Assets](#loading-assets)
|
|
|
|
# The Bare Minimum
|
|
|
|
<!-- MD026 - Hello, World! looks better with the ! -->
|
|
<!-- markdownlint-disable-next-line MD026 -->
|
|
## Hello, World!
|
|
|
|
Example | Description
|
|
--- | ---
|
|
[`hello_world.rs`](./hello_world.rs) | Runs a minimal example that outputs "hello world"
|
|
|
|
# Cross-Platform Examples
|
|
{% for category, details in all_examples %}
|
|
## {{ category }}
|
|
|
|
{% if details.description is string %}{{ details.description }}
|
|
{% endif %}Example | Description
|
|
--- | ---
|
|
{% for example in details.examples %}[{{ example.name }}](../{{ example.path }}) | {{ example.description }}
|
|
{% endfor %}{% endfor %}
|
|
# Tests
|
|
|
|
Example | Description
|
|
--- | ---
|
|
[How to Test Systems](../tests/how_to_test_systems.rs) | How to test systems with commands, queries or resources
|
|
|
|
# Platform-Specific Examples
|
|
|
|
## Android
|
|
|
|
### Setup
|
|
|
|
```sh
|
|
rustup target add aarch64-linux-android armv7-linux-androideabi
|
|
cargo install cargo-apk
|
|
```
|
|
|
|
The Android SDK must be installed, and the environment variable `ANDROID_SDK_ROOT` set to the root Android `sdk` folder.
|
|
|
|
When using `NDK (Side by side)`, the environment variable `ANDROID_NDK_ROOT` must also be set to one of the NDKs in `sdk\ndk\[NDK number]`.
|
|
|
|
### Build & Run
|
|
|
|
To run on a device setup for Android development, run:
|
|
|
|
```sh
|
|
cargo apk run --example android_example
|
|
```
|
|
|
|
When using Bevy as a library, the following fields must be added to `Cargo.toml`:
|
|
|
|
```toml
|
|
[package.metadata.android]
|
|
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
|
|
|
|
[package.metadata.android.sdk]
|
|
target_sdk_version = 31
|
|
```
|
|
|
|
Please reference `cargo-apk` [README](https://crates.io/crates/cargo-apk) for other Android Manifest fields.
|
|
|
|
### Debugging
|
|
|
|
You can view the logs with the following command:
|
|
|
|
```sh
|
|
adb logcat | grep 'RustStdoutStderr\|bevy\|wgpu'
|
|
```
|
|
|
|
In case of an error getting a GPU or setting it up, you can try settings logs of `wgpu_hal` to `DEBUG` to get more informations.
|
|
|
|
Sometimes, running the app complains about an unknown activity. This may be fixed by uninstalling the application:
|
|
|
|
```sh
|
|
adb uninstall org.bevyengine.example
|
|
```
|
|
|
|
### Old phones
|
|
|
|
Bevy by default targets Android API level 31 in its examples which is the <!-- markdown-link-check-disable -->
|
|
[Play Store's minimum API to upload or update apps](https://developer.android.com/distribute/best-practices/develop/target-sdk). <!-- markdown-link-check-enable -->
|
|
Users of older phones may want to use an older API when testing.
|
|
|
|
To use a different API, the following fields must be updated in Cargo.toml:
|
|
|
|
```toml
|
|
[package.metadata.android.sdk]
|
|
target_sdk_version = >>API<<
|
|
min_sdk_version = >>API or less<<
|
|
```
|
|
|
|
Example | File | Description
|
|
--- | --- | ---
|
|
`android` | [`android/android.rs`](./android/android.rs) | The `3d/3d_scene.rs` example for Android
|
|
|
|
## iOS
|
|
|
|
### Setup
|
|
|
|
You need to install the correct rust targets:
|
|
|
|
- `aarch64-apple-ios`: iOS devices
|
|
- `x86_64-apple-ios`: iOS simulator on x86 processors
|
|
- `aarch64-apple-ios-sim`: iOS simulator on Apple processors
|
|
|
|
```sh
|
|
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
|
|
```
|
|
|
|
### Build & Run
|
|
|
|
Using bash:
|
|
|
|
```sh
|
|
cd examples/ios
|
|
make run
|
|
```
|
|
|
|
In an ideal world, this will boot up, install and run the app for the first
|
|
iOS simulator in your `xcrun simctl devices list`. If this fails, you can
|
|
specify the simulator device UUID via:
|
|
|
|
```sh
|
|
DEVICE_ID=${YOUR_DEVICE_ID} make run
|
|
```
|
|
|
|
If you'd like to see xcode do stuff, you can run
|
|
|
|
```sh
|
|
open bevy_ios_example.xcodeproj/
|
|
```
|
|
|
|
which will open xcode. You then must push the zoom zoom play button and wait
|
|
for the magic.
|
|
|
|
Example | File | Description
|
|
--- | --- | ---
|
|
`ios` | [`ios/src/lib.rs`](./ios/src/lib.rs) | The `3d/3d_scene.rs` example for iOS
|
|
|
|
## WASM
|
|
|
|
### Setup
|
|
|
|
```sh
|
|
rustup target add wasm32-unknown-unknown
|
|
cargo install wasm-bindgen-cli
|
|
```
|
|
|
|
### Build & Run
|
|
|
|
Following is an example for `lighting`. For other examples, change the `lighting` in the
|
|
following commands.
|
|
|
|
```sh
|
|
cargo build --release --example lighting --target wasm32-unknown-unknown
|
|
wasm-bindgen --out-name wasm_example \
|
|
--out-dir examples/wasm/target \
|
|
--target web target/wasm32-unknown-unknown/release/examples/lighting.wasm
|
|
```
|
|
|
|
The first command will build the example for the wasm target, creating a binary. Then,
|
|
[wasm-bindgen-cli](https://rustwasm.github.io/wasm-bindgen/reference/cli.html) is used to create
|
|
javascript bindings to this wasm file, which can be loaded using this
|
|
[example HTML file](./wasm/index.html).
|
|
|
|
Then serve `examples/wasm` directory to browser. i.e.
|
|
|
|
```sh
|
|
# cargo install basic-http-server
|
|
basic-http-server examples/wasm
|
|
|
|
# with python
|
|
python3 -m http.server --directory examples/wasm
|
|
|
|
# with ruby
|
|
ruby -run -ehttpd examples/wasm
|
|
```
|
|
|
|
### Optimizing
|
|
|
|
On the web, it's useful to reduce the size of the files that are distributed.
|
|
With rust, there are many ways to improve your executable sizes.
|
|
Here are some.
|
|
|
|
#### 1. Tweak your `Cargo.toml`
|
|
|
|
Add a new [profile](https://doc.rust-lang.org/cargo/reference/profiles.html)
|
|
to your `Cargo.toml`:
|
|
|
|
```toml
|
|
[profile.wasm-release]
|
|
# Use release profile as default values
|
|
inherits = "release"
|
|
|
|
# Optimize with size in mind, also try "s", sometimes it is better.
|
|
# This doesn't increase compilation times compared to -O3, great improvements
|
|
opt-level = "z"
|
|
|
|
# Do a second optimization pass removing duplicate or unused code from dependencies.
|
|
# Slows compile times, marginal improvements
|
|
lto = "fat"
|
|
|
|
# When building crates, optimize larger chunks at a time
|
|
# Slows compile times, marginal improvements
|
|
codegen-units = 1
|
|
```
|
|
|
|
Now, when building the final executable, use the `wasm-release` profile
|
|
by replacing `--release` by `--profile wasm-release` in the cargo command.
|
|
|
|
```sh
|
|
cargo build --profile wasm-release --example lighting --target wasm32-unknown-unknown
|
|
```
|
|
|
|
Make sure your final executable size is smaller, some of those optimizations
|
|
may not be worth keeping, due to compilation time increases.
|
|
|
|
#### 2. Use `wasm-opt` from the binaryen package
|
|
|
|
Binaryen is a set of tools for working with wasm. It has a `wasm-opt` CLI tool.
|
|
|
|
First download the `binaryen` package,
|
|
then locate the `.wasm` file generated by `wasm-bindgen`.
|
|
It should be in the `--out-dir` you specified in the command line,
|
|
the file name should end in `_bg.wasm`.
|
|
|
|
Then run `wasm-opt` with the `-Oz` flag. Note that `wasm-opt` is _very slow_.
|
|
|
|
Note that `wasm-opt` optimizations might not be as effective if you
|
|
didn't apply the optimizations from the previous section.
|
|
|
|
```sh
|
|
wasm-opt -Oz --output optimized.wasm examples/wasm/target/lighting_bg.wasm
|
|
mv optimized.wasm examples/wasm/target/lighting_bg.wasm
|
|
```
|
|
|
|
For a small project with a basic 3d model and two lights,
|
|
the generated file sizes are, as of Jully 2022 as following:
|
|
|
|
|profile | wasm-opt | no wasm-opt |
|
|
|----------------------------------|----------|-------------|
|
|
|Default | 8.5M | 13.0M |
|
|
|opt-level = "z" | 6.1M | 12.7M |
|
|
|"z" + lto = "thin" | 5.9M | 12M |
|
|
|"z" + lto = "fat" | 5.1M | 9.4M |
|
|
|"z" + "thin" + codegen-units = 1 | 5.3M | 11M |
|
|
|"z" + "fat" + codegen-units = 1 | 4.8M | 8.5M |
|
|
|
|
There are more advanced optimization options available,
|
|
check the following pages for more info:
|
|
|
|
- <https://rustwasm.github.io/book/reference/code-size.html>
|
|
- <https://rustwasm.github.io/docs/wasm-bindgen/reference/optimize-size.html>
|
|
- <https://rustwasm.github.io/book/game-of-life/code-size.html>
|
|
|
|
### Loading Assets
|
|
|
|
To load assets, they need to be available in the folder examples/wasm/assets. Cloning this
|
|
repository will set it up as a symlink on Linux and macOS, but you will need to manually move
|
|
the assets on Windows.
|