Click or hold inside the box to pour sand onto the balance. Balance the iron weight to within 2% to win. Every level drops a random amount of sand per click (shown in the bottom bar). Press Reset for a new level.
Left torque: 0
Pour sand to balance the scale
Right torque: 0
Click or hold inside the box to pour sand. Per click: 0 g. Grains: 0 / spilled: 0
Reset
Want to know how it works? Read the tutorial: Three.js Falling Sand: Build a Balance-the-Scale Physics Game .
Sand Balance // game logic flowchart
One frame: input changes state, fixed physics steps move the sand, torque tilts the beam, then three.js draws it.
INPUT // STATE // LOOP Click or hold in the box spawn(x, burst) 10-50 g per click (random) matching rate while held Reset button reset(): new level random iron weight random sand per click Shared state grains[ ] beamBins[ ] floorBins[ ] angle requestAnimationFrame Accumulator run fixed 1/60 s steps clears adds step(dt) // EVERY FREE GRAIN Gravity and move vy += g dt, x += v dt Bounce off box walls toLocal(): into beam space Landed on beam pile? settleOnBeam() slide to a lower bin Pile taller than the lip? Stacked on beam adds weight to its side Hit floor pile? settleOnFloor() resting Spill over edge free again yes no no yes yes no: keep falling falls step() reads BALANCE // HUD // DRAW Torque sum of mass x lever arm left side vs right side Target tilt -0.32 tanh(torque / 1500) Damped spring sets beam.rotation.z All settled and within 2 percent? BALANCED! Heavier side shown draw() positions to BufferGeometry THREE.Points renderer.render() after grains yes no next frame