1
0
forked from sass/tipibot
Files
tipibot/DEV_NOTES.md
2026-04-04 20:27:15 +03:00

13 KiB
Raw Blame History

TipiLAN Bot - Developer Reference

File Structure

File Purpose
bot.py All Discord commands, views (UI components), event handlers, reminder system
economy.py All economy logic, data model, constants (SHOP, COOLDOWNS, LEVEL_ROLES, etc.)
pb_client.py Async PocketBase REST client - auth token cache, CRUD on economy_users collection
strings.py Single source of truth for all user-facing text. Edit here to change any message.
sheets.py Google Sheets integration (member sync)
member_sync.py Birthday/member sync background task
config.py Environment variables (TOKEN, GUILD_ID, PB_URL, etc.)

Adding a New Economy Command

Checklist - do all of these, in order:

  1. economy.py - add the do_<cmd> async function with cooldown check, logic, _commit, and _txn logging
  2. economy.py - add the cooldown to COOLDOWNS dict if it has one
  3. economy.py - add the EXP reward to EXP_REWARDS dict
  4. PocketBase - if the function stores new fields, add them manually in the PB admin UI at http://127.0.0.1:8090/_/. Fields not in the PB schema are silently dropped on PATCH.
  5. strings.py CMD - add the slash command description
  6. strings.py OPT - add any parameter descriptions
  7. strings.py TITLE - add embed title(s) for success/fail states
  8. strings.py ERR - add any error messages (banned, cooldown uses CD_MSG, jailed uses CD_MSG["jailed"])
  9. strings.py CD_MSG - add cooldown message if command has a cooldown
  10. strings.py HELP_CATEGORIES["tipibot"]["fields"] - add the command to the help embed
  11. bot.py - implement the cmd_<name> function, handle all res["reason"] cases
  12. bot.py - call _maybe_remind if the command has a cooldown and reminders make sense
  13. bot.py - call _award_exp(interaction, economy.EXP_REWARDS["<cmd>"]) on success
  14. strings.py REMINDER_OPTS - add a reminder option if the command needs one
  15. bot.py _maybe_remind and _restore_reminders - if item-modified cooldown, add elif branch
  16. bot.py _REMINDER_COOLDOWN_KEYS - add "cmd": "last_cmd" mapping if reminder-capable

Adding a New Shop Item

Checklist:

  1. economy.py SHOP - add the item dict {name, emoji, cost, description: strings.ITEM_DESCRIPTIONS["key"]}
  2. economy.py SHOP_TIERS - add the key to the correct tier list (1/2/3)
  3. economy.py SHOP_LEVEL_REQ - add minimum level if it is T2 (≥10) or T3 (≥20)
  4. strings.py ITEM_DESCRIPTIONS - add the item description (Estonian flavour + English effect)
  5. strings.py HELP_CATEGORIES["shop"]["fields"] - add display entry (sorted by cost)
  6. If the item modifies a cooldown:
    • economy.py - add the if "item" in user["items"] branch in the relevant do_<cmd> function
    • bot.py _maybe_remind - add elif cmd == "<cmd>" and "<item>" in items: branch with the new delay
    • bot.py _restore_reminders - add the same elif branch
    • bot.py cmd_cooldowns - add the item annotation to the relevant status line

Adding a New Level Role

  1. economy.py LEVEL_ROLES - add (min_level, "RoleName") in descending level order (highest first)
  2. bot.py _ensure_level_role - no changes needed (uses LEVEL_ROLES dynamically)
  3. Run /economysetup in the server to create the role and set its position

Adding a New Admin Command

  1. strings.py CMD - add "[Admin] ..." description
  2. strings.py OPT - add parameter descriptions
  3. strings.py ADMIN - add response and DM strings
  4. strings.py HELP_CATEGORIES["admin"]["fields"] - add the entry
  5. economy.py - add do_admin_<name> function
  6. bot.py - add command with @app_commands.default_permissions(manage_guild=True) and @app_commands.guild_only()

Economy System Design

Storage

All economy state is stored in PocketBase (economy_users collection). pb_client.py owns all reads/writes. Each do_* function in economy.py calls get_user() → mutates the local dict → calls _commit(). _commit does a PATCH to PocketBase.

Currency & Income Sources

