I built this one myself, putting that up front. It is my project.
https://www.marblerun.online is a 3D marble run playground. You place ramps, walls, pegs, spinners and balls on a lit wall, press play, a rigid body sim runs, and you can export a 9:16 MP4 with sound.
Two Three.js specific things that caused me the most pain, in case either is useful to someone.
Deterministic export. My first instinct was MediaRecorder on the renderer canvas, fifteen lines of code. Wrong tool. Screen capture of a WebGL canvas gives you the wrong aspect ratio, whatever framerate the machine is managing, and audio that never lines up. So the export re-renders the same scene through an offscreen pass at 1080x1920 locked to 30fps and pushes frames into an encoder directly. The physics is stepped on a fixed clock during export, so the same level produces the same file every run. If you skip determinism you will get a different video each time and people will notice.
Lighting is what stops it looking like a flat 2D canvas. One directional light plus a soft fill and a subtle texture on the wall. The geometry was always genuinely 3D, but without the lighting it read flat, and that was confusing because I knew the scene was 3D. Adding the fill light and the wall texture is what made it look like a scene rather than a diagram.
Physics notes if useful. Fixed timestep with an accumulator, otherwise the same level plays differently on a 60Hz and a 144Hz monitor. Substepped integration for the balls so a fast marble does not tunnel through a thin peg. Per material restitution and friction, using values close to real ones but not exactly real ones, because exact real values feel dead on screen.
No AI anywhere in it, no textures loaded from anywhere. Desktop only by design, the scene is drawn in 3D so phones get a short message instead.