The aiming line that was off by a factor of 17
· 4 min read
In a slingshot game the dotted line is the whole contract with the player. You pull back, the dots show where the shot will go, you let go. If the dots lie, there is no skill to learn — only luck, and the feeling that the game is cheating you.
The first playtest of ScaleSling came back with two sentences: "the forts fall down on their own" and "it doesn't go where the line says." Both were true, and neither was a tuning problem. This post is about the second one. The forts get their own post.
What the line was doing
Pull the dragon back at any angle and the dotted guide rose off the top of the screen and never came down. Not at a steep angle, not at a shallow one, not at full power or at a nudge. The dragon, meanwhile, flew a perfectly ordinary arc and landed somewhere the line had never pointed.
The guide works by stepping a pretend projectile forward in time: start at the sling, add the velocity, add gravity to the velocity, repeat, and drop a dot every few steps. That loop added gravity as the gravity setting multiplied by the length of one step.
The physics engine underneath the game does not do that. It applies gravity as a force, and a force becomes a change in velocity through the step length squared. At sixty steps a second one step is about 16.7 milliseconds, so the guide was using roughly one seventeenth of the gravity the dragon actually felt. A projectile with a seventeenth of its gravity does exactly what the line showed: it rises and keeps rising.
There was a second, smaller lie on top of the first. The dragon has air friction, which eats about half its speed in two seconds. The guide ignored it. Fixing only the gravity would have produced a line that came down in the right shape but in the wrong place.
The corrected step is two lines — multiply the velocity by the drag, then add the squared-step gravity — and the drag value now lives in one shared settings file instead of inside the dragon, because two different pieces of code need it and they must never disagree again.
Proving it, instead of eyeballing it
The tempting way to check a fix like this is to pull the sling a few times and see whether the dots look right. That is how the bug survived in the first place: a line that is a little wrong looks plausible, and nobody lands the same shot twice.
So there is now a small script that runs the real physics engine, with no browser and no screen, using the game's own constants. It launches a body at a spread of angles and powers, steps it forward, and compares where it actually goes with where the guide's arithmetic says it will go.
Before the fix, the two had drifted apart by 1,300 pixels after 90 steps. After it, the difference is zero, and the landing point matches to the pixel. The script runs in under a second, and it runs again whenever anybody touches the guide, the physics settings or the dragon's body.
The probe that lied, too
While chasing this we had an automated player — a script that fires shots at every level and reports which ones can be cleared. It reported that level 2 could not be won and that level 4 could not be damaged at all.
Both verdicts were false, and the reason is worth knowing if you build with a physics engine that lets bodies sleep. To save work, the engine stops simulating anything that has been still for a while. A dragon waiting in the sling has been still, so it is asleep. Setting a velocity on a sleeping body writes a number the engine never reads: the shot left the sling at a speed of 17.9 and stayed exactly where it was, forever.
A human never saw this, because dragging the dragon moves it every frame and keeps it awake. Only a shot fired without dragging failed — which is precisely what an automated tester does. Every "unwinnable" in that report was a dragon that had never moved, and we had already started changing level materials because of it.
The fix is one call to wake the body before launching it. The lesson is larger: before trusting a machine that says something is impossible, check that the thing it tested actually happened. The probe now records how far each shot travelled. A result of zero damage at zero distance is broken instrumentation, not difficulty.
What changed for the player
The dotted line is now the path. Where it ends is where the dragon lands, at every angle and power, and that is checked by a machine rather than by someone squinting at a screen. If you have played ScaleSling before and found the slingshot unfair, it was — and it isn't any more.
Filed under gamedev, physics, testing.
