# 4. Milestone Challenge System

[< Back to Index](README.md) | [Next: Rating Boosts >](05-rating-boosts.md)

---

## 4.1 Milestone Design Philosophy

Milestones are evaluated by querying existing `stratplay`, `decision`, and `stratgame` tables at
the `player_id` level, filtered to games played after the card's `created_at` date. No new event
tables or pipeline changes needed.

**Performance Milestones** (looked up from `player_season_stats`):
- Record N hits
- Hit N home runs
- Reach base N times (H + BB + HBP)
- Strike out N batters (pitcher)
- Record N scoreless appearances (pitcher)

**Game Outcome Milestones** (looked up from `player_season_stats`):
- Win N games (any mode, with card in the rostered team)
- Win N games in a specific mode (campaign, gauntlet, unlimited)
- Record N saves or holds (pitcher)
- Record N quality starts (pitcher, from `decision` where is_start = true + derived ERA check)

Most milestone types resolve to a single column lookup against `player_season_stats` rather than
a full `stratplay` table scan. See [06-database.md](06-database.md) for the aggregate table
schema and [02-architecture.md](02-architecture.md) for the incremental update design.

**Event Milestones** (tracked via post-game callbacks):
- Complete a gauntlet event (any placement)
- Place top 3 in a gauntlet event
- Win a gauntlet event
- Complete a campaign stage with this card in the active roster

## 4.2 Milestone Quantity Targets

Milestones are calibrated so an average active player (4-6 games per week) completes a full track
in 4-8 weeks. This avoids both instant gratification and grind fatigue.

**Batter example milestones by tier:**

| Tier | Milestone A | Milestone B | Milestone C |
|------|-------------|-------------|-------------|
| T1 | Win 3 games with card rostered | Record 15 hits | — |
| T2 | Win 8 games with card in active lineup | Hit 5 HR | Reach base 30 times |
| T3 | Win 15 games with card in active lineup | Hit 12 HR | Record 60 hits |
| T4 | Complete a gauntlet with card rostered | Hit 20 HR | — |

**Starting pitcher example milestones by tier:**

| Tier | Milestone A | Milestone B | Milestone C |
|------|-------------|-------------|-------------|
| T1 | Win 3 games with card rostered | Record 10 strikeouts | — |
| T2 | Win 8 games as starter | Record 3 quality starts (6+ innings, 3 or fewer ER equiv) | Record 25 strikeouts |
| T3 | Win 15 games as starter | Record 8 quality starts | Record 60 strikeouts |
| T4 | Complete a gauntlet with card rostered | Record 12 quality starts | — |

**Relief pitcher example milestones by tier:**

| Tier | Milestone A | Milestone B | Milestone C |
|------|-------------|-------------|-------------|
| T1 | Win 3 games with card rostered | Record 5 holds or saves | — |
| T2 | Win 8 games with card active | Record 12 holds or saves | Record 25 strikeouts |
| T3 | Win 15 games with card active | Record 20 holds or saves | Record 3 scoreless appearances |
| T4 | Complete a gauntlet with card rostered | Record 30 holds or saves | — |

## 4.3 Milestone Completion Logic

Milestones are evaluated after each game completes. The post-game callback queries
`stratplay`/`decision`/`stratgame` for all cards on the team that participated, computes
accumulated progress against each milestone threshold, and updates `evolution_card_state.current_tier`
and `evolution_progress.current_count` as needed. Tier completion is evaluated after all milestones
in a tier are marked complete. The bot sends a Discord notification to the team channel when a
tier is completed and a rating boost is applied.

Progress can also be recomputed on-demand via the evaluate endpoint (useful for admin correction
or cache invalidation after a data fix).
