Skip to content

0.3.7

Latest

Choose a tag to compare

@Sparks-code1 Sparks-code1 released this 05 Sep 16:46
· 33 commits to main since this release
A comeback power is claimed against the copy it is written to.

The pool is exclusive: no two factions may ever hold the same power, and it is
a permanent campaign mark. Both claim paths took the first id THEIR OWN copy
said was free, and that copy is a snapshot.

Two players knocked out by one stroke choose on two machines. Neither has heard
of the other's claim, so both modals offer the same power and both take it --
and the merge cannot help, because nothing about the result looks wrong to it:
one faction key added on each side, kept, and one id added to
claimedComebackPowers twice, deduped. Two factions holding one power and a
claimed list saying it went once. Nothing downstream can tell that happened.

claimComebackPower makes the pick against whatever copy it is handed. As
`reapply` that is the freshly-read row, so a preference still free is honoured,
one taken since is replaced by the next free power, and a faction that already
holds one is returned untouched -- which is what makes it safe to re-run.

RE-PICKING RATHER THAN REFUSING is a decision, not an oversight: refusing
leaves an eliminated player with no comeback power at all, which is worse than
a different one. It is not silent either -- the swap says so on their screen,
because it is a permanent mark on their own faction.

Both paths go through the one rule now, so the AI's automatic pick and the
human's choice cannot drift apart on exclusivity. The rule is in gameLogic,
parameterised by the pool so lib does not import a component, and unit-tested
rather than pinned by source.

Six sabotages: the preference trusted when taken, the already-holds guard
removed, an exhausted pool handing out the last power again, the human path
deciding from a snapshot, and each of the two rebuilds unwired separately.

One note on the tests. Unwiring the AI's rebuild passed at first: both paths
spell it identically, so `.test()` was satisfied by the human's and the pin sat
green over the bug. It counts the occurrences now, and each path fails on its
own. Found by the sabotage meant to prove the pin worked -- which is the
argument for running it.

113/113 unit, 24/24 e2e, build green, edge 16/16.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>