Under the Hood

Bot Setup & Config

A Python discord.py bot with a FastAPI server in the same process. This page is for running your own instance.

Install and run

Terminal
cd "GK Discord Bot"
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env      # then fill it in

# Normal start:
python bot.py

# After adding or changing slash commands:
python bot.py --sync

Only sync when commands change

Pass --sync only when the slash command set has actually changed. Repeated syncing hits Discord’s rate limit and will leave you unable to sync when you genuinely need to.

Where configuration lives

.env

secrets, never committed

Discord token, Firebase credentials, the Gemini key, and the API signing secret. Read once at import time into a singleton every module shares.
settings.py

gameplay balance

XP rates, cooldowns, prices, reward curves, channel and role IDs. Holds no secrets, so it is safe to commit and review like any other gameplay change. Cogs read these constants rather than hard-coding their own, so one edit rebalances the whole economy consistently.
i18n.py

strings

Two-tier localisation: one lookup for public messages keyed by server, another for private replies keyed by the individual. Currently English only, but the lookup is what makes adding a language a data change rather than a code change, so new strings should still go through it.

The settings that actually matter before you expose it

API_SECRET_KEY

required

Signs every session token. A known or placeholder value lets anyone forge a login for any user, so the bot refuses to start with one. Generate a long random value and treat it like a database password.
KSP_2FA_ENABLED

default true

The Discord approval step during linking. Off is for testing; leaving it off in production means a leaked 6-digit code is a full account takeover.
KSP_DEVICE_BINDING_ENABLED

default true

Binds each install's random device id to the account and blocks any other. Note that the moderation report it enables collects information that your privacy policy has to disclose.
KSP_VERSION_CHECK_ENABLED

default true

Blocks outdated game clients until they update, based on a published version and hash. With nothing published yet it blocks nobody regardless.
API_DOCS_ENABLED

default false

Interactive API docs. Off by default so the endpoint list is not public. Local development only.
DEBUG_ENDPOINTS_ENABLED

default false

Debug and test-only routes, which return 404 when off. Development servers only, never production.
COMMAND_GROUP

default empty

Nests every slash command under one group. Empty means bare top-level commands. See the commands page.

Exposing it safely

The recommended shape is a TLS-terminating reverse proxy in front of the API, with the API itself bound to localhost so only the proxy can reach it, and the proxy’s address listed as a trusted proxy so the real client address is read from the forwarded header for rate limiting.

Serving HTTPS directly is also supported by pointing at a certificate and key. Leaving both blank serves plain HTTP, which is correct for localhost and correct behind a proxy that terminates TLS, and wrong everywhere else.

Browser CORS should stay empty. The game client is not a browser and needs none of it.

Cost controls

Gemini and Firebase both bill by usage, and the bot ships with a monthly budget for each plus a brake that trips before the bill does. The defaults are conservative and every value is adjustable at runtime, which matters because the failure worth planning for is a false stop from a wrong price constant. See Architecture.

Structure

Every feature is a discord.py cog under cogs/, loaded at startup. Shared state goes through the store, the settings module and the localisation module. A few cogs do import each other directly where one genuinely owns a helper another needs, but prefer the shared modules for new work.

The API surface lives in a single module alongside them, and the Firestore layer under data/.