not to be dramatic, but

I started making a clock-thing

Something that I think is cool about NES games is that the NES is a single thing. The hardware platform has a precise definition, and therefore the software is written for exactly that platform and no other. In my work-life, it's not like this at all. There are many "configurations" possible and the software is full of branches dedicated to this.

So, recently, in my time, I built a simple thing. I rescued an original raspberry pi. I can't even find a link to a picture on the raspberry pi website anymore. This thing had lived a hard life as an overseer in the bitcoin mines, and I thought it would be good to give it a more pleasant retirement. So I bought a 32x8 display and attached it.

I decided that I wanted to build a thing that did something useful, all on its own. It will run detached from the network. Taking away all of the extensibility made it implicitly a finite system, and allowed me to focus on aesthetics. So with that requirement, I wrote some software to draw a few things on it.

God this was rewarding. I wrote the thing in Python, which let me develop it relatively quickly. I struggled a bit with understanding the protocol that the board supported over SPI. There is no documentation for the screen unit I bought, although it's a daisy chain of MAX7219s which have a pdf. I found that the path of least resistance was to reverse engineer a working driver. The key piece I got stuck on was understanding that, there is a difference, in SPI, between an 8 byte write, and 4 2-byte writes. You have do 8 byte writes (or really, 2N byte writes, where N is the length of the chain). Once I got past that, the whole thing came together nicely.

Like I mentioned, aesthetics are important for this. I never do direct user interfaces. Perhaps I write a CLI here or there, but the vast majority of the software I develop expresses itself through UI I don't control. So that led me to take the time to focus on things I never think of. How bright should the LEDs be? I have 16 choices. I didn't look at them all, but I did a manual binary search until I found one that is pleasing. How fast should the game of life iterate? There's no way to make a slider, so I found one that I liked and I went with it. Along the way I experimented with frame rates that exceeded the performance of this Python, so I wrote life implementations in Zig (ten times as fast as Python) and in Rust (twice as fast as Zig). I will talk more about those, elsewhere. Switching to pypy is worth considering as well.

Conway took about 85 lines to write. 25 of them are to calculate the next frame. 30 of them are some various ways to calculate initial states. The other 30 are running the loop, and terminating it when it becomes uninteresting - right now it stops on flip-flopping states, but permits cyclical tristates. I think this is the right balance which avoids uninteresting displays for long periods of time. It pauses for a few seconds when it gets to the end, so that the shift to the next display isn't too jarring. I find it interesting to see how much of me showed up in this code. It's written to be something that I find nice to look at. Finally, life records any initial states that don't terminate. I am not thrilled with this, as they go straight to disk and I'm running on an SD card that has a limited write volume. I should keep these in memory and flush them to disk every few days.

Snake was much simpler than I expected. It clocks in at 25 lines. The snake is entirely greedy at the moment. I would like to tune this a bit more. Right now it walks a stair-step diagonal to get to the food, but that's not how I play. I'm too lazy to push so many keys, so I typically line up one axis, and then the other. I think another iteration is in order. But it's not bad. But maybe before that I will add a leaderboard. I'm curious what the longest snake is, so far.

The clock was fun. It's the longest piece of code. The code is the longest because I made my own font, which I'd never done before. I've contributed to a font, but never made one from scratch. I think it would be cool to write a graphical font designer so that I could click the digits on and off and see the change on the display immediately, with some sort of backing store. That's probably the way to iterate next, here.

Unfortunately, I was sent a defective display, so I have a query into the vendor. Perhaps I will get a free replacement. I wonder what I'll do with a second display. The Pi supports a second SPI device, so I suppose I will extend to a 32x16 canvas.

The code can be found here. I was pleased that the whole program fits in a single file. I was pleased that I was able to use outer functions to self-contain each game rather than being forced to make each a Class and having to type self a lot. I will call this structural style Buddhist code from now on.

I would like to add a couple button inputs so that the time were settable, like an alarm clock you find at a hotel. I would like to tune this Linux so that system services never write to disk so that the flash card lasts a long time. I would like to 3d print a case to hold the whole thing. I'll do this at the Bellevue Library Maker Space, but I'll wait until the light rail connects to there. It is scheduled to happen this summer. I can't wait to ride the first-in-the-world light rail on a floating bridge.