Interesting Bugs in Potato Cop's development

Infinite collision

Potato Cop's sprites are not symmetrical and have very iffy rotation axis. For example, here is Baked Potato.

Frame by frame of Baked Potato's spritesheet, including hitbox outline

While the frame of the image is 1:1 and the rotation axis is set onto the middle of the frame, the drawing of the character is not centered or symmetrical.

Demonstration of Baked Potato flipping in position when he hits a wall

In the case of Baked Potato, when he walks into a wall and we flip his sprite, he will end up clipping into the wall, and it throws him into a cycle of colliding and flipping.

Many Baked Potatoes clipping through walls

The fix for this? We had to detect walls just a few coordinates away from the copy so the sprites get flipped before the actual collision. A rudimentary fix but it worked out in the end.

Damage on pause

Initially, there wasn't a plan to use a timer on Potato Cop as we wanted to try out a pause feature. This wasn't a problem until Hot Potato was created. When the player takes damage from Hot Potato, they take burn damage every second until the burn status wears off.

Instead of using the built-in timer function, CtTimer, we used JavaScript’s setInterval function, which ignores ct.js’ ticket speed value, resulting in the player continuing to take burn damage even when the game was paused.

Instead of keeping the pause feature and fixing the bug, we decided to forgo the pause feature and remove it entirely. This way, the bug wouldn’t affect gameplay and we did not have to complicate the code even further.

Infinitely spawning crumblings??

One of the trickiest bugs we encountered involved Crumblings which are spawned by Crumbs.

This was a tricky one and wouldn't have been caught if not for the reset feature.

Ct.js provides very helpful event listeners that can be attached to Copies. One of them was an "on Animation loop" event which the Crumb copies use. Everytime a Crumb's animation loops, we check if he's Enraged. Then, we check if he has any Crumblings attached. If there's an empty slot, there's a chance to spawn a new Crumbling.

On animation loop:
  If Crumb.isNotEnraged:
    If Crumb.Crumblings < 2:
      20% chance to spawn Crumbling

It was to our surprise one day when we hit the reset button to restart the game and found Crumblings in places they weren't supposed to be.

Infinitely spawning Crumblings

We are still not 100% sure what was happening. But here’s our guess. 

Even though the Crumb copy wasn’t visible in the map, his code wasn’t garbage collected, hence the animation loop was still happening in the background. This caused the Crumblings to spawn infinitely. The fix was simple. We declared a runId every time the player started a new run and destroyed any copies that did not match the current runId.

Summary

These were really important lessons to take away for future projects and we are glad we encountered them. Especially that last bug where a game can have infinite Copies if the player spams the restart button!