Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/noskap/kojima-bot/llms.txt

Use this file to discover all available pages before exploring further.

Kojima Bot stores all persistent state — channel spawn configuration, per-server player profiles, and achievement records — in a single SQLite file. By default this file is named bot.sqlite and is created in the working directory automatically on first run. The database layer is managed by Drizzle ORM, which provides type-safe queries and a schema-push workflow suited for self-hosted bots.

Tables

users

A minimal global cache of Discord usernames, populated whenever the bot resolves a user.
ColumnTypeNotes
idtextPrimary key (Discord user ID)
usernametextDiscord username, defaults to ""

channels

Per-channel spawn configuration and live spawn state. One row per channel that has been set up with /kojima setup.
ColumnTypeNotes
idtextPrimary key (Discord channel ID)
guild_idtextDiscord server ID
cattextMessage ID of the active spawn, or "0" if none
spawn_times_minintegerMinimum seconds between spawns (default 60)
spawn_times_maxintegerMaximum seconds between spawns (default 450)
lastcatchesintegerUnix timestamp of the last catch
yet_to_spawnintegerUnix timestamp when the next spawn is scheduled
forcespawnedbooleanWhether the current spawn was force-triggered
cattypetextRarity display name of the current spawn
appeartextSpawn appearance message ID
coughttextCatch confirmation message ID
webhooktextWebhook URL for the channel (if configured)
cat_rainsintegerRain event counter
rain_should_endintegerUnix timestamp when the rain event ends
last_catcher_idtextDiscord user ID of the last catcher
last_catcher_nametextDisplay name of the last catcher
last_catch_raritytextRarity display name of the last caught spawn

profiles

Per-server player statistics. Each (user_id, guild_id) pair is unique — a player has a separate profile in every server the bot runs in.
Column groupColumns
Identityid (autoincrement PK), user_id, guild_id
Catch statstotal_catches, total_catch_time, time (best catch seconds), timeslow (worst catch seconds), funny
Rarity countscat_Fine, cat_Nice, cat_Good, cat_Rare, cat_Wild, cat_Baby, cat_Epic, cat_Sus, cat_Brave, cat_Rickroll, cat_Reverse, cat_Superior, cat_Trash, cat_Legendary, cat_Mythic, cat_8bit, cat_Corrupt, cat_Professor, cat_Divine, cat_Real, cat_Ultimate, cat_eGirl
Gamblingroulette_balance (starts at 100), gambles, slot_spins, slot_wins, slot_big_wins, roulette_wins, roulette_spins, flip_plays
Giftingcats_gifted, cat_gifts_recieved
There is a unique index on (user_id, guild_id)profiles_user_guild.

achievement_unlocks

Records which achievements each player has unlocked, with a timestamp.
ColumnTypeNotes
idintegerAutoincrement primary key
user_idtextDiscord user ID
guild_idtextDiscord server ID
keytextAchievement identifier (see src/lib/achievements.ts)
unlocked_atintegerUnix timestamp of when the achievement was unlocked
A unique index on (user_id, guild_id, key)achievement_user_guild_key — prevents duplicate unlock records.

Migrations

Drizzle Kit manages schema evolution. The schema source of truth is src/db/schema.ts; generated migration SQL files are stored in drizzle/.
CommandWhat it does
bun run db:pushPushes the current schema directly to bot.sqlite — the simplest way to apply changes during development without generating migration files
bun run db:studioOpens Drizzle Studio in your browser — a visual table editor for inspecting and editing rows live
The Drizzle config (drizzle.config.ts) points at ./src/db/schema.ts as the schema source and bot.sqlite as the target database.

Auto-migration on startup

When src/db/index.ts is first imported at process startup, it immediately calls ensureSqliteSchema() before the bot even logs in to Discord. This function uses SQLite’s PRAGMA table_info to check for missing columns and issues ALTER TABLE … ADD COLUMN statements for any that are absent. The separate initDB() function that is called on the ClientReady event only logs a confirmation message — the schema check has already completed by that point. This mechanism protects against no column named … errors when upgrading an existing deployment from an older schema — you do not need to manually run migrations for additive column changes. The auto-migration currently covers all columns in channels, profiles, and the creation of the achievement_unlocks table if it does not exist.

Resetting the database

To wipe all data and start fresh:
  1. Stop the bot.
  2. Delete bot.sqlite from the working directory.
  3. Re-create the schema: bun run db:push
  4. Start the bot again.
pm2 stop kojima-bot
rm bot.sqlite
bun run db:push
pm2 start ecosystem.config.cjs

Changing the database file path

Set DB_FILE in .env to an absolute or relative path to use a different file location:
# .env
DB_FILE=/data/kojima/state.sqlite
Always stop the bot before deleting bot.sqlite. Deleting the file while the process is running may corrupt the file or cause unrecoverable write errors.
Use bun run db:studio to browse data during development — it opens a browser-based table editor where you can inspect profiles, channel state, and achievement records without writing any SQL.

Build docs developers (and LLMs) love