# 9. System Integrations [< Back to Index](README.md) | [Next: Economy >](10-economy.md) --- ## 9.1 Crafting System (#49) — Future Integration The crafting system (Gitea #49) is out of scope for this PRD and has not been fully designed. When crafting ships, the evolution system will need to define interaction rules (e.g., what happens to evolution state when a card is used as a crafting ingredient, whether evolution tier affects crafting output). Those rules will be specified in the crafting PRD. --- ## 9.2 Campaign Mode Evolution milestones of the `complete_campaign_stage` type are met when the team completes a campaign stage. The bot already records campaign stage completions; the evolution subsystem hooks into the post-game callback. Evolved cards used in campaign games contribute normally to game mechanics. No special campaign-mode rules for evolved cards. ## 9.3 Gauntlet Mode Gauntlet is the highest-stakes game mode. Two milestone types reference it directly: `complete_gauntlet` (finish any gauntlet) and `win_gauntlet` (place first). These are evaluated via the `gauntletreward` table's post-event callback, which triggers milestone evaluation for all active teams. Fully evolved cards used in gauntlet display their evolved name in the gauntlet bracket display, providing social prestige incentive for completing evolutions before entering gauntlet events. ## 9.4 Unlimited / Ranked PvP Evolved cards are legal in all game modes. Their higher ratings reflect the investment of gameplay time, not additional spending. This positions evolved cards as earned rather than bought power, which is important for PvP mode balance. There is no separate evolved card bracket or ladder. Evolved cards compete in the same pool. ## 9.5 Scouting System The scouting reports (`pd-cards scouting all`) aggregate stats at the `player_id` level across all cardsets. Evolution creates `variant`-specific rating rows, which the scouting report generator should ignore (it reads `variant = 0` base rows). No changes needed to scouting scripts. A future enhancement could flag evolved cards in scouting output with a visual marker. ## 9.6 Trading (Not Yet Implemented — Roadmap) Trading is not yet implemented but is on the roadmap. When it ships, the following rules apply: **Evolution resets on trade.** The traded card's `card.variant` is set to `0`, and it is disassociated from the selling team's `evolution_card_state` record. If the new team already has an `evolution_card_state` for this `player_id`, the traded card inherits that state (and its variant). If the new team has no prior state for this player, a fresh `evolution_card_state` is created with `current_tier = 0` and `progress_since` set to the trade date. The new team starts fresh — only stats accumulated in games played by the *new* team count toward milestones. **The selling team's state is unaffected.** If Oakland still has other copies of the same player_id, their `evolution_card_state` remains intact. The trade only affects the specific card instance being transferred. Example: If Mark McGwire evolves to T2 on the Oakland Athletics and that card gets traded to the St. Louis Cardinals, the Cardinals' McGwire card starts at T0 (assuming they had no prior McGwire cards). Only stats from Cardinals games count toward the new evolution progress. **The card's variant resets.** `card.variant` is set to `0` on the traded card instance, meaning it falls back to `player.image` and base ratings. The old variant's `battingcard`/`pitchingcard` rows and S3 images are NOT deleted — they may still be shared by other cards with the same hash. **The evolved card name resets.** Since the card is at T0 on the new team, no evolved name is displayed. **Purchased cosmetics do not transfer.** Cosmetics are attached to the selling team's `evolution_card_state`. The new team does not inherit the previous owner's premium visuals. **Design rationale:** This creates a loyalty incentive — the longer you keep a card, the more evolved it becomes. Trading away a fully evolved card is a real sacrifice, creating meaningful tension when trading eventually ships. ## 9.7 Pack Opening and paperdex When cards are acquired (pack opening, reward, etc.), the system resolves evolution state using a **batched eager** approach so that card flair is visible immediately during the opening: 1. Collect all `player_id` values from the pack's cards 2. Single batch query: `SELECT player_id, current_tier, variant FROM evolution_card_state WHERE team_id = ? AND player_id IN (?...)` 3. For cards with an existing state: set `card.variant` to match (inherits tier, cosmetics, flair) 4. For cards without a state: batch `INSERT` new `evolution_card_state` rows at `current_tier = 0`, `progress_since = card.created_at` 5. Batch `UPDATE` card variants for all cards that inherited existing state This reduces evolution resolution to ~3 queries total regardless of pack size, avoiding per-card round trips. The eager approach ensures evolved card visuals (and any future random cosmetic effects like holo pulls) display immediately during the pack opening experience rather than loading lazily on first view. paperdex tracks ownership booleans at the team+player level and does not need modification for evolution.