Using WASM as a mod system for a game built in rust #2627
Replies: 6 comments
-
I think this is a compelling use case for Wasm, however how you do it depends on your trust model. If a server is taking user-uploaded mods at runtime, then you will need as much sandboxing as possible. However if you're using Wasm more as a scripting system and the Wasm modules are trusted, you don't need to worry about sandboxing as much. When fully sandboxed, the guest Wasm and the host (using the wasmer library) do not share memory. The host can look directly into guest memory, but you must be careful to avoid undefined behavior (for example using The way I'd structure this if I were doing it is:
There are ways to avoid the serialization / deserialization step, but I think it's probably not worth it in general, it'll take more careful design and planning and is less flexible. If you want some inspiration for what an API with less parsing of blobs of data might look like, check out the design of WASI, specifically how directory entries are listed. WASI is designed around the host never allocating memory in the Wasm, so everything is fully controlled by the Wasm guest. |
Beta Was this translation helpful? Give feedback.
-
Hi, The plan is for this to be added to an offline single player game (IE. the game lives entirely on the users machine), so the trust model is entirely on what they choose to install. To this extent I don't think that any form of sandboxing is strictly necessary, the user themselves should perform some due-diligence on whether or not the mod is safe and suitable. I will be adding in some basic checks to make sure the mod is compatible and not just a random WASM file that was added to the folder, but beyond that, its down to the user themselves. You mention about avoiding serialization / deserialization, I just want to check does WASM support structs, or would it have to be some form of encoding to pass it back and forth? |
Beta Was this translation helpful? Give feedback.
-
Wasm types don't include structs, however, functions can return multiple values once support for multi-value was added, and not all Wasm ecosystem software has been updated for that yet. For example, if you go to the Rust playground and write code that returns a struct (select "show wasm" from the dropdown to the right of "Build ▶"), it will create a Wasm function that returns nothing, and the struct data is written into the Wasm memory. The question of how a language-level struct is passed in Wasm code is akin to an ABI for native code, but in Wasm. I don't think Rust documents their Wasm ABI. |
Beta Was this translation helpful? Give feedback.
-
Oops, sorry I dropped the ball on responding here, @nlewycky is correct but I'd just like to add one thing! The default ABI, if unspecified, in rust is For example The equivalent for structs is |
Beta Was this translation helpful? Give feedback.
-
I am also implementing a scripting solution in a similar vein. |
Beta Was this translation helpful? Give feedback.
-
Veloren game has a plugin support using Wasmer runtime, might be interesting: https://gitlab.com/veloren/veloren/-/blob/6cfb4bd74d565f2cffb583c1960bafb7c384685a/common/sys/src/plugin/module.rs |
Beta Was this translation helpful? Give feedback.
-
Summary
A clear and concise summary of your question.
I've been looking at using Rust for a simple prototype 2d game with support for modding built in to the core of the game.
For the modding I am looking at WASM, where there would be a directory of
<mod>.wasm
files that can be loaded and they provide the modded functionality.The way I was looking at doing this would be to
glob
all of the files in amod
directory somewhere, and in the initial boot of the game load them all and call a simple registration method which would return to the game which events they want to hook into.My question is focused on the event hooks. I want to be able to pass through core parts of the game in the structure that the game uses them (ie, as structs) and get them returned back to me as a struct that is usable.
Is this something that is possible, or is it not doable, and if it isn't doable, what would be your recommended way to handle something like this?
I could convert the entire struct to some other data structure (either structured text / json), for it to be handled and accept that back, but that would require more validation on my side to make sure the core structure isn't lost.
Beta Was this translation helpful? Give feedback.
All reactions