Rocks'n'diamonds in a browser!

Discussion around programming R'n'D, its source code and its tools.

Moderators: Flumminator, Zomis

User avatar
armanelgtron
Posts: 29
Joined: Sat Jul 25, 2015 8:25 pm

Rocks'n'diamonds in a browser!

Post by armanelgtron »

Rocks'n'Diamonds was compiled using Emscripten with some modifications (source and diff below, though admittedly not the best work). It actually wasn't as hard to get running as I thought it would be. If you want to build, you must have Emscripten and use `emmake make`
Note that the wasm binary itself is ~60 MB, so it might take a little while to load depending on your connection speed.

https://armagetron.kevinh.us/rnd/

Yes, it is the development version

Problems
* Game may run slower than it should depending on the browser and configuration
* Uses more RAM than it seems like it should, especially when reloading
* No local storage support - settings and level progress will be lost after you quit
* No .mod support - music converted to low-bitrate .ogg files
* In-game fullscreen doesn't reliably work (and when it does, it's stretched)
* Double texture rendering is flickery
* No auto-scaling - you must go into setup and change the scaling yourself (or use the browser's probably lower-quality zoom control)
* Network support is enabled but doesn't seem to actually work
Attachments
In a Chromium-based browser
In a Chromium-based browser
Screenshot from 2020-11-20 04-43-43.png (50.65 KiB) Viewed 9176 times
rnd-emscripten.7z
Source
(6.69 MiB) Downloaded 266 times
rnd-emscripten.diff
Changes
(7.14 KiB) Downloaded 264 times
Image
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

Wow, this is really cool!!! :D

Just played it (took a few seconds to load it), and everything seems to work just fine! :)

In fact, porting R'n'D to Emscripten was already on my agenda for the near future (whatever this may mean ;-) ). I thought it would be fun to port it, but I am also very happy to see that somebody else has done it now! :-D

It's cool (and impressive) to see how few changes are needed (and many of them are just trivial things like the fopen/fopen64 changes), so it will be easy to add that port to the current code base!

And I think it was just about the right time to make that port! There is already an Emscripten port of Emerald Mine (based on the same EM engine code that is used in R'n'D), and the latest member of the "family" is "Supaplex Online", an Emscripten port of Supaplex (based on the C code of the SP engine that was directly taken from R'n'D)!

Here they are:

Emscripten Emerald Mine: http://www.emeraldmines.net/play/
Emscripten Supaplex: https://www.supaplex.online/

I will also try to build your port by myself! :)

(BTW: Do you have an idea what might cause the large size of the WebAssembly code?)

Such a Web/JavaScript version of R'n'D would allow for some nice things that would require much more work when adding it to the native code version, like loading and saving high scores, tapes and levels on a central server...

Regarding the problems you noticed:
* Game may run slower than it should depending on the browser and configuration
* Uses more RAM than it seems like it should, especially when reloading
This worked surprisingly well for me, although I wonder if the memory footprint could be reduced (especially regarding the large size of the resulting wasm file.
* No local storage support - settings and level progress will be lost after you quit
This could be stored on a server, but would probably require some sort of account to login before playing.
* No .mod support - music converted to low-bitrate .ogg files
Yes, I already stumbled upon this (Emscripten port of SDL_mixer not supporting MOD files) when I evaluated an Emscripten port of R'n'D some time ago. :-/
* In-game fullscreen doesn't reliably work (and when it does, it's stretched)
As Emscripten Emerald Mine and Supaplex (see above) support this, it might just need some changes to better support it.
* Double texture rendering is flickery
Well, R'n'D's whole redraw system is a little bit ... special (for historic reasons) and would probably need a better "redraw the complete screen every frame" approach to support better rendering in the Emscripten port.
* No auto-scaling - you must go into setup and change the scaling yourself (or use the browser's probably lower-quality zoom control)
At least, scaling from the setup menu works quite good, but it would of course be much better to be able to just scale to the current browser window size. Not sure what needs to be done for it though...
* Network support is enabled but doesn't seem to actually work
I've read something about what changes would be required for the current socket based code to work from within a browser... the current method of UDP broadcasting to auto-detect a network server and then connect via TCP would probably have to be changed. But making network code work is probably not the highest priority. (Not sure if it is possible at all to connect to a second instance of R'n'D running in another browser.)

But this port is really cool, and I would really love to integrate it into my release workflow, to always have the latest version of the game as a live preview available on the R'n'D web site! :-D
filbo
Posts: 647
Joined: Fri Jun 20, 2014 10:06 am

Re: Rocks'n'diamonds in a browser!

Post by filbo »

> Such a Web/JavaScript version of R'n'D would allow for some nice things that would require much more work when adding it to the native code version, like loading and saving high scores, tapes and levels on a central server...

This might be a bit heretical, but -- these seem like things which would be nearly trivial to do in a scripty language like Python or JavaScript (nodejs). Suppose you added those features to native code as callouts to some simple Python scripts?

> (Not sure if it is possible at all to connect to a second instance of R'n'D running in another browser.)

Surely wasm programs can use socket communications? Connections could be brokered through a central point. A player could 'put out a call' to play 2P in (whatever level they're looking at). Other players could contact the broker and pick a proposed game to join.

Without a central exchange point, there's a difficult chicken-and-egg problem getting players connected in the first place. It isn't like you could UPnP the entire Internet looking for The Other RnD Player :)
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

This might be a bit heretical, but -- these seem like things which would be nearly trivial to do in a scripty language like Python or JavaScript (nodejs). Suppose you added those features to native code as callouts to some simple Python scripts?
Yes. This is heretical! ;-)

