PICO Payun post mortem
| Tags: game development post-mortems
PICO Payun is a small, retro shoot'em up game I made with PICO-8. This article is a post mortem of the development, so I'd recommend you play the game first (you can do it directly in your browser).
Scope of the project
The idea for the game came up due to this tutorial series. While I quickly diverged in the codebase it is a good tutorial in terms of which features to implement. It also put a lot of emphasis in visual effects and feedback to the user (a concept often referred as juiciness in game design), which is something I never put too much attention in PICO-8. So I decided to take the gist of each video, implement it my way, and add / remove stuff as I saw fit.
In the end, PICO Payun features:
- 8 different levels (including two boss battles)
- 2 weapons (1 main weapon and 1 special attack)
- Pickable power-up's.
- 6 different enemies, each with a unique attack.
- Background music.
- Score.
- Loads of visual effects (explosions, sparks, shooting muzzles, etc.)
If you're not familiar with PICO-8, it's a "fantasy console" with limitations that force you to think out of the box and keep your games small. The most relevant restrictions are:
- Palette of 16 colors (including 1 transparent color)
- 128x128 pixels display
- 8192 source code tokens (for instance, a variable name is a token, special characters like
(
or=
are tokens too) - Limited memory for storing graphics (bank of 128 8x8 sprites)
- 4 channels of audio
Code
Nothing too complicated in this regard. Half of the codebase relates to the enemies and levels, and the code ended up being quite messy until I started to put some "order" in the new stuff I was implementing (I did not refactor previous code).
-
It turns out PICO-8 has coroutines! They are amazing to implement sequences. I used them to implement the cinematic sequence when you finish the game and the ship moves on its own.
-
The final boss is implemented with an actual finite state machine, since it has a few attack patterns, plus the transitions between them, plus its destroy sequence. The other enemies' attacks are also FSM but they are not implemented cleanly that way, and it's painful to see (luckily I didn't need to modify existing behavior because enemies worked well).
-
Collisions are implemented with rectangular and circle bounding boxes. It's a quick system and enough for this game. Of course, the size of the bounding boxes are tweaked so the player feels that they're "fair". For instance, the one for the ship is very small, so enemies clearly need to hit the player's ship in order to damage it. However, power-up's have a large bounding box so it's easy to pick them up.
In total, the codebase takes 7300+ tokens, which is near the limit of PICO-8's 8192 tokens. I didn't optimize for this and have a lot of auxiliary functions that make the code more readable, but with more tokens.
Development
The game was implemented over a span of ~2 months. I didn't work on it every day, and when I was up to the task it was usually in small chunks of time (20-60 mins at a time).
I ended up consuming most of the tokens and a lot of the space in the sprite banks (but I didn't bother to optimize for any of this, so I guess I could have added a few more enemies, power-up's or weapons…)
I tweeted the whole process (you can follow the thread here), which was good for morale and also for getting feedback. I even published a playable release at the middle of the development for people to try out! I got good feedback (and bugs!) and the game was definitely fun to play, so that gave me the energy to push forward and finish.
Art
I wanted the game to be cute and colorful. This can get tricky with PICO-8's small color palette, but I think I ended up achieving it.
Most of the animations are just 2 or 3 frames long. For instance, the main ship is just a 3-frame 8x8 sprite (one frame for staying still, and then two different ones for each direction). The animation for the engine thrust is a separate sprite, and keeping it separate gives the illusion of a more complex sprite.
For the enemies I chose them to be "organic", kind of like alien monsters. That helped to be cohesive and to differentiate them from the player's ship —which is "mechanic".
All of the enemies —including the bosses— feature a 2-frame animation that is a squash and stretch. They shrink and squash agains a virtual surface, and then they "rebound" and stretch to their original size. Again, this helps with coherence (and also with production!). It's seen most clearly with the slime alien:
Most special visual effects are based on drawing filled or unfilled circles. There's a primitive (due to the fact that PICO-8 doesn't allow for transparency or blending mode) particle system in place, that is used for explosions, weapons, etc. Example:
Audio
Sound effects are core to this "juiciness" we were referring to, and the game features different sound effects for shooting, impacts, pick-up's, etc.
The most lacking aspect is background music, in which I struggled a lot to compose something that made sense and that did not occupy all the audio channels (PICO-8 only has 4) to leave space for the sound effects to be played.
The main track for the game ended up more cheerful that I intented, but I didn't want to spend a lot of time on this task, so I went with it anyway.
Lessons learned
What went well
- Project is finished and didn't took ages!
- The game is quite polished, specially in terms of audio and visual feedback given to the player.
- It was a stress-free process, since it was done in very small chunks of time and I didn't have a deadline looming in the air.
- I was able to limit the scope —specially given there was no deadline— so the game could be released.
- PICO-8 limitations in terms of graphics (palette, sprite bank size, etc.) actually helped me a lot in achieving a balance between art that was "good enough" and time spent on it.
What went wrong
- The code for enemy behavior is a mess. I was very, very lucky I didn't have to modify it significantly out of feedback from players.
- Near the end of the project I took a few weeks' break and then I felt unmotivated to actually take it up again and finish it. Breaks are fine, but I should have made myself easier to return to the project, like a list of what was actually left (very little!) and notes on what to do next exactly.
To try next time
- Have an actual list of tasks, even if the project is small (I usually keep one, but didn't for this project)
- Keep using PICO-8 for small games and prototypes. Jump to a fully-featured engine like Godot for more feature-packed projects.
- Put a bit more emphasis in code readability, even if it's just a small Lua game.