• they/them

i am into accessibility and game design. i go by sysopod on other platforms as well



edit: thanks for the shares! i think i have figured out the way forward now

note up front for anyone who wants to give me advice (which i will appreciate!)- i am doing this as an exercise to learn how to use rust and web assembly (wasm), so any suggestions that it would be easier to just not use rust or wasm will not be viable, even if that is probably very accurate. just wanted to say that to save time and energy for any kind people offering their thoughts.

this is for the js13k submission i'm working on. i need to keep the current game state in memory (what floor the player is on, what items are haunted, how much progress has the player made, etc) and i need to do that while also taking input from the player via their interactions with the html.

i had previously created a demo of the game as a pure rust command line version. in that version of the game, this whole thing is handled by std::io::stdin and just passing around the game state as a struct in a loop in the main run() function. the problem is, i don't really know how to modify or recreate std::io::stdin to fit with taking input from html form data/JS functions through wasm, so i've been trying to just switch to passing the game state as an object to the js/browser to keep in memory there and then throw it back to rust whenever i need to modify it/run some logic on it. that's a lot of work, wasm_bindgen is not exactly easy to make work with custom structs or even standard composite data types like vectors, and the whole endeavour is probably wasteful in terms of making me write redundant code when i really don't need to be using the game struct at all in the js- which should just be asking the rust code for the result of input taken from the html/user interactions.

i could go down the rabbit hole of trying to create a web worker to handle messaging between the rust code and the js, so it keeps the game state in memory and then modifies and renews it as needed...? but that also seems really janky. i'm kinda at a loss for what the correct direction is, here. rust/wasm seems to be pretty under supported, given the main tutorial in the book is flatly broken due to dependency issues and the community seems pretty fractured (this might be a misconception, i'm just going off what i can find online), so it's not like i can find a ton of support or wealth of historical solutions to this stuff like i can with most other languages.


You must log in to comment.

in reply to @silasoftrees's post:

Repeating for myself so I didnt miss stuff:

  • You have a rust demo console app that normally manages the run loop (reading the stdin to do stuff in the game world).
  • The core game code runs inside WASM. When an input event happens on the client - the game state gets serialized from the WASM instance into a JS value so it can be edited JS side, and then it gets serialized again so the state can be passed back to the WASM instance, and then the run loop can is called.

Your run loop - is it like a classic console program where it's "wait for user input" and then "process user input" (rinse and repeat), or it running in a loop and polling/simulating some game state and listening for inputs on the side?

This is probably due to my ignorance for the specifics of how the game is laid out, but would it make sense for (depending on how input handling works) you to define and export a set of function rust-side representing all the inputs that might happen HTML-side, and then just have the HTML event handlers call the rust code when one of them happens, passing in the State struct/reference and letting game code handle the specifics of how to handle it.

I don't have a huge amount of experience with rust and js together (know a bit about them separate), but a combination program of those is really interesting to me. Let me know if this helps (or more likely, doesn't)

thank you for your reply! this did solve my problem- you got me thinking about how rust handles references. i realized i could pass the game state as a mutable reference, keeping it live in memory in the js.

there isn't a loop in the browser version - it actually works exactly like your suggestion, but i hadn't been accounting for how rust eats the state if i pass it to rust directly.

Maybe this is a stupid solution, but have you considered using the lazy_static crate to get a global variable, and then wrapping the state struct in a refcell to let you mutate the global state value?
It's maybe not the most "rusty" design pattern, but the language provides the escape hatch to go create a single, globally-mutable, state for a reason. It's still safe, even though that safety is enforced through runtime errors rather than statically, and it could be a 3-line solution for this otherwise quite thorny problem.