-
Notifications
You must be signed in to change notification settings - Fork 0
Developer Documentation
This page is for contributors and anyone interested in the internal structure of Idleology.
The project has a very strict, well-defined layered architecture. Following the patterns exactly is required to keep the codebase maintainable. Deviating creates technical debt.
For the most complete and up-to-date reference (including detailed examples and newer subsystems such as Companion Mastery, Slayer Tree, Settlement plots/Zeal/DT/projects/Uber Shrine/Black Market tree, full Apex Soul Stone mechanics, etc.), always consult the source files in the repo:
- AGENTS.md — Portable guide optimized for AI coding agents.
- CLAUDE.md — The authoritative, detailed developer guide.
This wiki page provides a high-level overview and quick reference.
Idleology is a text-based idle RPG Discord bot.
- Runtime: Python 3.11.5+
- Discord library: discord.py
-
Database: SQLite via aiosqlite (
database/schema.sql) -
Game data: CSV/JSON/TXT files in
assets/(monsters, items, exp tables, partners, etc.) -
Current version: See
UPDATES.mdandREADME.md
cogs/ → Discord command handlers (thin entry points only)
core/ → Game logic, models, UI views, and pure mechanics
base_view.py → Mandatory base class for ALL Discord views
models.py → Dataclass wrappers for DB rows + computed properties
util.py
[module]/
mechanics.py / logic.py → Pure math and business logic (no I/O)
views.py → Primary discord.ui.View classes
views/ → Subdirectory for complex modules
list_view.py, detail_view.py, gear_view.py, modals.py, ...
upgrades/ → Upgrade flows (BaseUpgradeView parent)
ui.py / <module>.py → Stateless embed and component builders
data.py → Asset loading and lookup tables
items/
factory.py → DB rows → dataclasses (create_weapon, etc.)
equipment_mechanics.py → Forge, refine, temper, imbue, potential
essence_mechanics.py → Essence stat calculations
essence_views.py → Essence management UI
hatchery/ → Hatchery (egg incubation) UI + mechanics
database/
__init__.py → DatabaseManager (single entry point)
base.py → BaseRepository
repositories/ → All SQL lives here (never elsewhere)
assets/ → Game data (monsters.csv, partners.csv, etc.)
scripts/ → One-off tools (image audit, reseed, upload)
Core principle: Cogs are thin. All logic lives in core/. All SQL lives in database/repositories/.
See the full architecture diagram and explanations in AGENTS.md and CLAUDE.md.
Every discord.ui.View must inherit from core/base_view.py:BaseView.
- Provides timeout handling, ownership checks, and automatic
state_manager.clear_active(). - Two styles: normal (pass
user_id/server_id) or child (passparent=to inherit). - Always set
view.message = await ...after sending. - Never extend
discord.ui.Viewdirectly.
- No business logic.
- No raw SQL — use
self.bot.database.<repository>. - Always
await interaction.response.defer()before slow/DB operations. - Check
state_manager.is_active(user_id)before interactive work. - Set/clear active state around long-running interactions.
-
models.py: Pure dataclasses. Computed properties (@property) are allowed. No DB calls. -
mechanics.py(orlogic.py): Static methods and pure functions only. No I/O. - Views: Extend
BaseView. Stateless builders go inui.pyor a dedicated<module>.py. - Use
core/items/factory.pyfor all equipment model construction.
- All SQL in
database/repositories/. - Access via
bot.database.<repo_name>(e.g.users,equipment,settlement,slayer,paradise, etc.). - Always call
await repo.commit()after writes. - See the full repository table in AGENTS.md or CLAUDE.md.
Major models are documented in detail in the source guides:
-
Player(central dataclass with gear, companions, partners, parts, alchemy, codex, combat state, etc.) - Equipment models (Weapon, Armor, Accessory, Glove, Boot, Helmet)
-
DelveState,Companion,Partner,MonsterModifier,CodexTome,Settlement, etc.
Full lists of repositories, endgame systems (Ascent, Codex, Uber, Maw, Prestige, Consume, Delve, Partners, Hematurgy, Alchemy, Settlement, Slayer, Journey, etc.), and combat architecture are in the linked .md files.
Complex modules should follow the core/inventory/ gold standard:
-
inventory.py— stateless UI builders -
views/—list_view.py,detail_view.py,gear_view.py,modals.py -
upgrades/—base.py+ specific upgrade views (BaseUpgradeView pattern withgo_back()) -
__init__.pyre-exports the public API
Settlement uses a similar split (views/base.py, construction.py, black_market.py, etc.).
Split when a single file would exceed ~600–800 lines or when distinct sub-features appear.
-
Schema →
database/schema.sql+ migration if needed. -
Repository → New or extended method in the appropriate
database/repositories/*.py. -
Model → Update
core/models.py(or a run-scoped dataclass incore/<module>/mechanics.py). -
Logic → Pure functions in
core/<module>/mechanics.py. -
UI → Extend
BaseView. Stateless parts inui.pyor<module>.py. Split views/ if complex (inventory/settlement pattern). -
Command → Thin handler in
cogs/<module>.py. -
State → Use
state_manager.set_active/clear_activefor interactive features (upgrade subviews rely on_processingguard). -
Assets/Images → Flag new entity types for
scripts/audit_images.pyetc. - Tests/Docs → Update relevant docs (wiki, AGENTS.md, CLAUDE.md) and (if applicable) tests.
- Fetch player + gear via
database.users.get+ factory functions +create_.... - Child views: pass
parent=to inherit user/server IDs and avoid duplication. - Re-entry guards (
self._processing = False) on every state-mutating button. - Combat state reset rules are strict (see matrix in AGENTS.md for jewels, transients, etc. across normal/Ascent/Codex/Uber).
- Passive and modifier registries are the single source of truth — do not hardcode effects.
- Image assets: Use the managed pipeline in
assets/images/and the upload/audit scripts.
- No SQL strings in cogs or core.
- No game math in cogs.
- No
wait_for()— use Views. - Do not extend
discord.ui.Viewdirectly. - Do not skip defer before DB writes or long work.
- Do not add speculative abstractions.
- Do not forget to clear active state on all exit paths.
- Do not hardcode modifier values outside
core/combat/mobgen/modifier_data.py. Usemonster.get_modifier_value(name). - Do not mutate state on a button without a
_processingguard. - State sessions have no auto-expiry — always explicitly
clear_activeon navigation/exit paths.
- Read AGENTS.md and CLAUDE.md in full.
- Study the reference implementations:
core/inventory/andcore/combat/. - Make small, focused changes that follow existing patterns.
- Run the bot locally and test your changes interactively.
- When in doubt, re-read the relevant section of the guides.
Contributions are welcome! The project emphasizes long-term maintainability over clever shortcuts.
See also the main README.md for installation and high-level usage.
It's all in the mind — and in the code structure.
Last updated: June 2026 (synced recent systems: Companion Mastery, Slayer Tree, Settlement details, state manager notes, repo expansions, and architecture updates from AGENTS.md / CLAUDE.md + live code)