Game Development
Building a PICO-8 Starter Project for Myself
I'm working on a PICO-8 starter project that will hopefully bring me back to my days making weird little games in Flash.
For years, I have wanted to get into PICO-8 development.
That probably sounds obvious if you know me at all. I like small tools, I like retro games, and I especially like when something forces you to make a lot out of very little. PICO-8 is basically built for that: tiny screen, tiny palette, tiny constraints, and weird little games that can be shared without needing a production plan, a publisher, or a spreadsheet explaining why the market wants it.
And yet I kept bouncing off it.
Part of that is just the friction of learning another tool. I have already spent years in Unity, Godot, and what feels like a lifetime making Flash games. Starting over in a new environment is always a little harder than the fantasy version of it. You imagine yourself making something charming and strange in a weekend. Then you open the tool, hit the first awkward blank page, and suddenly you are thinking about project structure instead of making a game.
The other part is Lua.
I know Lua is one of the reasons PICO-8 works as well as it does. It is small, flexible, and very much in the spirit of the machine. But I do not naturally think in Lua. I am a pretty OOP-minded developer, and while you can bend Lua into something object-shaped, doing that too aggressively starts to eat away at the minimalism that makes PICO-8 appealing in the first place.
So I started building a small starter project for myself.
Not a framework. Not an engine. Not a grand declaration that I have solved PICO-8 development. Just a set of little helpers that lower the barrier of entry enough that I can get to the fun part faster.
The starter uses game.p8 as the working cart and keeps most of the code in src/, where the pieces can be included or removed as needed. There is a state-driven title and gameplay placeholder, an entity loop, sprite animation, timers, tweens, particles, camera movement, input helpers, text and panel drawing, overlap boxes, tile collision, entity blockers, and a small transition system with wipe and fade effects.
That sounds like a lot, but the point is not to include everything in every game.
PICO-8 gives you a very real token budget, and I wanted this project to respect that from the start. When a module has been measured, I put its approximate token count near the top of the file so I can see what it costs before pulling it into a cart. The entire library may eventually account for a meaningful chunk of the available token allotment, but most projects should not use all of it. A small arcade game should not pay for systems it does not need. A platformer might pull in animation, collision, camera, and state transitions. A puzzle game might skip half of that.
The starter should feel like a toolbox. I love woodworking and I have a LOT of tools - most projects use the same few every time and then add a couple other tools specific to the project. I wanted this thing to feel the same.
The entity helper is probably the cleanest example of the thesis. Entities are just plain tables copied from prototypes. If a prototype has upd() or drw() methods, the shared loop calls them. If it has animation definitions, the animation helper attaches only the small bit of state and behavior it needs. There is no elaborate class system. No inheritance tree. Just enough structure to make the way I like to write games feel natural.
The collision helpers follow the same pattern. Overlap boxes are good for collectibles, hazards, buttons, and triggers. Tile collision handles sprite-flagged map tiles and simple slide movement. Entity solids cover wall-like objects such as chests, doors, statues, and stationary NPCs. They are intentionally not trying to become a physics engine.
When making something like this, I spent a lot of time thinking about "intent". There are hundreds of ways you could structure a project like this. What drives most of my decision making is: what's the intent? How am I going to use it? Why do I need it?
That pushed a lot of the modules toward narrow, specific jobs instead of broad systems that try to own whole parts of the game:
- The input helper does not own player movement. It just returns d-pad direction.
- The text helper does not become a dialogue system. It just prints with a shadow.
- The panel helper draws a box and leaves layout to the game.
- The particle system has multiple versions because sometimes you want the fuller pixel particle helper with sine drift and tile landing, and sometimes you just need cheap sparks or dust.
- The easing file is a commented catalog so a cart only pays for the functions it actually uses.
I want the helpers to be flexible, but not endlessly capable. If a game needs a more powerful animation system, great. Blow it out. If a game needs richer collision behavior, build that on top or swap the module entirely. But the starter itself should stay low-footprint enough that it feels like a starting point instead of baggage.
I also put real time into documentation and examples. Some of that is for future me, because future me has a heroic ability to forget why present me made perfectly reasonable decisions. But it is also because I may eventually release this publicly, and if I do, I want someone else to be able to open the project and understand what is going on without having to go spelunking through my code.
There are runnable example carts for the bigger pieces, including entities, animation, basic collision, camera movement, and another dozen or so smaller helpers. Those examples are not just smoke tests. They are little explanations of what each helper is for, what it is not for, and where the tradeoffs live.
I also know there are already PICO-8 starter projects out there. Some of them are probably better. Some of them are probably more complete. That is fine.
The critical distinction is that this one is designed for the way I prefer to make games.
I could grab a starter project off the rack, but for me that sometimes feels a bit like wearing someone else's underwear. Technically functional. Not ideal. If I am going to finally make something in PICO-8, the process has to feel comfortable enough to return to, and ideally joyful enough that I actually want to use it.
That is why the repo is not public yet. I have not made enough with it to know whether the thesis holds up. I need to build a few small games, see what sucks, and see which helpers survive actual projects. On the one hand, yes it's fine to include everything because it's not an all-or-nothing starter, but the more the fluff distracts from the core utility of it. Building one module at a time, even as an experienced game developer, I may have made some choices that are only good on paper.
I can see the meta. I can limit dependencies. I can imagine how modules will be used together. But theory is one thing, and practice is an entirely different thing.
So for now, this is a private experiment. A small piece of infrastructure for getting me past the blank page. A way to make PICO-8 feel less like a new mountain to climb and more like a desk I want to sit down at.
My conclusion so far is: I am excited by where this is going.
It might actually be the thing that finally gets me using PICO-8, which is especially nice given how much I love small, experimental games. In a lot of ways, PICO-8 feels like it is carrying forward what I loved so much about the Flash game scene on Newgrounds, Armor Games, and Kongregate: small ideas, rough edges, weird mechanics, and not a commercial viability consideration in sight.
This is the part of myself I am trying to return to.
If this starter project keeps moving in the right direction, I will make a few small games with it, clean up (or kill) whatever stuff needs work, and eventually put it on my GitHub page. If that happens, I will probably cover it on my YouTube channel too, so subscribe there if you want to keep an eye or ear out for where this goes next.
Time will tell. For now, I am just happy that PICO-8 feels inviting again.