
Rocket – A Rust game running on WASM - wofo
https://aochagavia.github.io/blog/rocket---a-rust-game-running-on-wasm/
======
haberman
Looks like the actual artifacts are a 6kB html (with embedded JS) and a 52kB
.wasm file.

[https://github.com/aochagavia/rocket_wasm/tree/master/html](https://github.com/aochagavia/rocket_wasm/tree/master/html)

It's very nice to see that this "scales down", so-to-speak. It can be really
disheartening to see small programs compile into hundreds-of-kB binary images.
It's great to see that Rust+WASM can be so lean!

~~~
steveklabnik
a "add one to a number and return it" compiled this way results in a ~100 byte
binary. It's about twice the size of writing it by hand, but those gains get
lost as soon as you start doing real things, so it's not a big deal.

One big jump in binary size starts when you use the allocator, as then it
needs to include the allocator's code.

~~~
haberman
It would be nice if there was a modern malloc implementation (with good multi-
threaded performance) that optimized for size.

~~~
steveklabnik
We use a Rust port of dlmalloc with this toolchain.

Multithreading doesn't matter to wasm yet, incidentally; it's still single
threaded.

------
Aissen
I'd love if those to see those web games start to use KeyboardEvent.code
[https://developer.mozilla.org/en-
US/docs/Web/API/KeyboardEve...](https://developer.mozilla.org/en-
US/docs/Web/API/KeyboardEvent/code) ; which is much more portable across
keymaps and layouts than "key". Unfortunately, it's hindered by slow Edge &
Android adoption:

[https://caniuse.com/#feat=keyboardevent-
code](https://caniuse.com/#feat=keyboardevent-code)

~~~
mrec
I hadn't seen KeyboardEvent.code before, but after a quick skim I can't see
how you'd use it in practice. Being able to recognize physical key positions
is nice and all, but how do you map those to the character printed on the key
so that you can tell the user what the controls are, before the user has
pressed them?

The demo in that MDN page has the help text "Use the WASD (ZQSD on AZERTY)
keys to move and steer" which doesn't inspire much confidence if it implies
that you need to list controls for every possible keyboard layout and rely on
the user knowing what they've got.

~~~
htgb
I'm not sure if it's possible to access the character given the key code (the
docs you linked implies it's not), but when we're interested in physical keys,
I'd much rather use that nonetheless.

A good way to illustrate the controls could maybe be with an image? The keys
on the image could say WASD for all I care, as long as I'm able to see the
position of them, which is what matters.

There are similar issues for other things than games. Quite a few programs
have `Ctrl + /` or similar as a keyboard shortcut, which is easy on an
american keyboard, but on a Swedish one there's no dedicated key for slash
(it's `Shift + 7`). The same goes for most symbols except A-Z (I use Swedish
QWERTY), they are in other locations and with other modifiers.

Best, of course, is when you can get the character based on the physical key.
One example of this is Visual Studio Code, where the shortcut for toggling the
console is `Ctrl + Ö`, and presented as such. I assume they defined the
shortcut by the physical key (the one to the right of `L` in this case) and
presented it by its character.

~~~
mrec
Yeah, in a native app you'd use something like MapVirtualKey [1], but I don't
think there's a web equivalent yet.

You still see native apps getting this wrong, though. On a UK keyboard Sublime
Text's view menu says that "Show Console" is Ctrl-` (backtick), but the key
that _actually_ shows the console is Ctrl-' (single quote). Took me a while to
find that.

[1] [https://msdn.microsoft.com/en-
us/library/windows/desktop/ms6...](https://msdn.microsoft.com/en-
us/library/windows/desktop/ms646306\(v=vs.85\).aspx)

~~~
KwanEsq
Huh, I'm using SublimeText with a UK keyboard and Ctrl+` shows the console
(Ctrl+' just types a ')

That's on Linux though, what are you on, Windows? SublimeText Version 3.0,
Build 3143

~~~
mrec
Yeah, Windows 3126. May have been fixed, but definitely not just me: see
[https://forum.sublimetext.com/search?q=console%20uk](https://forum.sublimetext.com/search?q=console%20uk)

------
junke
Very good. As for the game itself, the fact that the yellow asteroids can
appear right in front of the ship is frustrating (death by bad luck: the
player can't do anything to avoid it).

~~~
gpm
And apart from that holding space + arrow is a very effective strat, doubly so
if you do it so half your circle wraps from one end to the other confusing the
tracking.

Maybe shooting needs a cost associated with it.

~~~
v512
Also if you are able to circle between top-bottom or left-right then the balls
get confused and change their direction constantly so easy to kill.

------
maffydub
Nice one, and thanks for the write-up!

I spent the weekend playing around with Rust/WebAssembly too - calling between
Rust and WebAssembly is a bit more fiddly than I expected, but I can
understand why they did it.

I ended up trying to write a text adventure in Rust/WebAssembly for Ludum Dare
([https://ldjam.com/events/ludum-dare/40](https://ldjam.com/events/ludum-
dare/40)). Due to other commitments, I ran out of time for the (48-hour)
"competition", but am hoping to get something working in time for the
(72-hour) "jam", which ends tonight.

(Brief blog on my initial experiences at
[https://maffydub.wordpress.com/2017/12/02/getting-started-
wi...](https://maffydub.wordpress.com/2017/12/02/getting-started-with-rust-
webassembly/) .)

~~~
frik
It sucks, there is no way to view the code in Chrome DevTools. The WASM file
isn't listed in DevTools "source" tab at all.

[https://aochagavia.github.io/js/rocket.wasm](https://aochagavia.github.io/js/rocket.wasm)

A binary blob, that cannot be viewed except with an offline hexeditor.

WASM sucks. Please remove support and go back to ASM.js, at least it was
readable and fast. Or transpile to JS in the first place. Thanks for
destroying the open web.

~~~
maffydub
It's listed in Chrome for me.

If I go to
[https://www.hellorust.com/demos/add/index.html](https://www.hellorust.com/demos/add/index.html),
bring up the "Sources tab under Chrome Developer Tools and click on "Run",
then a "wasm" item appears - clicking on that shows me the disassembly.

Do you not see a "wasm" item?

While WebAssembly clearly isn't as readable as non-minified JavaScript, it's
probably not much worse than minified Javascript, and I really can't see any
difference from a readability perspective between this and ASM.js.

~~~
diggan
Adding another comment about that this is supported in Firefox as well. Using
[https://www.hellorust.com/demos/sha1/index.html](https://www.hellorust.com/demos/sha1/index.html)
as a example, I can see the following:

[https://i.imgur.com/rnOtuty.png](https://i.imgur.com/rnOtuty.png)

------
blixt
Cool!

One question – you are moving a lot in and out of the JavaScript and Rust
"worlds" in your render function. Have you measured the difference of just
creating a simple data structure with the render instructions and passing that
once to JavaScript instead? I would expect that to be much faster.

~~~
Game_Ender
The interface between WASM and JS is limited to native types that WASM
supports which is just integers [0] (and maybe doubles?). With that limited
API you cannot pass full structures around, the best you can do is pass what
are essentially pointers to memory around [1].

[0] - [https://developer.mozilla.org/en-
US/docs/WebAssembly/Underst...](https://developer.mozilla.org/en-
US/docs/WebAssembly/Understanding_the_text_format#Signatures_and_parameters)

[1] - [https://becominghuman.ai/passing-and-returning-
webassembly-a...](https://becominghuman.ai/passing-and-returning-webassembly-
array-parameters-a0f572c65d97)

~~~
wofo
Doubles are supported as well through the `f64` type I think. Interestingly, I
am passing booleans in my code as well... and it seems to work.

~~~
landonxjames
I wonder if its converting them to 0's and 1's and sending that to the
javascript?

~~~
wofo
Just checked what is going on and that is indeed the case. Rust booleans
compile now to the i32 type (though there is no guarantee that will stay like
that in the future).

------
zengid
Excellent write up! Thank you for taking the time: I've been uncertain how
people manage to get the JS to interop with <Compile-to-WASM-lang>.

------
Tade0
Nice! I was worried that there would always be a lot of tweaking necessary to
make things compile for this target but apparently that's not the case.

~~~
wofo
It was surprisingly easy after I figure out some basic WASM stuff!

------
cproctor
Finally, I broke 500! If you get your ship circling so that it appears briefly
in each corner, you can get a nice stationary cloud of dots.

~~~
dm319
This game needs a highscore...

------
exabrial
Interesting to see WASM targets for languages popping up. My personal favorite
is this one for JVM->WASM: [http://teavm.org/](http://teavm.org/)

------
krylon
I have to admit I was surprised how smoothly this runs, even on a relatively
low-power CPU (Core m3).

------
mring33621
wow -- starts and runs very smoothly! A very good POC!

------
King-Aaron
You might want to look up the colloquial meaning behind "red rocket" before
using it in branding exercises... :P

------
sebringj
just periodically hold down left and space to get lots of points awesome
future ahead for games!

------
Karrot_Kream
Slightly off-topic. Does WASM support function pointers yet?

~~~
fasquoika
I think so. See `call_indirect` here:
[https://github.com/WebAssembly/design/blob/master/Semantics....](https://github.com/WebAssembly/design/blob/master/Semantics.md#table)

------
jerianasmith
Slow Edge & Android adoption are a major hindrance. The time needed to figure
out integration between JavaScript and Rust is too long.

~~~
executesorder66
Why does Edge adoption matter? The highest browser usage share I could find
for Edge was 4.21%

~~~
hood_syntax
4% is still a decent portion of the market, and likely contains a more
desirable market demographic than those that are on IE (depending on your
product, obviously). I'm not saying it's really important, but any potential
users gained is a good thing, right?

~~~
nullifidian
I don't understand how it's a problem. Just show a message "Your browser is
not supported. Please use one of the following browsers." To play games on
Windows people install MANY proprietary launchers(From Blizzard, EA, UBI, etc.
Steam is a glorified launcher also), I don't see how installing Chrome just to
play a game is more difficult.

~~~
hood_syntax
I'm with you on that, and it's the reason at my job we aren't bending over
backwards for compatibility. We don't support IE. It's not _really_ a problem,
but it could lose you users. How many, I don't know. Whether that's a problem
or not is up to you.

~~~
hinkley
Turn the question around: can we do something else with those resources to get
4% more users and an increase in goodwill?

