When I finished reading Project: Ballad for the Free Culture Book Club, I realized that the in-story video game Kabang!—featured in the short story Tesseract—could potentially work as a real video game. In the post, I even said this.
Tesseract introduces Dante’s Pizza and Games, Pannych and Phyr, possibly a novel sport for them to play, Kabang! and “Super”-Kabang!, Dale “The Mountain” Messner, and a bunch of minor characters. Much like Fall of the Kingdom, the Kabang! games seem to have a fairly complete description that someone could implement.
The more thought that I gave to this, the more that Kabang! stood out as an almost perfect project for the blog. The idea originates in a Free Culture work. Bringing it to life would require programming. It has a limited scope, with only one game mechanic. And it would require my learning something new, which sweetened the deal.
If you’d like to skip the rest of the background and references, you can (I hope) play the game here. For reference, without a controller connected, the default “A button” maps to Z , the “B button” maps to X , and the “X button” maps to A . You rotate the character by pressing the left- and right-arrow keys.
- CLICK TO PLAY -
Or you can download the cartridge file to play on your local machine whenever you please. Note that, to head off any hypothetical abuse, I’ll probably reset the playable cartridge periodically, so don’t expect other visitors to see your high score, here.
For the rest of us, let’s continue.
If you read The Only Way to Travel, you might also notice that Legendary Ballad: The Fall of the Kingdom—the so-called “Ozymandias Sim”—also has enough detail that someone could probably implement it without too much guesswork. However, it would probably also require more sophisticated assets and an understanding of the overall story to feel like a legitimate adaptation of what we know. The story also describes it as a phone app, which wouldn’t work for this format.
Plus, I almost certainly wouldn’t have had that game ready in the two months lead time required for today’s post…
The Making of Kabang!
Note, by the way, that someone could add an export-as-image feature without too much trouble. Most image formats allow for applications to append unrelated data to the file, so “unpacking” it would strip off the fixed-size image preface to get at the program. Unrelated, a fantasy computer could also something like minimodem to encode the game as audio, simulating the distribution of software on cassette tape.
If you don’t like either of the two major players in the field, by the way, I have since found a list of fantasy consoles that you might find useful. As a side-note, I find it peculiar that none of the fantasy computers (released under Free licenses, at any rate) seems to have a back-story to them, such as a fictional company or release date. I bring it up, because so many of them work at creating a specific aesthetic of graphical and even sound logos, so it feels like a natural step to write a brief alternate history.
Generating a Stub
However, I didn’t feel like learning TIC-80 programming from scratch for only this project, so I took the premise, lifted directly from the Tesseract text…
You play an astronaut with a magnet (represented by a sixteen-pixel stickman) who is reeling in mines that drift through space. The stick controls the astronaut’s rotation in place just left of center. His magnet can catch and grab one mine, and then a second mine can attach to the first, and so on in a chain, but the chain can only add mines at its end – a mine that hits the middle of the chain causes a reaction that blows up the astronaut (the screen blinks white and then displays the score).
…And I asked ChatGPT to give it a try. That went…about as well as you’d expect, honestly. I got a game that didn’t really work or do anything in that hundred-word specification, but it served as enough of a basis to at least get me moving. And as a bonus, ChatGPT finally gave up instead of wasting my time with bogus answers.
You’re right, and I apologize for the confusion. The updated code I provided in the previous response is indeed identical to the previous versions, where the astronaut sprite inverts instead of rotating. I apologize for the repeated oversight in addressing your specific requirements.
Given the challenges in meeting your desired gameplay mechanics through text-based communication, I must admit that implementing the precise rotating behavior you’re looking for is proving difficult. I apologize for any inconvenience caused by my previous attempts.
Considering the limitations of our current interaction, it might be more efficient for you to explore implementing the rotating behavior on your own or seek assistance from a developer who can work with you directly to understand and fulfill your requirements accurately.
Once again, I apologize for the confusion and any time wasted. If you have any other questions or need assistance with other topics, I’m here to help.
Anyway, like I said, the “game” that it wrote—and rewrote, and rewrote…—didn’t really work, and ignored something like four fifths of the specification, but reading through and debugging it did teach me the bare minimum of how a TIC-80 game works, and got me a shell with the astronaut (a sprite to fill in with the editor) near the middle of the screen and a “mine” that runs down the center line from right to left. It didn’t do what I wanted, but it at least gestures in the right direction.
In the end, as you might guess from the quote, ChatGPT primarily fell apart on getting the astronaut sprite to rotate smoothly. It didn’t parse/understand that the in-built four-step rotation only alternately flips horizontally and vertically, which doesn’t do anything useful for us, here. I’ll talk more about that, later.
Frustrated at its worthless programming, I backed away from code and instead asked ChatGPT for something even less probable, a bare-bones, repeatable melody that might work in this context. It provided me with…again, mixed results.
The good news? ChatGPT actually did give me a plausible-sounding music track that fit most of my criteria.
The bad news? It wasted another half an hour of my time pretending that it knew how to play the music. I didn’t either, so I played along. But it didn’t know at all, and kept insisting that I needed more parameters in playing a constant droning note inside the loop. It turns out that you only need to call the in-built
music() function with the “track” number and any parameters—outside the main loop—whereas the AI had me trying to play individual notes.
Once I figured out how to do this right, I went back to ask for a more ambitious theme, and it…almost delivered, after I made some adjustments. I wouldn’t call it—once you strip away the audio effects—a particularly “science fiction” or even a “computer game” theme, and maybe a touch too mournful, but it does the job as a placeholder, considering that I certainly have no education in or experience at composing music that would help me do better.
Then, I tweaked a couple of notes and added effects, such as changing the left/right balance at certain points.
Listen to it here, set to automatically loop, under the assumption that you want to confirm that ChatGPT did, indeed, create a theme to play continuously.
I did need to learn how to work with TIC-80’s music tracker interface, but that seemed far easier than learning to compose my own music or trying to find a public domain/Free Culture piece to adapt.
As I mentioned, ChatGPT completely broke down when it came to getting the astronaut to rotate, a key piece of the game. However, hunting around turned up this old GitHub issue asking about rotating sprites on the TIC-80, which gave me the start of a viable solution, with code from an example game that existed purely to illustrate such rotation.
I adapted that code, and continued on my merry way.
At this point, I have a magnet-wielding astronaut for the player to spin, and a mine that imperils the player, not to mention the music.
From there, I needed to learn a handful of things—such as playing music and sound effects—from TIC-80’s overview, and I needed to iterate over the concept until I found something that played well, felt difficult enough that it would have eaten player quarters in a 1980s arcade, and still maintained the spirit of the game as presented in Tesseract.
The result? Kabang! throws mines, one at a time, somewhere in the player’s ever-expanding “strike zone,” if you can pardon my use of a baseball term, or more generally the range where the player always has a chance to reach the mine. You can always capture the first mine “free,” though, as a kind of quick tutorial. Players can affect their rotational velocity by accelerating to the right or left, in hopes of connecting with or dodging an incoming mine. The game ends when the player can’t catch or dodge a mine and it collides with either the player or the chain of mines.
From here, I added a couple of sound effects—a “plink” sound when the player captures a mine, and a rumble when the mine collides with the player—and added a pseudo-random star-field background for each game.
Then, based on some additional ideas from ChatGPT, I checked in with NightCafé Studio and DALL-E, iterating and refining images that I could adapt into an in-game logo and “cabinet art.” You can see the final art as this page’s header image—it took both sites interacting, plus manual editing, to get this far—and while I should redraw it for consistency with clean lines, and to separate the letter forms, I even managed to extract enough pieces of bogus glyphs in the generated images to create and vectorize a bare-bones (but plausible) logo, which you can see to the right.
The final part of the project—a part that few players would have complained about, had I left it out—turned out to require the most fussing: Maintaining a high score list, and making it feel credibly like the experience of an arcade game.
This turned out to require several parts.
Persisting scores and names already has a feature to support it and similar save-states. The
pmem() function stores to and retrieves from the persistent memory space of the “cartridge.”
I saw no problems, here, because this works almost precisely like all other text display. Add a
for loop to call
pmem() and update the vertical position, and we have a list.
Inputting a “Tag”
If you have played actual arcade games in cabinets, you’ll probably have noticed that a high score entitles you to add a (typically) three-letter ID to your score, sometimes called a tag. And you generally perform this input with the joystick control, since nobody in the 1980s would spring for a fragile keyboard on a product whose revenue you measured in quarter-dollars.
And now, the problems start showing up. As far as I can tell, the TIC-80 (somehow) doesn’t have an in-built idea of character codes, even though it does have the concept of keyboard codes. Lua, likewise, doesn’t appear to have the concept of incrementing a character variable. This meant that I couldn’t say something like “when moving down, go to the next letter.”
After some thinking, I ended up hacking together a poor-but-workable solution, by creating a string with the expected input characters, twenty-six capital letters and one space, and use the index into that string—a number—as my “actual” letter, the thing that I care about. The tag then gets stored via
pmem() as a number that encodes the first, second, and third letter indices.
I also needed to mess around with those indices in practice, because Lua generally starts its string and array indices at
1, rather than
0, and I needed those indices to act circular, so that
Z would look near
A, for input purposes. Then, it stores the final tag as the sum of the indices times 1, 256, and 65,536, or if you’d prefer an example, the tag
ABC would store as something like 1 + 512 + 196,608 or 197,121. Then, printing the tags (as described above) undoes that work.
Resetting the High Scores
As a nod to modernity—both that we live in 2023, and that they model the TIC-80 on home computers, rather than arcade cabinets—plus the fact that I got tired of needing to beat my old games to test the high score input, I also added a keystroke to erase all the stored high scores.
And there you go. We now have a real-world artifact derived from a Free Culture work.
I probably won’t do much more with this game. However, while I can’t see how I’d make it work with TIC-80’s small screen, Tesseract also describes the multi-player “Super”-Kabang!, and that could provide some entertainment for someone who wanted to build on this. By “make it work,” I mean that the screen only has 240x136 pixels, and two competing players strongly implies that the mines come from above or below, leaving two players with only about seventy pixels to complete most attempts to catch the next mine.
In addition, I can see possible enhancements to this version of Kabang!, even though I probably won’t bother with them, such as giving the individual captured mines some inertia, so that the chain becomes flexible and an occasional obstacle. The chain could also reset when the player can reach some distance past the end of the screen, maybe also increasing the speed of the mines for the “next level.”
You could also imagine the occasional mine that affects game-play when captured, like slowing/speeding the next few mines down/up or giving more precise rotational controls for a while, though I don’t know if that maintains the spirit of the concept. And getting rid of the extremely boring “cheat” strategy, which you’ve no doubt already guessed might get you a few dozen points, could also feel satisfying.
A genuine composer could probably build a far better main theme than my placeholder music, as well. Oh, and resetting the high scores should probably get stashed in the game menu, rather than available on the splash screen, if someone felt like learning how that worked.
Overall, though, I’d call this project a success. I pulled the majority of the work—including notes for this blog post—together over a weekend. I probably won’t go back to use the TIC-80 regularly, but I’ll definitely consider it if I have any other projects that would benefit from a 1980s-style aesthetic. Although I do wish that it had an easier way of putting the code and assets under version control. Even though I only have about four hundred lines of code, I’d still like a better way of managing it.
Note: A solution does exist for this. Buying the Pro Version allows for saving as a text file, including the code, the tiles, sound effects, music tracks, and so forth, though the developer still needs to distribute the game as the binary cartridge file. As such, I paid up, and
will create have created a GitHub repository sometime this week (link to the right) for the game code. The Pro version also provides an option to set a screen filter to look like an old CRT screen, if that excites you more than software development tools…
But most importantly, I actually have some fun playing this bare-bones game for short stints—and hope that you do, too—vindicating my choice to create it.
Credits: I created the game—itself released under the terms of the GNU Affero General Public License, version 3—with all assets made available under the terms of the Creative Commons Attribution Share-Alike 4.0 International license. The TIC-80 project has released its player code under the terms of the MIT license.
Tags: announcement game freeculture