This is the second part of my diary about making my first-ever game, using PICO-8. Yesterday, I grappled with ideas and fiddled around with code enough to realise that most of them are beyond me. But now I have a concept I think I can make: a game in which you push frogs into boxes. It’s called No Frog Left Behind.
And yet… I have no idea whatsoever how to start. Other than to hit escape, which brings up PICO-8’s suite of tools, and typing out its fundamental structure in an attempt to feel constructive and full of direction.
These are the key functions for a game: init(), which the system calls only when the game first runs so you can use it to set stuff up; update(), which the system calls for each frame, so 30 times a second; and draw(), which then draws what got updated. But how do you even start to structure code for a game about pushing frogs into boxes?
OK, I know I need to put a sprite on the screen and I need to be able to control it, and it needs to be able to shoot something which pushes another computer-controlled sprite. I also like the idea of the levels having impassable areas. Being about frogs, perhaps the impassable areas are water, and you walk around on … lily pads? So I draw some, using PICO-8’s standard 8×8 pixel sprites and its 16 colours.
My aim is to use the map editor to draw the levels using these sprites, and after a little random splurging and the following code, I get a level filling the screen.
function _draw() map(0,0,0,0,16,16) end
This feels good! It looks like a game! A game without any function whatsoever. But it’s a start.
But how to stop the player going where they shouldn’t? It’s collision time, and I’m already afraid of collisions because Benjamin Soule’s fateful words are still echoing around my head: “Collisions and readjusting position code are sometimes tricky.”
I start to look at collision code in other games, but they tend not to be based on grids like mine will be. And it’s incredibly complex. There are all kinds of variables and maths going on that I can’t follow. And it’s all tied into other systems, systems I only have the haziest awareness of their function. I spend a couple of hours copying other people’s code into my text window, seeing if I can get it to work (it generally doesn’t) and being tempted into building in systems that I don’t understand or need.
But one of these bits of code is from PICO-8’s built-in demos, called Collide, made to show off realtime ball-bouncing physics. I notice that other games have used its code, too, and reading the first few lines I realise it has a pretty neat way of spawning objects which I can totally nick to create the player, the frog, the projectiles you shoot. Each can be loaded with variables and it sets up x and y coordinates for where they appear. It doesn’t give any answers to solving collision, but after several hours of agonised wondering about how to get started, I’ve finally got something on the screen. OK, they’re an awful lurid frog and a weird figure, but they’re something.
But my jubilation is short-lived, since this poses a new problem. How do I get them to move on a grid that is matched to the 8×8 pixel sprites of lily pads I’ve drawn? Afraid of pulling myself into another fretful and confusing tour of how proper games work, I hit on my own solution: if the screen is 128×128 pixels and my tiles are 8×8, I can simply always divide the on-screen coordinates by 8. Instantly, the character snaps to a 16×16 grid. I stick in some lines to take inputs from PICO-8’s six-button controls; here’s the up button:
if btnp(2) then player.y -= 8 end
I also decide to make the level a bit smaller. And I have a moving character (and a stationary frog).
I have a strong suspicion that I’ve broken every rule, that what I’m doing will lead to terrible repercussions as the game becomes more complex, but I feel I’m on the road, because solving one thing naturally led to the next thing to make.
And now collision has to be next.
Here’s the full series, which we’ll be publishing daily over the week of Christmas. Also, just to note that PICO-8 is available right now in a Humble GameDev Software Bundle, in case you’re interested in trying it out.