# AI Agent Guide — IdleMaxx

IdleMaxx is an OSRS-inspired idle/incremental game written in Python. Players level up skills by
running activities. There is no real-time combat — only skilling and progression. The game is
playable via a terminal UI (`idlemaxx`) or a Discord bot (`idlemaxx-discord`).

This file contains step-by-step instructions for making common changes. Read the relevant section
before starting any task.

---

## Prerequisites

The only required tool is **uv** (Python package manager). Install it with:

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Or on macOS/Linux with Homebrew: `brew install uv`

The `just` task runner is an optional convenience. If it is not available, use the equivalent
commands shown in each section below.

---

## Environment Setup

Run once after cloning the repo:

```bash
uv sync --locked --dev
uv run pre-commit install
```

Or, if `just` is available: `just setup`

**To verify setup worked:**
```bash
uv run pytest
```

All tests should pass.

---

## Project Structure

```
src/idlemaxx/
├── models/
│   ├── models.py     ← Activity enum, all game data definitions, ORM models
│   ├── skills.py     ← Skill enum (list of all skills)
│   └── items.py      ← Item enum (list of all items)
├── game.py           ← ALL game logic (never put game logic elsewhere)
├── cli.py            ← Terminal UI frontend
└── discord_bot.py    ← Discord bot frontend
tests/
├── test_game.py      ← Tests for game logic
├── test_models.py    ← Tests for data models
└── test_cli.py       ← Tests for the terminal UI
dev/
├── context.md        ← Context for any in-progress feature
├── plan.md           ← Implementation plan for current feature
└── todo.md           ← Task checklist
```

---

## How to Add a New Skill

**Example:** Adding a "Cooking" skill.

### Step 1 — Add the skill to the Skill enum

Edit `src/idlemaxx/models/skills.py`:

```python
class Skill(Enum):
    MINING = "mining"
    WOODCUTTING = "woodcutting"
    FISHING = "fishing"
    SMELTING = "smelting"
    COOKING = "cooking"      # ← add this line
```

The string value must be lowercase with underscores, matching the enum name.

### Step 2 — Create activities that use the new skill

Follow the "How to Add a New Activity" section below.

### Step 3 — Verify

```bash
uv run pytest
```

---

## How to Add a New Item

**Example:** Adding "Raw Salmon".

Edit `src/idlemaxx/models/items.py`:

```python
class Item(Enum):
    TIN_ORE = "tin_ore"
    COPPER_ORE = "copper_ore"
    # ... existing items ...
    RAW_SALMON = "raw_salmon"   # ← add this line
```

The string value must be lowercase with underscores, matching the enum name.

**Verify:**
```bash
uv run pytest
```

---

## How to Add a New Activity

Activities define what players can do (e.g. chop a tree, mine ore, catch fish).

**Example:** Adding "Cook Salmon" — requires level 25 Cooking, consumes 1 Raw Salmon, rewards
50 Cooking XP, produces 1 Cooked Salmon.

### Step 1 — Ensure the required Skill and Items exist

Add `COOKING` to `skills.py` and `COOKED_SALMON` / `RAW_SALMON` to `items.py` if not already
present (see sections above).

### Step 2 — Add the activity to the Activity enum

Edit `src/idlemaxx/models/models.py`. Find the `Activity` enum and add a new member:

```python
class Activity(Enum):
    # ... existing activities ...

    COOK_SALMON = ActivityData(
        name="cook_salmon",          # unique snake_case identifier
        action_time=1.5,             # seconds per action
        category=ActivityCategory.COOKING,
        skill_requirements=[
            ActivitySkillRequirement(skill=Skill.COOKING, required_level=25),
        ],
        materials=[
            ActivityMaterial(item=Item.RAW_SALMON, quantity=1),  # consumed per action
        ],
        skill_rewards=[
            ActivitySkillReward(skill=Skill.COOKING, xp=50),
        ],
        item_rewards=[
            ActivityItemReward(item=Item.COOKED_SALMON, quantity=1),
        ],
    )
```

**Field reference:**

