🕹️ Reviving 1,300+ 90s Chiptune & Tracker Hits in the Browser: WebAssembly, 3D Demoscene & AI Pair-Programming If you grew up during the 90s or 2000s, you probably know that unmistakable sound: 8-bit chip basslines, sparkling sample-based arpeggios, and mesmerizing hex note matrices scrolling down the screen in FastTracker II , ProTracker , or legendary demoscene cracktros. C-4 01 v64 A0F | ··· .. .. ··· | G-5 02 v48 ... D#4 01 v64 ... | F#4 03 v32 C20 | ··· .. .. ··· Many developers dream of building the ultimate retro tracker player in the browser. Not just an MP3 jukebox, but a true WebAssembly synthesis workstation that allows per-channel soloing, tempo modulation, interactive 3D WebGL demoscene worlds, and live FastTracker II pattern scrolling. Today, I'm excited to share Tracker Music — a live, 60 FPS in-browser chiptune machine packed with 1,300+ authentic modules (from Unreal Superhero 3 and Razor 1911 to Skaven, Purple Motion, and 4mat). Here is the story of how we engineered it using WebAssembly (LibOpenMPT), Three.js, Canvas 2D, and an AI agentic copilot that took care of low-level profiling, database audits, and V8 optimization. ⚡ What's Under the Hood? 1. Real-time WASM Synthesis with LibOpenMPT Playing pre-rendered MP3 recordings ruins the magic of tracker music. Real tracker files ( .mod , .xm , .s3m , .it ) contain raw instrument samples and sequenced pattern commands executed in real-time. LibOpenMPT in WebAssembly: We compiled the battle-tested libopenmpt C/C++ engine into WebAssembly via Emscripten. Sub-millisecond Audio Pipeline: Generates 4096-sample stereo audio chunks in a WebAudio context with direct memory pointer access. Dynamic Channel Isolation: Every channel can be muted or soloed independently in real-time. Pitch-Free Tempo Scaling: You can speed up or slow down playback from 40 to 300 BPM on the fly using play.tempo_factor without pitch distortion. // Fetch and synthesize tracker module via WASM const modulePtr = libopenmpt . _openmpt_module_create_from_memory ( ptrToFile , byteArray . byteLength , 0 , 0 , 0 ); const bpm = libopenmpt . _openmpt_module_get_current_estimated_bpm ( modulePtr ); const speed = libopenmpt . _openmpt_module_get_current_speed ( modulePtr ); 🌌 4-Layer Visualizer Suite (60 FPS) To capture the true demoscene aesthetic, we built four visualizer layers: Master Oscilloscope & Spectrum FFT (512 Bands): Dual-pass neon glow oscilloscope with retro phosphor persistence. FastTracker II Full Pattern Matrix: Dynamic 60 FPS Canvas 2D note scroller with full syntax highlighting (Cyan notes, Gold instruments, Pink volume, Purple effect commands) and real-time channel VU meters. Channel Animation Rack: Scroller: Individual vertical channel note strips. Waveforms: Live per-channel oscilloscope traces. Waterfall: Falling neon piano-roll blocks (Guitar Hero style). 3D WebGL Demoscene Engine (Three.js): 5 procedural worlds including a Synthwave wireframe grid with a pulsing sun, Cyber Tunnel, Demoscene Core, Voxel Matrix, and Digital Skyline. 🤖 How an AI Copilot Solved the Hardest Bottlenecks Building this as a solo side-project would normally take months of tedious evenings. Here is where pair-programming with an autonomous AI coding agent made a massive difference: 1. Auditing & Indexing 1,300+ Modules The AI wrote automated node scripts to inspect module headers via virtual WASM instances, validating sample counts, channel structures, and detecting corrupt files. It verified module integrity, extracted embedded sample credits, and built a clean, searchable metadata index. 2. Squeezing 60 FPS out of Three.js & TypedArrays On lower-end CPUs, animating thousands of terrain vertices was lagging. The AI identified that calling posAttr.getY(i) and posAttr.setY(i, val) was introducing function call overhead in V8 JIT loops. By refactoring to direct Float32Array memory indexing ( posAttr.array[i * 3 + 1] ), vertex updates achieved a 10x speedup : // High performance zero-overhead TypedArray indexing const arr = posAttr . array ; for ( let i = 0 ; i < count ; i ++ ) { const idx = i * 3 + 1 ; arr [ idx ] = Math . sin ( time + i ) * amplitude ; } posAttr . needsUpdate = true ; 3. Killing shadowBlur in Canvas 2D In Chromium, setting ctx.shadowBlur forces software Gaussian blur on the CPU. The AI replaced it with a hardware-accelerated dual-pass stroke (a wide semi-transparent glow pass under a sharp core stroke), dropping visualizer CPU consumption from 45% to under 5%. 4. Zero CPU in Background Tabs Using the Page Visibility API , canvas rendering completely sleeps when the browser tab is hidden ( document.hidden === true ), playing background music with ~0% CPU overhead . 🕹️ Live Demo & Favorite Tracks Try it out directly in your browser: 👉 https://tracker.snakelair.ru/ Must-listen starter tracks: Unreal Super Hero 3 (Kenet & Rez) Space Debris (Captain / Markus Schneider) Stardust Memories (Jesper Kyd) Desert Dawn (Purple Motion / Future Crew) Razor 1911 Crackintro Classics What are your all-time favorite tracker modules and demoscene memories? Drop them in the comments below!

Reviving 1,300+ 90s Chiptune & Tracker Hits in the Browser: WebAssembly, 3D Demoscene & AI
Eugene Pascheko

