Commit Graph

15 Commits

Author SHA1 Message Date
funman300 9364603db1 Teach the boss cautions two silencers beyond the card killers
The Water removes every discard at blind start (blind.lua:208, returned
only after the fight), idling discard granters and payoffs alike; The
Eye blocks a repeated hand type outright (blind.lua:189/577), giving a
one-hand build exactly one shot. BOSS_KILLS entries now carry a tag SET
and their own factual phrase, since "debuffs X" stopped being the only
true sentence. The Arm and The Ox were chased and rejected -- level
drain does not touch the planet jokers, and The Ox fires on the
player's own hand choice, the same reasoning that rejected the Card
Sharp/Obelisk clash -- recorded in the BOSS_KILLS comment so nobody
re-adds them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:23:16 -07:00
funman300 43e1ea2bc6 Put the known traps in the catalog, as an open book
A Traps tab joins the synergy catalog: clash duos rendered like the
Combos tab, then the per-joker cautions, one pager spanning both page
kinds. Deliberately no discovery gating and no Progress entry -- the
Combos tab hides pairs to keep the fun of finding them, but a warning
locked behind fielding the bad pair would reward exactly what it warns
against. register_clash now maintains JCA.clash_list alongside the blurb
map so third-party clashes appear on the tab, re-registration updates
without duplicating, and blurbs are read back through clash_blurb at
build time so the newest wording always wins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:18:24 -07:00
funman300 21995589df Answer for shop copiers before the player pays
A purchase always lands in the rightmost slot (buy_from_shop emplaces at
the end, button_callbacks.lua:2279), which the two copiers experience in
opposite ways: a bought Blueprint arrives copying nothing, a bought
Brainstorm copies the leftmost joker immediately. The buy-area tooltip
now says which, by name — JCA.copy_source_if_bought resolves the arrival
target (chaining through a leftmost copier exactly like copy_source),
and Blueprint's line names the joker to slot it against after buying.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:05:02 -07:00
funman300 a2d16ae12f Integrate with the mods actually installed beside us
New integrations.lua, loaded pcall-wrapped at the end of main.lua;
every integration gates on its target's global so a missing mod is
silence. Both targets load before us by priority.

JokerDisplay: each known joker's display definition gains a live
'(2 combos)' counter in JD's own parenthetical reminder style --
the same partner count the hover tooltip names -- by appending a
dynamic element to reminder_text (created when absent) and wrapping
calc_function to fill card.joker_display_values. The wrapper pcalls
the original calc and blanks the text when the new jd_combos config
toggle is off, so it flips mid-run in both directions.

Too Many Jokers: registers the SEARCH_FIELD_FUNCS hook its api.md
documents, indexing every joker under its tag labels on both sides,
so the collection search finds jokers by 'money', 'Hearts',
'held-card retriggers'. Unknown centers stay nil.

The smoke scenario now asserts the JokerDisplay patch against the
real mod: 13/13 in-game.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:03:35 -07:00
funman300 2b43d24994 Recap the run's high-water mark: peak board synergy
JCA.board_synergy sums every owned pair once; the emplace hook that
already drives discovery keeps the maximum in G.GAME.jca_peak_synergy
(it can only rise when a joker arrives). The post-run recap shows it,
now also on runs that fielded no famous pair.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:48:47 -07:00
funman300 f73507f5c6 Frame suit and hand jokers with this run's actual deck and levels
Buy-area tooltips on suit-tagged jokers now show the deck ratio
('Your deck: 18 of 52 cards are Hearts', from card.base.suit -- the
field vanilla scores by) and hand-cluster jokers show the hand's level
when it has been built past 1. Pure context: the pairwise score never
reads the deck, the lines are capped at two, and iteration order is
fixed so the tooltip is stable across hovers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:47:27 -07:00
funman300 445171dc0b Warn when the upcoming boss will silence the joker on sale
Five bosses debuff a whole card class for the fight (game.lua P_BLINDS,
applied in Blind:debuff_card blind.lua:708): The Club/Goad/Head/Window
kill a suit, The Plant kills faces. A debuffed card scores nothing and
triggers nothing, so a shop joker wanting that class is a dead ante --
and one GIVING it is worse: Pareidolia under The Plant converts the
whole deck into debuffed faces, so givers warn too. JCA.upcoming_boss
reads G.GAME.round_resets and goes quiet once the boss is defeated.
Warning-only, never a score change, kept in learning mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:46:18 -07:00
funman300 ea8faac434 Respect the other two stickers: rentals bleed, perished jokers are dead
JCA.is_rental and JCA.is_perished read ability.rental and
ability.perishable/perish_tally, the same flags vanilla uses
(card.lua:684/676). The sell advisor now docks a rental 2 points (it
drains $3 every round, game.lua:1957) and treats a perished joker --
tally 0, debuffed permanently per card.lua:716 -- as dead weight that
outweighs any synergy score. Tooltips gain the mechanical facts:
countdown on ticking perishables, drain rate on rentals (shop phrasing
notes the $1 price), and 'Perished - it will never work again' instead
of the misleading 'does nothing this blind' on permanently dead cards.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:44:52 -07:00
funman300 665bd9b396 Point a dead copier at its fix: name the best target one reorder away
JCA.best_copy_target scans the board for copyable jokers (same truth
test as copy_source: blueprint_compat must be true, debuffed excluded,
other copiers excluded) and prefers the ones the database marks
copy_target. When a Blueprint or Brainstorm reports anything but 'ok',
the tooltip now adds the reorder that revives it: 'Fix: slot this just
left of Baron' / 'Fix: make Baron your leftmost joker'. Explanation,
not verdict, so learning mode keeps it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:42:50 -07:00
funman300 b81a6c6dcd Add the shopping list: name the gaps the board wants filled
JCA.build_gaps() splits the board's tags into unmet wants (some joker
wants it, no OTHER joker gives it) and untapped hooks (given, nothing
pays it off). Rendered at the top of the in-run Combos overlay via
TAG_LABEL; engine roles stay excluded because they hint nothing.
Board slots are compared by index, not db-entry identity, so two
copies of one cluster joker correctly feed each other.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:41:32 -07:00
funman300 ff71a8ef12 Split rank-limited retriggers so Hack stops courting face payoffs
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>
2026-07-14 13:30:20 -07:00
funman300 de67970a15 Stop giving advice the game will not let you follow
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>
2026-07-14 12:50:47 -07:00
funman300 8ce5619273 Chase the audit's leads: verify, implement, or reject
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>
2026-07-14 12:36:01 -07:00
funman300 e688de0efb Fix enabler phrasing, wake two silent jokers, read the board order
* 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>
2026-07-14 12:24:33 -07:00
funman300 07cada9e49 Add a test suite, and fix the three dead-data bugs it found
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>
2026-07-14 11:15:10 -07:00