Skip to content

AI evaluates start world choices from a game state it has never seen before #68

Description

@davidspies

This only affects games with a start world choice — any expansion, or the New Worlds promo. In the plain base game, start worlds are simply dealt and revealed, and you make your discard decision already knowing your opponent's world; the AI's discard logic evaluates positions with everyone's world on the table, which is the kind of position the net trained on, so the problem never arises. But as soon as start world choice is in play, the ordering changes: you pick your world and your discards before seeing what your opponent got. That decision goes through a different code path, and that's where the trouble is.

When the AI makes that combined choice, ai_choose_start_aux() (src/ai.c:5049) simulates a first round to score each option. But in that simulation, only the AI's own start world gets placed. The opponents get nothing — no start world, no actions, just an assumption that they'll discard 2 cards (src/ai.c:5093).

So the neural net is asked to score a position where the opponent has an empty tableau after a full round of play. That can never happen in a real game, which means the net was never trained on anything like it. Faced with "my opponent has literally nothing," it concludes the game is basically already won and returns scores like 0.95+ for every single start world option.

To be fair, some of this is forced by the rules: since the choice is simultaneous, the AI legitimately can't know the opponent's world. But "unknown world" and "no world at all" are very different positions to show the net — an honest unknown would still be somewhere in the range of normal games.

I found this while building a review tool that replays BoardGameArena games through this engine and shows the AI's score for each option.

Concrete example, from this 2-player advanced game (viewable by any BGA account): https://boardgamearena.com/table?table=866845342

At the start of that game I was offered Epsilon Eridani or Alpha Centauri, with a hand of Export Duties, Free Trade Association, Galactic Survey: SETI, The Last of the Uplift Gnarssh, Reptilian Uplift Race, and Replicant Robots. The engine's scores for the best line with each world:

  • Epsilon Eridani (discarding Galactic Survey: SETI + Replicant Robots): 0.995
  • Alpha Centauri (discarding Reptilian Uplift Race + Replicant Robots): 0.927

A 99.5% win chance before the game has started, against an opponent who hasn't even placed a world yet.

To see where the inflation comes from, I re-scored the same choice two more ways (my opponent's world turned out to be Terraforming Colonists):

How it's evaluated Epsilon Eridani Alpha Centauri
What the AI does: simulate my first round, opponent empty 0.995 0.927
Same first-round simulation, but opponent's world placed 0.919 0.821
No simulation, just score the position with both worlds placed 0.603 0.675

So the empty opponent accounts for part of the inflation, and the rest comes from the lookahead itself: the AI simulates a full round of progress for itself while the opponent does nothing, then scores that lopsided result. Only the bottom row is the kind of position the net was actually trained on, and only there do the numbers look like a believable turn zero.

Note the bottom row also flips the ranking: the plain positional score prefers Alpha Centauri, while both lookahead versions prefer Epsilon Eridani. That flip isn't caused by the empty-opponent bug (the ranking survived fixing that, middle row) — it's the lookahead seeing first-turn plans that a static evaluation can't. I'm not claiming the static ranking is the right one; the point is just that the absolute numbers the AI works from at this decision are far outside anything it was trained on.

Does this make the AI play badly? Probably not much. It only uses these scores to rank its options against each other, and at least in this example the "opponent has nothing" bonus inflated both options about equally, so the ranking survived. But the net is guessing in territory it knows nothing about, so there's no guarantee that always holds. And anything that prints these raw scores (debug output, analysis tools) will show nonsense numbers at this one decision.

Easy to reproduce without BGA: any 2-player game with an expansion (or the New Worlds promo) enabled, so there's a start world choice; print b_s per candidate in ai_choose_start_aux().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions