Guides

Community Guides & Mentors with Guide handbooks

Deploying a sustainable mentor program requires database architecture for bidirectional player relationships, automated routing of help requests, and circuit breakers to prevent volunteer burnout. This guide assumes you have administrative access to your MUD codebase (Evennia, CoffeeMUD, Diku derivative, or custom engine) and a SQL or document database for player metadata. Implementation covers in-game flag systems, external chat bridges, state machine ticketing, and retention telemetry without impacting game performance.

3-4 weeks8 steps
Community Guides & Mentors with Guide handbooks hero illustration
1

Design Database Schema for Mentor-Mentee Relationships

Create tables or object attributes to track bidirectional assignments. Include: mentor_uuid (indexed), mentee_uuid (indexed), assigned_date (timestamp), status (enum: active/paused/completed), session_log_ref (foreign key), and disengagement_reason (text). Implement foreign key constraints with ON DELETE SET NULL to handle player deletion without orphaning records. Add composite index on (mentor_uuid, status) for fast lookup of active assignments.

⚠ Common Pitfalls

  • Storing relationships in flat files without referential integrity
  • Not indexing the mentee lookup field causing O(n) scans when checking if a player already has a mentor
2

Implement In-Game NEWBIE Flag and HELP Routing

Modify player object initialization to set is_newbie=true for accounts under 5 hours total playtime or characters below level 5 (configure thresholds in database, not code). Override the HELP command to check this flag: if true, duplicate the message to a dedicated mentor-alert channel with higher priority weighting and prepend [NEWBIE] tag. Ensure the flag auto-clears upon threshold breach via login hook or periodic batch job.

commands/help.py
def cmd_help(caller, args):
    msg = f"Help requested by {caller.name}: {args}"
    
    # Route to standard channel
    CHANNELS['help'].msg(msg)
    
    # Check newbie status from DB, not session cache
    if caller.db.is_newbie:
        CHANNELS['mentor-alert'].msg(f"[NEWBIE][PRIORITY] {msg}")
        # Log for metrics
        TicketLog.create(player=caller, ticket_type='newbie_help')

⚠ Common Pitfalls

  • Hardcoding newbie thresholds in source requiring reboots to adjust
  • Routing every help request to mentors without spam filtering causing notification fatigue
3

Build Ticket Queue State Machine

Implement a ticketing table with states: OPEN → CLAIMED → RESOLVED → ARCHIVED. Required fields: ticket_id (UUID), claimant_id (mentor UUID, nullable), opened_date (indexed), claimed_date, resolved_date, resolution_type (enum: solved/escalated/abandoned/no_response), and content (text). Create a view or API endpoint that mentors query for oldest OPEN tickets (SELECT * FROM tickets WHERE status='OPEN' ORDER BY opened_date ASC LIMIT 10). Prevent multiple claims via row-level locking or atomic UPDATE statements checking status='OPEN' before assignment.

⚠ Common Pitfalls

  • Allowing mentors to hard-delete tickets instead of marking resolved
  • Not archiving resolved tickets leading to table bloat and slow queries after 6 months
4

Deploy Discord-to-MUD Bridge for Async Support

Create a webhook endpoint receiving messages from Discord #newbie-help channels. Map Discord user IDs to MUD accounts via an external_accounts table storing (mud_uuid, platform, external_id, oauth_token). When a Discord message arrives, check if the user is online in-game; if yes, route to their MUD mail or immediate notification. If offline, store as pending ticket linked to their account for next login. Implement rate limiting (5 requests/minute per Discord user) to prevent spam injection.

bridge/discord_webhook.py
@app.route('/webhook/discord', methods=['POST'])
def handle_discord():
    data = request.json
    discord_id = data['user_id']
    
    # Lookup MUD account
    account = ExternalAccount.objects.get(
        platform='discord', 
        external_id=discord_id
    )
    
    # Check online status via session cache
    if account.mud_uuid in ONLINE_PLAYERS:
        notify_immediate(account.mud_uuid, data['content'])
    else:
        Ticket.create(
            player_id=account.mud_uuid,
            content=data['content'],
            source='discord_bridge',
            status='OPEN'
        )

