ADR-004: EMA Smoothing for Profile Updates¶
Status: Accepted Date: 2026-03-02 Context: The player decision profile needs to update after every game to reflect evolving behavior. The update mechanism must balance responsiveness to genuine shifts with stability against noise.
Decision¶
All profile distribution updates use Exponential Moving Average (EMA) with alpha = 0.3:
This applies to: - Category driver distributions: How a player's driver tendencies shift per category - Context rule behavior distributions: How a player responds under each context trigger - Delegation preferences (multiplayer): Trust strength between peer pairs
Updates are further weighted by:
- Decision strength (1-5 conviction scale): weight = 0.5 + (strength - 1) × 0.25 — a "no contest" choice (5) has 2x the weight of a "toss-up" (1)
- Game type multiplier: multiplayer = 1.0, solo = 0.85, speed_round = 0.4, intake = 0.0
Rationale¶
EMA at alpha=0.3 means the last ~3 games contribute roughly half the signal. This is responsive enough to detect genuine behavioral shifts (e.g., a player becoming more cautious after a bad experience) without overreacting to a single outlier game.
The decision strength weighting is critical: a player who marks a choice as "clear winner" (5/5) is expressing strong values alignment, while a "toss-up" (1/5) means the choice reveals little about their preferences. Without this weighting, ambiguous decisions would pollute the distribution equally with decisive ones.
Alternatives Considered¶
- Simple averaging (1/n): All games weighted equally. Rejected because early games would dominate the profile forever, making it impossible to detect genuine behavioral evolution.
- Sliding window (last N games): Only consider recent games. Rejected because it discards historical patterns — a player who was consistently principled for 50 games then pragmatic for 3 would look purely pragmatic.
- Higher alpha (0.5+): More responsive but unstable. A player having one atypical game would dramatically shift their profile. Alpha=0.3 was chosen empirically.
- Bayesian updating: More theoretically sound but significantly more complex to implement and debug. EMA approximates Bayesian updating well enough for this use case.
Consequences¶
- Profiles are always "warm" — there's no cold start after a break, because EMA preserves all history.
- A player who genuinely changes their decision-making style will see their profile shift within 5-10 games.
- Low-confidence patterns (< 5% weight or < 15% confidence) are pruned to prevent noise accumulation.
- The alpha value (0.3) is a constant in code, not a config parameter. Changing it requires a code change and understanding the downstream effects on prediction accuracy.
Key files:
- src/lib/ai/player-model.ts — EMA_ALPHA constant (line 65), updateCategoryPatterns(), updateContextRules()