Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web exports guide #15

Merged
merged 2 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/other/.markdownlint.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
"names": ["Godot", "GDScript", "Rust", "GDExtension", "gdext", "godot-rust"],
"code_blocks": false
},
"no-inline-html": {
"allowed_elements": ["br"]
},
// Horizontal rules: --- or ***.
"hr-style": {
"style": "---"
},
// Indented vs ```-fenced.
"code-block-style": {
"style": "fenced"
Expand Down
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- [Compatibility and stability](toolchain/compatibility.md)
- [Selecting a Godot version](toolchain/godot-version.md)
- [Debugging](toolchain/debugging.md)
- [Export to Web](toolchain/export-web.md)
- [Contributing to gdext](contribute/index.md)
- [Dev tools and testing](contribute/dev-tools.md)
- [Code and API conventions](contribute/conventions.md)
4 changes: 2 additions & 2 deletions src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Welcome to the **godot-rust book**! This is a work-in-progress user guide for **gdext**, the Rust binding for Godot 4.

If you're new to Rust, before getting started, it is highly recommended that you familiarize yourself with concepts outlined in the officially
maintained[Rust Book](https://doc.rust-lang.org/book/).
maintained [Rust Book](https://doc.rust-lang.org/book/).

To read the book about gdnative (Godot 3 binding), follow [this link](../gdnative-book).

Expand All @@ -21,7 +21,7 @@ language and also provides official support for C++ and C# bindings. Its GDExten
in our case Rust.

Rust brings a modern, robust and performant experience to game development. If you are interested in scalability, strong type systems or
just enjoy Rust as a language, you may consider combining it with Godot, to combine the best of both worlds.
just enjoy Rust as a language, you may consider using it with Godot, to combine the best of both worlds.


## About this project
Expand Down
162 changes: 162 additions & 0 deletions src/toolchain/export-web.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<!--
~ This Source Code Form is subject to the terms of the Mozilla Public
~ License, v. 2.0. If a copy of the MPL was not distributed with this
~ file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->

# Export to Web

Web builds are a fair bit more difficult to get started with compared to native builds.
This will be a complete guide on how to get things compiled.
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.

```admonish warning
Web support with gdext is experimental and should be understood as such before proceeding.
```


## Installation

Install a nightly build of `rustc`, the `wasm32-unknown-emscripten` target for `rustc`, and `rust-src`.
The reason why nightly `rustc` is required is the unstable flag to build `std` ([`-Zbuild-std`][flag-build-std]).
Assuming that Rust was installed with `rustup`, this is quite simple.


```sh
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
rustup target add wasm32-unknown-emscripten --toolchain nightly
```

Next, install Emscripten. The simplest way to achieve this is to install [`emsdk` from the git repo][emsdk-git].
We recommended version 3.1.39 for now.[^1]

```sh
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 3.1.39
./emsdk activate 3.1.39
source ./emsdk.sh (or ./emsdk.bat on windows)
```

It would also be **highly** recommended to follow the instructions in the terminal to add `emcc`[^2] to your `PATH`.
If not, it is necessary to manually `source` the `emsdk.sh` file in every new terminal prior to compilation.
This is platform-specific.

[flag-build-std]: https://doc.rust-lang.org/cargo/reference/unstable.html#list-of-unstable-features
[emsdk-git]: https://github.com/emscripten-core/emsdk#readme


## Project Configuration

Enable the [`experimental-wasm`][api-cargo-features] feature on gdext in the `Cargo.toml` file.
It is also recommended to enable the [`lazy-function-tables`][api-cargo-features] feature to avoid long compile times with release builds
(this might be a bug and not necessary in the future). Edit the line to something like the following:

```toml
[dependencies.godot]
git = "https://github.com/godot-rust/gdext"
branch = "master"
features = ["experimental-wasm", "lazy-function-tables"]
```

If you do not already have a `.cargo/config.toml` file, do the following:

- Create a `.cargo` directory at the same level as your `Cargo.toml`.
- Inside that directory, create a `config.toml` file.

This file needs to contain the following:

```toml
[target.wasm32-unknown-emscripten]
rustflags = [
"-C", "link-args=-sSIDE_MODULE=2",
"-C", "link-args=-pthread", # was -sUSE_PTHREADS=1 in earlier emscripten versions
"-C", "target-feature=+atomics,+bulk-memory,+mutable-globals",
"-Zlink-native-libraries=no"
]
```

Edit the project's `.gdextension` file to include support for web exports.
This file will probably be at `godot/{YourCrate}.gdextension`.
The format will be similar to the following:

```ini
[libraries]
...
web.debug.wasm32 = "res://../rust/target/wasm32-unknown-emscripten/debug/{YourCrate}.wasm"
web.release.wasm32 = "res://../rust/target/wasm32-unknown-emscripten/release/{YourCrate}.wasm"
```

[api-cargo-features]: https://godot-rust.github.io/docs/gdext/master/godot/#cargo-features


## Compile the Project

Verify `emcc` is in the `PATH`. This can be as simple as doing the following:

```sh
emcc --version
```

Compile the code.
It is necessary to both use the nightly compiler and specify to build std[^3], along with specifying the Emscripten target.

```sh
cargo +nightly build -Zbuild-std --target wasm32-unknown-emscripten
```


## Godot editor setup

Add a web export in the Godot Editor. In the top menu bar, go to `Project > Export...` and configure it there.
Make sure to turn on the `Extensions Support` checkbox.
Comment on lines +112 to +113
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention to download export templates if they are not yet configured?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you get a prompt if it's missing to download it, and should be downloaded at the same time you'd download templates for any other export. I'd have to intentionally trigger that and see about that.

Copy link

@PgBiel PgBiel Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the last time I tried it in my VM, I believe the Export window displays some red text at the bottom suggesting you need Export Templates, but I think you still need to click some buttons to prompt the download. Could be useful to list the steps needed, but very briefly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. It's fine to not explicitly mention it then.


![Example of export screen](images/web-export.png)

If instead, the bottom on the export popup contains this error in red:

> No export template found at expected path:

Then click on `Manage Export Templates` next to the error message, and then on the next screen select `Download and Install`.
See [Godot tutorial][godot-export-templates] for further information.


### Running the webserver

Back at the main editor screen, there is an option to run the web debug build (_not_ a release build) locally
without needing to run an export or set up a web server.
At the top right, choose `Remote Debug > Run in Browser` and it will automatically open up a web browser.

![Location of built-in web server](images/web-browser-run.png)


```admonish warning title="Known Caveats"
- Godot 4.1.3+ or 4.2+ is necessary.
- Only Chromium-based browsers (Chrome or Edge) appear to be supported by GDExtension at the moment; Firefox and Safari don't work yet.
Info about browser support can be found [here](https://github.com/godotengine/godot-cpp/pull/1247#issuecomment-1742197814).
```

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`)
and open it in a supported browser such as Google Chrome or Microsoft Edge.

[godot-export-templates]: https://docs.godotengine.org/en/stable/tutorials/export/exporting_projects.html#export-menu


## Debugging

Currently, the only option for WASM debugging is
[this extension](https://chromewebstore.google.com/detail/cc++-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb?pli=1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add the name of the extension in the link text, and use the [<name of extension>][wasm-debugger] format (i.e. move the actual link to the end of the section)?

for Chrome. It adds support for breakpoints and a memory viewer into the F12 menu.


<br>

---

[^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`.

[^2]: `emcc` is the name of Emscripten's compiler.

[^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).

Binary file added src/toolchain/images/web-browser-run.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/toolchain/images/web-export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading