Commit Graph

13 Commits

Author SHA1 Message Date
funman300 048ab40f85 Warn about perishable scalers and rental money jokers at buy time
Per-instance sticker cautions, unlike the per-joker CAUTIONS table: the
same joker is a fine buy without the sticker. Perishable debuffs a joker
for good after 5 rounds (Card:calculate_perishable, card.lua:2652), so a
perishable Ride the Bus or Hologram is investment about to be wiped --
the new SCALERS set in synergies.lua lists the jokers whose stored gains
die that way, excluding computed (Bull) and round-scoped (Hit the Road)
values and Egg, whose sell value survives a debuff. Rental charges
every round (card.lua:2647), which can eat a money joker's whole payout.

The scaler-key integrity test caught j_canio for j_caino on the first
run -- the misspelled vanilla keys strike again.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 19:44:32 -07:00
funman300 b88fd0ea07 Pair Burglar with Card Sharp; caution the two hand-cost jokers
Card Sharp's x3 needs the same hand twice in ONE round -- it checks
played_this_round > 1 (card.lua:4465) and that counter resets each
round (state_events.lua:252). Burglar's +3 hands makes the replay
routine, so it gets the famous pair plus a hands_up want, same shape
as Burglar + Acrobat. The old verdict rejecting the Obelisk clash
stands; the audit entry now records both decisions.

Troubadour and Merry Andy join the cautions: their buried costs (one
fewer hand every round, one hand size) are the same shape as
Stuntman's existing warning.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 18:59:16 -07:00
funman300 53907424b0 Fix four tag gaps and a contradiction found by the full-database audit
Cross-checked all 150 jokers' tags against JOKER_EFFECTS.md and the dump:

- Drop the Vampire + Marble clash: Vampire gains xMult from any non-base
  scoring card (card.lua:3907), Stones included, so Marble feeds it --
  the same shape as the Midas Mask pair. The data even scored the duo
  as a combo while warning against it. Stone-build harm stays covered
  by the Vampire + Stone Joker line.
- Delayed Gratification wants discards_up: it pays per unused discard,
  same shape as Banner.
- The Idol wants suit_flex: it checks is_suit (card.lua:3530), so
  Smeared doubles its eligible cards, like Ancient Joker.
- 8 Ball wants retrig_scoring: the 1-in-4 rolls per scored 8 in the
  individual pass (card.lua:3507), so retriggers re-roll it.
- Reword the suit give phrasings: nothing vanilla turns cards into a
  suit, so 'turns cards into Spades' was a lie whenever Blackboard sat
  across from a one-sided giver like Wrathful or Arrowhead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 18:51:49 -07:00
funman300 c4a3847c6a Stop calling DNA a Pair enabler
DNA only fires on the round's first hand and only for a single played
card (dump/card.lua:3956) - sacrificing a full hand to enable the
easiest hand in the game is not a synergy. Its trips/quads enabling
stays; that is what the one-copy-per-round loop actually builds toward.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 18:36:30 -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 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 47721d1acf Fix a backwards clash, and add 19 verified traps
Every entry here was checked against the running Steamodded source in
Mods/lovely/dump, not from memory.

The headline is a correction: the shipped CLASHES table warned that
Smeared Joker + Flower Pot "cannot make all four" suits. It is backwards.
Flower Pot fills its four suit slots with a greedy if/elseif chain
(card.lua:4256) and SMODS.smeared_check makes Hearts answer for Diamonds
and Spades for Clubs, so the second Heart falls through into the Diamond
slot: any two red + two black cards fill the pot. It is one of the
strongest combos in the game and the mod was steering players away from
it -- while simultaneously scoring the pair +2 via suit_flex, which
should have been the tell. It is now a famous pair.

New clashes (4 -> 22), all traced to the mechanism:
* Burglar zeroes discards_left on blind select (card.lua:2905), which
  switches off every discard-gated joker for the rest of the run: Banner,
  Delayed Gratification, Castle, Yorick, Hit the Road, Burnt, Mail-In
  Rebate, Faceless, Trading Card, and it wipes the discards Drunkard and
  Merry Andy hand you. Delayed Gratification is the cruellest -- "no
  discards used" reads like a synergy, but the code also requires
  discards_left > 0, so it pays exactly $0.
* Vampire strips enhancements in the `before` pass, ahead of the
  per-card `individual` pass where enhancement payoffs are read, so it
  eats what Golden Ticket, Glass, Stone Joker, Marble and Driver's
  License are counting.
* Joker Stencil scales on EMPTY slots, so Riff-Raff and Abstract Joker
  fight it.
* Splash makes every played card score, so a face card that used to be a
  harmless kicker now resets Ride the Bus.

New cautions (3 -> 15): the positional traps (Blueprint dead in the
rightmost slot, Brainstorm in the leftmost), Mime doing nothing without a
held-card payoff, and the decay timers, whose numbers are exact from
game.lua (Ice Cream 100/5 = 20 hands, Popcorn 20/4 = 5 rounds).

Also corrects the stale game path in CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 11:22:35 -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
funman300 cc26ae6767 Add 12 famous pairs to the combo database (19 -> 31)
Blueprint+Brainstorm, Mime+Raised Fist, Mime+Shoot the Moon,
Hack+Fibonacci, Photograph+Sock and Buskin, Smiley+Sock and Buskin,
Four Fingers+Shortcut, Four Fingers+Smeared, Smeared+Bloodstone,
Bull+To the Moon, Marble+Hologram, Egg+Campfire. All blurbs within the
34-char tooltip budget; discovery and the Combos tab pick them up
automatically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 14:01:20 -07:00
funman300 4a882e8101 Add anti-synergy warnings: CLASHES pairs and per-joker CAUTIONS
Warning-only data in synergies.lua — never touches the synergy score.
Tooltips gain a red 'Clashes - <owned joker>: <why>' line when a hovered
joker fights one you own (Ride the Bus + Pareidolia, Vampire vs Steel
Joker/Lucky Cat, Smeared vs Flower Pot), and a 'Caution:' line in the
buy area for jokers that harm a board you keep (Ceremonial Dagger,
Madness, Stencil). Learning mode keeps warnings — they teach.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 13:58:10 -07:00
funman300 e37b56471b Cap generic mult/xmult bonus per candidate; opt Stencil out of it
Any xMult joker used to pulse 'recommended' on a board of four unrelated
+Mult/+Chips jokers: the generic engine-complement +1 in JCA.score
accumulated once per owned joker in partners_for, reaching the threshold
of 4 with zero listable partners (pairwise scores never hit 2), so the
card pulsed while its own tooltip said 'No synergy with your jokers.'

- partners_for now counts the generic +1 once per candidate. Tag/pair
  scores are even, so the generic bonus can no longer flip a
  recommendation at all; a pulsing card always has a nameable partner.
- Joker Stencil is the one xMult joker the generic rule actively
  misreads (its multiplier grows with EMPTY slots), so entries support
  {no_generic = true} which suppresses the rule in score() and the
  generic fallback lines in explain(). Stencil also gains copy_target:
  its real famous synergy is being copied by Blueprint/Brainstorm.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 13:51:54 -07:00
funman300 8783785283 Initial release: Joker Combo Advisor v1.0.0
Steamodded mod that teaches Balatro joker synergies: hover tooltips
explain why jokers combo (famous-pair blurbs + tag-based reasons),
combo discovery tracking with catalog grey-out and run recap, an
in-game synergy catalog with real card sprites, learning mode, and
a HUD shortcut.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 21:54:04 -07:00