Well... it would indeed be an easy way to add complex things like HTTPS calls to a server (to handle the things described above). Although I could imagine that it would be easier to do on Linux and Mac than on Windows and Android.

Besides that, it would also mean a 180° turn from trying hard to keep the dependency tree as small as possible (to make it as easy as possible to port the game to different platforms) to suddenly adding several layers of freakin' bullshit to the game, just to do a few network calls. :-(

I mean, I even hesitate to add a libhttp dependency (or, dare I say, libcurl) for doing simple HTTP calls (not even speaking of libssl/libcrypto for HTTPS). As long as I control the server (which I will do), I should be able to get away with some simple socket read/write operations anyway, and just give a shit about encryption. :mrgreen:

Things like this are indeed on my "things I could do next in R'n'D" list, else I wouldn't care about it that much... ;-)

Update:
Surely wasm programs can use socket communications?
I assume that they can.
Connections could be brokered through a central point. A player could 'put out a call' to play 2P in (whatever level they're looking at). Other players could contact the broker and pick a proposed game to join.
That would be something like this feature request, yes.
Without a central exchange point, there's a difficult chicken-and-egg problem getting players connected in the first place. It isn't like you could UPnP the entire Internet looking for The Other RnD Player :)
That's right of course. Currently it is designed to just work in a local subnet, to connect people sitting next to each others, which works just fine. A central game server would be another story...
User avatar
armanelgtron
Posts: 29
Joined: Sat Jul 25, 2015 8:25 pm

Re: Rocks'n'diamonds in a browser!

Post by armanelgtron »

Holger wrote: Fri Nov 20, 2020 10:55 pm (BTW: Do you have an idea what might cause the large size of the WebAssembly code?)
I would guess all of the dependencies. Although, it turns out passing the resulting wasm through Binaryen's wasm-opt (-O2) shrinks it right down to under 4MB.
Image
filbo
Posts: 647
Joined: Fri Jun 20, 2014 10:06 am

Re: Rocks'n'diamonds in a browser!

Post by filbo »

> passing the resulting wasm through Binaryen's wasm-opt (-O2) shrinks it right down to under 4MB

Wow! That's a major reduction from 60MB. Does it have a noticeable effect on runtime speed, or just download time?

Can you put an optimized version up at e.g. https://armagetron.kevinh.us/rnd-opt/ ?
User avatar
armanelgtron
Posts: 29
Joined: Sat Jul 25, 2015 8:25 pm

Re: Rocks'n'diamonds in a browser!

Post by armanelgtron »

