Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.8 KiB
11. Anti-Abuse Safeguards
< Back to Index | Next: API Endpoints >
11.1 Milestone Threshold Tuning
The primary anti-abuse lever is milestone threshold configuration. Thresholds defined in
evolution_milestone.threshold are tunable by admin without code changes. If data shows
milestones being completed too quickly (e.g., full T4 in under a week), admin raises thresholds.
If players stall at a specific milestone, admin can lower the threshold. Already-credited
completions are not retroactively revoked.
11.2 Game Mode Diversity Requirements
"Win games" milestones do not specify a mode and can be completed in Exhibition (vs AI). This is intentional — exhibition games are still real games with real D20 outcomes. Gauntlet and campaign milestones specifically cannot be completed in exhibition, creating incentive to engage with competitive and narrative modes.
If exploitation is observed (e.g., players spinning up exhibition games specifically to complete
milestones without meaningful play), a safeguard can restrict "win games" milestones to campaign,
gauntlet, or unlimited modes via the game_mode field on evolution_milestone.
11.3 Evaluation Deduplication
The post-game evaluator must be idempotent. If the game pipeline retries a post-game callback,
progress counts should not double. The evaluator recalculates current counts by re-querying the
source tables (not by incrementing cached values) and compares against the stored current_count.
Progress is updated only when the newly computed count exceeds the stored count.
11.4 Rarity Cap Enforcement
A fully evolved card receiving a rarity upgrade cannot exceed HoF (the maximum rarity). If a Sta
card completes T4, it becomes All-Star. If a card is already HoF, it receives the T4 boost deltas
but no rarity change. This is enforced at application layer by checking player.rarity_id
against the HoF ceiling before incrementing.
Rating cap enforcement: Individual stat columns have hard caps (e.g., hold rating at -5).
The apply_evolution_boosts() function truncates any delta that would exceed a cap and
discards the excess (no redistribution — see 05-rating-boosts.md).
This is an intentional soft penalty for cards already near their ceiling.
11.5 Evaluation Performance
Milestone progress is resolved via player_season_stats (a materialized view of aggregate
stats), not raw stratplay table scans. Each post-game evaluation is a simple SELECT keyed
on (team_id, player_id) — lightweight and independent per team. Concurrent games across
different teams do not contend since evolution state is keyed by (player_id, team_id).
The post-game callback should only evaluate cards that participated in the just-completed game, not the entire roster.