# The game itself (boring) I made a sorta-proof-of-concept game for the original Game Boy in Nim (with the help of GBDK/SDCC as the compiler), with custom assembly bootstrapping and minimal dependency on GBDK libraries.
<https://github.com/ZoomTen/pocket-clicker> Basically, it's a very simple (and very boring) Cookie Clicker clone; nothing much at the moment. ## …but why? I've been using Nim for a few months now and I've really enjoyed it. Personally, Nim's highlight for me is how I can make applications and scripts that are performant yet easy to read and write. It advertises itself mainly as a "systems programming language" (though IMO it doesn't necessarily _need_ to be), and that much is proven with projects to program [Arduino](https://github.com/dinau/nimOnAVR), [ESP32](https://github.com/elcritch/nesper) devices, and even the existence of @exelotl's [Natu](https://github.com/exelotl/natu) toolkit for creating Game Boy Advance games along with [successful projects](https://www.goodboygalaxy.com/) made with it. The latter of which made me think if it was even possible to do with the original Game Boy—that would be really funny, I thought. The mere existence of a C compiler for Game Boy proved to be enough to try. This is actually my second attempt at doing such a thing—my first used a lot of bindings to GBDK and remained careful not to use things that require managed memory like Nim strings and seqs: <https://github.com/ZoomTen/nim-gb-test> ## but how? I started out this project trying to compile some standard Nim (that is, your basic Hello World) with SDCC to see what kind of stuff I needed to work around, using things like `-d:danger`, `-d:useMalloc`, and `--checks:off`. In lieu of the Makefile I previously used, I decided to use Nim's tasks instead. Seeing how `os:any` seems to be recommended over `os:standalone`, I tried adding that. Unfortunately, I quickly realized that there's still a major difference between `os:any` and `os:standalone` at the moment, namely the former assumes in its `system` module that a standardized output device even exists for the architecture (FILE*, stderr, stdout). I _could_ spoof the incompatible calls out in my custom `nimbase.h`, but C macro substitution could only do so much, and I eventually hit a roadblock (specifically, I couldn't patch out `nimDestroyAndDispose` yet). So I switched back to the tried and tested `os:standalone`. With a few calls to `fwrite` and such spoofed out to 0, [it compiled](https://gist.githubusercontent.com/ZoomTen/d34915d1664763f9ff2dbafdd02c0345/raw/ec05bfd7e47eb5da1e984662cb66f39b2457fbce/gbnimtest2.zip). Overriding `echo` with a call to GBDK's `printf` (and of course converting the Nim string to a `cstring`) made it display the text. But what was more surprising though, was the fact that _even_ seqs, objects, and `repr`-ing them [worked too](https://gist.githubusercontent.com/ZoomTen/d34915d1664763f9ff2dbafdd02c0345/raw/ec05bfd7e47eb5da1e984662cb66f39b2457fbce/image.png). That discovery motivated me to go further with the idea. Here I faced another problem of not being able to specify the C compiler invocation template. To get around it, I had to use NimScript. Since I couldn't exactly use the `.exe` and `.options.always` parameters to use the current Nim binary with the correct arguments, the NimScript needed to be executed directly as if it was a standard shell script (which is the point, isn't it?) There were some more problems I encountered that I eventually worked around, such as SDCC crashing with "unbalanced stack" errors with certain parts of Nim's C codegen, and the `.uint8` / `'u8` litter needed for _performant_ ASM codegen and type satisfaction. The end result of all that, however, is a program written (mostly) in Nim, its compilation controlled with Nim, and I gained a level of control over the output slightly higher than what stock GBDK would grant me (thanks to being able to compile my ASM code in the same build process). * * * Ultimately I think this endeavor proved to me even more that Nim really _can_ be described as a "systems language", even if some elbow grease is needed to make it work on exotic architectures. Standing on the shoulders of giants turned out to be a very good idea :)
