Minecraft Simple Voice Chat <-> Discord voice bridge + group music (Folia plugin + Node sidecar)
- JavaScript 57.4%
- Java 41%
- Dockerfile 1.1%
- Shell 0.5%
| deploy | ||
| plugin | ||
| sidecar | ||
| .gitignore | ||
| DEPLOY.md | ||
| DESIGN.md | ||
| GO-LIVE.md | ||
| LESSONS.md | ||
| LICENSE | ||
| PROTOCOL.md | ||
| README.md | ||
EternelVoiceHub
Bridges an in-game Simple Voice Chat general group ⇄ a Discord voice channel (both
directions, including Bedrock/web players via SimpleVoice-Geyser) and streams group music
into both. Targets a Luminol/Folia (Minecraft 1.21.11) server running SVC bukkit 2.6.20. The
moderation/recording backend described in the design notes is intentionally not included here.
Shape
Luminol server (Folia) host
┌──────────────────────────────┐ authed WS ┌────────────────────────────────┐
│ EternelVoiceHub plugin (Java) │◀──(docker)──▶ │ voice-bridge sidecar (node 22) │
│ · persistent SVC group │ │ · @discordjs/voice 0.19 +DAVE │
│ 'general' (fixed UUID) │ │ · one drift-corrected 20ms │
│ · mic tap (bounded ring) │ │ loop: paced send + inject │
│ · injector: per-connection │ │ · soft-limiter mix │
│ sendStaticSoundPacketTo │ │ · music (yt-dlp+cookies+deno │
│ (reaches Geyser web too) │ │ /ffmpeg loudnorm) │
│ · /voice /vmute /music │ │ · echo dedup via links.json │
│ · consent gate + kill switch │ │ · /mcmute · voice-status line │
└──────────────┬─────────────────┘ └───────────────┬────────────────┘
│ (plugin runs INSIDE the MC container) │ outbound UDP only
▼ ▼
SVC UDP Discord #general VC
Repo layout
plugin/— Folia plugin (Gradle Kotlin DSL + shadow, folia-api 1.21.11, voicechat-api 2.6.20).sidecar/— Node.js bridge (src/) + Dockerfile + tests (test/incl. the send-path testgate).deploy/—docker-compose.yml+.env.example.PROTOCOL.md— the plugin⇄sidecar wire protocol.DESIGN.md/DEPLOY.md/GO-LIVE.md— design notes, deploy runbook, go-live checklist.LESSONS.md— hard-won gotchas (read before touching audio or commands).
Build
- Plugin:
cd plugin && gradle clean shadowJar(JDK 25 → Java-21 bytecode). - Sidecar: build on an amd64 host (
docker build -t eternel-voice-bridge:v1 .) — an arm64 build's native opus/sodium modules won't run on an amd64 server.
Configuration & secrets
All secrets come from the environment — nothing is hardcoded or committed:
DISCORD_VOICE_TOKEN— a bot token for a separate Discord application (two gateway sessions on one token conflict). Put it in the host.envonly.HUB_SECRET— shared between the sidecar.envand the pluginconfig.ymlhub.secret.
See DEPLOY.md for the full deploy and LESSONS.md for the things that will bite you.
License
MIT — see LICENSE.