Taps can be unreliable inside this app's built-in browser. For the full experience, use its menu to open this page in your browser.
Skip to content

The CPU Hid The Puck In A Corner

A devlog by Neeraj Kotwani, who builds every game on Elipar.

Paddle Clash is neon air hockey. You can play it against another person on the same phone, laid flat between you, or against the computer.

A player sent a screenshot captioned "stuck in corner". The computer's mallet was jammed in the top-left corner of the table. There was no puck anywhere in the picture.

The puck was in the screenshot

It was underneath the mallet. Mallets are drawn on top of the puck and they're about twice its radius, so a puck directly beneath one is completely invisible. The screenshot was accurate; I was reading it wrong.

I nearly went looking for a bug where the puck gets deleted, which would have been a fun afternoon.

So: if a screenshot seems to show something missing, check whether it's behind something else before you go looking for the code that removes it. Draw order is the boring explanation and it's usually the right one.

Three things fighting over one puck

The computer wants to hit the puck downward, toward your end. To do that it aims for a spot slightly above the puck, so that moving into it pushes it away. Sensible.

It also can't leave the table, so its position is clamped.

Now put the puck very close to the top wall. "Above the puck" is outside the table, so the clamp pulls the mallet back to the edge, which is exactly where the puck is. The computer is now trying to stand in the same place as the puck.

What happens next runs every frame, forever. The collision code pushes the puck out of the mallet, which shoves it further into the corner. The wall clamp pushes it back out of the wall, which puts it back under the mallet. Push, clamp, push, clamp. The puck sits perfectly still in a corner, hidden, and because it's in the computer's half you physically cannot reach it to dig it out.

Not a crash. Not a glitch. Three individually reasonable rules, each doing its job, arriving at a stalemate.

Fixed in three layers, and I needed all three

Stop trying. The computer only goes for that knock-it-downward move if the puck is far enough from the wall that getting above it is actually possible, or if the puck is moving fast enough to be worth chasing.

My first attempt at that threshold was too low, and it produced something almost funnier than the original bug: the mallet would nudge the puck, the nudge was just fast enough to re-arm the chase, so it nudged it again, and the computer stood in the corner fussing at the puck indefinitely. I'd turned a frozen stalemate into a busy one. The threshold has to sit above the minimum speed a hit imparts, or the fix feeds itself.

Always impart something. A mallet touching the puck now always leaves it moving at some minimum speed away from the contact. A puck resting dead against a mallet is now impossible rather than merely unlikely, which removes the whole family of "two things touching and neither moving" states in one line.

And a backstop. If the puck stays within about 40 pixels of where it was for three seconds of live play, it gets re-served from the centre, toward whichever half it died in. Scores untouched.

The first two fixes address the cause I found. The third addresses causes I haven't found, and I wanted it because I'd just spent an afternoon learning that three reasonable rules can deadlock in a way I didn't predict. Real air hockey video games have exactly this rule, which was reassuring.

Making sure the backstop isn't worse than the bug

A watchdog that fires during a normal rally would be far more annoying than the corner it exists to fix, so it got the most testing.

The anchor resets on every serve and every goal, and a moving puck constantly re-anchors itself, so the three seconds only accumulate if the puck is genuinely going nowhere. I traced 3.6 seconds of ordinary bouncing play and it never came close to firing. Then I traced the dead corner case with nothing touching the puck: fires at exactly three seconds, re-serves from the centre, the computer intercepts it at its usual guard position, normal play resumes.

The re-serve is deliberately identical to the one after a goal. Same position, same speed. That way it introduces no new situation to reason about and can't hand out a cheap goal, because it's a state the game already reaches dozens of times a match.

Paddle Clash is free in a browser, one phone, two thumbs, no download. If you want something similar without an opponent, Pool Master is the other one with pucks that refuse to behave.

We use cookies to keep games running and, once ads are live, to show relevant content. See our Privacy Policy for details.