Namek / js13k_2019

playground for C++ -> WebAssembly + WebGL (failed attempt at game design for js13k game jam in 2019)
https://namekdev.net/2019/09/webassembly-cpp-and-webgl-for-js13k-game-jam/
16 stars 2 forks source link

WebGL + WASM dev advice based on your experience? #1

Open KTRosenberg opened 4 years ago

KTRosenberg commented 4 years ago

I came across this repository after having begun a project similar to yours: build a simple game engine in wasm C++ using WebGL. You mention that the project failed. What did you find were some of the pitfalls and issues? I'm currently compiling standalone and testing with canvas2d instead, and calling into javascript every time I interact with the binding/wrapper API. I noticed that the frames per second decreased and became unstable. I wonder if this is due to the number of javascript calls, or if it's due to a worse problem.

My next thought is to do all calculations in the C++ and write to a command buffer on the C++ side, directly into the imported memory buffer at some specific offsets. Then the js would execute all the commands on its side at the end of the frame. This way, the C++ would never call into the js. Does this approach seem possible / from your experience? I am not sure what the performance characteristics are of just writing directly into the memory. Are there any drawbacks?

My hope is also to serialize the game state in binary just by saving the raw WebAssembly.Memory information and reloading it in the future.

Based on your experience, what do you think might work / what should I watch out for? Thank you for your time!

Namek commented 4 years ago

Hi!

There were 2 failures:

  1. C++ -> WASM not supported as well as I wished for development
  2. The idea for the game, it was not easy to understand for the player

Due to pitifals and issues please have a read on https://namekdev.net/2019/09/webassembly-cpp-and-webgl-for-js13k-game-jam/

calculations in the C++ and write to a command buffer on the C++ side, directly into the imported memory buffer at some specific offsets. Then the js would execute all the commands on its side at the end of the frame. This way, the C++ would never call into the js. Does this approach seem possible / from your experience?

You should know you can't have a thread running on the WebAssembly part. So, the WASM code cannot run on itself, it has to be triggered by the JavaScript.

I am not sure what the performance characteristics are of just writing directly into the memory. Are there any drawbacks?

I've seen some research about the performance and it's really doing great job. But it's hard to program manually all the collections (like vector, map) and stuff. If you don't disable some things in emscripten then you get a huge binary size for just having built-in collections which may not be the best ones for WASM.

My hope is also to serialize the game state in binary just by saving the raw WebAssembly.Memory information and reloading it in the future.

Sounds cool! Every game should have save/load state as a pure byte array, not requiring any additional logic wiring up things with pointers to the memory blocks. Let me know if this works for you. It's really hard to manage such pattern in real world, it would be best if a language supported it. Maybe the Jai language from Jonathan Blow (if you're interested lookup his language videos on YouTube/Twitch) will support this someday (relative pointers and such), who knows.

Based on your experience, what do you think might work / what should I watch out for? Again, please go to my article and the Resources (links on the bottom of it). I'm surprised I didn't link it to this repo. I'll do it right now.

One thing you should know is that I have targetted for the smallest size possible. This brought me maaany issues. So if you don't care on really small size of the WASM binary then my experience may not be useful to you.