
Hey fellow devs!
While building OBOL: The Cursed Coin Pusher (an 1890s occult debt-rigging roguelike where you rig a mechanical coin pusher to pay off an animatronic Collector before a 3D Finger Guillotine takes your digits), we had to solve two gnarly technical problems:
- How do you make stacked coins hang 45% off a brass lip without jittering or sliding like hockey pucks?
- How do you play 70 metallic coin collisions per second during a cascade without
.wavsample machine-gunning?
Here is a breakdown of how we solved both across our WebGL 2, Godot 4.7.2, and Unity 6 builds!
1. Why Coin Pushers Need a 240Hz Sub-Stepped Solver (dt = 1/240s)
- Ratcheted Shelf-to-Pusher Friction: Coins on the upper shelf inherit
100%of the pusher bar's forward stroke while asymmetric friction (mu_pusher = 0.52vsmu_shelf = 0.28) compresses the bed on the backstroke. - Overhang Torque Counter-Balance (
Z = +3.35): Downward normal weight from overlapping rear coins counteracts tipping torque at the lip-allowing multi-coin overhang bridges to teeter on the edge. - Live On-Board Mythic Fusions: When 3 matching tokens cluster within
d < 1.15on the moving shelf for0.65s, lightning merges them live into a giant1.45x-radius Mythic Medallion.
2. Zero-Sample Euler-Bernoulli Brass Plate Synthesis

Instead of shipping .wav files, OBOL uses 0 external audio samples. All 25 sound categories are generated procedurally using inharmonic circular plate modes ([1.00, 2.08, 3.41, 4.96, 6.72]) scaled by coin mass and collision velocity from the 240Hz solver.
Test the Solver & Synth in Your Browser
- Playable WebGL 2 Build (Zero Install): https://saaalahy933-blip.github.io/obol-cursed-coin-pusher/
- Source & Desktop Releases (v1.0.0): https://github.com/saaalahy933-blip/obol-cursed-coin-pusher/releases/tag/v1.0.0
- Technical Architecture Press Kit: https://saaalahy933-blip.github.io/obol-cursed-coin-pusher/presskit/presskit.html
Happy to answer any questions about the 240Hz constraint solver, WebAudio/PCM modal synthesis, or how we kept 100% mechanical parity across WebGL 2, Godot 4.7, and Unity 6!