Guides

Discord Bots with open-source tools

This guide outlines the architecture for a bi-directional bridge between a legacy MUD server and a Discord community. It focuses on using a middleware bot to handle Telnet-to-Discord translation, ensuring stability without requiring deep modifications to the MUD's core socket handling.

4-6 hours5 steps
Discord Bots with open-source tools illustration
Placeholder illustration shown while custom artwork is being produced.
1

Establish the Middleware Architecture

Do not connect the MUD directly to Discord's API. Instead, create a middleware service that acts as a Telnet client to the MUD and a Bot client to Discord. This prevents MUD crashes if the Discord API experiences latency and allows for easier restarts of the bridge without dropping game connections.

bridge-core.js
const net = require('net');
const { Client, GatewayIntentBits } = require('discord.js');

const mudClient = new net.Socket();
const discordClient = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });

mudClient.connect(4000, '127.0.0.1', () => {
  console.log('Connected to MUD');
});

⚠ Common Pitfalls

  • Binding the bridge to the same port as the MUD.
  • Failing to handle 'ECONNRESET' when the MUD reboots for a hotfix.
2

Filter and Sanitize ANSI Escape Codes

MUDs transmit color via ANSI escape sequences (e.g., ^[[31m). Discord does not support these. Your bridge must strip or convert these sequences before sending strings to the Discord API to avoid raw control characters appearing in chat.

parser.js
function stripAnsi(text) {
  return text.replace(/[\u001b\u009b][[\]()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
}

⚠ Common Pitfalls

  • Incomplete regex patterns leaving trailing brackets.
  • Accidentally stripping legitimate brackets used in MUD syntax like [Group].
3

Implement Webhook for Player Identity

Using a standard Bot profile for all messages makes the chat hard to follow. Use Discord Webhooks to dynamically update the username and avatar of the sender to match the in-game player's name.

webhook-sender.js
async function sendToDiscord(channel, playerName, message) {
  const webhooks = await channel.fetchWebhooks();
  const bridgeHook = webhooks.first();
  await bridgeHook.send({
    content: message,
    username: playerName,
    avatarURL: `https://api.dicebear.com/7.x/bottts/png?seed=${playerName}`
  });
}

⚠ Common Pitfalls

  • Creating a new webhook for every message (hits Discord rate limits).
  • Hardcoding webhook URLs in public repositories.
4

Configure Rate Limit Buffering

MUDs generate text faster than Discord's 5-messages-per-5-seconds limit. Implement a message queue that aggregates small lines into a single Discord message or delays transmission during high-traffic combat events.

buffer.js
let messageQueue = [];
setInterval(() => {
  if (messageQueue.length > 0) {
    const batch = messageQueue.splice(0, 5).join('\n');
    discordChannel.send(batch);
  }
}, 2000);

⚠ Common Pitfalls

  • Infinite loops where Discord messages are relayed back to the MUD and then back to Discord.
  • Buffer overflows during 'spam' events if the queue isn't capped.
5

Secure the In-Game Bridge Account

The bridge connects to the MUD like a player. Create a specific 'Bridge' user in the MUD with restricted permissions. Ensure this user can only see specific channels (e.g., OOC, Gossip) and cannot be targeted by NPCs or players.

⚠ Common Pitfalls

  • Leaving the bridge account vulnerable to 'force' or 'teleport' commands.
  • Mapping staff-only channels to public Discord channels by mistake.
  • Allowing the bridge user to trigger game commands via Discord without strict role-based access control.

What you built

A successful Discord-MUD integration requires a robust middle layer that handles the disparate protocols of legacy Telnet and modern REST APIs. By implementing ANSI stripping, webhook identity mapping, and rate-limit buffering, you can extend your MUD's community reach without compromising game performance or security.