Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions docs/playability/ai-behavior-findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# AI behaviour findings — warhead mix, hoarding, game length

Follow-up analysis across all 300 games (100 per level), computed by
`scripts/playability/extra.ts` (deterministic replay of the same seeds; AI =
the four computer players, i.e. every cast member except the human `player1`).
Every number below is machine-computed, not eyeballed.

## Q1 — Did the AI mostly use small nukes? Yes, and more so as difficulty rises.

Share of AI warheads **fired**, by yield (built mix is within ~1pt, so they
fire what they build):

| Level | small | medium | large |
|--------|-------|--------|-------|
| easy | 71.3% | 16.4% | 12.4% |
| normal | 89.2% | 7.0% | 3.8% |
| hard | 98.5% | 1.5% | 0.0% |

Small warheads dominate everywhere. The trend is monotonic: the *harder* the
level, the *more* the AI concentrates on small warheads (hard is almost purely
small, and never fired a single large warhead in 100 games). Small warheads are
the cheapest, most AP-efficient way to keep a salvo in the air; the tuned
planners converge on them. The large-warhead usage on **easy** is the exception,
and it is a symptom of randomness, not strategy (see the paradox below).

## Q2 — Did they fire evenly or hoard? They fire almost everything, front-loaded — not hoarders.

**Almost no hoarding.** Warheads fired as a percentage of warheads built:

| Level | fired/built | leftover warheads at game end (all 4 AI, per game) |
|--------|-------------|-----------------------------------------------------|
| easy | 91.7% | 3.95 |
| normal | 95.4% | 2.71 |
| hard | 95.6% | 3.11 |

The AI builds warheads to shoot them, not to stockpile. The small leftover
(~3–4 warheads across all four AI combined) sits mostly on leaders who die
before they can fire the last one — and final-retaliation empties even that on
elimination.

**Cadence is front-loaded, not even.** Share of all AI launches by game-third:

| Level | early | mid | late |
|--------|-------|------|------|
| easy | 40.8% | 34.2%| 25.0%|
| normal | 45.5% | 33.9%| 20.6%|
| hard | 38.1% | 39.6%| 22.4%|

They open aggressively — the early/mid thirds carry ~75–80% of all launches —
and taper in the final third, largely because leaders are dead by then and there
are fewer guns left firing. There is no "build up quietly, then unload" hoarding
pattern; the shooting starts early and thins out as the board empties.

## Q3 — Average game length

| Level | avg rounds | median | min | max |
|--------|------------|--------|-----|-----|
| easy | 15.21 | 15 | 6 | 36 |
| normal | 17.47 | 17 | 8 | 34 |
| hard | 17.37 | 17 | 17 | 18 |

Easy games are the **shortest** (and the widest spread). Hard is almost fixed at
17–18 rounds — a symptom of its near-deterministic script (see the hard
playability report).

## Bonus — why is the human's success lower on easy (8% survival) than normal (18%)?

Counter-intuitive, but the AI-behaviour data explains it. "Easy" injects **30%
random AI moves**; that does not make the AI weaker in a way that helps a
cautious human — it makes them **chaotic and more lethal**:

- easy AI fires **large** warheads 3× as often as normal (12.4% vs 3.8%) — random
deviation from the tuned small-warhead plan puts bigger, deadlier strikes on
the board,
- easy games are **shorter** (15.2 vs 17.5 rounds) and far more often end in
**mutual annihilation** (42% pyrrhic vs 17% — see the per-level reports).

The human proxy is *measured-reactive*: it waits, retaliates, and never opens
fire. Against sharp-but-predictable **normal** AI (mostly small warheads,
consistent targeting), games run longer and resolve to clean single-survivor
endings a patient player can outlast → 18% survival. Against **erratic easy** AI,
big random strikes land unpredictably and the board detonates before any stable
order emerges → the passive human is caught in the crossfire → 8% survival.

**Takeaway:** lowering AI skill *raised outcome variance and lethality*, which
punishes a cautious human more than a competent-but-legible opponent does. If
"easy" is meant to be gentler for new players, the current randomness knob is the
wrong lever — it should reduce AI aggression/targeting quality, not add noise
that manifests as bigger, more chaotic nukes.
100 changes: 100 additions & 0 deletions docs/playability/easy/games.jsonl

Large diffs are not rendered by default.

403 changes: 403 additions & 0 deletions docs/playability/easy/games.md

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions docs/playability/easy/play-summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Playability Run Summary — easy

Source: `docs/playability/easy/games.jsonl` (100 records) and `scripts/playability/aggregate.ts` output. All numbers are from the aggregate JSON.

## Run

- Games played: 100
- Finished: 100
- Unfinished (hit 60-round cap): 0

## Outcome distribution

- survivor: 58
- pyrrhic: 42
- apocalypse: 0

## Winner distribution

- chump: 40
- mileigh-hem: 36
- player1 (human): 18
- netanyahoo: 3
- carnage: 3

## Human (player1) metrics

- Win rate: 18%
- Survival rate: 8%
- Win-or-survive rate: 18%
- Avg placement: 1.5 (placement dist: 1st ×50, 2nd ×50)
- Avg rounds per game: 15.21 (median 15, min 6, max 36)
- Avg launches made: 7.15
- Avg launches received: 11.13
- Avg hits landed: 5.02
- Avg hits taken: 10.37
- Avg final population: 0.85
- Avg eliminated round: 12.33

## Game-level

- Avg total launches: 50.51
- Avg total impacts: 46.5
- Avg eliminations: 4.42
56 changes: 56 additions & 0 deletions docs/playability/easy/playability-outcome.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# easy — Playability Outcome Report

## Verdict: PUNISHING

At the difficulty setting labelled "easy", a competent, measured human policy **wins 18% of games, survives just 8%, and is dead in 82%** — while being out-damaged roughly two-to-one (10.37 hits taken vs 5.02 landed). The game is coherent and always resolves, and a skilled opening *can* win, but the label promises the opposite of what the player gets. "Easy" here plays as the hardest thing a casual player will meet, not the gentlest.

*All figures from `scripts/playability/aggregate.ts easy` (100 games). Example seeds cited from `docs/playability/easy/games.md`.*

---

## Is it FUN / FAIR / WINNABLE?

**Winnable: yes, but barely, and mostly the wrong way.** The human takes the game in 18 of 100 seeds. But 10 of those 18 are **pyrrhic** — the human wins and dies in the same exchange (easy-1, 13, 14, 20, 31, 43, 50, 60, 67, 84). Only **8 games** end with the human actually alive and holding the board (easy-11, 12, 42, 52, 61, 71, 74, 76). So the "you win and walk away" experience — the thing a player would call a win — happens **8% of the time on the easiest setting.**

**Fair: no, for a level called "easy."** Difficulty is the only independent variable across levels (fixed cast, fixed human policy), so the comparison is clean, and at the bottom of the ladder the human still: dies in 82% of games, dies before the median game ends (avg eliminated round 12.33 vs median 15), and finishes on zero population in ~92% of games (avg final pop 0.85M). 27 of 100 games are already lost for the human by **round 8** — before the player has meaningfully acted. A first-time player on the "easy" level would lose four out of five games, most of them quickly. That is not a fair on-ramp.

**Fun: mixed.** The good news is the engine never breaks — 0 apocalypse, 0 round-cap stalls, every game reaches a decision, and there is genuine outcome variety (58 survivor / 42 pyrrhic). The bad news is two structural drags on enjoyment: the 42% mutual-destruction rate means half your "wins" are deaths, and the attritional long tail (below) turns roughly a fifth of games into a boring lob-fest.

---

## Player agency: thin, front-loaded, and often overridden

Agency exists but it is narrow. The clearest signal: **every clean human win is built on a concentrated early volley.** easy-61 (final pop 20M, won), easy-42 (17M), easy-74 (17M), easy-11 (12M) all show the human landing 8–13 launches in the first handful of rounds and reaching the endgame with population banked. When the human hits hard and early, it wins and lives. That is real agency.

But it is swamped by the AI melee for three reasons:

1. **The opening burst is not under the human's control.** carnage and netanyahoo die in a round 4–8 crossfire in the overwhelming majority of games regardless of what the human does (easy-5, 6, 10, 19, 22, 23, 66, 75, 88, 89…). The human is frequently caught in that same burst — 27 games end in human death by round 8.
2. **The measured-reactive posture structurally loses.** Never-first-strike + always-retaliate means the human is perpetually a step behind: out-launched 11.13 to 7.15 and out-hit 10.37 to 5.02. A policy that only ever answers cannot out-trade attackers who open. At an "easy" level a patient, reasonable player should be rewarded, not punished 2:1.
3. **The endgame is a coin-flip on who swings last.** With 42% of games pyrrhic, the deciding factor in the final exchange is timing of the last salvo, not accumulated skill — the human can play a clean game and still die in the mutual-destruction finish (easy-20, easy-67: human wins and dies in the final round alongside mileigh-hem).

Net: the human meaningfully affects *whether it wins big early*, but the *base rate* of the game — early carnage, 2:1 damage deficit, MAD endgame — is set by the AI cast, not the player.

---

## Difficulty feel

