diff --git a/README.md b/README.md index 23976c2..8b098cd 100644 --- a/README.md +++ b/README.md @@ -483,7 +483,15 @@ Every slash command invocation is logged with the user ID, display name, and all ``` ├── bot.py # Discord client, event handlers, shared helpers; wires command modules together -├── strings.py # All user-facing strings (command descriptions, help text, errors) +├── strings/ # All user-facing strings, split by domain; re-exported so `import strings` works unchanged +│ ├── __init__.py # Re-exports every name from the submodules +│ ├── common.py # System messages, embed TITLEs, ERR, CD_MSG, status/send/patchnotes/reminders +│ ├── commands.py # CMD + OPT descriptions, HELP_CATEGORIES, HELP_UI +│ ├── member.py # /check, member/birthday/channel/economy-setup UI +│ ├── economy.py # Income flavour + income/profile/shop/quests/leaderboard/request UI +│ ├── admin.py # Admin responses, season reset, prestige +│ ├── games.py # Slots, roulette, RPS, blackjack, heist, jailbreak +│ └── fishing.py # Fish catalogue, rarities, /fish UI ├── config.py # Environment variable loader ├── core/ │ ├── economy/ # TipiCOIN business logic (re-exported via core/economy/__init__.py) diff --git a/docs/DEV_NOTES.md b/docs/DEV_NOTES.md index 3ce8aeb..a2b98d6 100644 --- a/docs/DEV_NOTES.md +++ b/docs/DEV_NOTES.md @@ -9,7 +9,7 @@ The codebase is split into **`core/`** (domain logic), **`commands/`** (Discord | File | Purpose | |---|---| | `bot.py` | Discord client, event handlers (`on_ready`, `on_member_join`, ...), background tasks (presence rotation, daily birthday loop), shared helpers (`_award_exp`, `_maybe_remind`, `_parse_amount`, `_PAUSED`), and `register_*_commands(...)` wiring for every command module | -| `strings.py` | **Single source of truth for all user-facing text.** Edit here to change any message. | +| `strings/` | **Single source of truth for all user-facing text**, split into domain submodules (`common`, `commands`, `member`, `economy`, `admin`, `games`, `fishing`) and re-exported via `strings/__init__.py` so `import strings` / `strings.NAME` works unchanged. Edit the relevant submodule to change any message. | | `config.py` | Environment variables (TOKEN, GUILD_ID, PB_URL, etc.) | ### `core/` - domain logic, no Discord coupling @@ -60,16 +60,16 @@ Checklist - do all of these, in order: 1. **`core/economy.py`** - add the `do_` async function with cooldown check, logic, `_commit`, and `_txn` logging 2. **`core/economy.py`** - add the cooldown to `COOLDOWNS` dict if it has one 3. **`core/economy.py`** - add the EXP reward to `EXP_REWARDS` dict -4. **`strings.py` `CMD`** - add the slash command description -5. **`strings.py` `OPT`** - add any parameter descriptions -6. **`strings.py` `TITLE`** - add embed title(s) for success/fail states -7. **`strings.py` `ERR`** - add any error messages (banned, cooldown uses `CD_MSG`, jailed uses `CD_MSG["jailed"]`) -8. **`strings.py` `CD_MSG`** - add cooldown message if command has a cooldown -9. **`strings.py` `HELP_CATEGORIES["tipibot"]["fields"]`** - add the command to the help embed +4. **`strings/commands.py` `CMD`** - add the slash command description +5. **`strings/commands.py` `OPT`** - add any parameter descriptions +6. **`strings/common.py` `TITLE`** - add embed title(s) for success/fail states +7. **`strings/common.py` `ERR`** - add any error messages (banned, cooldown uses `CD_MSG`, jailed uses `CD_MSG["jailed"]`) +8. **`strings/common.py` `CD_MSG`** - add cooldown message if command has a cooldown +9. **`strings/commands.py` `HELP_CATEGORIES["tipibot"]["fields"]`** - add the command to the help embed 10. **`commands/economy__commands.py`** - inside `register_*_commands`, add `@tree.command(name="", ...)` `cmd_`; handle all `res["reason"]` cases 11. **`commands/economy__commands.py`** - call `maybe_remind(user_id, "")` if the command has a cooldown and reminders make sense (the helper is passed in via the `register_*` signature) 12. **`commands/economy__commands.py`** - call `await award_exp(interaction, economy.EXP_REWARDS[""])` on success -13. **`strings.py` `REMINDER_OPTS`** - add a reminder option if the command needs one +13. **`strings/common.py` `REMINDER_OPTS`** - add a reminder option if the command needs one 14. **`bot.py` `_maybe_remind`** - if the command has an item-modified cooldown, add an `elif` branch (this helper still lives in `bot.py` and is shared across all command modules) --- @@ -81,8 +81,8 @@ Checklist: 1. **`core/economy.py` `SHOP`** - add the item dict `{name, emoji, cost, description: strings.ITEM_DESCRIPTIONS["key"]}` 2. **`core/economy.py` `SHOP_TIERS`** - add the key to the correct tier list (1/2/3) 3. **`core/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) +4. **`strings/economy.py` `ITEM_DESCRIPTIONS`** - add the item description (Estonian flavour + English effect) +5. **`strings/commands.py` `HELP_CATEGORIES["shop"]["fields"]`** - add display entry (sorted by cost) 6. If the item modifies a cooldown: - **`core/economy.py`** - add the `if "item" in user["items"]` branch in the relevant `do_` function - **`bot.py` `_maybe_remind`** - add `elif cmd == "" and "" in items:` branch with the new delay @@ -100,8 +100,8 @@ Checklist: ## Adding a New Admin Command -1. **`strings.py` `CMD`** - add `"[Admin] ..."` description -2. **`strings.py` `HELP_CATEGORIES["admin"]["fields"]`** - add the entry +1. **`strings/commands.py` `CMD`** - add `"[Admin] ..."` description +2. **`strings/commands.py` `HELP_CATEGORIES["admin"]["fields"]`** - add the entry 3. **`commands/economy_admin_commands.py`** (or `commands/ops_admin_commands.py` for non-economy ops) - add the handler with `@app_commands.default_permissions(manage_guild=True)` and `@app_commands.guild_only()` --- @@ -183,26 +183,26 @@ The `SHOP_LEVEL_REQ` dict in `core/economy.py` controls per-item lock thresholds --- -## strings.py Organisation +## strings/ Organisation -Imported as `import strings as S` everywhere. Dicts are read from `bot.py` and from every `commands/*.py` module. +Imported as `import strings as S` everywhere. `strings/` is a package: the names below live in domain submodules and are re-exported from `strings/__init__.py`, so `S.CMD`, `S.ERR`, etc. resolve unchanged regardless of which submodule they live in. Dicts are read from `bot.py` and from every `commands/*.py` module. Edit the submodule shown in the **Module** column. -| Section | Dict | Typical usage | -|---|---|---| -| 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` (in `bot.py`) | -| Banned message | `MSG_BANNED` | All banned checks | -| Maintenance mode | `MSG_MAINTENANCE` | Shown when `_PAUSED=True` in `bot.py` (toggled by `/pause` in `commands/ops_admin_commands.py`) | -| Reminder options | `REMINDER_OPTS` | `RemindersSelect` dropdown | -| Slots outcomes | `SLOTS_TIERS["tier"]` → `(title, color)` | `cmd_slots` (in `commands/economy_games_commands.py`) | -| 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 (`cd_ts` helper passed in by `bot.py`) | -| Shop UI | `SHOP_UI["key"]` | `_shop_embed` (in `commands/economy_support_commands.py`) | -| Item descriptions | `ITEM_DESCRIPTIONS["item_key"]` | `core/economy.py` `SHOP[key]["description"]` | -| Patch notes UI | `PATCHNOTES_UI["key"]` | `commands/info_commands.py` (`/patchnotes`) | +| Section | Dict | Module | Typical usage | +|---|---|---|---| +| Flavour text | `WORK_JOBS`, `BEG_LINES`, `CRIME_WIN`, `CRIME_LOSE` | `economy.py` | Randomised descriptions | +| Command descriptions | `CMD["key"]` | `commands.py` | `@tree.command(description=S.CMD["key"])` | +| Parameter descriptions | `OPT["key"]` | `commands.py` | `@app_commands.describe(param=S.OPT["key"])` | +| Help embed | `HELP_CATEGORIES["cat"]` | `commands.py` | `cmd_help` (in `bot.py`) | +| Banned message | `MSG_BANNED` | `common.py` | All banned checks | +| Maintenance mode | `MSG_MAINTENANCE` | `common.py` | Shown when `_PAUSED=True` in `bot.py` (toggled by `/pause` in `commands/ops_admin_commands.py`) | +| Reminder options | `REMINDER_OPTS` | `common.py` | `RemindersSelect` dropdown | +| Slots outcomes | `SLOTS_TIERS["tier"]` → `(title, color)` | `games.py` | `cmd_slots` (in `commands/economy_games_commands.py`) | +| Embed titles | `TITLE["key"]` | `common.py` | `discord.Embed(title=S.TITLE["key"])` | +| Error messages | `ERR["key"]` | `common.py` | `send_message(S.ERR["key"])` - use `.format(**kwargs)` for dynamic parts | +| Cooldown messages | `CD_MSG["cmd"].format(ts=cd_ts(...))` | `common.py` | Cooldown responses (`cd_ts` helper passed in by `bot.py`) | +| Shop UI | `SHOP_UI["key"]` | `economy.py` | `_shop_embed` (in `commands/economy_support_commands.py`) | +| Item descriptions | `ITEM_DESCRIPTIONS["item_key"]` | `economy.py` | `core/economy.py` `SHOP[key]["description"]` | +| Patch notes UI | `PATCHNOTES_UI["key"]` | `common.py` | `commands/info_commands.py` (`/patchnotes`) | --- diff --git a/strings/economy.py b/strings/economy.py index 2a20e50..1fdb01e 100644 --- a/strings/economy.py +++ b/strings/economy.py @@ -314,7 +314,7 @@ COOLDOWNS_UI: dict[str, str] = { "note_monitor": " *(monitor: 40min)*", "note_hiirematt": " *(hiirematt: 3min)*", "note_ussipurk": " *(ussipurk: 90s)*", - "jailed": "\n� **Vanglas** - vabaneb ", + "jailed": "\n🔒 **Vanglas** - vabaneb ", "jail_expired": "\n🔓 Vangla lõppes", }