How do you control multiple Minecraft bots in real-time from a web browser? We needed instant feedback.no lag, no polling, no page refreshes.
Our Solution: Dual WebSocket Architecture
We built a real-time control center at mc.craycon.no:4000

and a live 3D viewer at mc.craycon.no:3000, both powered by WebSockets.

Viewer Server (Socket.IO)const io = socketIo(server, { path: '/socket.io' })
io.on('connection', socket => {
const worldView = new WorldView(bot.world, 6, bot.entity.position, socket)
bot.on('move', () => socket.emit('position', { pos: bot.entity.position, yaw: bot.entity.yaw }))
})
Control Server (Native WebSocket)const { WebSocketServer } = require('ws')
const wss = new WebSocketServer({ server })
setInterval(() => {
const payload = { bots: Array.from(bots.values()).map(buildTelemetry) }
broadcast({ type: 'telemetry', payload, ts: Date.now() })
}, 500)
What We Built
- Live telemetry: Health, position, inventory updates stream to all connected clients
- WASD controls: Keyboard input via WebSocket, bot movement in <50ms
- Mouse look: Right-click drag translates to bot camera rotation instantly
- Multi-bot support: Switch between bots, all synced in real-time
- 3D world viewer: Watch your bot’s perspective update live via prismarine-viewer The Magic When you press W in the browser, it fires a WebSocket message. The server calls bot.setControlState(‘forward’, true). The bot moves. The 3D viewer updates.
All in real-time, no HTTP requests, no polling. Try it yourself:
http://mc.craycon.no:4000 (Control Center) | http://mc.craycon.no:3000 (Bot Viewer)
PS: the secret auth token is YOLO_SWAG