- **Pacing.** Median 15 rounds is fine. The problem is the tail: once the board narrows to 2–3 depleted leaders, matches degrade into single-launch, zero-impact rounds that drip for 10–25 turns before a final burst. easy-54 runs **36 rounds with ~20 of them landing nothing** (r16–r33 are all 1-launch/0-impact); easy-3, 31, 84, 86 show the same limp. This is the main frustration point — not lethal, just tedious.
- **Snowballing.** Front-loaded rather than snowballing. The heavy early exchange (rounds 4–8) does most of the killing (4.42 of 5 leaders eliminated per game); whoever emerges from it with population banked tends to close it out. There is no runaway-leader snowball, but there *is* an early-elimination cliff the human frequently falls off.
- **Dominant strategy.** For the human, the only strategy that clearly works is **hit hard and early** — the opposite of the measured-reactive policy under test. The passive retaliate-only posture is dominated. For the AI, chump and mileigh-hem's approach (76 combined wins) dominates carnage and netanyahoo's (6 wins), so the "easy" field is really two strong AIs plus fodder.
- **Frustration points.** (a) Dying by round 8 with little input (27 games). (b) Winning and dying anyway (10 of 18 wins). (c) The 20-round lob-fest tail. (d) Being out-damaged 2:1 on the *easiest* setting.

---

## Recommendations (prioritised)

1. **Dial down AI aggression / launch volume at easy (highest impact).** The human is out-hit 10.37 to 5.02. At the easiest setting the target should be rough parity or a human advantage. Reduce AI launches-per-turn or AI targeting priority on the human specifically so hits-taken ≈ hits-landed. This is the single lever most likely to move win-rate from 18% toward a level-appropriate 50%+.

2. **Cut the pyrrhic rate (currently 42%).** The endgame rewards the last swing over survival. Introduce an endgame survival incentive — cheaper/stronger shields in the final phase, damage falloff as leader count drops, or an AP tax on all-in final salvos — so a decisive last strike doesn't reliably kill the striker. Goal: push pyrrhic well below 25% so "winning" usually means "surviving."

3. **Rebalance the AI cast, or make "easy" gentle across the board.** chump (40) + mileigh-hem (36) win 76%; carnage (3) + netanyahoo (3) are fodder that die rounds 4–8. Either the "easy" setting should suppress the two dominant AIs (not just create early victims), or the four AIs should be brought toward parity so the human isn't effectively fighting two bosses.

4. **Fix the attritional tail.** Once ≤3 leaders remain with depleted arsenals, games drip 1-launch/0-impact for up to ~30 rounds (easy-54). Add escalating AP over time, a soft round-count pressure that raises stakes late, or improved targeting so a trailing leader can't limp indefinitely. Median pacing is good; only the tail needs surgery.

5. **Stop surfacing `avgPlacement` as a player metric.** It reads 1.5 (dist {1:50, 2:50}) but is a cast-order tie-break among zero-population leaders (see `runner.ts:143`), not earned rank — it makes the human look like it's placing top-2 every game while it actually dies 82% of the time. Report win-rate and survival-rate; drop or relabel placement.

6. **Reconsider the intended human baseline for "easy."** The policy under test is deliberately measured (never first-strike). If the design intent is that a reasonable, non-aggressive player should comfortably clear the easiest level, the AI must be gentle enough that pure retaliation wins the majority. Today retaliation loses 82%, so either the AI is too hot for the label or the level should be renamed to reflect its real difficulty.
59 changes: 59 additions & 0 deletions docs/playability/easy/trend-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# easy — Trend Analysis

*Source: `scripts/playability/aggregate.ts easy` over 100 games (`docs/playability/easy/games.jsonl`). Every number below is from that aggregate JSON; example seeds are cited from `games.md`.*

## Headline

At "easy" the human dies in **82 of 100 games** and takes roughly **twice the damage it deals** (10.37 hits taken vs 5.02 landed). Games resolve cleanly — no apocalypse, no round-cap stalls — but nearly half (42%) end in mutual destruction, and the win column is owned by two AIs (chump + mileigh-hem = 76 wins) while the other two are early fodder. This does not read as an "easy" difficulty curve for the player.

## How games END — outcome mix

| Outcome | Count | Meaning |
|---|---|---|
| survivor | 58 | one leader left standing, others dead |
| pyrrhic | 42 | the "winner" also died — mutually assured destruction |
| apocalypse | 0 | — |
| unfinished (60-round cap) | 0 | — |

Two things stand out. First, **games always conclude**: 100/100 finished, zero hit the round cap, zero ended with the whole board dead. The engine drives every match to a decision. Second, **42% of decisions are pyrrhic** — the winner blows itself up landing the final blow. This is a very high mutual-destruction rate: on almost half the board the last exchange kills the striker too. The endgame is decided by whoever throws the last punch, not by who is left standing, which is why so many "wins" are corpses (e.g. easy-63 r9: 21 launches wipe four leaders at once; easy-65 r6: 22 launches kill all five simultaneously).

