Skip to content
Β 
Β 

Latest commit

Β 

History

292 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ§™ ROTMG PPE Discord Bot

A comprehensive Discord bot for managing competitions and more in Realm of the Mad God. You can track loot, complete quests, set points for items, and maintain a variety of leaderboards.

Having issues or confused? Check out our FAQ for common questions!

An admin guide can be found here, at the Administrator Guide!

Features

Player Features

  • Create & Manage PPEs: Create PPEs with automatic penalty calculations.
  • Season Management: Track whole season loot, beyond individual characters. Auto-updated with character loot.
  • Item Sets: Complete item sets automatically to earn bonus points and receive congratulations messages. Track completed sets per PPE.
  • Account Quests: Get item, shiny, and skin quests with automated completion tracking via /myquests, including board views for active and completed quest sets.
  • Team Functionality: You can be added to a team and be assigned a team-specific role with points automatically counted together.
  • Loot Tracking: Track and graphically view regular, shiny, and divine items and skins automatically or manually.
  • Sniffer Integration: Automatically connect in-game characters to your bot account via sniffer for automated logging.
  • Bonus System: Add character bonuses such as fame and maxed stats.
  • Point Management: Automated and adjustable point calculations with duplicate handling.
  • Personal Dashboard: Use /myinfo as a central menu for all player actions.

Admin Features

  • Player Management: One central dashboard for managing any player via /manageplayer.
  • Quest Management: View and reset quest progress for any contest player, configure quest mode (Global vs Team Shared), and manage global quest pools via /managequests.
  • Set Completion Configuration: Configure bonus points for completed item sets (separate for ST and UT) via /manageseason -> Manage Point Settings.
  • Team Management: Use /manageteams to create, update, and delete teams; assign members through /manageplayer
  • Global Season Management: Manage the overall season and the nitty gritty details of how the bot works with /manageseason. Note: this board is still a work in-progress.

Bot Setup

Note: These are instructions for self-hosting the bot. The bot typically costs less than a dollar a month to run, and you can try self-hosting it with Railway for free. If you have a large community, you may eventually need to pay for their Hobby plan ($5/month). Make sure to set up monetary limits on your hosting account if you decide to upgrade!

Prerequisites

  • A GitHub Account
  • A Discord Account

Step 1: GitHub Setup

  1. Fork the Repository
  • Click on the Fork button at the top right of this repository's webpage.
  • Click Create Fork.
  • This builds a personal copy of the project under your own GitHub account.
  1. Update main.py
  • In your newly created fork, click on the main.py file.
  • Click the pencil icon (labeled Edit this file) in the top right corner of the file view.
  • Locate the following lines of code:
# In main.py, update these IDs to your discord server's ID:
SERVER1_ID = 000000000000000000  # Replace with your server ID
SERVER2_ID = 00000000000000000000  # Add more servers as needed
SERVER3_ID = 00000000000000000000  # Add more servers as needed
  • Update the value of SERVER1_ID to match your Discord server's ID. (To find this, enable Developer Mode in your Discord advanced settings, then right-click your server icon and select "Copy Server ID".)
  • If you intend to only have the bot in one Discord server, you can delete the lines for SERVER2_ID and SERVER3_ID.
  • If you delete them, be sure to update the very next line of code to look exactly like this:
guilds = [discord.Object(id=SERVER1_ID)]
  • Click on Commit Changes at the top right, and then click Commit Changes again without changing any settings.

Tip: Whenever you want to update your bot to the latest version in the future, just go to your GitHub repository and click the Sync button!


Step 2: Getting a Discord Token & Invite Link

