Gravity Golf
Drag to launch, slingshot around the planets, sink it. Every hole is proven solvable before you see it.
What it is
Golf, in a gravity field. Drag to aim and set power, let go, and watch the ball fall through the system. Off the course or into a planet just resets it, and the only score is strokes. N for a new hole. E switches the integrator, which is the interesting bit.
How it works
Planets are point masses and the ball feels the sum of their pull, softened by adding a small constant to r² so a direct hit can’t divide by zero and fling the ball out at infinite speed.
The integration is leapfrog, not Euler, and that’s a bigger deal than it sounds. Both evaluate the same forces with the same timestep, leapfrog just takes its velocity half-step at both ends of the interval. That makes it symplectic, so its energy error is bounded and oscillates rather than accumulating.
Over two thousand steps of a circular orbit, leapfrog’s total energy moves by 0.00005%. Euler’s moves by 1.3%, and at five times the timestep, by 21%. Press E and watch a stable orbit slowly unwind.
Levels are generated the opposite way round to a construction. There’s no way to place planets so a solution is guaranteed by algebra, so the generator fires a few hundred simulated shots at each candidate layout and keeps it only if one of them lands.
It also keeps looking after the first hit and takes the longest flight it found, because the first solution is almost always a near-straight putt that ignores the planets entirely, which makes a gravity course feel like a flat one.
What surprised me
The solver ran at its own timestep and its guarantee was worthless.
It simulated at dt = 0.02 while the game ran at 1/120, and shots it had proved would sink sometimes missed when the game replayed them.
The two paths don’t diverge dramatically. I measured the gap between them at the end of a flight and it was around 0.03 course units. BUT the hole’s radius is 0.34. A gap ten times smaller than the target is still plenty to turn a hit into a miss when it lands near the rim.
So the timestep is now a single exported constant the game loop and the solver both use, and the test that matters replays the solver’s answer at exactly that timestep. A generator that proves things about a slightly different simulation than the one you ship has proved nothing.
What I would do next
Moving planets, so a hole is only open for part of its orbit.