Skip to main content

Making a game in PICO-8: Bashing against collision

Making games is easy

This is the third part of my diary about making my first-ever game, using PICO-8 [official site]. So No Frog Left Behind now has a map and you can move the player around. But I’m now on my third big session on it and I’ve got a long way to go before there’s any kind of game there.

Key to getting an actual game running is working out when things collide, like players with impassable water and frogs with bullets, and frogs with boxes. For this is a game about pushing frogs into boxes with bullets. And collision is my Agincourt.

Having looked at proper games’ code and not really understood it, I know I’m going to have to solve this my own terrible way, but I can see that they often use ‘flags’ on sprites so the game knows which are solid objects. With a little more investigation, I find that you can get the game to consult the flag on a given sprite with something called fget(). And there’s another command called mget(). This looks at a location in the map sheet you’ve drawn for the game in the editor.

I’ve got a plan. We mark water with a flag to say you can’t move there. We get the game to continually look up on the map what tiles are to the sides, above and below the player’s position, and if they’re flagged as impassable, it doesn’t let the player move.

What follows is a great deal of mistake-making. First I fail to put the right number of brackets into my nested horror equation and end my statements properly. Then I fail to marry the map’s small 16x16 scale to the screen’s 128x128 scale properly so it’s looking up the wrong place on the map. As I spend hours muddling through it all, I get the game to write out on the screen what it thinks is passable around the player (FALSE) and impassible (TRUE), along with the player’s coordinates.

Here is the rats nest of a solution I came to for checking to the left:

if btnp(0) and (fget((mget((((player.x-32)/8)-1), ((player.y-32)/8))),0)) == false then
    player.x -= 8
end

Bear in mind it also needs to check in each other direction, too. I know this is a complete horrorshow and I apologise profusely. But it works! My character now walks on the lily pads! (Though the frog here moves about completely randomly and freely because I haven’t done that bit yet.)

My little internal system is functioning. I feel great. It’s at this point that I decide, flushed with success and on a total whim, that I’ll make the game turn-based, so things will happen only after you move. Something like this transforms a game utterly from action to strategy. And it takes about 15 seconds to implement, using a little counter that resets every time you press a button. I’m realising that game development is easy!

And thus I go to work on the frog and so begins my great chastening.

I try to apply the same principles to the frog so, realism be damned, it also can’t go in the water, but instead of taking player input it’s going to move randomly, because, believe it or not, I probably can’t program an AI system. I have it pick a random direction, then check whether it can move there. If it can’t it’ll stay where it is for some froggy-style unpredictability.

It doesn’t really behave itself from the start. It sometimes moves diagonally (because I used the variable for going down twice). It goes in the water for no apparent reason (I was checking for the wrong flag). Even when I finally see it behaving correctly, I still don’t trust it, so I also put up debug text about what it thinks is around it.

But it totally doesn’t make any sense, contradicting the frog’s own movements entirely. I can’t see any pattern to the madness and pore over my spaghetti code. After about 45 minutes of my head in my hands I realise the text is reporting the frog’s last move because I was capturing the information about its location before the move that you see.

Game development is hard and it is always my fault. And next I have to make bullets to fire at the frog. It feels like the cliff face just keeps getting sheerer.

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.

Read this next