Project Roadmap
From fork to the best N64 emulator on the internet.
Overview
Phase 1: Better Engine
:::tip STATUS: COMPLETE (May 16, 2026) SIMD enabled, Emscripten upgraded, controller support fixed, UI redesigned. :::
What We Did
| Task | Impact | Status |
|---|---|---|
Fork N64Wasm (MIT) → wbaxterh/n64-wasm | Foundation | Done |
Remove -DNOSSE, -DNO_ASM | Unlocked SIMD codepaths | Done |
Add -msimd128, -mrelaxed-simd, -msse, -msse2 | 11,979 SIMD instructions in RSP vector unit | Done |
Add -DARCH_MIN_SSE2 | SSE2 → WASM SIMD translation for all RSP ops | Done |
| Upgrade Emscripten 2.0.7 → 5.0.7 | 4-year compiler upgrade, better codegen | Done |
| Fix type errors for Clang 20 compat | gzFile, implicit int, pointer types | Done |
| N64 USB controller mapping | All 14 buttons mapped (A,B,Z,Start,L,R,C-pad,D-pad) | Done |
| C-button joypad support in UI | Added Joypad remap buttons + handler for CUP/CDOWN/CLEFT/CRIGHT | Done |
| Retro terminal UI redesign | Dark theme, Press Start 2P font, N64 color palette | Done |
| Gamepad auto-detect wizard | Interactive "press each button" mapping flow with localStorage | Done |
Add -pthread + PROXY_TO_PTHREAD | 30-50% throughput | Planned |
| Benchmarks vs baseline | Quantify SIMD gains | Planned |
Results
- THPS running at 60 FPS on M1 Mac with N64 USB controller
- 11,979 SIMD instructions compiled into the WASM binary (was 0)
- All C-buttons, D-pad, analog stick working via Gamepad API
- Retro terminal aesthetic matching docs site
Phase 2: Better Shell
:::tip STATUS: COMPLETE (May 16, 2026) NextJS app deployed with native React component, no iframe. :::
What We Did
| Task | Impact | Status |
|---|---|---|
NextJS 16 app (wbaxterh/n64-web) | App Router + TypeScript + Tailwind | Done |
N64Emulator React component | Client-side, dynamic import, no iframe | Done |
| COOP/COEP headers | SharedArrayBuffer ready for threading | Done |
GamepadStatus component | Connection indicator, bottom-right | Done |
| Deploy to play.weshuber.com | Amplify CI/CD, auto-deploys on push | Done |
| Retro terminal theme | Matching docs site aesthetic | Done |
| Keyboard controls reference | Collapsible panel on /play page | Done |
| AudioWorklet ring buffer | Zero-latency audio | Planned |
| OffscreenCanvas rendering | Off-main-thread rendering | Planned |
| Touch control system | Mobile-first UX | Planned |
Live URLs
- Emulator: play.weshuber.com
- Docs: n64.weshuber.com
Success Criteria (Remaining)
- THPS plays with zero audio pops on Chrome, Firefox, Safari
- Works on iPhone (Safari) and Android (Chrome)
- Embeds in TrickBook website without iframe hacks
Phase 3: Better Features
:::warning STATUS: PLANNED The differentiators. Things no other browser emulator has. :::
Goals
- Social gaming — clips, scores, challenges
- Cross-device continuity — cloud saves
- Installable — PWA with offline play
Features
Clip Recording
User plays THPS → lands sick combo → hits "Clip That"
→ Last 30 seconds saved as WebM → Share to TrickBook feed
canvas.captureStream(30)for videoMediaRecorderwith VP9 codec- Rolling 30-second buffer (DVR mode)
- Web Share API for one-tap sharing
Cloud Saves
User plays on phone → saves game → opens laptop
→ Save is already there → continues playing
- OPFS for local persistence (3-4x faster than IndexedDB)
- Background sync to TrickBook backend
- Conflict resolution (timestamp-based, last-write-wins)
THPS Leaderboards
User completes a run → score extracted from emulator memory
→ Posted to TrickBook leaderboard → Friends see it
- Memory address watching for score values
- Server-validated (anti-cheat via save state verification)
- Per-level and overall leaderboards
Save State URL Sharing
User at cool moment → generates shareable link
→ Friend opens link → lands at exact same game state
- Serialize save state → compress (Compression Streams API) → base64
- Short URL generation
- Recipient loads state directly into emulator
Challenge System
Creator sets up challenge: "Land a 50k combo in 2 minutes"
→ Shares challenge URL → includes starting save state + rules
→ Others attempt it → results posted to leaderboard
Phase 4: WebGPU ParaLLEl-RDP
:::danger STATUS: FUTURE (2027) The moonshot. Bitexact N64 rendering in the browser. :::
Goals
- Pixel-perfect rendering matching real hardware
- HD upscaling (2x, 4x, 8x resolution)
- HD texture packs
- Widescreen hacks
Approach
- Analyze ParaLLEl-RDP's ~30 Vulkan compute shaders
- Port to WGSL (WebGPU Shading Language)
- Integrate with emulation core (replace HLE graphics path)
- Add upscaling pipeline
- Add texture replacement system
Why This Matters
- Only browser emulator with hardware-accurate rendering
- Supports games that HLE can't handle
- Enables features only possible with LLE (HD packs, widescreen)
- Technical moat — hard to replicate
Phase 5: The Long Game
Beyond 2027 — optional, aspirational
- Rust rewrite — unified codebase via wgpu (desktop + browser + mobile)
- Netplay — P2P multiplayer via WebRTC with rollback
- RetroAchievements — achievement integration
- Other consoles — PS1, Saturn, Dreamcast using same architecture
- AI upscaling — neural network texture enhancement in WebGPU compute
Metrics We Track
| Metric | Baseline (N64Wasm) | Phase 1 Target | Phase 2 Target |
|---|---|---|---|
| SM64 FPS (M1 Mac) | 45-55 | 60 | 60 (locked) |
| THPS FPS (M1 Mac) | 50-60 | 60 | 60 (locked) |
| Audio drops/minute | 5-10 | 5-10 | 0 |
| Input latency | ~30ms | ~25ms | ~15ms |
| Time to playable | 3-5s | 3-5s | <2s |
| WASM size | 2.5MB | 3MB | 3MB |
| Mobile FPS (iPhone 14) | 30-50 | 45-60 | 55-60 |