Raylib 15 Game

Thank you to @chrboesch, for creating:

It inspired me to create a raylib gui for this game and add additional features.

Play the Game

screenshot000
https://simonlschlee.github.io/zig15game/

qrcode

Wasm

Thank you to everyone in the Zig community that has made wasm/emscripten easier to use, improved Zigs support for it and created examples / projects that compile to wasm.

I especially want to thank @permutationlock for:

This game doesn’t use threads, but this example made wasm and emscripten look a lot less intimidating. Especially the clear and straightforward build.zig.

I looked at these references:

In the future I want to look more into wrapping emscripten as a build dependency.

But while it would be nice to have the emscripten download and install automated, from a practical standpoint, it doesn’t seem absolutely necessary because the resulting wasm files are already portable, so having to generate them manually/locally isn’t that problematic.

This project by @floooh already uses emscripten as a dependency:

It uses emscriptens workflow of downloading and using the prebuilt binaries, it stores those in Zigs cache and then reuses them, it is a bit of a hack, but also useful and a good first step towards something a bit more automated.

I wanted to pull out the code and package it as a emsdk-zig package, however attempting that, I realized that I still have some knowledge gaps concerning the build system and I was wondering what would be the appropriate steps to ziggify emscripten as a zig dependency.

I might revisit that at some later point.

GitHub Pages

For now I found it easier to run the wasm build on my machine and then commit the built version to the pages branch of my repo and use that for the github pages workflow, thank you to @tensorush making it easy for me to figure out my deploy script by looking at:

And specifically liza/src/templates/.github/workflows/cd.yaml at main · tensorush/liza · GitHub here is the modified version: zig15game/.github/workflows/pages.yaml at pages · SimonLSchlee/zig15game · GitHub

Game ideas

I plan to add multiple different board sizes in the future 2, 3, 4, 5 ..., with very big board sizes the current randomization strategy doesn’t scale / fails to provide good results. There are algorithms for calculating whether a random board is solvable based on parity calculations 15 puzzle - Wikipedia, so that in combination with a shuffle might enable better randomization for bigger boards.

However I fear that bigger boards are boring anyway, because it seems like the vast majority of elements can simply be rearranged in an unconstrained manner, until you essentially get back to a 4x4 in the bottom corner again.

The barrier feature I added may add sufficient constraints, to make even these bigger boards interesting, but that is something I still have to play test. Because I still haven’t used bigger boards and barriers at the same time (the bigger boards were in a feature branch I haven’t updated yet).

I thought about adding portals that would allow you to move across further distances, additionally it would allow to move between barrier enclosed regions, I think that could add a lot of potential to make bigger boards both more interesting and less annoying (having to move tiles too far).

It is possible that the parity based solvability checker might not work with certain features, so while adding new features you also have to think about how to generate the initial randomized board.

I think that certain portal configurations might even make every board configuration solvable (just very tedious by having to reorder pieces). All of that are areas for future work / research.

If you have ideas for what could be added to the game, please let me know, but it could take a while before I have time to experiment with the idea and test it out.
(Partially because I want to create other games and have a few other projects I need to finish)

Alternatively you could try adding things yourself. The code is currently relatively minimalist, using math and manual calculations for the layout, that keeps the code relatively compact, but requires some manual effort in calculating offsets and sizes.

17 Likes

I’ve never played a variant of this game where there are barriers. That was a lot of fun! Thanks for the small distraction and for sharing so much detail about your process :smile:

3 Likes

Thanks you for sharing much detail a process to get the game in wasm. Your project is my golden source now.

3 Likes

A post was split to a new topic: How to compile raylib wasm game

I have this also on my mental todo list but won’t get around to it anytime soon unfortunately… such an emsdk-zig package should provide the following features IMHO:

  • use the Emscripten SDK as C sysroot (e.g. at least make the Emscripten C headers available to C code or Zig code via @cImport)
  • delegate linking to the Emscripten linker (including ‘linking’ Javascript shim files)
  • allow to manage the Emscripten SDK installation via zig build, e.g. tunnel the emsdk cmdline tool through a build.zig step so that they can be invoked via zig build emsdk-xxx: install emsdk into Zig cache, activate a specific emsdk version, uninstall (remove) the emsdk from the Zig cache (and maybe also use the local Zig cache instead of the global one)

…e.g. the emsdk maintenance workflow could look like this:

zig fetch --save emsdk=...
zig build emsdk -- install
zig build emsdk -- list
zig build emsdk -- activate [version]
zig build emsdk -- uninstall

…another thing I wonder about is whether it’s worth it trying to make EM_JS work within Zig code (e.g. embed JS source code directly into Zig code), not sure if that can be done as conveniently as in C code though, because in C this is built around the C preprocessor. But I think in Zig projects it’s not such a big deal to keep the JS code inside separate .js source files.

Things I would like to see in the Zig build system for such a use case:

  • allow dependency build.zigs to directly define ‘custom/external linker’ build steps (or more generally: some way to inject custom build steps into the build system) and without having to import the emsdk build.zig manually into the toplevel build.zig. Currently the Emscripten linker is integrated via b.addSystemCommand() and an exported function emLinkStep() in sokol-zig, but this requires to split the build.zig into two separate code paths, one for native platforms, and one for Emscripten, for instance the Zig main module needs to be compiled as a static link library for the ‘Emscripten build path’ instead of an executable - it’s also important to know that the Emscripten linker does a lot more than just linking the WASM file, it also code-generates a merged, optimized and minified JS shim file - including user-provided JS snippets, creates an index.html, and runs additional tools like wasm-opt / Bynarien over the linked WASM blob.
  • allow to add zig custom commands via build.zig, e.g. it would be nice if I could expose the Emscripten SDK maintenance commands via zig emsdk install, zig emsdk list, zig emsdk activate [version], zig emsdk uninstall.

I hope that some of those build system requirements will be tackled once the Clang toolchain moves into a external package (e.g. the ‘LLVM divorce’), because using Clang as external toolchain is pretty much the same situation as using Emscripten as an external toolchain (maybe with the exception of being able to easily use the ‘external toolchain linker’, which is quite critical for Emscripten, but probably not needed for Clang since the Zig linker replaces the Clang linker)

1 Like