Command Cooldown Base Earn Notes
/daily 20h (18h w/ korvaklapid) 150⬡ ×streak multiplier, ×2 w/ lan_pass, +5% interest w/ gaming_laptop; prestige daily_plus adds +20% per level
/work 1h (40min w/ monitor) 15-75⬡ ×1.5 w/ gaming_hiir, ×1.25 w/ reguleeritav_laud, ×3 30% chance w/ energiajook; prestige work_plus +20%/level
/beg 5min (3min w/ hiirematt) 10-40⬡ ×2 w/ klaviatuur
/crime 2h 200-500⬡ win 60% success (75% w/ cat6), +30% w/ mikrofon; fail = fine + jail
/rob 2h 1025% of target 45% success (60% w/ jellyfin); fail = fine; cannot rob TipiBOT directly
/heist 4h personal + 1h global 2055% of house / n players solo allowed, max 8; 35%+5%/player success (cap 65%); fail = 3h jail + ~15% balance fine
/fish 2min (90s w/ ussipurk) varies by fish rarity Interactive minigame; catches go to inventory; sell with /fishsell
/slots - varies pair=+0.5× bet; triple tiered; karikas jackpot ×25; ×1.5 w/ monitor_360; miss=lose bet
/roulette - 2× red/black, 14× green 1/37 green chance
/blackjack - 1:1 win, 3:2 BJ, 2:1 double Dealer stands on 17+; double down on first action only

Fishing System

  • /fish - interactive minigame: cast → wait 515s for bite → press button within 2s (3s w/ echolood) → keep or sell
  • Fish stored in fish_inventory (list of {fish_id, weight, value} objects)
  • /fishbook - paginated fish collection showing caught species and inventory counts
  • /fishsell - sell all fish from inventory at once
  • fish_inventory and fish_book survive prestige resets
  • kalavork (T3, 5000⬡): bumps all caught fish up one rarity tier
  • ussipurk (T2, 3500⬡): cooldown 2min → 90s
  • echolood (T3, 8000⬡): bite window 2s → 3s

Prestige System

  • Requires level 30 (9000 EXP)
  • Resets: balance, EXP, items, cooldowns, jail
  • Preserves: fish_book, fish_inventory, lifetime stats, prestige_points, season_total_exp, prestige_upgrades
  • Awards prestige_points = max(1, exp ÷ 1000) at time of prestige
  • Each prestige increments prestige_level counter
  • Prestige coin/exp multipliers apply to all earned values

Prestige Shop (PRESTIGE_SHOP in economy.py):

Upgrade Max Level Cost/level Effect
coin_mult 5 5 PP +8% coin multiplier per level
exp_mult 5 5 PP +8% EXP multiplier per level
daily_plus 3 7 PP +20% daily base reward per level
work_plus 3 7 PP +20% work earnings per level

"all" Keyword

Commands that accept a coin amount (/give, /roulette, /rps, /slots, /blackjack) accept "all" to mean the user's full current balance. Parsed by _parse_amount(value, balance) in bot.py.

Daily Streak Multipliers

  • 1-2 days: ×1.0 (150⬡)
  • 3-6 days: ×1.5 (225⬡)
  • 7-13 days: ×2.0 (300⬡)
  • 14+ days: ×3.0 (450⬡)
  • karikas item: streak survives missed days

Jail

  • Normal duration: 30 minutes (JAIL_DURATION)
  • Heist fail duration: 3 hours (HEIST_JAIL) + fine 15% of balance (min 150⬡, max 1000⬡)
  • gaming_tool: prevents jail on crime fail
  • /jailbreak: 3 single-button dice rolls (both dice at once), need doubles to escape free. Animated reveal with TipiDICE emoji. On fail after 3 tries - bail = 20-30% of balance, min 350⬡. If balance < 350⬡, stay jailed until timer.

EXP Rewards (from EXP_REWARDS in economy.py)

EXP is awarded on every successful command use. Level formula: floor(sqrt(exp / 10)), so Level 5 = 250 EXP, Level 10 = 1000, Level 20 = 4000, Level 30 = 9000.

Fish EXP is awarded per catch (varies by rarity, defined in FISH_CATALOGUE). Prestige exp_mult upgrade applies to fish EXP.


Admin Commands Reference

Command What it does
/pause Toggle maintenance mode - blocks all non-admin commands
/admincoins @user <amount> <reason> Give/take coins (positive/negative). DMs user.
/adminexp @user <amount> <reason> Give/take EXP (positive/negative). Auto-applies level roles on change. DMs user.
/adminitem @user <item_id> <anna|eemalda> Give or remove any shop item for free. DMs user.
/adminjail @user <minutes> <reason> Manually jail a user. DMs user.
/adminunjail @user Remove jail from a user.
/adminban @user <reason> Ban from all economy commands. DMs user.
/adminunban @user Lift economy ban.
/adminreset @user <reason> Wipe balance, EXP, items, streak. DMs user.
/adminview @user Full profile: balance, EXP/level, streak, prestige, fish stats, items, timestamps.
/adminseason <top_n> End season: DM top N players, reset all EXP.

