Another WebAssembly example: Meta tic-tac-toe
Dennis
dkorpel at gmail.com
Wed Aug 22 12:22:34 UTC 2018
Try it: https://dkorpel.github.io/tictac/
Source: https://github.com/dkorpel/tictac
I planned to port an assembly Meta tic-tac-toe game to D for a
while now, and with the recent addition of WebAssembly to LDC I
saw the opportunity to do some client-side web-development in D.
I first made the command line version (with -betterC in mind),
and then added a Javascript back-end to it. Thanks to the image
dithering example, I already was aware of most issues and
limitations so it went smoothly. Here are the findings that I had:
1. I saw that my application was expecting 'env.memcpy' and
'env.memset' to be present, I presume this is because the
compiler emits these calls for struct/array
copying/initialization. I solved it by providing simple
implementations in the D code, hopefully that didn't have too
much impact on performance.
2. The image dithering example had a JavaScript implementation to
compare it to. I haven't made a JavaScript implementation, but I
did compare how long the A.I. took to find a move with the
command line version. Around 2 million moves were considered,
here are the results:
| Version | Time | Factor |
|---------------|---------|--------|
| Ldc (release) | 357 ms | 1.0 |
| Dmd (release) | 671 ms | 1.9 |
| Wasm (-O3) | 967 ms | 2.7 |
| Dmd (debug) | 1651 ms | 4.6 |
| Ldc (debug) | 2159 ms | 6.0 |
| Wasm (-O0) | 2807 ms | 7.9 |
The WebAssembly version was tested in FireFox, in Chrome it seems
to be ~1.5x slower for some reason.
3. Loading WebAssembly in a way that allows for both local
testing and Github Pages deployment was annoying. The sample code
from the wiki works on FireFox both locally and online, but
Chrome complains you're loading a .wasm larger than 4Kb (16 Kb in
my case) synchronously. I tried using fetch and
instantiateStreaming, as suggested by:
https://developers.google.com/web/updates/2018/04/loading-wasm
But then when testing with live-server, it would complain about
the request having an unknown MIME type. So I settled with an
asynchronous XMLHttpRequest approach that works both offline and
online, only for Chrome you still need live-server because for
security it won't load requests using 'File://'.
4. I ran into some betterC issues:
- Final switch can't be used in debug mode since it throws an
error in the default case. Solution: only compile in -release
mode. See: https://issues.dlang.org/show_bug.cgi?id=19087
- Indexing `enum string[] messageStrings` with a runtime value
gives a TypeInfo error. Solution: make it a __gshared immutable
string[].
Related: https://issues.dlang.org/show_bug.cgi?id=19169,
https://issues.dlang.org/show_bug.cgi?id=18949
- And, of course, the inability to use some language/library
features. For this simple game it's okay, but for bigger projects
I'd like to have some malloc/sprintf/math solutions.
5. Dub doesn't support WebAssembly targets. I solved this by
making a build script that allows you to execute `rdmd build
wasm` and then a simple refresh in the browser would show the
results.
Overall it was very pleasant, kudos to the LDC team!
More information about the digitalmars-d-ldc
mailing list