Mar 8, 2025
It started, as it often does, with my kids. They got curious about a chess variant called Monster chess. But none of the websites out there have an implementation of it. So I set out to build one. In Lua Carousel, of course, my cross-platform app for editing and running little Lua scripts on phone, tablet or computer.

Now, like all the best chess variants, this one uses all the rules of chess, just with one crucial, minimal tweak. So to implement Monster chess I had to first implement chess. Which I did (and not for the first time). But by the time I'd implemented all the legal moves, castling, en passant, pawn promotion, forbidden moving into check -- I was at 500+ lines of code. At that scale of program, Carousel's janky scrollbars get too thin for my fat fingers to acquire on the phone. Carousel's only nice up to 100-150 lines.

So I switched to my template repository for standalone apps using the Carousel UI. I've done this before, most notably with my Sokoban client which you can edit the source code for right on your phone. Indeed, editing the source code is the expected way to skip 10 or 60 levels. On some level everything I do stems from the desire to believe that editing source code can be a nice user experience.

I soon had a second chessboard app. But it felt like spaghetti. The Carousel template lets me split up a large program into multiple files, but with all the problems of text-based program navigation, and all my bespoke janky tools to boot. You're looking for a specific function. Which file is it in? It's hard to read code you didn't write, and on some level everything I do is an attempt to make it easier. You know, literacy. Computational literacy. The ability to read a novel of code or write an email of code. But we're not at the promised land yet, and meanwhile I have spaghetti nobody should bother with.

So I ripped out all my Carousel stuff and made it just a plain LÖVE app. File size dropped from 128KB to 8KB. So clean! But now it's not easy to modify, particularly on a phone. You have to unpack the zip file, find a text editor, etc. And on some level everything I do is an attempt to keep things easy to modify.

So I spun my wheels for a while. Eventually I remembered that I'm drawing on a graphical canvas, and that I know how to draw box-and-arrow diagrams. What I really need here, I decided, is a way to draw little box-and-arrow diagrams about my program, tapping on boxes to jump to files. It's still extremely janky, but… well, take a look.

screenshot of Lua Carousel showing a rudimentary screen to select time controls for a game of chess

When you run the app you're faced with a screen to select a time control. Edit it to taste, tap ‘submit’ and now you're on the main screen.

That's all there is to using the app. But there's also a button on the bottom left for editing its source code. Tapping on that brings you to this screen.

screenshot of Lua Carousel showing the two screens in the chessboard app and the variables they share

The chessboard app consists of two screens. You start out setting the timer, then you play. There's no way to go back to set the timer. You have to quit and restart the app. Timer page and main game page share two variables: start_time and increment.

Tapping on the timer page brings you to a screen of code that implements it.

click on the first/left screen: setting the timer click on the first/left screen: setting the timer

I don't have any ideas to make it easier, so at this point you're stuck reading banal textual code. Hopefully the introductory screen helps find your bearings.

Tapping on the right hand box brings up a second picture, showing some substructure.

click on the first/left screen: setting the timer click on the first/left screen: setting the timer

Now there are more boxes to tap on, and each of them brings you to a chunk of code to read and digest.

click on the first/left screen: setting the timer click on the first/left screen: setting the timer
click on the first/left screen: setting the timer click on the first/left screen: setting the timer

Again, hopefully drawing the eye to certain highlights helps get the reader oriented in a new codebase.

The drawings are just documentation so far. They're redundant with the code, and can go out of date. So I've tried to highlight only the highest level, most permanent features.

Here's another drawing about a problem I often think about: how to explain a Lisp interpreter to someone seeing it for the first time.

diagram showing the functions that might compose a Lisp interpreter, showing that only one of them uses an argument even though all of them pass it around

Arrows indicate function calls. A Lisp interpreter is a recursive function. But it can get long and complex, so it's often split into multiple functions. But now the recursion is less obvious, and it can seem intimidating to a newcomer. The word env often shows up everywhere. But as this diagram makes clear, the purpose of env is highly localized. It's only used to look up the value of a variable/symbol. Everywhere else just passes it around to get it where it's needed.

Anyways. This “markup language” (I'm just using Lua literals) for box-and-arrow diagrams and hyperlinks seems like an expressive mechanism for communicating a variety of relationships.

This post is part of my Freewheeling Apps Devlog.

Comments gratefully appreciated. Please send them to me by any method of your choice and I'll include them here.

archive
projects
writings
videos
subscribe
Mastodon
RSS (?)
twtxt (?)
Station (?)