KryptixBot is a Discord bot that enables server administrators to create and run custom cryptic hunts (puzzle/riddle competitions) within their Discord servers. Players progress through sequential levels by solving riddles, puzzles, and cryptographic challenges. The bot tracks individual progress, awards points, provides hints with penalties, and maintains server-wide leaderboards.
Preferred communication style: Simple, everyday language.
- Make your own hunt with easy to use JSON format (easy to format with an llm)
- support for hints & images
- Leaderboard tracking based on points
- admin suite for managing hunts
- statistical tracking for players
- takes 1/2 minutes to selfhost
- literally sqlite so no need for a database server
Runtime Environment
- Node.js v16+ with JavaScript
- Discord.js v14.18.0 for Discord API interactions
- SQLite3 v5.1.7 for local data persistence
- dotenv v17.2.0 for environment configuration
Architectural Pattern
The application follows a modular, event-driven architecture organized around Discord bot patterns:
Entry Point (index.js)
- Minimal bootstrap layer that initializes database connections
- Registers Discord event listeners (ready, interactionCreate, messageCreate)
- Implements graceful shutdown handlers for SIGINT, SIGTERM, and uncaught exceptions
- Ensures database cleanup on process exit
Modular Organization (src/ directory structure)
client.js: Discord client initialization with gateway intents (Guilds, GuildMessages, MessageContent)config/: Centralized configuration management using environment variables and owner whitelistdatabase/: Database connection pooling and all CRUD operationscommands/: Slash command definitions using Discord.js SlashCommandBuilder patternhandlers/: Event handlers separated by interaction type (slash commands vs prefix commands)utils/: Validation logic and permission checking utilitiesdata/: Static gamification content (trivia challenges, hint examples)
Event-Driven Design
The bot responds to three primary Discord events:
ready: One-time initialization for command registrationinteractionCreate: Handles slash commands and button interactions (player-facing features)messageCreate: Handles prefix commands (admin-only features withkprefix)
Command Architecture
Two distinct command systems serve different user roles:
Slash Commands (Player & Admin)
/hunt- Display current level question/answer- Submit answer for current level/hint- Request hint with point penalty/leaderboard- View server rankings/progress- Check personal progress/previous- View completed questions/setup-hunt- Admin: Upload hunt JSON file/hunt-status- Check active hunt status/help- Display bot usage information
Prefix Commands (Owner-only)
k!help- Admin command referencek!answers- View all answers for debuggingk!leads- Display hint strategy examplesk!fun- Show gamification activitiesk!add <user> <points>- Manually adjust user pointsk!pause- Pause the hunt (blocks all player commands)k!con- Continue/resume the hunt
Permission Model
Three-tier permission system:
- Bot Owners: Hardcoded whitelist in
owners.json(5 users) with access to prefix commands - Server Administrators: Users with Administrator permission or server ownership can use
/setup-hunt - Players: All users can access gameplay slash commands
SQLite Database (data/hunt.db)
The application uses a single-file SQLite database with the following schema:
Tables
-
guild_hunts- Hunt configurations per Discord serverguild_id(PRIMARY KEY): Discord server identifierhunt_data(TEXT/JSON): Complete hunt structure (questions, answers, hints, points)created_by(TEXT): User ID who created the huntcreated_at(INTEGER): Unix timestampactive(INTEGER): Boolean flag (1 = active, 0 = inactive)
-
user_progress- Individual player progress trackinguser_id(TEXT): Discord user identifierguild_id(TEXT): Discord server identifierlevel(INTEGER): Current level numberpoints(INTEGER): Total points earnedhint_used(TEXT): Comma-separated list of levels where hints were usedstart_time(INTEGER): Unix timestamp of hunt start- PRIMARY KEY: (user_id, guild_id)
-
completed_levels- History of completed levelsuser_id(TEXT): Discord user identifierguild_id(TEXT): Discord server identifierlevel_id(INTEGER): Completed level numbercompleted_at(INTEGER): Unix timestamppoints_earned(INTEGER): Points awarded for this level- FOREIGN KEY: (user_id, guild_id) references user_progress
-
leaderboard- Cached leaderboard datauser_id(TEXT): Discord user identifierguild_id(TEXT): Discord server identifierusername(TEXT): Display namepoints(INTEGER): Total pointslevel(INTEGER): Current levelstart_time(INTEGER): Hunt start timestamp
-
hunt_paused- Hunt pause state per serverguild_id(TEXT PRIMARY KEY): Discord server identifierpaused(INTEGER): Boolean flag (1 = paused, 0 = active)paused_by(TEXT): User ID who paused/resumedpaused_at(INTEGER): Unix timestamp
Data Flow
Hunt creation flow:
- Admin uploads JSON file via
/setup-hunt - Validation checks structure, field types, and constraints
- Hunt data stored as serialized JSON in
guild_huntstable - Previous hunt data (if any) is deleted, resetting all player progress
Gameplay flow:
- Player uses
/huntto retrieve current question from hunt JSON - Player submits answer via
/answer - Answer validation (case-insensitive, supports multiple correct answers)
- On correct answer:
user_progressupdated (increment level, add points)completed_levelsrecord insertedleaderboardcache updated
- On wrong answer: No state change, player retries
Hunt Data Format
Hunts are defined in JSON files with this structure:
{
"name": "Hunt Name",
"description": "Hunt description",
"levels": [
{
"id": 1,
"question": "Question text",
"answer": ["answer1", "answer2"], // Array or single string
"hint": "Hint text",
"points": 100,
"image": "https://optional-image-url.com/image.png"
}
]
}Validation Rules
- Maximum 100 levels per hunt
- Level IDs must be unique and between 1-1000
- Questions limited to 2000 characters
- Answers can be array (multiple accepted answers) or string (single answer)
- Points must be positive integers
- Image URLs optional
Hint System
Dynamic penalty calculation:
- Base penalty: 20% of level points
- Scaling penalty: +5% per level (capped at 50%)
- Formula:
min(20 + (level - 1) * 5, 50)% - Hints tracked per-user to prevent multiple penalties on same level
Point System
- Points defined per level in hunt JSON
- Reduced by hint penalty if hint requested
- Manually adjustable by bot owners via
k!addcommand - Leaderboard ranked by total points (tiebreaker: completion time)
Progress Tracking
- Linear progression (must complete levels sequentially)
- Cannot skip levels
- Can view previous questions via
/previous - Hunt completion requires finishing all defined levels
Discord Platform
- Discord API via discord.js library
- Requires bot token from Discord Developer Portal
- Uses Gateway v10 with three intents: Guilds, GuildMessages, MessageContent
- Slash commands registered globally via REST API
Production Dependencies
discord.js(v14.18.0): Discord API client library with builders, collections, and REST utilitiessqlite3(v5.1.7): Native SQLite3 bindings for Node.jsdotenv(v17.2.0): Environment variable loader from.envfile
Development Dependencies
nodemon(v3.1.9): Auto-restart development server on file changestypescript(v5.2.2): Type definitions (unused in current JavaScript codebase)
Environment Variables (.env file)
DISCORD_TOKEN: Bot authentication token from Discord Developer Portal
Static Configuration (src/config/owners.json)
- Hardcoded list of bot owner Discord user IDs with admin privileges
- Currently contains 5 whitelisted users
Database Storage
- SQLite database file located at
data/hunt.db - Created automatically if missing
- Requires read/write permissions
Hunt Definition Files
- JSON files uploaded as Discord attachments
- Parsed and validated before storage
- Examples provided:
example-hunt.json,hunt.json