Probability Modifier¶
The minigame score does not directly determine whether an activity succeeds or fails. It adjusts the probability that the server's resolution engine uses when rolling outcomes. The server remains the authority; minigame score is an input to that calculation, not the output.
Formula¶
$$ \text{modifier} = \text{clamp}(0.7 + \text{score} \times 0.7,\ 0.7,\ 1.4) $$
Where:
score∈ [0.0, 1.0] — submitted by client, capped server-side before usemodifier∈ [0.7, 1.4] — output range, bounded regardless of score- Score 0.0 → modifier 0.70 (30% probability penalty)
- Score 0.5 → modifier 1.05 (5% probability bonus)
- Score 1.0 → modifier 1.40 (40% probability bonus)
Score → Modifier Table¶
| Score | Modifier | Effect |
|---|---|---|
| 0.00 | 0.70 | −30% |
| 0.10 | 0.77 | −23% |
| 0.20 | 0.84 | −16% |
| 0.30 | 0.91 | −9% |
| 0.40 | 0.98 | −2% |
| 0.50 | 1.05 | +5% |
| 0.60 | 1.12 | +12% |
| 0.70 | 1.19 | +19% |
| 0.80 | 1.26 | +26% |
| 0.90 | 1.33 | +33% |
| 1.00 | 1.40 | +40% |
How Modifier Applies to Settlement¶
Settlement is the Durable Object alarm pass that resolves an expedition or activity. The modifier multiplies the activity's base success probability before the dice roll.
Example: Expedition Combat Round¶
Base hit_chance for a character = 0.65 (from loadout + skill + terrain).
Minigame score = 0.80 → modifier = 1.26.
Adjusted chance = min(0.65 × 1.26, 0.95) = 0.819, capped at 0.95.
// settlement pass (TownSettlementDO or ExpeditionGroupDO)
const base_chance = computeBaseChance(character, encounter);
const modifier = minigameResult?.modifier_applied ?? 1.0;
const adjusted = Math.min(base_chance * modifier, MAX_CHANCE);
const success = Math.random() < adjusted;
MAX_CHANCE = 0.95. No activity can be guaranteed by any modifier. The cap is enforced in the DO — not client-configurable.
Example: Crafting Quality¶
Crafting doesn't succeed/fail as binary — it produces a quality tier. The modifier shifts the quality distribution:
const base_quality_roll = seededRng.float(); // 0–1
const modified_roll = Math.min(base_quality_roll * modifier, 1.0);
const quality_tier = rollToQuality(modified_roll);
// quality tiers: poor / common / good / fine / exceptional / masterwork
Higher modifier = higher roll = better quality tier. Lower modifier = worse quality tier.
Example: Gathering Yield¶
Yield quantity is a base value with a multiplier:
const base_yield = template.base_yield; // e.g. 3–5 units
const yield_modifier = minigameResult?.modifier_applied ?? 1.0;
const actual_yield = Math.round(base_yield * yield_modifier);
Score 0.0 → ~30% less yield. Score 1.0 → ~40% more yield.
Skipping Minigame¶
If a player skips via Passive Mode (server-side flag), the Worker injects score = 0.5, modifier = 1.0. Activity proceeds with no penalty and no bonus. This matches the base Aelghar game behavior exactly.
If a player's session token expires before they submit (left the page open too long), the subsequent activity action returns 409 minigame_required. Client must request a new session and play again.
If the player never played and the activity_ref_id is a time-gated board order that expired, the Worker returns 410 board_order_expired.
Passive Mode Modifier¶
Passive Mode modifier is always 1.0. It is a fixed neutral value, not a penalty. The intent is that Passive Mode players participate in the same economy as Interactive Mode players — they just cannot gain the modifier bonus, which caps their ceiling at the base game's ceiling.
Skill Band and Score Equivalence¶
Higher skill band makes the minigame easier (wider windows, larger targets, bonus start score). This means:
- A Master-level character achieves a higher score on the same minigame content than an Untrained character, for the same real-world player skill level.
- The probability modifier therefore scales with the character's in-game progression — as intended.
- A highly skilled real player at low character skill still benefits but is bounded by the minigame's starting difficulty.
- A low-skilled real player at high character skill achieves moderate scores more easily due to the wider windows.
This is the intended design: both real-world player engagement and in-game progression contribute to outcomes. Neither alone is sufficient to dominate.
Modifier in Quality Score (Expeditions)¶
The base expedition model uses quality_score (0.0–1.0) accumulated over phases, written to expedition_result.quality_score at settlement. In the Interactive branch, the minigame modifier per departure is applied as a multiplier on the quality roll at each phase:
// ExpeditionGroupDO alarm handler
const minigameModifier = await getMinigameModifier(characterId, expeditionId, phase);
const phase_quality = rollPhaseQuality(encounter, loadout) * minigameModifier;
cumulative_quality = (cumulative_quality + phase_quality) / 2; // running average
A character who plays well every phase of a multi-phase expedition accumulates a compounded quality improvement. A character who plays poorly every phase incurs compounded quality loss. Single-phase expeditions (short runs) are affected by one minigame session only.
Anti-Exploitation Notes¶
- Score ceiling: Server clamps score to [0.0, 1.0] before applying formula. Submitted scores above 1.0 are silently clamped, not rejected (not worth punishing for floating-point edge cases).
- Modifier ceiling: 1.4× is the hard cap. A perfect automation bot gains at most 40% bonus — not a win condition.
- Modifier floor: 0.7× minimum even on score 0. This prevents the minigame from being used to deliberately tank outcomes (griefing guild expeditions).
- Guild expedition participation: Each expedition member submits their own session. The group modifier is the average of all member modifiers. One bad score pulls the average down slightly but cannot tank a group.