Getting Started
Architecture
A single bot process runs everything on the community side and serves a private REST API. The KSP mod is the only client of that API.
One process, two servers
The entry point starts the Discord bot and a uvicorn-hosted FastAPI server as concurrent asyncio tasks in the same process. The bot handles Discord interactions; the API handles requests from the game. They share the same in-memory data layer.
Process diagram: bot, API server and data layer
Image placeholder · 16/9
Data flow
User data, namely XP, balance, message counts, unlocked levels and language preference, lives in Firestore under guilds/{guild_id}/users/{user_id} and is mirrored in an in-memory dictionary. Writes are buffered and flushed on a timer; a local JSON file acts as a fallback cache.
guilds/{guild_id}/users/{user_id} # XP, balance, levels, language
contracts/ # contract documents
corps/ # player corporations
weekly_missions/ # generated weekly objectives
mission_classifications/ # cached AI results (1 per week)Sync vs. async
Firestore access through the firebase-admin SDK is synchronous, while Discord and API handlers are async. Write operations are wrapped so they can be awaited; simple reads stay synchronous.
Mind the boundary
Use the async helpers for writes (for example await store.add_balance(...)). Reads such as store.get_user(...) are plain synchronous calls.
The mimic system
The bot patches three internal discord.py dispatch points so an administrator can act as another user, with the swapped identity applied before any handler runs. Code that needs the genuine caller reads it back from interaction extras.
# Recover the real administrator behind a mimicked interaction
real_user = interaction.extras.get("_mimic_real_user")