⚠ Common Pitfalls

  • Exposing webhook endpoints without IP whitelisting or HMAC signature validation
  • Storing Discord OAuth tokens in plain text instead of encrypted fields
5

Automate Mentor Vetting Workflow

Build a promotion pipeline triggered by criteria: account_age > 30 days, total_playtime > 100 hours, help_points > 50 (tracked via existing help command usage), zero active disciplinary flags. When criteria met, atomically update role to 'MENTOR_CANDIDATE' granting access to training documentation channels but not live tickets. Require admin approval (manual review of recent chat logs) before transitioning to 'ACTIVE_MENTOR' status. Log all transitions in audit table with admin_uuid and timestamp.

⚠ Common Pitfalls

  • Auto-promoting candidates without human review of communication logs
  • Not checking for alternate accounts circumventing playtime requirements via multi-boxing
6

Implement Load Balancing and Burnout Circuit Breakers

Enforce hard limits via database constraints or application logic: max_concurrent_mentees = 5, max_tickets_per_week = 20, mandatory_cooldown_hours = 48 after 10 consecutive interactions. When limits hit, atomically set mentor status to 'UNAVAILABLE' and trigger redistribution of assigned mentees via round-robin to other active mentors. Create admin alerts when >30% of active mentors hit limits simultaneously, indicating systemic overload.

sql/circuit_breaker.sql
-- Circuit breaker check triggered on ticket claim
SELECT COUNT(*) as active_count 
FROM mentor_sessions 
WHERE mentor_id = $1 AND status = 'active';

-- If active_count >= 5, reject claim
-- Check weekly load
SELECT COUNT(*) as weekly_tickets
FROM ticket_log
WHERE claimant_id = $1 
AND created_at > NOW() - INTERVAL '7 days';

-- If weekly_tickets >= 20, set unavailable
UPDATE mentors 
SET status = 'UNAVAILABLE', 
    circuit_tripped_at = NOW() 
WHERE uuid = $1;

⚠ Common Pitfalls

  • Circuit breakers triggering only after burnout manifests as mentors quitting
  • Failing to redistribute mentees automatically when a mentor becomes unavailable
7

Deploy Retention Metrics Pipeline

Schedule daily batch jobs (cron or Celery) calculating: 7-day retention rate of mentored vs non-mentored cohorts, median time-to-first-help for new players, mentor churn rate (tickets handled vs deactivation), and escalation rate (tickets moved to admin tier). Store results in separate analytics schema or time-series database (InfluxDB/TimescaleDB) to prevent SELECT queries from locking production game tables. Expose dashboard via Grafana or similar querying the analytics replica, never the production database.

⚠ Common Pitfalls

  • Running analytics aggregations on production game database during peak hours causing lag
  • Tracking personally identifiable information in analytics warehouses violating GDPR/CCPA
8

Architect Graceful Handoff and Session Persistence

Ensure mentor-mentee bonds survive game reboots. Serialize active sessions to Redis or disk (JSON/MsgPack) with TTL of 7 days before shutdown. On startup, restore sessions and validate mentor still exists and is active; if not, redistribute mentees immediately. Implement 'handoff' command allowing mentors to transfer specific mentees to colleagues with full context transfer (chat history, current quest status, struggling concepts). Store handoff logs for quality review.

⚠ Common Pitfalls

  • Losing session data during unexpected crashes due to write-through caching only
  • Not validating mentor existence before restoring sessions causing null pointer exceptions on first interaction

What you built

A production mentor system requires treating volunteer capacity as a constrained resource with circuit breakers, not an infinite pool. Prioritize database referential integrity for mentor-mentee links to prevent orphaned assignments during player deletion. Keep analytics processing off the critical path of game commands to maintain tick rate performance. Monitor the ratio of mentors to new players weekly; when it drops below 1:20, pause newbie marketing until recruitment catches up. Test handoff procedures with simulated crashes before production deployment.