Business Card claimed a synergy with Hack, but Hack only retriggers
2s-5s and Business Card only pays on faces. The single retrig_scoring
tag lumped every retriggerer with every retrigger payoff.
retrig_scoring now means rank-agnostic (Dusk, Seltzer, Hanging Chad,
Splash). Hack gives retrig_low; Sock and Buskin gives retrig_faces.
Payoffs want only the scopes their ranks can reach: low-rank payoffs
(Even Steven, Odd Todd, Walkie Talkie, Fibonacci, Wee) add retrig_low,
face payoffs (Scary Face, Business, Photograph, Triboulet) add
retrig_faces, rank-agnostic ones (Hiker, the suit gems, The Idol) add
both. Scholar keeps only retrig_scoring - no retriggerer targets Aces.
This also kills Hack+Scholar, Hack+Scary Face, Hack+Photograph,
Hack+Triboulet, and Sock and Buskin vs every low-rank payoff.
Both new tags are full themes (catalog page, label, teaching line) so
Hack and Sock and Buskin stay visible in the Engine tab.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four fixes, all traced to the running source.
* The sell advisor could tell you to sell an ETERNAL joker, which
Card:can_sell_card refuses outright (card.lua:1993). It now never names
one, though they still count toward the best score -- they are part of
the build you are keeping. Advice you cannot take is worse than none.
* Copiers CHAIN. SMODS.blueprint_effect recurses (utils.lua:2269) and
Blueprint's own blueprint_compat is true, so Blueprint -> Blueprint ->
Baron really does give two Barons. The tooltip used to answer "Copying
Blueprint", the one reply that helps nobody; it now walks the chain to
the joker actually copied and shows the route. Capped at the board size
like vanilla, and a Blueprint/Brainstorm ring resolves to nothing
instead of hanging.
* blueprint_compat is tested for TRUTH by vanilla (utils.lua:2254), not
for `~= false` as I had it. A modded joker that simply omits the flag is
NOT copyable, and this mod supports other mods' jokers by design, so
saying otherwise was a lie about someone else's content.
* A debuffed joker copies as nothing (same line), and a debuffed joker
does nothing at all this blind -- both now say so. Scoring is left
alone: a debuff is temporary and the advisor advises on the build, so
hiding a debuffed partner from "Active combos" would misrepresent it.
Also: never call SMODS.is_eternal() from an advisor path. It runs a full
SMODS.calculate_context per call (utils.lua:3079) -- far too heavy for a
hover -- and outside a live run it reported EVERY joker as Eternal, which
silently disabled the sell advisor. The smoke harness caught that; the
stub could not have.
721 pass locally, 12 in-game.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every lead in AUDIT.md, traced to the running source and then settled.
Ceremonial Dagger DESTROYS the joker to its right at blind select
(card.lua:2945) and skips Eternals. The card says so; what it cannot say
is WHICH of your jokers is about to die. JCA.dagger_victim names it in
the tooltip -- "WILL DESTROY Baron at the next blind" -- while there is
still time to reorder, and stays quiet when the neighbour is Eternal.
Four jokers that scored 0 against all 150 now have partners, all verified
in card.lua rather than recalled:
* Burglar + Ramen: Ramen decays per discarded card and is DESTROYED at x1
(SMODS.destroy_cards). Burglar zeroes discards, so it never decays and
never dies. Same for Burglar + Green Joker, which is only punished by
discarding.
* Trading Card + Erosion: Erosion pays per card MISSING from the deck,
and Trading Card permanently destroys the card it discards.
* Chaos the Clown + Flash Card: a free reroll every shop, and a joker
that grows per reroll. Both were inert.
Erosion is the mirror of card_gen, so it now clashes with every joker
that permanently adds a card: DNA, Marble, Certificate.
Rejected, with the reasoning recorded so nobody "fixes" it later:
Card Sharp and Supernova reward replaying a hand and Obelisk punishes it,
but neither destroys the other's precondition -- the player's hand choice
does. That is an opposed incentive, not an opposed effect. The clash list
only earns trust while every entry is mechanical.
The audit's own silent-check was wrong: it flagged Square Joker, which
has been paired with Four Fingers all along, and I duplicated that pair
before the suite caught it. Silence now means no tags AND no famous pair.
711 pass locally, 10 in-game.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* The tooltip mis-taught every pure enabler. JCA.explain used a cluster
tag's `both` text whenever EITHER side was a full member, so Four
Fingers next to Runner claimed "both reward Straights" -- Four Fingers
does not reward Straights, it makes them reachable. `both` now requires
both sides, and every cluster tag carries give/want phrasings.
* Blue Joker and Abstract Joker scored 0 against all 150 jokers. Blue
Joker scales on #G.deck.cards, so it wants card_gen (DNA, Marble,
Certificate); Abstract scales on #G.jokers.cards, so it wants joker_gen
(Riff-Raff is +6 Mult on its own). Both verified in card.lua. Steel and
Glass Joker look like the same fix but are NOT: they need Steel/Glass
specifically, and the only enhance_gen givers make Gold and Stone, so
tagging them would invent a synergy that does not exist.
* Copy jokers are positional and the board order was there all along.
JCA.copy_source reports what an owned Blueprint/Brainstorm is actually
copying, including when the target is one of the 29 centers vanilla
refuses to copy (blueprint_compat = false), or when it is copying
nothing at all.
* The sell advisor now counts clashes when ranking what to cut. JCA.score
stays pure -- a trap must never make a card look like a combo -- but a
joker eating another one's payoff is exactly the one to sell.
The suite caught a real bug while writing this: `(mode == 'right') and
cards[idx+1] or cards[1]` falls through to the LEFTMOST joker when the
right-hand slot is nil, so a rightmost Blueprint would have named the
wrong card. 673 pass here, 9 in-game via the smoke harness.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was no test file -- CLAUDE.md described the harness in prose and
referred to an "orphan-tag check" that did not exist. test.lua now stubs
the game globals and exercises the real engine, database and catalog tab
builders. It found three bugs on its first run:
* four_kind was the only theme in the catalog that could never be
discovered. Theme discovery needs a giver and a wanter on two DIFFERENT
fielded jokers, and The Family was its sole member -- so the Hands bar
and the overall Progress bar could never reach 100%. DNA is the real
enabler (copying a card is how you stack duplicate ranks, the only
vanilla route to a reliable Four of a Kind), so it now gives the
matching-hand tags as a pure enabler.
* hand_level was given by Space Joker and Burnt Joker and wanted by
nobody, so it could never contribute to a score and its "want" tooltip
text was unreachable. Nothing in vanilla rewards hand levels; the tag
is dropped rather than faked.
* Invisible Joker had no tags at all, so it scored 0 against the entire
game. Selling it duplicates one of your Jokers -- the same "stronger
target, better payoff" logic Blueprint and Brainstorm already model --
so it now wants copy_target.
The suite guards both directions of the tag contract (no orphan wants, no
dead gives), theme reachability, blurb widths, the inert-joker list, and
the card materialize fix from the previous commit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>