An external game I made for my community of 400+ members. The idea is an integration of this service within a team's discord channel. The image is a super mario world inspired progress window that directs them through a customizable list of generated tasks across 4 worlds.
The result was a successful event with 100% uptime and great feedback from my community!
How does it work? Refer to the image below. In this example, the team (~15 members) must work together to obtain 6 Enhanced Crystal Teleport Seeds within in MMORPG "Oldschool Runescape". Once they're done, they submit their progress via this Discord bot and an admin approves it. Following this, they advance in the world, and a new image is generated showing their next "level".
- Progressive World System: 4 unique worlds with escalating difficulty and specialized mechanics
- Dynamic Tile Generation: Procedurally shuffled tile layouts for unknown, non-leakable fair competition
- Complex, Fun Trial Systems: Multi-stage key trials with branching paths and strategic decision-making
- Boss Encounters: High-stakes finale challenges requiring team coordination
- Smart Cooldown Management: Ranking-based skip timers to maintain competitive balance
- Slash Commands: Modern Discord.py implementation with autocomplete and validation
- Media Submission System: Seamless image upload and approval workflows
- Real-Time Notifications: Contextual embeds with rich formatting and visual feedback
- Persistent View Components: Stateful UI elements that survive bot restarts
- Containerized Deployment: Full Docker Compose stack for easy scaling and maintenance
- ** MongoDB Integration**: Optimized data models for complex team state management
- Dynamic Image Processing: On-demand board generation with custom fonts and overlays
- RESTful API Design: Clean separation between Discord bot and game logic
- Comprehensive Error Handling: Graceful degradation and user-friendly error messages
| Command | Description | Usage |
|---|---|---|
/board |
View current team board | Available in team channels only |
/submit |
Submit tile completion | /submit option:[1-5] image:[attachment] |
/skip |
Skip current tile | Cooldown varies by ranking |
| Command | Description | Usage |
|---|---|---|
/admin_register |
Register new team | /admin_register team_name user1 user2 ... |
/admin_view_board |
View any team's board | /admin_view_board @user |
/admin_force_complete |
Force complete tile | Emergency admin tool |
/admin_create_leaderboard |
Initialize leaderboard | Creates auto-updating message |
World 1: Mystic Cove → 18 tiles + 5 key trials + boss
World 2: Scarab's Labyrinth → 20 tiles + branching path trials + boss
World 3: Icy Path → 16 tiles + brazier lighting system + boss
World 4: Drakan's Shade → 20 tiles + void trials + final boss
- Player Submission: Image upload with option selection
- Admin Review: Reaction-based approval in dedicated channel
- State Update: Automatic progression and embed updates
- Notification: Team and leaderboard updates
- 1st Place: No skipping allowed (maintains competitive integrity)
- 2nd-5th Place: 16-hour skip cooldown
- 6th+ Place: 12-hour skip cooldown
SummerBingo/
├── discord_bot/ # Discord.py bot implementation
│ ├── cogs/ # Modular command handlers
│ ├── views/ # Persistent UI components
│ ├── utils/ # Helper functions
│ └── enums/ # Type definitions
├── game_service_api/ # Flask REST API
│ ├── controllers/ # API endpoints
│ ├── models/ # Data models
│ ├── services/ # Business logic
│ └── constants/ # Game configuration
├── planning/ # Game design documents
└── sample_api_requests/ # API testing suite
# Clean separation of concerns in cog architecture
class PlayerCog(commands.Cog):
@app_commands.command(name="submit")
async def submit(self, interaction, option: int, image: discord.Attachment):
# Handles complex submission logic with state validation# Auto-updating leaderboard with 3-minute refresh cycle
@tasks.loop(minutes=3)
async def update_leaderboard(self):
# Fetches latest team data and updates Discord embed# Dynamic embed generation based on game state
def get_embed_for_board(self, team_data: Dict, board_info: Dict):
# Returns appropriate embed type based on world and game state// Team Document Structure
{
_id: ObjectId,
team_name: String,
discord_channel_id: String,
players: [Player],
current_world: Number,
current_tile: Number,
game_state: Number, // 0=overworld, 1=key, 2=boss
completion_counter: Number,
last_rolled_at: Date,
// World-specific progression data
w1_shuffled_tiles: [Number],
w2_path_chosen: Number,
w3_braziers_lit: Number,
// ... extensive state tracking
}This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ for the Discord community
Showcasing modern Discord bot development practices and enterprise-grade architecture