Overview
Project Stardust uses PostgreSQL (via Supabase) with asyncpg for async database operations. The schema supports gacha mechanics, team building, progression systems, and social features.Database Initialization
All tables are created incore/database.py:34 via the init_db() function:
Entity Relationship Diagram
Core Tables
users
Central table tracking player resources and progression.core/database.py:73-85
Key Columns:
gacha_gems- Premium currency for summoningcoins- Secondary currency for shop purchasespity_counter- Tracks pulls until guaranteed SSRbanner_points- Spark system progress (resets on banner change)team_level- Applies 1% power boost per level to entire teambounty_keys- Daily mission resource (max 3, regenerates)
core/database.py:87-106
inventory
Stores each player’s character collection with dupe tracking.core/database.py:154-164
Key Columns:
dupe_level- Duplicate count (0-10), each dupe adds +5% powerbond_level- Character affinity, adds +0.5% power per levelis_locked- Protection from mass scrappingUNIQUE(user_id, anilist_id)- One row per character per player
characters_cache
Caches AniList character data to reduce API calls.core/database.py:217-230
Key Columns:
rarity- SSR (1-250), SR (251-1500), R (1501-10000) based on rankrank- AniList favorites rankingtrue_power- Calculated from favorites usingcalculate_effective_power()ability_tags- JSON array of skill names (e.g.["Surge", "Guard"])is_overridden- When TRUE, prevents auto-updates from batch cache
core/database.py:323-328
Team System
teams
Active team composition (5 character slots).core/database.py:181-190
Schema:
- Each
slot_Xstores aninventory.id(NOT anilist_id) - Slots can be NULL (empty)
- One team per user
team_presets
Saved team loadouts for quick switching.core/database.py:193-204
Gacha System
banners
Timed rate-up events.core/database.py:60-70
Key Columns:
rate_up_ids- Array of anilist_ids with boosted ratesrate_up_chance- Probability of featured character (0.5 = 50%)spark_pity- Points needed to guarantee a featured unitend_timestamp- Unix timestamp for auto-expiration
Progression Systems
expeditions
Passive gem generation.core/database.py:207-214
Mechanics:
slot_ids- Array of inventory IDs deployed- Earns gems based on time elapsed and character skills
- Skills like “Hardworker” (+15%) and “Master of Coin” (+10%) stack
daily_tasks
Daily mission progress tracking.core/database.py:233-242
Task Keys: easy, normal, hard, expert, nightmare, hell, pvp
achievements
Permanent achievement unlocks.core/database.py:49-56
boss_kills
Tracks special boss victories.core/database.py:40-46
Usage: cogs/battle.py:246-253 - Records kills against special user ID 1463071276036788392
Economy
user_items
Item inventory (tokens, consumables, etc.).core/database.py:132-139
daily_shop
Rotating daily shop inventory.core/database.py:143-148
Schema:
date- YYYY-MM-DD formatitems- JSON array:[{id, price, rarity}, ...]
Bounty Board System
bounty_board
Shared server-wide bounty missions.core/database.py:109-116
Key Columns:
slot_id- Board position (e.g. 1-5)enemy_data- JSON object with enemy statstier- Difficulty levelexpires_at- Auto-refresh timestamp
user_bounty_status
Tracks individual completion per slot.core/database.py:119-126
Global Settings
global_settings
Server-wide feature toggles.core/database.py:245-250
Helper Functions
get_user(user_id)
Fetches or creates user record.batch_add_to_inventory(user_id, characters)
Adds characters with auto-scrapping.get_inventory_details(user_id, sort_by=“date”)
Retrieves full inventory with calculated power.mass_scrap_r_rarity(user_id) / mass_scrap_sr_rarity(user_id)
Bulk scrap operations.(count, gems, coins)
- R: 100 gems + 5 coins each
- SR: 500 gems + 25 coins each
Migration Pattern
Dynamic column additions useALTER TABLE ... ADD COLUMN IF NOT EXISTS:
Best Practices
Connection Management
Always use connection pool:Parameterized Queries
Prevent SQL injection:Transactions
Group related operations:Next Steps
- Bot Architecture - Overall system design
- Skills System - Battle mechanics
- Commands Reference - User-facing documentation