Ride the music. Beat the track.
Hackathon Project — May 22–23, 2026
SoundSurf is a music-driven 3D racing game inspired by AudioSurf. Drop in any song and the game analyzes the BPM, beat timing, energy, and mood to generate a unique race track. Curves, obstacles, speed, and colors all reflect the music in real time.
| Name | Role | Tools |
|---|---|---|
| Ayush Rabadia | Backend Engineer | Express · WebSocket · Jamendo API |
| Wai Lok Daniel Tam | Algorithm Engineer | WebAssembly · DSP · Beat Detection |
| David Newman | Frontend Engineer | React · R3F · Three.js · Zustand |
1. Audio Analysis
- User searches for a track or uploads an audio file
- Jamendo API returns full track MP3 URL, BPM, and genre tags — no OAuth needed
- WASM processor runs FFT and beat detection on the raw audio
- Beat grid (array of timestamps) is sent to the backend
2. Track Generation
- Backend converts BPM + beat grid into a track config
- Spline control points define where the road curves
- Obstacles are placed at beat-precise timestamps
- Speed ramps up over the song length
- Colors are chosen based on mood and energy
3. 3D Rendering
- React Three Fiber renders a procedural CatmullRom spline track
- Player car advances at BPM-driven speed
- Obstacles spawn on beats — dodge them to score
- Score and streak tracked in real time
| Frontend | Backend | Audio / DSP | Dev Tools |
|---|---|---|---|
| React + Vite | Node.js | Web Audio API | VS Code |
| React Three Fiber | Express.js | WebAssembly | Git + GitHub |
| Three.js | WebSocket (ws) | Emscripten | nodemon |
| Zustand | dotenv | Jamendo API | Postman |
| Tailwind CSS | uuid | FFT (C) | npm |
- Node.js v20+
- npm v10+
- Jamendo Developer account (free, no credit card)
git clone https://github.com/dnew0101/SoundSurf.git
cd SoundSurfcp server/.env.example server/.envFill in your Jamendo client ID in server/.env:
Get your free client ID at developer.jamendo.com — takes 2 minutes.
cd server
npm install
npm run devServer runs at http://localhost:8000
Health check: http://localhost:8000/api/health
cd client
npm install
npm run devApp runs at http://localhost:5173
cd server
node tests/spotify.test.js| File | What it does |
|---|---|
server/index.js |
Entry point — starts Express, loads routes and WebSocket |
server/middleware/cors.js |
Blocks requests from unauthorized origins |
server/middleware/auth.js |
Validates Bearer tokens on protected routes |
server/routes/game.js |
Endpoints for sessions, track generation, scores |
server/routes/music.js |
Proxies all Jamendo API calls |
server/routes/scores.js |
Leaderboard read and write endpoints |
server/controllers/gameController.js |
Session management, scoring, difficulty curve |
server/controllers/trackController.js |
Converts BPM + beat grid into 3D track config |
server/controllers/jamendoController.js |
Track search, featured tracks, full MP3 URLs |
server/websocket/gameSocket.js |
Real-time score sync and beat events |
server/services/scoreService.js |
Reads and writes scores to JSON file |
server/tests/spotify.test.js |
Mock tests for all music API routes |
client/src/App.jsx |
Root React component, toggles Menu and GameCanvas |
client/src/components/GameCanvas.jsx |
R3F Canvas — 3D scene, camera, lighting |
client/src/components/RaceTrack.jsx |
Procedural spline geometry from track config |
client/src/components/PlayerCar.jsx |
Player vehicle moving along the spline |
client/src/components/BeatObstacle.jsx |
3D obstacles spawned at beat timestamps |
client/src/hooks/useAudioAnalysis.js |
WASM bridge — returns BPM and beat grid |
client/src/hooks/useGameLoop.js |
R3F frame loop — moves player, checks collisions |
client/src/store/gameStore.js |
Zustand — score, speed, beat events, session state |
wasm/audio_processor.c |
FFT + onset detection compiled to WebAssembly |
wasm/beat_detector.c |
Rhythmic grid extraction from FFT output |
wasm/fft.c |
Fast Fourier Transform in C |
POST /start— create a new game sessionPOST /generate-track— convert BPM + beat grid to track configPOST /score— submit final scoreGET /session/:id— get session stateDELETE /session/:id— end a session
GET /search?q=— search Jamendo for a trackGET /track/:trackId— get a single track with full MP3 URLGET /featured— get top 20 popular tracks for the main menu
GET /leaderboard— top 10 scoresGET /track/:trackId— scores for a specific trackPOST /— save a new score
SoundSurf · Hackathon 2026 · Ayush Rabadia · Wai Lok Daniel Tam · David Newman