Documentation Index
Fetch the complete documentation index at: https://mintlify.com/developer51709/Noxie/llms.txt
Use this file to discover all available pages before exploring further.
utils/economy.py is Noxie’s single source of truth for all persistent user data. It provides every SQLite CRUD operation the cogs need — balance reads and writes, hunt recording, cooldown checks, inventory management, badge awarding, and donation logging — organized into four logical groups that map directly to the four database tables. All public functions accept a sqlite3.Connection as their first positional argument. That connection is created by helpers.get_db_conn() with row_factory = sqlite3.Row, which means every row returned can be accessed by column name as well as by index.
Schema Initialization
CREATE TABLE IF NOT EXISTS, making the call safe to run on every bot startup. Called once during NoxieBot.setup_hook() before any cog is loaded.
Tables created:
| Table | Primary Key | Description |
|---|---|---|
economy | (user_id, guild_id) | Per-user-per-guild balances, hunt counts, streaks, and last-hunt timestamp |
inventory | id (autoincrement) | One row per caught creature, with fused flag for future fusion feature |
badges | id (autoincrement), unique on (user_id, badge_name) | Badge awards with timestamps; the unique constraint prevents duplicates |
donations | id (autoincrement) | Immutable donation log; each transaction is a new row |
Balance Functions
These functions manage theeconomy table — the core currency and hunt-stat store.
get_balance()
dict. Calls _ensure_row() first, so it always returns a valid dict even for first-time users.
Return shape:
add_currency()
UPDATE … SET x = x + ? statement, making it safe for concurrent writes. Either or both currency amounts may be specified; defaults of 0 mean unspecified currencies are unaffected.
spend_currency()
False if the user cannot afford the cost (checked individually per currency); returns True and commits the deduction otherwise.
spend_currency() performs a read-then-write in two separate statements. For production use at high concurrency, wrap calls in a transaction or use BEGIN IMMEDIATE to prevent race conditions.Hunt Functions
record_hunt()
total_hunts by 1, increments hunt_streak by 1, sets last_hunt to time.time(), and credits glow_earned Glow Shards and coins_earned Vibe Coins — all in a single UPDATE statement. Returns the updated balance dict (same shape as get_balance()).
check_hunt_cooldown()
float. Returns 0.0 if the cooldown has expired or the user has never hunted. The cooldown duration is read from config.json under the hunt_cooldown key (defaults to 30 seconds if not set).
Usage pattern in cogs/hunt.py:
Inventory Functions
Theinventory table stores one row per caught creature instance. The same creature can appear multiple times (if caught more than once), and instances can be marked fused=1 to flag them as consumed by a future fusion mechanic.
add_to_inventory()
caught_at = time.time() and fused = 0. Always inserts a new row — duplicates are intentional and represent multiple copies of the same creature.
get_inventory()
caught_at DESC (most recently caught first). Includes fused entries.
Return shape per item:
count_creature()
fused = 0) of a specific creature in the user’s inventory. Returns 0 if the user has none.
Badge Functions
Badges are global per user (not per guild). Thebadges table uses a UNIQUE(user_id, badge_name) constraint to guarantee idempotency.
award_badge()
True if the badge was newly awarded, or False if the user already has it (caught via sqlite3.IntegrityError from the unique constraint). Use the return value to trigger first-time badge announcements.
Example usage in cogs/hunt.py:
get_badges()
badge_name strings for the user, ordered by awarded_at ASC (oldest first). Returns an empty list if the user has no badges. Pass this list to build_mood_pulse_container() along with BADGE_DISPLAY to render the formatted badge line in the profile card.
Donation Functions
log_donation()
donations table. Called by cogs/donate.py after OxaPay confirms payment, before credits are awarded. tx_id stores the OxaPay trackId for reconciliation.
get_donation_total()
amount_usd values across every donation row for the user, across all guilds. Returns 0.0 if the user has never donated. Uses COALESCE(SUM(...), 0) so the query always returns a number.
BADGE_DISPLAY
BADGE_DISPLAY is a module-level constant that maps internal badge_name keys to their display strings with emoji. Import it directly wherever badge rendering is needed (e.g. cogs/profile.py).
badge_name | Display | Awarded When |
|---|---|---|
donor | 💎 Donor | First confirmed donation |
hunter_10 | 🏹 Hunter I | 10 total hunts |
hunter_50 | 🏹 Hunter II | 50 total hunts |
hunter_100 | 🏹 Hunter III | 100 total hunts |
legendary | 🌟 Legendary Finder | Catching any legendary creature |
mythic | 🌌 Mythic Witness | Catching any mythic creature |
streak_25 | 🔥 Hot Streak | 25-hunt streak |
Internal Helpers
_ensure_row() is called internally by most economy functions before any read or write. It executes INSERT OR IGNORE INTO economy (user_id, guild_id) VALUES (?, ?), creating a default row with all-zero balances if the user-guild pair doesn’t exist yet. You never need to call it directly — any public function in this module handles first-time users automatically.