Before we can host the bot, we need to create it on Discord and get its "password" (the token).

  1. Create the Application
  • Head over to the Discord Developer Portal.
  • Log in, click New Application in the top right, give your bot a name, and click Create.
  1. Get Your Bot Token
  • On the left-hand menu, click on the Bot tab.
  • Under the bot's username, click the Reset Token button, then click Yes, do it!.
  • Click Copy to save your token. Keep this secret and save it somewhere safe! You will need it for the next section. (If you lose it, you'll have to come back and reset it again).
  • Optional but recommended: While on this page, scroll down to Privileged Gateway Intents and toggle on Message Content Intent, Server Members Intent, and Presence Intent, then save your changes.
  1. Generate Your Invite Link
  • On the left-hand menu, click on General Information (or OAuth2).
  • Find your Application ID (also called Client ID) and click Copy.
  • Take the link below and replace YOUR_CLIENT_ID_HERE with the number you just copied:

https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID_HERE&permissions=8&integration_type=0&scope=bot+applications.commands

  • Save this customized link! You will use it to invite the bot to your server after we finish hosting it in the next step.

Step 3: Hosting on Railway

For those unfamiliar with programming, Railway offers a simple way to host this bot 24/7 in the cloud with minimal setup. This is perfect if you don't want to run the bot on your personal computer.

Why Railway?

  • Affordable: Costs approximately $1–$2 per month (often less).
  • Reliable: 24/7 uptime for your bot.
  • Simple: No command-line experience needed.
  • Easy Deployment: Connect your GitHub account and deploy in minutes.

Railway Setup Instructions

  1. Create a Railway Account
  • Go to railway.app and sign up using your GitHub account.
  1. Create a New Project
  • Click Create New Project.
  • Select Deploy from GitHub repo.
  • Authorize Railway to access your GitHub account.
  • Select your forked rotmgppebot repository.
  1. Configure Environment Variables
  • In your Railway dashboard, click on your project, go to the Variables tab.
  • Add a new variable: Name it DISCORD_TOKEN and paste the bot token you saved earlier in the value box.
  • Add a new variable: Name it REALMSHARK_INGEST_HOST and set the value to 0.0.0.0.
  • (Optional) If you want the Sniffer integration to be allowed, add a third variable: Name it REALMSHARK_INGEST_ENABLED and set the value to true.
  1. Configure Settings
  • Navigate to the Settings tab. Keep all settings default except for the following:
  • Networking (For Sniffer Integration): If you enabled Sniffer, scroll to the Networking section. Type 8080 into the Port box and click Generate Domain. This creates your public web link (Endpoint) that you will give people later.
  • Build: Scroll to the Build section. Set the Builder to Dockerfile and set the Dockerfile Path to /Dockerfile.
  • Click the purple Deploy button.
  1. Create the Data Volume
  • This is critical: The bot stores all player records in a /data directory. If you skip this, player data will delete itself every time the bot restarts!
  • In the Railway project view, right-click on empty space (or click the 'New' button) and select Volume.
  • Attach it to your rotmgppebot service.
  • Go to your service settings, find the Volume section, and set the Mount Path to /data.
  • You will likely need to click Deploy again to apply these changes.
  1. Deploy
  • Railway will automatically deploy the bot. You can watch the build logs in the dashboard.
  • Once deployment completes successfully, your bot will start running!
  1. Add the Bot to Your Server
  • Paste the Invite Link you created in Step 2 into your web browser. (Note: You must have "Manage Server" permissions or be the owner of the Discord server to do this).
  • Select your server and authorize the bot.
  • Check your Discord server to make sure the bot is online.
  • Type /ppehelp in a channel to confirm it's responding!

Step 4: Initial Discord Setup

Now that the bot is in your server, you need to set up its basic functions:

  1. Create roles: Type /setuproles in your server to automatically create the required roles.
  2. Assign permissions: Give users access to the bot by using the /addplayer command to register contest members. You can use /manageplayer to give specific people access to management menus.

Step 5: Sniffer Setup (Optional)

Please note that this step assumes you've followed the regular Sniffer setup and can successfully use regular Sniffer. If you haven't, you can find the RealmShark sniffer here.

Note: The link to the custom sniffer extension for the bot can be found here. The original sniffer file will not work with it, so you will need to download the one attached below. You can also generate the file yourself.

  1. Verify Your Endpoint: Check if your bot's sniffer setup is working by opening a web browser and going to https://<your-railway-domain>/realmshark/health.
  • Make sure to replace <your-railway-domain> with the exact Networking Domain URL you generated in Railway Step 4! * If it works, the webpage should display: {"ok": true, "service": "realmshark-ingest"}.
  1. Enable in Discord: Go to your Discord server, type /managesniffer, and select Enable Sniffer.
  2. Set the Endpoint: Select Set Endpoint / Edit Endpoint and paste your ingest URL: https://<your-railway-domain>/realmshark/ingest. (Again, remember to replace the placeholder with your actual Railway domain).
  3. Download Required Files: Download the Sniffer File and the Loot CSV file here. Keep both of these files in the exact same folder on your computer.
  1. Use /mysniffer to see instructions on how to link your sniffer to the bot. Once you save the settings, you should be pinged by the bot!
  2. Customize Loot (Optional): You can edit your own version of rotmg_loot_drops_updated.csv by editing the file in your GitHub repository, saving it, and downloading it. This file determines the base point values of items and tells Sniffer which items to send to the bot. If an item drops but isn't being logged by the bot, it's likely missing from this CSV file!

Step 6: Image Recognition Setup (Optional)

If you don't want to set up the Sniffer, you can easily enable text-based image recognition instead.

Note: For the bot to recognize an item in a screenshot, the user must be actively hovering their mouse over the item in-game.

  1. Type /manageseason in your Discord server and click on Picture Suggestions.
  2. Enable it and select Add Channels. You can select any channel IDs where you want the bot to automatically scan images.
  3. Test it out! Post an in-game picture of an item in the designated channel, and the bot will reply with an option for you to accept the suggested item.

πŸ“‹ Command Reference

Player Commands

Command Description
/newppe Create a new PPE with class and penalty setup
/myinfo Open the reusable My Info menu (season loot, quests, character management, bonus editing)
/setactiveppe Switch between your PPE characters
/addloot Add items to your active PPE
/removeloot Remove items from your active PPE
/addbonus Add a bonus to your active PPE
/removebonus Remove a bonus from your active PPE
/addseasonloot Add a unique item to your season collection
/removeseasonloot Remove a unique item from your season collection
/myquests Open the same reusable quest menu available from My Info -> Show Quests

Admin Commands

Command Description
/addplayer Register a player for the contest
/addadmin Grant PPE Admin role to a member (server owner only)
/listplayers View all contest participants
/manageplayer Open the admin menu to manage a player's PPE, season loot, quests, team state, and roles (owner-only buttons for Make/Remove Admin)
/addlootfor Add items to any player's specific PPE
/removelootfrom Remove items from any player's PPE
/addbonusfor Add bonuses to any player's PPE
/removebonusfrom Remove bonuses from any player's PPE
/addpointsfor Manually add points to a specific PPE
/refreshpointsfor Recalculate points for a specific PPE
/refreshallpoints Fix all PPE point totals server-wide
/managequests View or update per-server quest targets (regular/shiny/skin), manage quest mode (Global/Team Shared), edit global quest pools, and run Reset All Quests from the menu
/manageseason Open season admin controls: step-by-step Reset Season, contests, picture suggestions, and point settings
/forcereset Emergency full data wipe for this guild (server owner only); use when you need a complete restart
/addseasonlootfor Add a unique item to another player's season collection
/removeseasonlootfrom Remove a unique item from another player's season collection

Legacy standalone commands for /myloot, /myppes, and /showseasonloot were retired in favor of /myinfo. The /myquests command and the My Info -> Show Quests button now use the same shared menu view implementation. When Team Shared Quests are disabled, each member's personal completed quests are rebuilt from team-completed quests they personally own in seasonal loot. Quest reset actions are now menu-integrated:

  • Use /myquests -> Reset Quests for self resets.
  • Use /manageplayer -> Show Quests -> Reset Quests for admin resets.
  • Use /managequests -> Reset All Quests for server-wide quest resets.

Season reset and recovery flow:

  • Use /manageseason -> Reset Season for the guided multi-step reset flow (each action has its own confirmation).
  • Use /manageseason -> Reset Season -> Reset Sniffer Information to selectively clear sniffer data.
  • Use /manageseason -> Manage Point Settings -> Edit Duplicate Item Points to set duplicate scoring reduction (set Point Reduction to 0 to disable duplicate points).
  • Use /forcereset only as an emergency full wipe when you want to delete all stored bot data for the guild and restart setup.

Team Commands

Command Description
/manageteams Open admin team management menu (create team, add/remove members, set leader, rename, delete, and view team leaderboard)
/myteam View your team members and their rankings (optional: specify team name)

Player team assignment/removal is now handled through /manageplayer in the Team actions panel. Standalone /removeppeadminrole was retired; use /manageplayer for admin-role toggles.

Utility Commands

Command Description
/leaderboard Open interactive leaderboard menu (PPE, Quest, Character by class, Season Loot, Team), all with paged embeds
/ppehelp Display all available commands
/listadmins View all PPE admins
/listroles Show server role information

Sniffer Commands

Command Description
/mysniffer Player sniffer dashboard: setup steps, generate token, unlink token, and open character configure panel
/managesniffer Admin sniffer dashboard: enable/disable, manage player sniffer view, manage/revoke tokens, change output channel, and reset all sniffer settings

RealmShark Character-Aware Routing

When Tomato sends loot with character_id, routing is policy-driven:

  1. If character_id is mapped to one of your PPEs, the bot logs through /addloot behavior on that mapped PPE.
  2. If character_id is mapped as seasonal, the bot logs through /addseasonloot behavior.
  3. If character_id is unseen/unmapped, the bot logs through /addseasonloot, pings the player, and stores a pending loot log (item + rarity + flags) for review.

Use /mysniffer and click Configure Characters to manage all character mappings and pending loot through an interactive panel. Start in Show All (all known characters) or Show Pending (only pending unmapped characters), then use the panel buttons to map characters to PPEs (which automatically applies pending loot), set characters as seasonal, clear pending logs, and navigate between entries. The panel is intuitive with Prev / Next buttons to cycle through characters, and all destructive actions require explicit confirmation. The panel/config view shows detected in-game character name/class when available, and mapping is class-validated: a character cannot be mapped to a PPE of a different class.

Pending unmapped character events are stored in per-player files so main guild config files stay compact.

Important Notes

  • Never commit your .env file with the bot token to GitHub
  • The /data volume is where all player records, loot tracking, and season data are storedβ€”never delete it
  • If you need to update the code, simply push changes to your GitHub repo and Railway will redeploy automatically
  • Check Railway's documentation for additional help

πŸ—οΈ Architecture

Data Structure

PlayerData
β”œβ”€β”€ is_member: bool
β”œβ”€β”€ active_ppe: int
β”œβ”€β”€ team_name: str (optional)  # Name of team player is on
β”œβ”€β”€ season_item_history: Dict[str, List[int]]  # season item variant key -> sorted timestamps
β”œβ”€β”€ quests: QuestData
β”‚   β”œβ”€β”€ current_items: List[str]
β”‚   β”œβ”€β”€ current_shinies: List[str]
β”‚   β”œβ”€β”€ current_skins: List[str]
β”‚   β”œβ”€β”€ completed_items: List[str]
β”‚   β”œβ”€β”€ completed_shinies: List[str]
β”‚   └── completed_skins: List[str]
└── ppes: List[PPEData]
    β”œβ”€β”€ id: int
    β”œβ”€β”€ name: ROTMGClass
    β”œβ”€β”€ points: float
    β”œβ”€β”€ completed_sets: List[str]  # Names of completed item sets
    β”œβ”€β”€ loot: List[Loot]
    β”‚   β”œβ”€β”€ item_name: str
    β”‚   β”œβ”€β”€ quantity: int
    β”‚   β”œβ”€β”€ divine: bool
    β”‚   └── shiny: bool
    └── bonuses: List[Bonus]
        β”œβ”€β”€ name: str
        β”œβ”€β”€ points: float
        β”œβ”€β”€ repeatable: bool
        └── quantity: int

Seasonal ownership, rarity spread, and time-based summaries are derived from `season_item_history` at read time.
When loot rarity is missing or `None`, it is treated as `common`.

TeamData
β”œβ”€β”€ name: str          # Team name
β”œβ”€β”€ leader_id: int     # Discord user ID of leader
└── members: List[int] # Discord user IDs of all members

πŸ”§ Configuration

Data Files

  • rotmg_loot_drops_updated.csv: Item point values
  • bonuses.csv: Available achievement bonuses
  • {guild_id}_{user_id}_loot_records.json: Player data storage (one file per player)
  • {guild_id}_teams.json: Team data storage (per guild)
  • {guild_id}_config.json: Per-server settings storage (quest target counts and future config)
  • {guild_id}_{user_id}_realmshark_pending.json: Pending unmapped character logs for each player

Role Requirements

  • PPE Player: Can create PPEs and manage own data
  • PPE Admin: Full administrative access to all features

🎯 Point System

Base Points

  • Items have base point values from rotmg_loot_drops_updated.csv.
  • Divine items: 2x multiplier
  • Shiny items: Special point values from separate entries

Duplicate Handling

  • First item: Full point value
  • Additional copies: Base value multiplied by the configurable Point Reduction setting (default 0.5)
  • Disable duplicates: Set Point Reduction to 0 in /manageseason -> Manage Point Settings -> Edit Duplicate Item Points
  • Removal: Correctly calculates which points to subtract

Penalties

  • Pet Level: -0.25 points per level
  • Exalts: -0.5 points per exalt
  • Loot Boost: -2 points per 1% boost
  • In-Combat Reduction: -10 points per 0.2 seconds

Set Completion Bonuses

  • What Are Sets: Item sets are collections of 4 special items (Weapon, Ability, Armor, Ring). When you collect all 4 items from a set, you complete the set.
  • Auto-Detection: The bot automatically detects when a set is completed as soon as you log the final item via /addloot, sniffer, or /submitloot.
  • Congratulations Message: When a set is completed, a public congratulation message is posted to the channel.
  • Point Rewards: Each completed set grants configurable bonus points (default: 0). Admins can set different points for ST (Standard) and UT (Unique) sets via /manageseason -> Manage Point Settings -> Manage Set Completion Points.
  • One-Time Per PPE: You only get the bonus once per set per PPE. Completing the same set on a different PPE grants the bonus again.
  • Configuration: Admins can manage set bonus points through the interactive menu, with separate sections for ST and UT sets. Use the form to set points per set (e.g., Golden Archer Set=50) or reset all to 0.

οΏ½ Team System

Overview

Teams enable collaborative PPE competition where multiple players combine their efforts for group rankings.

Key Features

  • Team Creation: Admins create empty teams from /manageteams and assign leader/member later
  • Member Management: Admins can add/remove players through /manageplayer
  • One Team Per Player: Players cannot be on multiple teams simultaneously
  • Team Leaderboard: Teams ranked by combined points (using each member's best PPE)
  • Team Viewer: /myteam shows all team members ranked by their best PPE points
  • Automatic Roles: Discord roles created automatically for each team
  • Team Renaming: Admins can rename teams from /manageteams
  • Season Reset: All teams are deleted when season resets
  • Robust Removal: Team removal works even for players no longer in contest records when handled from /manageplayer

Team Point Calculation

  • Each team member's highest-scoring PPE is counted toward the team total
  • Team points = Sum of all members' best PPE points
  • Members added/removed update totals automatically
  • Team leader can be viewed on the team leaderboard

Viewing Teams

  • /manageteams: Admin-only menu includes a Team Leaderboard button with paged rankings
  • /myteam: View your team members and their individual rankings (or specify a team name to view any team)

Player Removal Behavior

  • /manageplayer: Removes players from teams and/or contest data from a single admin panel, and exposes owner-only PPE Admin add/remove actions

Permissions

  • Admin Only: Create teams, delete teams, set leaders, rename teams, force remove players from teams
  • All Players: View team leaderboard, view own team with /myteam

Option Signature Format

Most non-regular PPEs are represented as a normalized signature like:

pet:yes|tiered:yes|minimum:legendary|shiny:no|enforce_shiny_rarity:no|duo:no

Fields:

  • pet: yes means pets allowed, no means no-pet rules.
  • tiered: yes means tiered items allowed, no means UT-only style rules.
  • minimum: minimum rarity floor (common, uncommon, rare, legendary, divine, plus internal all_shinies_allowed).
  • shiny: yes means shiny-only mode.
  • enforce_shiny_rarity: whether the minimum rarity also applies to shiny items.
  • duo: yes for duo mode, no for solo.

Full Label vs Compact Label

The bot may show:

  • A full label (for example Legendary or Shiny PPE).
  • A compact label (for example All_SH|LPE, DPE, Duo NPE) used in summaries and Type Multiplier (...) text.

Compact labels are generated from options, not only from static preset names, so custom combos can still produce meaningful shorthand.

All_SH Prefix Rules

All_SH|... means: minimum rarity applies to non-shiny items, while shiny items are still all allowed.

This prefix appears only when all of the following are true:

  • shiny:no
  • minimum is legendary or divine
  • enforce_shiny_rarity:no

Examples:

  • minimum:legendary, enforce_shiny_rarity:no -> All_SH|LPE
  • minimum:legendary, enforce_shiny_rarity:yes -> LPE
  • minimum:divine, enforce_shiny_rarity:no -> All_SH|DPE
  • minimum:divine, enforce_shiny_rarity:yes -> DPE

For minimum:rare (or lower), enforce behavior does not change label style. Internally, low minimum rarities normalize to enforce_shiny_rarity:yes.

Duo PPE Labels

Duo mode is a modifier on top of a base PPE ruleset.

How duo labels are shown:

  • The bot first computes the non-duo compact label.
  • Then it prefixes with Duo .

Examples:

  • Base PPE + duo -> Duo PPE
  • Base NPE + duo -> Duo NPE
  • Base All_SH|LPE + duo -> Duo All_SH|LPE

Multiplier behavior mirrors this model: base rules are resolved first, then duo multiplier is applied on top.

οΏ½πŸ› οΈ Development

Project Structure

rotmgppebot/
β”œβ”€β”€ main.py                    # Bot entry point
β”œβ”€β”€ dataclass.py              # Data structures
β”œβ”€β”€ requirements.txt          # Dependencies
β”œβ”€β”€ menus/                    # Shared menu/view architecture
β”‚   β”œβ”€β”€ myinfo/               # My Info menu package (home/season/character/common)
β”‚   β”œβ”€β”€ myquests/             # My Quests menu package (view/common)
β”‚   └── menu_utils/           # Reusable owner/confirm menu components
β”œβ”€β”€ slash_commands/           # Command implementations
β”œβ”€β”€ utils/                   # Utility modules
β”‚   β”œβ”€β”€ player_records.py    # Data persistence
β”‚   β”œβ”€β”€ calc_points.py       # Point calculations
β”‚   β”œβ”€β”€ autocomplete.py      # Dynamic suggestions
β”‚   β”œβ”€β”€ embed_builders.py    # Discord embeds
β”‚   └── role_checks.py       # Permission validation
└── data/                    # CSV and JSON files

Menu Reuse Design

  • Slash commands stay thin and delegate to reusable menu modules in menus/.
  • The same MyQuestsView is used by both /myquests and /myinfo -> Show Quests.
  • My Info and My Quests are split into focused submodules so each button path maps to a dedicated menu/view class instead of one bloated file.

Adding New Commands

  1. Create command file in slash_commands/
  2. Import in main.py
  3. Register with Discord using decorators
  4. Add to help system in ppehelp_cmd.py

Database Schema Updates

Use the migration system in player_records.py to safely update data structures without losing existing player data.

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with proper error handling
  4. Test thoroughly with edge cases
  5. Submit a pull request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Realm of the Mad God community for inspiration and feedback
  • Discord.py developers for the excellent library
  • Contributors who help improve the bot

πŸ“ž Support

  • Issues: Report bugs on GitHub Issues
  • Discord: Join our community server for help and updates
  • Documentation: Check the /ppehelp command for in-bot guidance

Made with ❀️ for the RotMG PPE community

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages