Asteroids game (Rust + WebAssembly)

awesome!

Nice game good job !

Note that there is a "glitch" with the bullets. When you shoot is angles in a certain way you can duplicate your shoting.

This is nice! I am just wondering, do you have any technical reasons to do the drawing with JS instead of Rust (wasm-bindgen/web-sys/js-sys)?

(I also noticed it is very slow on Firefox unlike on Chromium-based browsers)

A collision detection broad phase would probably improve performance a lot.

There wasn't a strong reason, but I liked the idea of decoupling the drawing target from the wasm bundle. The drawing calls used for the game are small and contained, and I didn't see an advantage in using web-sys to write a small section of Rust that would look like JS but end up compiled in the bundle.

Doing it this way allowed me to make a version that renders to SVG instead of canvas and uses the same wasm file, with only a few changes to the JS. (That version lets you to pause the game with spacebar and scrub through the last 10 seconds of the game with a slider. It's what I used to capture the SVG "screenshot" for the README.)


Is it still slow in Firefox for you? So far reports of low frame rate seem related to canvas filter effects and not game execution. (I'm guessing certain browser/hardware combinations cause the filter effects to be done on CPU instead of GPU.) I updated the page to turn off filter effects if the frame rate is low, and I haven't heard reports of low frame rate on that version yet.

So far reports of poor performance seem related to filter effects and not game execution, so I'm not sure.

For collision detection, each pair is compared first with an inexpensive bounds check on distance or even distance-squared. So in that sense, there's already a broad phase.

There are no optimizations to reduce the number of comparisons, but in this game that number ends up being small, in the hundreds at most (n asteroids + n blasts + n asteroids * m blasts). Would something like a spatial-subdivision tree pay for itself in this case? I'd be curious! But performance seemed fine this way, so I didn't pursue anything else.

I did not look at the rendering code, so it may be that there is some big inefficiency there. Rendering the game should cost basically nothing, so 10k checks can be pretty big.

A very simple thing you can do to reduce checks is to sort the things along one axis and sweep along the axis to find pairs that are sufficiently close on that axis. However, that only eliminates one dimension. To go all the way you need some pretty difficult data structures, or you need to rely on the fact that the scene changes very little from frame to frame.

Another method that could work for this game is to use a uniform grid larger than an asteroid and only collide objects that occupy the same grid squares.

I haven't used it but using https://ncollide.org/ might be an easy fix.

From my experience if there really are only around some hundred collisions,the simple code is much much faster than any data structure.
At least that is my experience when comparing some quadratic and cubic functions against some algorithms with n log n runtime or similar.

So all I really want to say is, profile it before trying to throw much more complicated algorithms at it :slight_smile:

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.