filbo wrote: Sat Nov 21, 2020 6:15 am Does it have a noticeable effect on runtime speed, or just download time?
I don't know, I couldn't notice a difference in runtime speed in my very limited testing.
filbo wrote: Sat Nov 21, 2020 6:15 am Can you put an optimized version up at e.g. https://armagetron.kevinh.us/rnd-opt/ ?
Sure... though admittedly, I had already replaced the one at /rnd/ after my previous post, but now the wasm at /rnd/ is the original one and the one at /rnd-opt/ is the optimized version.
Image
filbo
Posts: 647
Joined: Fri Jun 20, 2014 10:06 am

Re: Rocks'n'diamonds in a browser!

Post by filbo »

My x86_64 Linux binary is 3775K (2231K stripped), and links in 61 shared objects! 4M for a statically linked 'binary' expressed as wasm is pretty impressive, really.

Playing the 1st tutorial level on both builds, then playing back at fastest speed (click tape 'play' button 3x), the sounds of running over a long row of gems seem about the same. If there's a performance difference it's no more than 20% (I'm pretty sure I'd perceive the difference if it were more than that).
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

I've just built the Emscripten port of R'n'D by myself (using your patch), and everything works just great so far! :)

However, I have two questions:

1. In "src/Makefile", I had to explicitly add "-s USE_SDL_IMAGE=2 -s USE_SDL_NET=2 -s USE_SDL_MIXER=2" to "SYS_CFLAGS", else I got errors during compilation about not being able to include "SDL_image.h" etc.

Any idea what might have caused this? I have the suspicion that this should be done by "sdl2-config --cflags" somehow, but I also have the SDL2 packages installed on that system, so maybe it used the wrong one.

In any case, the above tweak also works fine.

2. I also got a WASM file of size 64,378,266 bytes initially, but when using "wasm-opt -O2" on it, it only shrinks to 61,650,594 bytes, which is much larger than "under 4 MB". :?

Any idea what's missing here to also get that much smaller size?

Besides the above issues, I'm impressed how well it works on my 2015 Mac with Chrome, and how small the required changes are! Well done, armanelgtron, and thanks a lot for this contribution! I hope to be able to host the Emscripten version of R'n'D on the R'n'D web site starting with the next minor release! :-D

Update: It also works fine in Firefox and Safari!
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

... just forgot that I had another question:

3. Did you craft the corresponding file "index.html" by hand, or is there a way to build it automatically?
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

Regarding (1): I have no idea why it did not work at first, but it suddenly also works without explicitly specifying the SDL libraries. Strange.
User avatar
armanelgtron
Posts: 29
Joined: Sat Jul 25, 2015 8:25 pm

Re: Rocks'n'diamonds in a browser!

Post by armanelgtron »

Holger wrote: Tue Nov 24, 2020 3:03 pm 2. I also got a WASM file of size 64,378,266 bytes initially, but when using "wasm-opt -O2" on it, it only shrinks to 61,650,594 bytes, which is much larger than "under 4 MB". :?