All admin commands require Manage Guild permission and work in any channel (bypass pause and channel restrictions).


Role Hierarchy (Discord)

Order top to bottom in server roles:

[Bot managed role]  ← bot's own role, always at top of our stack
ECONOMY             ← given to everyone who uses any economy command
TipiLEGEND          ← level 30+
TipiCHAD            ← level 20+
TipiHUSTLER         ← level 10+
TipiGRINDER         ← level 5+
TipiNOOB            ← level 1+

Run /economysetup to auto-create all roles and set their positions. The command is idempotent - safe to run multiple times.

Role assignment:

  • ECONOMY role: given automatically on first EXP award (i.e. first successful economy command)
  • Level roles: given/swapped automatically on level-up; synced on /rank
  • /adminexp: automatically re-applies level roles if level changes

Shop Tiers & Level Requirements

Tier Level Required Items
T1 0 (any) gaming_hiir, hiirematt, korvaklapid, lan_pass, anticheat, energiajook, gaming_laptop
T2 10 reguleeritav_laud, jellyfin, mikrofon, klaviatuur, monitor, cat6, ussipurk
T3 20 monitor_360, karikas, gaming_tool, kalavork, echolood

Shop display is sorted by cost (ascending) within each tier. The SHOP_LEVEL_REQ dict in economy.py controls per-item lock thresholds.


strings.py Organisation

Section Dict Usage in bot.py
Flavour text WORK_JOBS, BEG_LINES, CRIME_WIN, CRIME_LOSE Randomised descriptions
Command descriptions CMD["key"] @tree.command(description=S.CMD["key"])
Parameter descriptions OPT["key"] @app_commands.describe(param=S.OPT["key"])
Help embed HELP_CATEGORIES["cat"] cmd_help
Banned message MSG_BANNED All banned checks
Reminder options REMINDER_OPTS RemindersSelect dropdown
Slots outcomes SLOTS_TIERS["tier"](title, color) cmd_slots
Embed titles TITLE["key"] discord.Embed(title=S.TITLE["key"])
Error messages ERR["key"] send_message(S.ERR["key"]) - use .format(**kwargs) for dynamic parts
Cooldown messages CD_MSG["cmd"].format(ts=_cd_ts(...)) Cooldown responses
Shop UI SHOP_UI["key"] _shop_embed
Item descriptions ITEM_DESCRIPTIONS["item_key"] economy.SHOP[key]["description"]
Fish UI FISH_UI["key"] /fish, /fishbook, /fishsell
Fish names FISH_NAMES["fish_id"] Fish display name
Admin responses ADMIN["key"] Admin command success/DM messages

Constants Location Quick-Reference

Constant File Description
SHOP economy.py All shop items (name, emoji, cost, description)
SHOP_TIERS economy.py Which items are in T1/T2/T3
SHOP_LEVEL_REQ economy.py Min level per item
COOLDOWNS economy.py Base cooldown per command
JAIL_DURATION economy.py How long jail lasts
LEVEL_ROLES economy.py [(min_level, "RoleName"), ...] highest first
ECONOMY_ROLE economy.py Name of the base economy participation role
EXP_REWARDS economy.py EXP per command
FISH_CATALOGUE economy.py All fish species (rarity, weight, coins, exp)
PRESTIGE_SHOP economy.py Prestige upgrade definitions
HOUSE_ID economy.py Bot's user ID (house account for /rob)
MIN_BAIL economy.py Minimum bail payment (350⬡)
COIN economy.py The coin emoji string

Balance Notes (as of current version)

  • Beg is most efficient for active players (3min cooldown + 2× multiplier w/ klaviatuur = high ⬡/hr)
  • Work is best for passive players (1h cooldown, fire and forget)
  • Crime is high risk/reward - best with cat6 + mikrofon
  • lan_pass (1200⬡) doubles daily - good long-term investment
  • gaming_laptop (1500⬡) 5% interest, capped 500⬡/day - snowballs with large balance
  • anticheat is consumable (2 uses) - only item that can be re-bought
  • karikas (T3) is the only item that preserves a daily streak across missed days
  • reguleeritav_laud (T2) stacks with gaming_hiir: combined ×1.5 × ×1.25 = ×1.875
  • Fishing is a steady passive income; kalavork (T3) dramatically increases fish value by bumping rarity