
Hello friends! It’s been a LONG time since my last update! Never a bad time to try again I suppose.
I’m working on a 2-week game jam right now called #LOWREZJAM! The only constraint is that the screen size be 64x64. I’m working with @Jammigans and @Mothense! I’m writing the code, Jammigans is on art, and Mothense is doing our background music 💜
This past week I’ve spent my time building out the basic systems for our game submission, Canyon Crisis! You play as a cowboy who has to defend the canyon against an alien invasion and rescue your cows!
I wanted to take some time to talk through how I created the infinite scrolling that’s present in the game, especially given PICO-8’s constraints.
Let’s talk about the screen first.
We’re following the jam guidelines, which means that the screen is 64x64 pixels! We also knew from the beginning that we wanted large sprites with a lot of charm, so we settled on a 16x16 sprite size and set the game on a tiled grid.


Obviously, a 4x4 grid of tiles is quite a small space to build an interesting game in. By adding a camera, we can get a much larger sense of space! The camera will move if the player advances forward a space, or moves to the first or fourth column on the screen.
We then need to decide how to construct the world around the player, and where each object will reside. We could randomly determine positions for each cactus and barrel, however, it’d be difficult to program all sorts of restrictions to prevent potential soft-lock scenarios. Instead, I’d rather handcraft particular regions that get randomly selected and inserted into the game.
Enter, PICO-8’s map editor!

Using the map editor, we can color in sprites where we want to see them appear in relation to one another and guarantee that any configurations won’t be a potential soft-lock scenario.
Let’s divide up our map memory into 16 regions. Each region will be 4 tiles wide and 16 tiles tall. That’s as much as we can fit into PICO-8’s upper map memory (we’ll save the lower map memory for extra spritesheet space).

Wow! That’s a lot of sprites placed on the map!
If you have a keen eye, you’ll notice only 15 regions have barrels and cacti sprites. In the final, right-most column there are some canyon floor textures. We’ll get to that later.
Here’s the breakdown of how we’ll approach loading objects around the player:
- Select a region from PICO-8’s map memory to read. It could be any one of the first 15 regions.
- Scanning through the map memory with mget, create an in-memory representation of that object and track it’s position relative to the player.
- Do this 2 other times so that we have a canyon 12 tiles wide (3 regions wide).
What if the player progresses forward enough to run out of the current map regions? To prevent this from happening, we actually track 6 total regions - 3 for the area that the player is currently in, and 3 for the area the player is approaching. When the player steps into a new area, we’ll throw away the old area and spawn in another 3 regions above the area we just stepped into. Is your head spinning yet?
When it comes time to draw the objects to the screen, we simply run a quick heapsort to sort the object list by their screen y-coordinate (to ensure the draw order is proper), then draw each object at their current location!

What about that sixteenth region on the map? That’s just the canyon floor texture. Because we have 15 regions of non-repeating patterns being placed into the game area, that gives us plenty of variety so that the player likely won’t notice a repeating pattern of cracks in the ground. So before drawing in all of our objects, we’ll just draw that one pattern underneath each of the 6 regions we’re tracking in memory.
And that’s it! Not too bad, right? Currently, running at 60 frames per second, all of this costs about 20% of the available processing time we have in between each frame. Definitely could be optimized a bit more, but also plenty of room to grow into!
Hope you found this interesting! There’s still one week of the game jam left, and I’m so excited to see what we’ll come up with!