godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.49k stars 21.26k forks source link

Add support for WebAssembly plugins and scripts #28303

Closed PoignardAzur closed 4 years ago

PoignardAzur commented 5 years ago

Godot currently supports exporting to WebAssembly, and through GDNative, importing from C/C++ and other languages. But it doesn't support importing WebAssembly modules, which I think is a big omission.

WebAssembly is a good format to import for the same reason glTF is:

WebAssembly plugins would have a lot of advantages over GDNative, including:

These would be the short-term benefits, that a good wasm implementation would provide. On the longer term, integrating wasm into Godot would leverage improvements from developers working on other parts of the ecosystem:

Now, WebAssembly as a standard isn't ready to be integrated in Godot yet. There are a few proposals (reference types, WebIDL bindings, WASI) that need to be standardized and implemented in compilers and runtimes before wasm can be integrated into Godot.

But I think it's worth starting to consider it now. I'm especially interested in what @Faless and @eska014 think on the subject. What kind of work is needed to integrate a wasm interpreter into Godot? Is it something that can plausibly be added to the 4.0 roadmap?

Calinou commented 5 years ago

I think this could be handled with a GDNative library (or C++ module) that integrates with a WebAssembly runtime, so you could load such modules when desired.

PoignardAzur commented 5 years ago

That would be a good first step.

But I want to emphasize, a tight wasm integration could completely replace GDNative in the long term. There would be a transition cost, but the benefits (ocap sandboxing, better introspection, standardized API) would be superior to keeping it as a GDNative front-end.

Calinou commented 5 years ago

@PoignardAzur What about performance? Many people use GDNative for performance-critical tasks.

PoignardAzur commented 5 years ago

I haven't looked into it too hard, but from what I remember, wasm is somewhere around 10% slower than native. I'd wager that it gets faster if you can disable bounds-checking and other safety features.

hackini commented 5 years ago

wasm would be really great for add-ons on the AssetLib, you'd get close to native performance but without the need of compilation or shipping multiple binaries.

Concerning WASI, this requires some thinking. WASI is an abstraction layer of the OS APIs, but so is Godot itself... So if you want to access let's say the microphone, WASI will surely have an API for that one day, but Godot already has that too.

It's not clear to me whereas WASI is necessarily used with wasm or if it can be used natively from compiled C++ ?

If you can call it from C++, then it would actually make sense for Godot itself to use WASI as a platform, on the long run it would save developer time because they wouldn't have to implement abstractions for all sensors and APIs over Mac, Win, Linux, IOS, Android, Web, etc... but it would be done by WASI for us.

Concerning GDNative, in any case it is important to keep the possibility to compile C++ / Rust / etc. natively. Currently wasm perf are still not the same as native (some plots here) also some people/studios might want to use special optimizations or some custom/proprietary/platform-specific libraries that are not accessible from wasm.

However, if WASI APIs can be called from C++ then GDNative could be transformed as a WASI Module (so one "Godot" box on that picture) and you would call those Godot WASI APIs from any language that can use WASI, whereas it is from native compiled code or from wasm.

In any case if I write a C++ / Rust / etc. add-on, it would be a shame that I have two different code bases, one that calls "GDNative APIs", one that calls "Godot wasm APIs".

Calinou commented 5 years ago

This may be of interest too (not sure): https://hacks.mozilla.org/2019/08/webassembly-interface-types/

Edit: There's also this as of 2019-11-21: https://v8.dev/blog/emscripten-standalone-wasm

PoignardAzur commented 5 years ago

Interface types aren't nearly mature enough to be useful to Godot. On the other hand, someone with some experience with Godot's internals should probably take part in the standardization process on the Interface Types repository, to make sure the needs of a game engine like Godot are taken into account.

syrusakbary commented 5 years ago

I just stumbled upon this issue, I think WebAssembly it's a great use case for plugins and scripts!

I work at Wasmer and I'd love to help an integration! (a few other projects are already using it for plugins!)

Let me know if you would like any help or assistance :)

Type1J commented 5 years ago

@syrusakbary Most of the projects that I've seen that use C++ and WASM use a .dll for the runtime. I think Godot would probably prefer a statically linked runtime. It's probably best if it's compiled as part of Godot's normal build with SCONS.

However, since Wasmer is written in Rust, and would likely have cargo build the static lib (probably started by SCONS), the WASM plugin using version of Godot should probably be a compile time option. The Mono/C# using build is the same way, so there is precedent.

Calinou commented 4 years ago

Closing in favor of https://github.com/godotengine/godot-proposals/issues/147, as we now track feature proposals on the Godot proposals repository.

follower commented 4 years ago

FYI for anyone subscribed: "WASM Engine for Godot" (https://gitlab.com/RancidBacon/godot-wasm-engine) now enables support for executing WebAssembly from Godot.

More details on the previously linked proposal issue: https://github.com/godotengine/godot-proposals/issues/147#issuecomment-670349142

@syrusakbary The project currently uses Wasmtime but it's likely Wasmer support could be added for the right price. ;)

syrusakbary commented 4 years ago

Good work on the integration!

I bet than when you want to maximize runtime speed Wasmer would come in handy 🤗

Type1J commented 4 years ago

A plugin to enable plugins? That's a step in the right direction. We really need it intergrated with Godot to enable it on all supported platforms, and the API should make it not be used on html to enable use with the html wasm target's native runtime when exporting to the html target.

ashtonmeuser commented 2 years ago

Ping for those subscribed. I've created a GDNative Godot Wasm addon that may address some of the functionality proposed here. Uses Wasmer as runtime.