Returning to Simple TIC-80 Gamedev

For the last 3 Game Jams I've participated in, I used TIC-80 with the tq-bundler tool. tq-bundler allows you to split your games into multiple files, and manages the work of bundling them together into a single cart. Today I just finished migrating those 3 games off of tq-bundler, back to a single file for the whole game.

Before going any further, I want to say that tq-bundler is a great tool! It does what it sets out to do, has lots of useful features, and bug free. If you're looking for a way to split your TIC-80 games into multiple files, try out tq-bundler.

With that out of the way, here's why I inlined my games source into single 3000 line files

Simple is on my mind

I've been thinking a lot about complexity recently. I work mainly in web development, and have become fairly convinced that this area of programming (and probably the whole coding industry) has made things too complicated. There are too many layers. Too much transpilers and polyfills and abstractions and frameworks and dependencies and straight up lines of code running to get a button to submit a form. I'm exaggerating.. but this is how I feel right now. Basically I've drunk the Grug brain Kool-Aid.

So, since game dev is a hobby I do outside of my normal work, I can let the pendulum swing faaaaaar the other way. To me, removing the layer of a build tool makes things feel simpler. My little games are a single file that runs on a build of TIC-80 I include in the git repo. There's not a lot else to remove.

Really, this is just a return to the philosophies of Fantasy Consoles. Every part of your game (art, music, levels, and scripting) is both made in and executed on a single application. These games are then easy to share and modify by the community.

Side Note: In my opinion one of the best ideas of pico-8, the original Fantasy Console, was to hide your whole game inside a PNG image. This really leans into the concept of it being a "Console", simplifies sharing even further as anybody can right-click-save an image on a website, and is just darn fun.

I think more things could look like this.

Code reuse did not end up happening

One of the main reasons I tried using tq-bundler was the hope of creating a shared library of reusable code. There are many snippets of code that I used in basically every game. Stuff like a Gamestate Manager, Screen shake manager, helper utility functions, and a fancy textbox. I had this grand idea of having all my games include from the same file, however that did not work out for 2 reasons

Sadly tq-bundler does not actually support multiple top level carts. Its caching and building expects you to only have a single "main" script, which was not how I wanted to organize stuff. I could add support for what I wanted, but being honest I just don't want to spend my time doing that because of reason 2..

I actually decided I DONT want to share code between projects like this! Game jam games are short lived projects that I develop quickly at most for a couple months. After that they go untouched basically forever, and I want them to continue to work for basically forever. If all my games imported from a shared folder of scripts, and change to the public API of those scripts would mean updating all those games! That's busy work I do not want to do.

The solution is to embrace Kill+Yank (Copy+Paste for the non-emacs users) with open arms. Like the "One for All" quirk from My Hero Academia (.. I'm showing my inner weeb here ..), each new project will take from the previous and enhance as needed. This has the side effect of allowing me to prune any unneeded functions/logic, tailor fitting everything to the actual game. It's kinda sad that the thought of every line of code being essential surprised me at first..


The big downside to all of this is that now my games are single files with >3000 lines of code. Wont that make it impossible to stay organized?

Well yes, but actually no.

Emacs (and probably any text editor) has a lot of great ways to search through a file. With Emacs 29.1 we got Treesitter support, which makes it even easier to search for a specific block of code. It turns out that when you make a game in a weekend, you really just remember what you named things! It also turns out a couple thousand lines isn't actually that much and you can scroll through things in a couple seconds.

I've also been experimenting with Emacs Pages feature, which I found by complete accident. It uses the Formfeed Character (used historically to denote page breaks when printing source code to hard copy) to add even more ways to separate stuff within a file. You can even display a "page" in a unique buffer, basically faking a separate file. I think this is so neat that TIC-80 should use it for its bookmark feature!

You can play all of my TIC-80 games here on this website. Their source, in all its single file glory, is here in this repo. I hope this inspires you to choose the simple path for your next project!