A Post-Apocalyptic RPG

"Canary" is yet another Rogue-type game as a weekend garage project. It is, in fact, a feeble low-res attempt at a love-letter to the original Fallout games.

Canary is written in C using SDL. Utilities (like converting text to binary data files) are mostly in Python. Code editing happens in CLion and Emacs (configured with Doom Emacs).

Wishlist on Steam HERE!

Follow me Bsky or the other place.

There's even a Facebook page if you're over there. You could be the first third follower!



Screenshots
2024-10-19 screen capture 2025 screen capture 2025 screen capture

Older screenshots

Lunatic ranting begins here:

2025-04-19

Thinking about this project, and thinking about my other projects that fell by the wayside. I wonder about just how many game development projects have been started that just fizzled out. It's probably like asking how many garage bands there have ever been.

Anyway, I spent $600 and got a low-end M4 Mac Mini. 16 gigs of ram and a 256 gb ssd doesn't seem like a lot, but it's compiling the game in less than two seconds (compared to my i7 machines that are taking 13 under Windows and 7 with Linux). I wanted to keep track of the system stats, though, so I was looking around for something unobtrusive.

Lo and behold, I found the perfect thing, installable with brew:

> brew install stats

Which gives me the stats I was looking for right in the menu bar, like so:

a stats display in my Macos menu bar.

Which kind of brings me to thinking about a future phase of development when I'm automatically downloading and building Canary under Mac, Windows, and Linux whenever I check the code in.

2025-04-08

I'll tell you what: my first try at implementing the pathfinding algorithm was a disaster. I had the general idea right, but creating(malloc-ing) and deleting(free-ing) all of the necessary nodes to find the path was not code you want to write in a hurry. I ended up debugging errors with (probably) freeing memory I'd already freed, and eventually realized that maybe I didn't need to do all that work on the heap (and subsequently clear all that out to get ready for the next guy who needed to find the quickest path by which to deliver a swing at the player's head).

That was the second thing I realized, though. The first was that my unit tests (which I'm pretty dependent on in my day job) could use some work.

Unit testing in C, at least as far as I've been able to find, is a lot less advanced(?) than it is in more modern languages like Python or Java. I kinda got Unity (no relation to the game engine) working, but, much like pathfinding algorithms, it's not something you want to try to add in a hurry. I took the Makefile suggestions literally and ended up with a spaghetti file of declared variables that started making me feel... uncomfortable.

So: I went looking for alternative solutions, and found this article that explains how to use Pytest (a unit test framework for Python) to test C code. With which I was able to compile my pathfinding file and use Pytest to exercise my get_path(...) function. Well, almost.

One of the parameters for get_path is a 2d array that represents the obstacles that might be between the angry scientist and the player, and I didn't have much luck creating the ctypes array in a way that was acceptable to the get_path function. Solution: create a get_path_with_empty_array function in the C file that create an empty 2d array and then calls get_path with that. For the purposes of testing whether the algorithm as written will play nicely with the system memory... so far so good. (The other parameters are the x/y coordinates for the attacker and the target (as integers, it might have been easier to send the entity data, but that's one fewer dependency the pathfinding file has))

2025-01-25

At some point I decided my task board should be a 'minimum viable product' board, so now I have 10 notes there that I'm ignoring while I finish getting an A* algorithm implemented in C. I had it working earlier than I thought it did: when I ran it it kept going crazy and crashing the program with corrupted memory. What I eventually realized was that I was setting the end position to the player location, which was registering as a blocked tile, so the algorithm started checking infinite other ways to access this impossible-to-land-on tile. Now that I set the end goal to getting within 1 tile of the target it works great. Other checked-off tasks include:

  • Exit saving
  • Quick saving
  • Screenshots (to tell where you were when you saved)
I also got the Steam page mostly populated, I got an email from the review process that I need to make some tweaks to the page graphics.


2024-10-20

Inspired by Friday's post, I dug in on Saturday and added an sqlite db to the mix to hold the entity type data. I had planned to use Gnumeric (spreadsheet) for game data, but the flexibility of integrating directly with a database seemed better in the long run.

I'm not ready to make data importing fully dynamic (the entity types are still #define PLAYER 10 in a constants file), so I wrote a python script to parse the .h file #define directives to match up with 'PLAYER', 'MONSTER_1', etc. in the database. From there it turns the db row into a binary version of the integer values and stores it in entities.bin which can be read by the game. These are just the entity 'types', the actual game entities are cloned from these base entities.

I'd marked October's "load entities from external file" and "use spreadsheet to define entity data" off the list, but I'm tracking down a few bugs today instead of moving on to the final October task of "Simplifying the model to make serialization easier".


2024-10-18

Over half-way through October. I've done a few minor things but have hardly gotten started on this month's list of tasks. I did get the ball rolling on publishing through Steam though, so there is that bit of wishful procrastination to check off the list.


2024-09-22

I took a few days off work to get some game coding time in, this week I got the basics of a character creation screen put together and made it pretty far with the saving and loading of games. Also started the process of distributing Canary through Steam.


2024-09-18

Starting a public work log as I get closer to finishing this game. I still have 6 months of planned work to go through, and I'm sure more things will come to mind.