| Field | Type | Description |
|-------|------|-------------|
| `name` | `str` | Unique identifier (snake_case). Used in the UI and internally. |
| `action_time` | `float` | Seconds to complete one action cycle. |
| `category` | `ActivityCategory` | Groups the activity in the UI. |
| `skill_requirements` | list | Skills + minimum level required to start. Omit if none. |
| `materials` | list | Items consumed per action (e.g. ores for smelting). Omit if none. |
| `skill_rewards` | list | XP granted per completed action. Omit if none. |
| `item_rewards` | list | Items produced per completed action. Omit if none. |

### Step 3 — Add a new ActivityCategory if needed

If the activity belongs to a category that doesn't exist yet, add it to `ActivityCategory`
in `src/idlemaxx/models/models.py`:

```python
class ActivityCategory(Enum):
    WOODCUTTING = ActivityCategoryData(display_name="Woodcutting", icon="🪓", abbreviation="wc")
    MINING      = ActivityCategoryData(display_name="Mining",      icon="💎", abbreviation="min")
    FISHING     = ActivityCategoryData(display_name="Fishing",     icon="🎣", abbreviation="fish")
    SMELTING    = ActivityCategoryData(display_name="Smelting",    icon="🔥", abbreviation="smelt")
    COOKING     = ActivityCategoryData(display_name="Cooking",     icon="🍳", abbreviation="cook")  # ← add
```

### Step 4 — Verify

```bash
uv run pytest
```

---

## How to Run the Game Locally

```bash
uv run idlemaxx
```

This opens the terminal UI. Create a character and start an activity to test your changes.

---

## How to Run Tests

```bash
uv run pytest           # all tests
uv run pytest tests/test_game.py   # single file
```

All tests must pass before publishing. Tests use an in-memory database and do not affect any
saved game data.

---

## Testing Requirements

These rules apply to all code changes:

- Every new feature must have tests covering the happy path and key edge cases.
- Every bug fix must include a regression test that would have caught the bug.
- Tests go in:
  - `tests/test_game.py` — game logic
  - `tests/test_models.py` — data models
  - `tests/test_cli.py` — CLI behavior
- Run `uv run pytest` before marking any task complete.

---

## How to Publish a New Version

Publishing creates a new release on PyPI so others can install it with `pip install idlemaxx`.

**Requirements before publishing:**
- You must be on the `main` branch
- All changes must be committed (no uncommitted files)
- The latest CI run on `main` must have passed
- The `gh` CLI must be installed and authenticated (`gh auth login`)

**Command:**
```bash
bash scripts/release.sh v0.3.0
```

Or, if `just` is available: `just release v0.3.0`

Replace `0.3.0` with the new version number. Follow this convention:
- Increment **patch** (0.3.**1**) for small fixes and new content (items, activities)
- Increment **minor** (0.**4**.0) for new features or new skills
- Increment **major** (**1**.0.0) for large breaking changes

The script will verify the branch, clean state, and CI status, then create a git tag, push it,
and watch the GitHub publish workflow complete.

**Do not** manually edit any version numbers in files — versioning is automatic via git tags.

---

## Architecture Rules

These rules must be followed for all changes:

1. **All game logic goes in `game.py`.** The `cli.py` and `discord_bot.py` files are frontends.
   They call methods on the `Game` class and display results. They do not calculate rewards,
   check skill levels, or manipulate game state directly.

2. **All game data is defined in enums.** Skills, items, and activities are enums with their
   properties (XP values, required levels, drop tables) in the enum value — not in a database
   or config file.

3. **Never rename an enum `.value` string that is already in production.** These strings are
   stored in the SQLite database. Renaming them will break existing save files.

4. **Type annotations are required on all functions.** The linter will reject code without them.

5. **Line length limit is 120 characters.**

---

## Frontend Requirements

These rules apply to all new functionality:

- New functionality must be implemented in the CLI (`cli.py`) at minimum before merging.
- Discord bot (`discord_bot.py`) support is encouraged but may be deferred.
- When deferring Discord bot support, add a `[ ]` item under "Discord Bot Parity" in `ROADMAP.md`
  so it is tracked and not forgotten.

---

## Tooling Reference

| Tool | What it is | How to install |
|------|-----------|----------------|
| `uv` | Python package manager (required) | `curl -LsSf https://astral.sh/uv/install.sh \| sh` |
| `just` | Task runner (optional) | `brew install just` or https://just.systems |
| `gh` | GitHub CLI (required for publishing) | `brew install gh` or https://cli.github.com |

**Never use `pip install`** — always use `uv add` to add dependencies.
