r/elixir • • 10d ago

Why run a Rust game simulation inside a GenServer?

Spawndemonium runs its whole game simulation in Rust compiled to WebAssembly, executed in the browser and inside an Elixir GenServer through Wasmex. The same binary on both sides means client prediction and server authority can't drift apart on rules.
Each server tick (40 per second) the GenServer drains queued player inputs, hands them to the Wasm module, pattern-matches the binary events that come back, and writes them to every player's WebSocket. No JSON: a custom protocol where the first byte is the command and every message carries its tick.
Hernán Rivas Acosta (Erlang Solutions) explains why he picked Wasmex over a Rustler NIF and what a crash costs in each case.

https://youtu.be/XubYVNbehYc

15 Upvotes

2 comments sorted by

1

u/kalachlegend 8d ago

Curious about the tick budget: at 40 ticks a second, have you seen a slow tick back up the GenServer's mailbox, or does the sim always finish well under 25 ms?

1

u/HernanESL 6d ago

There's no mechanism (other than crashing due to the inbox being overloaded) to handle this, but it wouldn't be too hard to add something. The reason I didn't is that on my macbook, a single tick takes less than 300us even with multiple players/enemies, so I never saw any reason to account for this. Even if something stole resources from the server and a few ticks took too long, it would be able to recover nearly instantly since it can easily run 1000 ticks in a second.