A local multiplayer karaoke fighting game where two players battle using their singing voices. Match the pitch of scrolling MIDI notes to deal damage to your opponent!
- 2 Players compete head-to-head on the same local network
- YouTube audio provides the backing track
- MIDI file defines the notes players must match
- LRC lyrics (optional) display synced lyrics
- Turn-based combat: Song is split into 4 segments, players alternate attacking
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LOCAL NETWORK โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Server (port 3001) โ
โ โโโ Socket.IO hub for real-time communication โ
โ โ
โ Host UI (port 3000/host) โ
โ โโโ Main display: YouTube, MIDI viz, fighters, HP โ
โ โ
โ Client 1 (port 3000/client?p=1) โ
โ โโโ Phone: Mic capture + pitch detection โ
โ โ
โ Client 2 (port 3000/client?p=2) โ
โ โโโ Phone: Mic capture + pitch detection โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- Node.js v18 or higher
- npm v9 or higher
- All devices on the same local network
- Microphone access on player devices
npm installnpm run devThis starts:
- Server on port 3001
- Client on port 3000
- Ngrok tunnels for mobile access from anywhere
The terminal will display the ngrok URLs that mobile devices can use to connect from any network (WiFi or cellular data).
The Host UI will show a green banner with copyable URLs for:
- ๐ฅ๏ธ Host UI
- ๐ค Player 1
- ๐ค Player 2
Mobile players can connect from anywhere using these ngrok URLs!
Note: The ngrok authtoken is already configured in the project.
If you only want localhost/LAN access without ngrok:
npm run dev:localAccess URLs (same WiFi only):
| Role | URL | Device |
|---|---|---|
| Host | http://localhost:3000/host |
Main display (TV/monitor) |
| Player 1 | http://<host-ip>:3000/client?p=1 |
Phone/tablet (same WiFi) |
| Player 2 | http://<host-ip>:3000/client?p=2 |
Phone/tablet (same WiFi) |
Note: Replace
<host-ip>with your computer's local IP address (e.g.,192.168.1.100)
On the Host UI:
- Paste a YouTube URL and click "Load"
- Upload a MIDI file (.mid) of the song
- (Optional) Paste LRC lyrics and click "Parse Lyrics"
On each Client UI:
- Click "Enable Microphone"
- Click "Ready Up"
Once both players are ready, the Host can click START BATTLE.
The song is divided into 4 equal segments:
- Segment 1: Player 1 attacks
- Segment 2: Player 2 attacks
- Segment 3: Player 1 attacks
- Segment 4: Player 2 attacks
- Perfect pitch (within 10 cents): 100% accuracy โ 20 damage
- Good pitch (within 25 cents): 70-100% accuracy โ 15-20 damage
- OK pitch (within 50 cents): 30-70% accuracy โ 9-15 damage
- Miss (>50 cents off): 0 damage
- Reduce opponent's HP to 0 โ KO Victory
- Song ends โ Higher score wins
- Tie score โ Higher accuracy % wins
ConuhacksX-VC/
โโโ server/
โ โโโ index.ts # Socket.IO server
โโโ pages/
โ โโโ HostPage.tsx # Host UI
โ โโโ ClientPage.tsx # Client/Player UI
โโโ components/
โ โโโ Fighter.tsx # Fighter character display
โ โโโ KaraokeHighway.tsx # Scrolling note visualization
โโโ services/
โ โโโ socketClient.ts # Socket.IO client wrapper
โ โโโ pitchDetection.ts # Autocorrelation pitch detection
โ โโโ midiParser.ts # MIDI file parser
โ โโโ lrcParser.ts # LRC lyrics parser
โ โโโ gameEngine.ts # Game logic & scoring
โโโ types.ts # TypeScript interfaces
โโโ constants.ts # Game constants
โโโ App.tsx # React router
โโโ index.tsx # Entry point
Edit constants.ts to adjust:
MAX_HP- Starting health (default: 100)BASE_DAMAGE- Minimum damage per hit (default: 5)MAX_BONUS_DAMAGE- Maximum bonus damage (default: 15)PERFECT_THRESHOLD_CENTS- Perfect pitch tolerance (default: 10)
- Place your
.midor.midifiles in theMidi Filesfolder in the project root - The Host UI will automatically detect and list them in a dropdown
- Select your MIDI file from the dropdown - no upload needed!
Alternatively, you can upload MIDI files directly through the Host UI using the file upload button.
You can find MIDI files for popular songs at:
Lyrics are fetched from or can be pasted from:
- lrclib.net - Search by song title
- Megalobiz
- Ensure the server is running (
npm run dev) - Check firewall settings for ports 3000 and 3001
- Grant microphone permissions in browser
- Use HTTPS or localhost (required for mic access)
- Check if another app is using the microphone
- Use your computer's local IP, not
localhost - Ensure all devices are on the same WiFi network
- Check firewall allows incoming connections
- Ensure you're running
npm run dev:mobile(not justnpm run dev) - Check that the ngrok URLs appear in the terminal output
- The Host UI will show a green banner with mobile URLs when ngrok is active
- If ngrok fails, check your internet connection
- Free ngrok accounts have session limits - tunnels may expire after a few hours
- Ensure mobile devices have internet access (can be on cellular data)
- Try opening the ngrok URL in a regular browser first to test
- Check that HTTPS warnings are accepted (ngrok uses HTTPS)
- Clear browser cache on mobile device
MIT License