Skip to content

Architecture

Gao edited this page Jun 25, 2026 · 3 revisions

Architecture Overview

Idleology uses a layered structure that separates Discord command handling from game logic, UI, and persistence. This organization developed alongside the many systems in the game.

The project is primarily vibe-coded: design principles are generally followed and have proven useful for maintainability, but there are inconsistencies and legacy patterns in places. This page simply describes the architecture as it exists.

High-Level Structure

cogs/          → Discord command handlers (primarily thin entry points)
core/          → Game logic, models, UI views, and mechanics
  base_view.py → Base class used by most Discord views
  models.py    → Backward-compat shim re-exporting dataclasses (see combat/items/settlement/partner models)
  util.py
  images.py    → Central image URL handling
  npc_voices.py
  [module]/
    mechanics.py / logic.py  → Business logic and calculations
    views.py                 → Primary discord.ui.View classes (simpler modules)
    views/                   → View subdirectory (used in complex modules)
      list_view.py, detail_view.py, gear_view.py, modals.py, ...
    upgrades/                → Upgrade flow views
    ui.py / <module>.py      → Stateless embed and component builders
    data.py                  → Asset / lookup data
  items/
    models.py                → Equipment dataclasses (Weapon etc.)
    factory.py               → DB rows → equipment dataclasses
    equipment_mechanics.py   → Forge, refine, temper, imbue, potential, etc.
    essence_mechanics.py
    essence_views.py
  combat/                    → Combat engine + Player model (subdivided)
database/
  __init__.py  → DatabaseManager (single entry point, exposes repositories)
  base.py      → BaseRepository
  repositories/ → SQL code lives here
assets/        → Game data (monsters.csv, partners.csv, exp tables, etc.)
scripts/       → One-off tools (image handling, migrations, audits)

Guiding idea: Keep cogs light. Put gameplay logic and views in core/. Keep all SQL in database/repositories/.

BaseView

Most views inherit from core/base_view.py:BaseView (rather than discord.ui.View directly).

Key points:

  • Normal views: BaseView(bot, user_id=..., server_id=...)
  • Child / sub-views: BaseView(bot, parent=parent_view) to inherit identity
  • Supplies self.bot, user/server IDs, interaction_check(), and timeout cleanup that clears active state via state_manager
  • After sending a response, code usually does view.message = await ...

Module Splitting Patterns

Complex areas split code:

  • core/inventory/: inventory.py (stateless builders) + views/ + upgrades/
  • core/settlement/views/: multiple focused files (construction, black_market, dashboard, plots, etc.)
  • core/combat/: calc/, turns/, mobgen/, economy/, ui/, views/, dojo/
  • Similar splits appear in partners/, alchemy/, character/, codex/, apex/, etc.

Stateless UI building is normally kept in separate files (ui.py, inventory.py, etc.) rather than inside View classes.

When a file grows large or a distinct sub-feature appears, splitting is common.

Layers (as implemented)

Cogs (cogs/)

  • Register commands and act as thin coordinators.
  • Common pattern: check state, defer, fetch data via bot.database.*, construct a view from core, send it.
  • A few simpler or legacy View classes are defined directly inside cogs (inheriting BaseView).

Core (core/)

  • models.py: backward-compat re-export shim. Actual dataclasses live in core/combat/models.py (Player), core/items/models.py, etc. No DB calls in models.
  • <module>/mechanics.py (or logic.py): functions that implement rules.
  • Views extend BaseView.
  • Equipment is usually built via core/items/factory.py.
  • core/combat/ is a larger self-contained subsystem.

Database (database/)

  • All raw SQL is in database/repositories/.
  • Access: bot.database.users, bot.database.equipment, bot.database.settlement, bot.database.partners, bot.database.slayer, bot.database.codes, bot.database.maw, etc. (see database/__init__.py for the full current list).
  • Writes are typically followed by await repo.commit().
  • Currencies were migrated to a dedicated player_currencies table (runes, keys, tomes, curios, fragments, etc.). Access and mutations go through users repo helpers (modify_currency, etc.) rather than the main user row.

Key Models

  • Player (re-exported from core/models.py; definition in core/combat/models.py): central dataclass. Holds level/stats/gear (populated via factory), companions, partners, monster parts (Consume), alchemy passives, codex state, ascension, slayer data, settlement context, combat transients, mastery fields, and more. Most consumable currencies (runes, keys, fragments, curios, etc.) live outside the Player dataclass in the player_currencies table.
  • Equipment: Weapon, Armor, Accessory, Glove, Boot, Helmet (plus essences). Built via core/items/factory.py and models now live in core/items/models.py.
  • Others: Companion, Partner, MonsterModifier, CodexTome, Settlement, Building, delve state, etc.
  • Note: core/models.py is now a backward-compat shim that re-exports from domain modules (combat/models, items/models, settlement/models, partners/models).

Combat Architecture

core/combat/ is broken into focused areas:

  • calc/ — math for hits, damage, crit, ward, etc.
  • turns/ — turn engine, player/monster actions, passives, jewels.
  • mobgen/ — encounters and modifier data.
  • economy/ — rewards, XP, drops, victory handling.
  • ui/ — embed builders.
  • views/ — the many interactive UIs (regular, elemental, dojo, multiple uber variants, warnings...).
  • dojo/ — training dummy support.

Major Systems

  • Ascent, Codex, Uber Bosses, Maw (weekly boss)
  • Settlement (buildings, workers, Black Market, projects, plots, Zeal, DT, Nursery, Idlem Foundry, Uber Shrine)
  • Partners (gacha, dispatch, affinity, boss parties)
  • Consume / Hematurgy + Hatchery
  • Slayer (tasks + Mastery Tree)
  • Alchemy (synthesis + distillation passives)
  • Apex (hunts + Soul Stones)
  • Delve, Journey, Prestige (cosmetic), Quests, Gathering skills (with mastery), PvP, Curios, Events, Minigames, Trade, Ideology, Companions (incl. mastery)
  • Codes / redeem system (flexible reward codes granting currencies and items)

Common Patterns

  • Fetch player data then use factory functions to attach equipped gear.
  • Child views use parent= to avoid repeating IDs.
  • State-changing buttons usually use a _processing flag to avoid re-entrancy.
  • Top-level interactive features use state_manager.set_active / clear_active.
  • BaseView.on_timeout helps with cleanup.
  • Modifiers and passives are generally handled through registries rather than hardcoded per monster.
  • New images/assets are processed via the tools and scripts under assets/.

Adding Features (typical flow)

  1. Schema change in database/schema.sql + repository methods.
  2. Model updates (usually core/models.py or module-local).
  3. Logic in <module>/mechanics.py.
  4. Views extending BaseView + any stateless builders.
  5. Thin command handler in a cog.
  6. State management around long-running interactions.
  7. Update asset pipelines if new visuals are involved.

Contributing Notes

Reference areas that demonstrate current factoring: core/inventory/, core/combat/, core/settlement/.

Changes that fit the style of nearby code tend to integrate cleanly.

Test changes by running the bot locally.

See the main README.md for setup instructions.

Last updated: June 2026 — synced with currency migration (player_currencies table), new codes repo + /redeem_code, models reorganization (shim + domain splits), settlement view logic refactors, and other June changes. The project follows the layering in spirit.

Clone this wiki locally