Any idea what's missing here to also get that much smaller size?
I have no idea. The WASM for me was 64,377,682 bytes (used at https://armagetron.kevinh.us/rnd/rocksndiamonds.wasm, compiled using em 2.0.7 on my system). Using wasm-opt ("version 97 (version_97-74-g5ae1724ad)", apparently included with the emscripten package here on Manjaro/Arch now), with otherwise default parameters:

`wasm-opt rocksndiamonds.wasm -o rnd-opt-1.wasm -O1`
3,869,909 bytes

`wasm-opt rocksndiamonds.wasm -o rnd-opt-2.wasm -O2`
3,857,209 bytes (built the same way as https://armagetron.kevinh.us/rnd-opt/ro ... monds.wasm)

`wasm-opt rocksndiamonds.wasm -o rnd-opt-3.wasm -O3`
3,835,930 bytes

`wasm-opt rocksndiamonds.wasm -o rnd-opt-4.wasm -O4`
3,932,218 bytes

`wasm-opt rocksndiamonds.wasm -o rnd-opt-s.wasm -Os`
3,823,530 bytes

`wasm-opt rocksndiamonds.wasm -o rnd-opt-z.wasm -Oz`
3,822,952 bytes

There was very little difference in sizes, but I assumed O2 would be a safe in-between speed and size.
Holger wrote: Tue Nov 24, 2020 6:17 pm 3. Did you craft the corresponding file "index.html" by hand, or is there a way to build it automatically?
Well, Emscripten CAN generate a .html file (I believe if you replace the output file rocksndiamonds.js to rocksndiamonds.html, it will generate a page). I tried to take that html document and strip out the unnecessary stuff leaving the minimum, also adding some simple css to make it centered and add a black background.

---------
Also, slightly off-topic, but I was thinking maybe emscripten should have been used to compile rnd 0.9, so 0.9 would have been playable in a browser without having to download and/or compile just to try it for about 5 minutes. Though, not sure Emscripten has any kind of X11 bindings or compatibility, so might not have been feasible I guess. I've also not really looked at 0.9's source but I'm sure it's changed a lot since. And you'd probably also have to emulate a joystick somehow or add keyboard support...
Image
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

Any idea what's missing here to also get that much smaller size?
OK, I also did some more exploration on this issue. (I am using the latest Emscripten SDK 2.0.9 here.)

I found out that when I use the "wasm-opt" included in the Emscripten SDK (at "upstream/bin/wasm-opt"), I got the unsatisfying results as described (which WASM file size over 60 MB).

However, when I installed the Ubuntu package "binaryen", which also contains a wasm-opt binary, and use this one for optimizing the WASM file, I indeed got the 3,8 MB file size, too! (I have no idea why there is such a big difference using these two variants of wasm-opt.)

But then I found out that there is still a better way to reduce the size of the WASM file, which is faster, results in an even smaller WASM file, and does not need a wasm-opt binary at all (if it is not used in the background, I don't know): Just add an "-O2" option not only to the compilation "emcc" commands, but also to the "emcc" command used for linking! This results in a WASM file size of 3,379,122 bytes for me! :)
I tried to take that html document and strip out the unnecessary stuff leaving the minimum, also adding some simple css to make it centered and add a black background.
Very good! So I will just take that one as it is. :)
Also, slightly off-topic, but I was thinking maybe emscripten should have been used to compile rnd 0.9, so 0.9 would have been playable in a browser without having to download and/or compile just to try it for about 5 minutes.
That would indeed be very cool!
Though, not sure Emscripten has any kind of X11 bindings or compatibility, so might not have been feasible I guess.
As far as I can see, there is no X11 support for Emscripten, but "only" SDL support. (Which is extremely cool, as the R'n'D source code could be compiled using the Emscripten SDK with nearly no changes at all!)

But that would make an Emscripten port a bit difficult, as all X11 library calls would have to be changed to SDL first (not to speak of the audio code)...
I've also not really looked at 0.9's source but I'm sure it's changed a lot since. And you'd probably also have to emulate a joystick somehow or add keyboard support...
Yes, indeed. There are indeed massive code changes between 0.9 and 4.2.0.x, and quite a number of these changes would have to be added to the 0.9 code base to make it work with Emscripten, which is really not worth the effort, I think.

I have now added Emscripten support to the "official" R'n'D code base, and after some minor code preparations (mainly regarding the use of "getpwuid()", which is not fully supported when compiled with Emscripten), the required patch is even smaller and cleaner than before.

Thanks a lot for your great work! :-D
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

BTW, I also found out about this issue:
1. In "src/Makefile", I had to explicitly add "-s USE_SDL_IMAGE=2 -s USE_SDL_NET=2 -s USE_SDL_MIXER=2" to "SYS_CFLAGS", else I got errors during compilation about not being able to include "SDL_image.h" etc.
and
Regarding (1): I have no idea why it did not work at first, but it suddenly also works without explicitly specifying the SDL libraries. Strange.
Not that strange anymore: Specifying those SDL libraries during compilation causes the Emscripten SDK to automatically download and build the SDL and zip libraries on-the-fly, which is really very cool. Once they are available in the SDK, it is not needed anymore to specify them. (So I added them to the Makefile to be able to build R'n'D also on a "clean" Emscripten SDK.)
User avatar
Holger
Site Admin
Posts: 4073
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Rocks'n'diamonds in a browser!

Post by Holger »

Just pushed the new Emscripten support in R'n'D to the public Git repository.

And just for fun, I also made the result available ("inofficially" for now, will probably be announced with the next release version):

https://www.artsoft.org/rocksndiamonds/play

:-D
Post Reply