A Python developer going by simin75simin just dropped a 2D physics sandbox on GitHub that caught my eye—not because it's trying to solve hard problems, but because it does something simple really well. The project, called "ball-sandbox," simulates thousands of bouncing balls in various container shapes and renders the whole thing with Pygame. It's the kind of thing you'd make to learn physics engines, except this one actually works. The repo ships two programs: an offline MP4 renderer (sim.py) that dumps a 10-second video at 60 FPS—22,000 balls in a 270-pixel circle, color-coded by height—and an interactive sandbox where you can tweak gravity, restitution, damping, ball radius, and spawn count on the fly. Click to drop clusters of balls, right-drag for continuous spray, scroll wheel to fine-tune sliders under your cursor. Four container shapes are available: circle, square, triangle, and ellipse.

Under the Hood

The implementation uses Position Based Dynamics (PBD) with semi-implicit Euler integration—v += g·dt; v *= damping; x += v·dt, repeated four times per frame at 240 Hz effective resolution. Wall constraints project balls back inside their container shapes and reflect velocity normals accordingly. Each shape handles this differently: circles use radial projection to R - r, squares check against four axis-aligned faces, triangles compute outward edge normals plus an apothem offset, and ellipses scale positions radially until they satisfy (x/a)² + (y/b)² ≤ 1, using the gradient as a surface normal for velocity reflection. Colors update each frame via HSV → RGB conversion based on current y-position so the ball cloud always reads as a top-red to bottom-violet spectrum. The developer recommends running with Numba JIT compilation for faster physics: uv run python interactive.py for development builds, or uv run python interactive_app.py if you want the pure-NumPy version that ships in the packaged .exe. Windows users can grab BallSandbox.exe from the latest release—roughly 20 MB, no Python required, though first launch takes a couple seconds while PyInstaller unpacks to %TEMP%.

Scaling Toward 2^27 Balls

The README doesn't pretend this hits the viral "2^27 balls in a circle" benchmark—that's around 134 million particles. The dev breaks down practical paths forward: Taichi or CUDA with ti.atomic_add for count/scatter/resolve operations (an RTX 30-series card sustains ~10⁷ balls at 30 FPS), NVIDIA Mochi using BVH ray-tracing on RT cores to reach 10⁸, or PIC/FLIP fluid simulation techniques that stop caring about individual collisions once balls shrink below one pixel. Most of those viral many-balls videos are honestly fluid sims rendered as particles—it's a clever distinction.

Key Takeaways

  • The offline renderer hits 60 FPS with 22K balls using Numba JIT compilation and position-based dynamics
  • Interactive sandbox supports four container shapes with live-tunable physics parameters and bilingual UI (EN/)
  • Wall constraints must apply after velocity re-derivation to prevent balls from sticking to boundaries
  • Scaling toward millions of particles requires GPU acceleration or fluid simulation approximations, not CPU optimization alone

The Bottom Line

This isn't going to change the world, but it's exactly the kind of project that shows what AI-assisted coding enables—someone had an idea for a fun physics toy, used Claude to scaffold the boilerplate, and shipped something that actually works. If you've ever wanted to see PBD constraints in action without reading a 50-page paper, clone this repo and start dropping balls.