|
| 1 | +<!-- |
| 2 | + ~ This Source Code Form is subject to the terms of the Mozilla Public |
| 3 | + ~ License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 | + ~ file, You can obtain one at https://mozilla.org/MPL/2.0/. |
| 5 | +--> |
| 6 | + |
| 7 | +# Export to Web |
| 8 | + |
| 9 | +Web builds are a fair bit more difficult to get started with compared to native builds. |
| 10 | +This will be a complete guide on how to get things compiled. |
| 11 | +However, setting up a web server to host and share your game is considered out of scope of this guide, and is best explained elsewhere. |
| 12 | + |
| 13 | +```admonish warning |
| 14 | +Web support with gdext is experimental and should be understood as such before proceeding. |
| 15 | +``` |
| 16 | + |
| 17 | + |
| 18 | +## Installation |
| 19 | + |
| 20 | +Install a nightly build of `rustc`, the `wasm32-unknown-emscripten` target for `rustc`, and `rust-src`. |
| 21 | +The reason why nightly `rustc` is required is the unstable flag to build `std` ([`-Zbuild-std`][flag-build-std]). |
| 22 | +Assuming that Rust was installed with `rustup`, this is quite simple. |
| 23 | + |
| 24 | + |
| 25 | + ```sh |
| 26 | + rustup toolchain install nightly |
| 27 | + rustup component add rust-src --toolchain nightly |
| 28 | + rustup target add wasm32-unknown-emscripten --toolchain nightly |
| 29 | + ``` |
| 30 | + |
| 31 | +Next, install Emscripten. The simplest way to achieve this is to install [`emsdk` from the git repo][emsdk-git]. |
| 32 | +We recommended version 3.1.39 for now.[^1] |
| 33 | + |
| 34 | +```sh |
| 35 | +git clone https://github.com/emscripten-core/emsdk.git |
| 36 | +cd emsdk |
| 37 | +./emsdk install 3.1.39 |
| 38 | +./emsdk activate 3.1.39 |
| 39 | +source ./emsdk.sh (or ./emsdk.bat on windows) |
| 40 | +``` |
| 41 | + |
| 42 | +It would also be **highly** recommended to follow the instructions in the terminal to add `emcc`[^2] to your `PATH`. |
| 43 | +If not, it is necessary to manually `source` the `emsdk.sh` file in every new terminal prior to compilation. |
| 44 | +This is platform-specific. |
| 45 | + |
| 46 | +[flag-build-std]: https://doc.rust-lang.org/cargo/reference/unstable.html#list-of-unstable-features |
| 47 | +[emsdk-git]: https://github.com/emscripten-core/emsdk#readme |
| 48 | + |
| 49 | + |
| 50 | +## Project Configuration |
| 51 | + |
| 52 | +Enable the [`experimental-wasm`][api-cargo-features] feature on gdext in the `Cargo.toml` file. |
| 53 | +It is also recommended to enable the [`lazy-function-tables`][api-cargo-features] feature to avoid long compile times with release builds |
| 54 | +(this might be a bug and not necessary in the future). Edit the line to something like the following: |
| 55 | + |
| 56 | +```toml |
| 57 | +[dependencies.godot] |
| 58 | +git = "https://github.com/godot-rust/gdext" |
| 59 | +branch = "master" |
| 60 | +features = ["experimental-wasm", "lazy-function-tables"] |
| 61 | +``` |
| 62 | + |
| 63 | +If you do not already have a `.cargo/config.toml` file, do the following: |
| 64 | + |
| 65 | +- Create a `.cargo` directory at the same level as your `Cargo.toml`. |
| 66 | +- Inside that directory, create a `config.toml` file. |
| 67 | + |
| 68 | +This file needs to contain the following: |
| 69 | + |
| 70 | +```toml |
| 71 | +[target.wasm32-unknown-emscripten] |
| 72 | +rustflags = [ |
| 73 | + "-C", "link-args=-sSIDE_MODULE=2", |
| 74 | + "-C", "link-args=-pthread", # was -sUSE_PTHREADS=1 in earlier emscripten versions |
| 75 | + "-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", |
| 76 | + "-Zlink-native-libraries=no" |
| 77 | +] |
| 78 | +``` |
| 79 | + |
| 80 | +Edit the project's `.gdextension` file to include support for web exports. |
| 81 | +This file will probably be at `godot/{YourCrate}.gdextension`. |
| 82 | +The format will be similar to the following: |
| 83 | + |
| 84 | +```ini |
| 85 | +[libraries] |
| 86 | +... |
| 87 | +web.debug.wasm32 = "res://../rust/target/wasm32-unknown-emscripten/debug/{YourCrate}.wasm" |
| 88 | +web.release.wasm32 = "res://../rust/target/wasm32-unknown-emscripten/release/{YourCrate}.wasm" |
| 89 | +``` |
| 90 | + |
| 91 | +[api-cargo-features]: https://godot-rust.github.io/docs/gdext/master/godot/#cargo-features |
| 92 | + |
| 93 | + |
| 94 | +## Compile the Project |
| 95 | + |
| 96 | +Verify `emcc` is in the `PATH`. This can be as simple as doing the following: |
| 97 | + |
| 98 | +```sh |
| 99 | +emcc --version |
| 100 | +``` |
| 101 | + |
| 102 | +Compile the code. |
| 103 | +It is necessary to both use the nightly compiler and specify to build std[^3], along with specifying the Emscripten target. |
| 104 | + |
| 105 | +```sh |
| 106 | +cargo +nightly build -Zbuild-std --target wasm32-unknown-emscripten |
| 107 | +``` |
| 108 | + |
| 109 | + |
| 110 | +## Godot editor setup |
| 111 | + |
| 112 | +Add a web export in the Godot Editor. In the top menu bar, go to `Project > Export...` and configure it there. |
| 113 | +Make sure to turn on the `Extensions Support` checkbox. |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | +If instead, the bottom on the export popup contains this error in red: |
| 118 | + |
| 119 | +> No export template found at expected path: |
| 120 | +
|
| 121 | +Then click on `Manage Export Templates` next to the error message, and then on the next screen select `Download and Install`. |
| 122 | +See [Godot tutorial][godot-export-templates] for further information. |
| 123 | + |
| 124 | + |
| 125 | +### Running the webserver |
| 126 | + |
| 127 | +Back at the main editor screen, there is an option to run the web debug build (_not_ a release build) locally |
| 128 | +without needing to run an export or set up a web server. |
| 129 | +At the top right, choose `Remote Debug > Run in Browser` and it will automatically open up a web browser. |
| 130 | + |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | +```admonish warning title="Known Caveats" |
| 135 | +- Godot 4.1.3+ or 4.2+ is necessary. |
| 136 | +- Only Chromium-based browsers (Chrome or Edge) appear to be supported by GDExtension at the moment; Firefox and Safari don't work yet. |
| 137 | + Info about browser support can be found [here](https://github.com/godotengine/godot-cpp/pull/1247#issuecomment-1742197814). |
| 138 | +``` |
| 139 | + |
| 140 | +If your default browser is not Chromium-based, you will need to copy the URL (which is usually `http://localhost:8060/tmp_js_export.html`) |
| 141 | +and open it in a supported browser such as Google Chrome or Microsoft Edge. |
| 142 | + |
| 143 | +[godot-export-templates]: https://docs.godotengine.org/en/stable/tutorials/export/exporting_projects.html#export-menu |
| 144 | + |
| 145 | + |
| 146 | +## Debugging |
| 147 | + |
| 148 | +Currently, the only option for WASM debugging is |
| 149 | +[this extension](https://chromewebstore.google.com/detail/cc++-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb?pli=1) |
| 150 | +for Chrome. It adds support for breakpoints and a memory viewer into the F12 menu. |
| 151 | + |
| 152 | + |
| 153 | +<br> |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +[^1]: Note: Due to a bug with `emscripten`, the maximum version of `emcc`[^2] that can one compile `Godot` with is `3.1.39`. gdext itself should be able to support the latest version of `emcc`, however, it may be a safer bet to stick to version `3.1.39`. |
| 158 | + |
| 159 | +[^2]: `emcc` is the name of Emscripten's compiler. |
| 160 | + |
| 161 | +[^3]: The primary reason for this is it is necessary to compile with `-sSHARED_MEMORY` enabled. The shipped `std` does not, so building `std` is a requirement. Related info on about WASM support can be found [here](https://github.com/rust-lang/rust/issues/77839). |
| 162 | + |
0 commit comments