How to correct a corner

There are many techniques that you can apply so that a platformer game feels good. One of those is corner correction.

https://media.amano.games/devlog/how-to-correct-a-corner/how-to-correct-a-corner/corner-correct.gif

As with most of these techniques, the goal is to assist the player in getting to the position where they want to be. Even if there is something in the way that wouldn't let them. In this case we are moving the player a few pixels to the sides so that they clear the platform above them.

In the PICO-8 version of Pullfrog, we solved this using multiple colliders. We would check which one of them triggered the collision, based on that, we would apply some logic to move them where we wanted. This worked fine but the problem is that we where checking all the colliders every frame. It was hard to maintain, and an expensive operation, dropping frames when there were a lot of pieces in the screen.

https://media.amano.games/devlog/how-to-correct-a-corner/how-to-correct-a-corner/ezgif.com-gif-maker.gif

When starting the Playdate version I imposed myself a challenge, to have the same behavior using only one collider. The first thing we tried was to compare the position of the player with the object they collided with. Check if the distance between them is less than a certain amount, and if it is, move the player in the opposite direction.

https://media.amano.games/devlog/how-to-correct-a-corner/how-to-correct-a-corner/03.png

This worked fine, but it was a little more complicated than what we needed, and caused a couple of undesired consequences. For example the jump distance would get altered and you would miss platforms that you would otherwise land on.

On top of that our physics logic for moving platforms was getting too complicated. Then someone on the Playdate Discord shared an old post by Maddy Thorson about the physics system on Towerfall and Celeste. After reading it a lot of things clicked, and I got excited to change my broken physics mess for a more elegant solution.

For the corner correction Maddy doesn't go in to detail, but you can see and implementation on the Celeste 2 PICO-8 game repo. It took me a while to understand it, because PICO-8 code tends to be a little bit hard to read.

The main takeaway I got from Maddy's post and the Celeste 2 code, was to split the movement into two functions. One for X and one for Y. This made everything easier to think about and easier to resolve the collisions. In the case of corner correction, once we detect a collision, we try to move you out of it depending on the direction that you where moving. If while correcting you in one axis you collide again then we just don't move you, after that it's time for the other axis to try and correct you.

I'm thinking of doing a more in-depth explanation with some code. But haven't had the time to add code snippets support to the Devlog and this post is already getting big!.

A nice thing about doing this from scratch, is that now the code is less coupled with the player. This allow us to apply the same logic on different stages of the game an player movement. For example: If you are going to get squished by a moving piece, now we try to move you to safety.

https://media.amano.games/devlog/how-to-correct-a-corner/how-to-correct-a-corner/squish-export.gif

Another example would be when you pull a piece and it collides with another one, we try to move the piece so that it ends up where you intended it to be.

https://media.amano.games/devlog/how-to-correct-a-corner/how-to-correct-a-corner/piece-correct-export.gif

Did you noticed how the piece pushed you? this was an added benefit form the new physics system and a big difference from the PICO-8 version of Pullfrog, but we will talk about this is a different post.

Comments

Other Posts

Archive

You can subscribe via RSS or follow us @amanogames_

Making a pinball game for Playdate: Part 07, the debugger

Making a pinball game for Playdate: Part 07, the debugger

Searching for a debugger on Linux

Making a pinball game for Playdate: Part 06, the profiler

Making a pinball game for Playdate: Part 06, the profiler

Learning how to use a profiler

Making a pinball game for Playdate: Part 05, the spatial partition

Making a pinball game for Playdate: Part 05, the spatial partition

2 Bits image formats.

Making a pinball game for Playdate: Part 04, the image format

Making a pinball game for Playdate: Part 04, the image format

2 Bits image formats.

Making a pinball game for Playdate: Part 03, the first level editor

Making a pinball game for Playdate: Part 03, the first level editor

How did we choose our first level editor for the game?

Making a pinball game for Playdate: Part 02, the physics

Making a pinball game for Playdate: Part 02, the physics

Let's talk about physics.

Making a pinball game for Playdate: Part 01, the language

Making a pinball game for Playdate: Part 01, the language

Welcome to this December adventure, where I will try to write about the process of our last game, Devils on the Moon pinball. Today I will talk about our choice of programming language for the game.

Let’s finish this

Let’s finish this

We are back working on Pullfrog! What happened?

Let's talk about Don Salmon

Let's talk about Don Salmon

Don salmon, a new platforming game made in Godot and a small update on Pullfrog

Spooky eyes and level editors

Spooky eyes and level editors

Last year we made the decision to take a break and focus on a spooky game around the spooky season.

This kills the frog

This kills the frog

After rewriting the physics system for the third time, it was time to start working on more fun stuff. The frog death system™.

On starting a game

On starting a game

A couple of things I would recommend when starting your first game on the Playdate.

On "Bouncy" Animation

On "Bouncy" Animation

Another Equally important decision, is choosing which poses you want to emphasize in order to get that reactive feeling when a character interacts with the world.

The collision stair case

The collision stair case

As stated on the previous post, updating all the pieces all the time was a bad idea. We needed to figure out a way to update only the ones that needed to be updated after another block got destroyed. The quick and dirty solution was to check all the pieces inside a bounding box on top of the piece that got destroyed.

About Amano & the collision conundrum

About Amano & the collision conundrum

So, a couple of months back, Mario and I were happily working away on The game, finding out the workflow and working out the kinks of developing for the PlayDate. We laid down the main mechanic, blocks were falling and colliding correctly the character was moving alright but we were doing everything on the simulator, NOT testing on the actual device. so when we decided to take it for a spin…  it crashed.

Pullfrog postmortem, Long Live Pullfrog 2-Bits

Pullfrog postmortem, Long Live Pullfrog 2-Bits

So towards the end of the year, Mario managed to get his hands on a Development console for the handheld "Playdate" and we decided to attempt do make a second version of Pullfrog, this time featuring a playful little crank and seemingly less restrictions except for the apparent ones like the black and white color of the screen. Oh the naivety.