The following post was submitted to Handmade Network and is mirrored here.
I am happy to be a new part of Handmade Network!
Progress since submission
There have been several things I've been working on since I submitted Cakelisp to the network:
Kitty Gridlock completion
Kitty Gridlock is a game I made in about 3 weeks (off-hours, weekends primarily) for my girlfriend. I had a deadline to deliver (her birthday), so I had a good goal and could limit scope effectively.
I wanted to prove to myself that I could be productive in Cakelisp in its current state, i.e., without making any modifications to the language. I was absolutely successful in this goal: I got the game done faster than expected, without having to make changes to Cakelisp.
Thanks to SDL's portability features, I was able to port Kitty Gridlock to the target platform, Android, in a matter of days. The use of C++ as the output language was a definite boon to this, because it naturally meant support for the Android NDK environment.
I'm no artist, but I was quite pleased with the end look of Kitty Gridlock, which I drew for my girlfriend to maximize cuteness:
It turns out having a target audience of a single person really narrows what styles I needed to consider :).
Cakelisp was an improvement over my previous development environment (C++ with Jam and shell for building) in several ways:
- I used compile-time code execution to extract and bin (convert to binary) the puzzle database when necessary
- Compile-time code execution copied generated source files over to the required Android JNI folder, further easing Android builds and making them more reliably up-to-date
- Generators allowed me to work around Cakelisp's missing features. I've now added many of the generators into C and C++ helper libraries for future projects to leverage
- I was much more satisfied and excited to work on Kitty Gridlock because I enjoyed the environment more. Developer satisfaction is important!
I plan on writing a more detailed blog post on Kitty Gridlock's implementation soon.
The code is here. Kitty Gridlock cloc'ed in at about 1,400 lines of Cakelisp, not including GameLib.
GameLib module reorganization
GameLib is a library which provides a variety of 3rd party dependencies via Cakelisp modules. Several problems encountered in Kitty Gridlock have revealed problems in GameLib, many of which were easily fixed.
GameLib was updated to not include any 3rd-party dependencies by default. The dependencies will be downloaded to a folder as soon as you import the dependency module. Previously, GameLib included all 3rd party libraries as git submodules.
This change allows me to continue adding useful tools to GameLib without having it balloon into hour-long submodule downloading. When I create a new project, only the modules I use will be downloaded to that project's directory.
I made this change because my latest project, Kitty Gridlock, did not use Ogre, but had to spend the ~30 minutes to download and build Ogre for no reason. This new strategy almost feels more like a ultra-lightweight package manager, because I feel like I have easy access to 3rd party libraries but only pull the ones I need.
At this point I've added the following 3rd party libraries:
- dear ImGui
- Handmade Math
- SDL 2
- Ogre3D (v. 2, aka ogre-next)
- tracy profiler
GameLib has been an important addition to my workflow because I always felt restrained by having to setup dependencies by hand on every new project. Thanks to Cakelisp's seamless compile-time code execution, I can download, build, and link to 3rd party dependencies simply by importing the Cakelisp module for that dependency.
The best part to me is there is no magical executable that is handling this operation: it's all easily readable in Cakelisp, and built into GameLib. It feels magical without being too magical, which was important to me.
I've made good progress on the precompiled headers feature. It nearly halves the amount of time needed to build all of Cakelisp's tests. I need to refactor the command generation code in order to cleanly port precompiled headers from compile-time to build-time, and I haven't done native Windows MSVC precompiled headers yet.
I want to stay true to my goal of using non-language-related projects to drive Cakelisp's development. I have two project ideas currently vying for my next project slot: a game prototype and a file system productivity application. I like to let things soak a bit before committing to make sure I remain interested in the idea. I'm in that phase right now.
I think the Handmade influence should be clear from reading my goals and implementation of Cakelisp. I'm looking forwards to checking out more Handmade projects and getting inspiration from all of you.