## Game-length distribution and escalation

- Rounds: min **6**, median **15**, avg **15.21**, max **36**.
- Per game: avg **50.51** launches, **46.5** impacts, **4.42** eliminations (of 5 leaders).

The median 15-round game is healthy, but the distribution has a **long degenerate tail**. The escalation trajectory is front-loaded: a heavy opening burst around rounds 4–8 knocks out the weak leaders (carnage and netanyahoo almost always die in this window — see easy-5 r5, easy-19 r4, easy-66 r5), then the survivors trade down. When the board narrows to 2–3 leaders with depleted arsenals, matches degrade into a **1-launch-per-round, 0-impact stalemate** that limps for 10–25 rounds before a final burst resolves it. easy-54 is the extreme: 36 rounds, of which ~20 are single-launch rounds landing nothing (r16–r33), before the human finally dies. easy-3 (31r), easy-31 (31r), easy-84 (31r), easy-86 (32r) show the same lobbing tail. So escalation is bimodal: a decisive early crescendo, then either a fast finish or a slow attritional drip.

## The human's typical trajectory

- Win rate: **18%** — of which **8 games** are clean survival (human alive at the end) and **10 games** are pyrrhic (human wins but dies: easy-1, 13, 14, 20, 31, 43, 50, 60, 67, 84).
- Survival rate: **8%** — the human walks away alive in only 8 of 100 games.
- Eliminated in the other **82 games**; **27 of those deaths land by round 8** (the opening burst).
- Avg eliminated round: **12.33**; avg final population **0.85M** (i.e. the human ends on zero in ~92% of games).
- Combat: launches **7.15** made / **11.13** received; hits **5.02** landed / **10.37** taken.

The through-line: the human is **out-launched (~11 vs 7) and out-hit 2-to-1**, dies before the median game ends, and finishes on zero population in all but the 8 clean wins. The measured-reactive policy (never open with a first strike, always retaliate) means the human spends the game absorbing more than it returns. When the human does win cleanly it is because it landed a big early volley and reached the endgame with population intact — easy-61 (final pop 20M), easy-42 (17M), easy-74 (17M), easy-11 (12M) all feature 8–13 human launches concentrated early. Those are the exception, not the pattern.

### Placement is a degenerate metric — ignore it

The aggregate reports avgPlacement **1.5** with a placement distribution of **{1: 50, 2: 50}** — the human never ranks below 2nd. This is **not** a signal of human strength. Placement is defined (`runner.ts:143`) as rank by final population, with eliminated leaders scored at 0 and ties broken by cast order (player1 is listed first). In the 42 pyrrhic games everyone ends at 0, so the human tie-breaks to rank 1; add the 8 clean-survival wins and that is exactly the 50 first-place finishes. The other 50 are survivor games won by an AI, where that AI has positive population and the human (0) tie-breaks to rank 2. The 50/50 split is a cast-ordering artifact of everyone dying, not a placement the player earned. **Read win-rate (18%) and survival-rate (8%), not placement.**

## Who actually wins — and what it says about the cast

| Winner | Wins |
|---|---|
| chump | 40 |
| mileigh-hem | 36 |
| player1 (human) | 18 |
| netanyahoo | 3 |
| carnage | 3 |

The cast is **badly lopsided**. chump and mileigh-hem take **76%** of all games; carnage and netanyahoo win **3 each** and are almost always the first two eliminated (they die together in the round 4–8 opening burst across easy-5, 6, 10, 19, 22, 23, 52, 59, 66, 75, 88, 89…). They function as early fodder, not competitors. So "easy" is not a uniformly gentle field — it is two dominant AIs, two punching bags, and a human that finishes third.

## Degenerate patterns to flag

1. **Human loses 82% of games at the easiest setting** — win 18%, clean survival 8%. The difficulty label and the player experience disagree.
2. **42% pyrrhic** — the endgame rewards throwing the last punch over surviving; nearly half of all wins are suicides.
3. **Cast dominance** — chump + mileigh-hem = 76 wins; carnage + netanyahoo = 6 wins and reliably die first. The field is not balanced within itself.
4. **Long attritional tail** — once down to 2–3 leaders, games drip 1 launch / 0 impacts per round for 10–25 rounds (easy-54 at 36r is the worst). Median pacing is fine; the tail is not.
5. **Placement metric is meaningless** here (cast-order tie-break among zero-pop leaders) and should not be surfaced as a player-performance number.
Loading
Loading