diff --git a/CLAUDE.md b/CLAUDE.md index 66f2653..cfcbe8e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,9 +46,9 @@ To poke at the engine by hand, copy the stub block from the top of `test.lua`. `~/.local/share/Balatro/Mods/JokerComboAdvisor -> ~/Documents/JokerComboAdvisor` (this repo). Edits here go live on next game launch — do not copy files anywhere. Lovely reads that folder as `C:\users\steamuser\AppData\Roaming\Balatro\Mods`. -- Game: Steam/Proton at `/mnt/games/Steam/steamapps/common/Balatro` (note: second - Steam library, not the default paths). Lovely injector + Steamodded 1.0.0-beta - are already installed; mods are managed via Balatro Mod Manager. +- Game: Steam/Proton at `~/.local/share/Steam/steamapps/common/Balatro`. Lovely + injector + Steamodded 1.0.0-beta are already installed; mods are managed via + Balatro Mod Manager. - Crash/load logs: `~/.local/share/Balatro/Mods/lovely/log/` (newest file). - Remote: `https://git.aleshym.co/funman300/JokerComboAdvisor` (private, user's Gitea). Pushes authenticate via the repo-local credential helper, which @@ -165,5 +165,16 @@ Three-layer split; `JCA` is the single global namespace: `CLASHES` (pairwise, red "Clashes -" tooltip line vs owned jokers) and `CAUTIONS` (per-joker, buy-area "Caution:" line) in `synergies.lua`, same ~34-char blurb budget as `PAIRS`. Learning mode keeps warnings visible. + **Verify every new trap against the dump before adding it** — a warning that + is merely plausible is worse than none. The mod once shipped a `j_smeared` + + `j_flower_pot` clash that was exactly backwards: Flower Pot fills its four + suit slots with a greedy `if/elseif` chain (`card.lua:4256`) and Smeared makes + Hearts answer for Diamonds, so any two red + two black cards fill the pot. It + is one of the best combos in the game, and the mod was warning players off it. + Most traps hinge on the scoring-pipeline order in `functions/state_events.lua` + (`before` → per-card `individual` → `joker_main`): Vampire strips enhancements + in `before`, so every enhancement payoff that reads them in `individual` — + Golden Ticket, Glass, Stone, Driver's License — is looking at cards it has + already eaten. - The UI hooks are the only untested-in-game surface; if a tooltip regression is reported, suspect the `aut.info` entry format first and check the lovely log. diff --git a/synergies.lua b/synergies.lua index 385c2f5..678e88d 100644 --- a/synergies.lua +++ b/synergies.lua @@ -229,6 +229,12 @@ local PAIRS = { {'j_bull', 'j_to_the_moon', 'interest piles up, chips follow'}, {'j_marble', 'j_hologram', 'every added Stone grows Hologram'}, {'j_egg', 'j_campfire', 'sell the grown Egg for xMult'}, + -- Flower Pot fills its four suit slots with a greedy if/elseif chain + -- (card.lua:4256) and Smeared 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 a top-tier combo, and this + -- mod used to warn against it. + {'j_smeared', 'j_flower_pot', 'any 2 red + 2 black fill it'}, } -- Known traps: pairs that actively hurt each other. Warning-only — they @@ -236,9 +242,40 @@ local PAIRS = { -- a red "Clashes" line. Keep warnings under ~34 chars (one tooltip row). local CLASHES = { {'j_ride_the_bus', 'j_pareidolia', 'every card counts as a face'}, - {'j_vampire', 'j_steel_joker', 'drains the Steel it counts'}, - {'j_vampire', 'j_lucky_cat', 'strips Lucky cards before they pay'}, - {'j_smeared', 'j_flower_pot', 'merged suits cannot make all four'}, + + -- Burglar sets discards_left to 0 when the blind is selected + -- (`ease_discard(-discards_left)`, card.lua:2905), so every joker that + -- reads a discard is switched off for the whole run. + {'j_burglar', 'j_banner', 'no discards left to count'}, + {'j_burglar', 'j_delayed_grat', 'pays per discard; you get 0'}, + {'j_burglar', 'j_castle', 'no discards, never grows'}, + {'j_burglar', 'j_yorick', 'no discards, never grows'}, + {'j_burglar', 'j_hit_the_road', 'no discards, never grows'}, + {'j_burglar', 'j_burnt', 'no discards to level a hand'}, + {'j_burglar', 'j_mail', 'no discards, no rebate'}, + {'j_burglar', 'j_faceless', 'no discards, no payout'}, + {'j_burglar', 'j_trading', 'no discards to trade in'}, + {'j_burglar', 'j_drunkard', 'its extra discards get wiped'}, + {'j_burglar', 'j_merry_andy', 'its extra discards get wiped'}, + + -- Vampire strips enhancements in the `before` pass (card.lua:3851/3906), + -- which runs ahead of the per-card `individual` pass where the enhancement + -- payoffs are read — so it eats the cards they are counting, permanently. + {'j_vampire', 'j_steel_joker', 'drains the Steel it counts'}, + {'j_vampire', 'j_lucky_cat', 'strips Lucky cards before they pay'}, + {'j_vampire', 'j_ticket', 'eats Gold before Ticket pays'}, + {'j_vampire', 'j_glass', 'strips Glass before it shatters'}, + {'j_vampire', 'j_drivers_license', 'strips the 16 enhanced cards'}, + {'j_vampire', 'j_stone', 'eats the Stone cards it counts'}, + {'j_vampire', 'j_marble', 'eats the Stones Marble adds'}, + + -- Joker Stencil's xMult is the count of EMPTY joker slots. + {'j_stencil', 'j_riff_raff', 'fills the slots Stencil needs'}, + {'j_stencil', 'j_abstract', 'one wants jokers, one wants slots'}, + + -- Splash makes every played card score, so a face card that used to be a + -- harmless kicker now lands in the scoring hand and resets the counter. + {'j_splash', 'j_ride_the_bus', 'any played face card resets it'}, } -- Per-joker cautions for the buy-area tooltip: the joker is fine on its @@ -248,6 +285,28 @@ local CAUTIONS = { j_ceremonial = 'eats the joker to its right', j_madness = 'destroys a random joker each blind', j_stencil = 'xMult grows with EMPTY joker slots', + + -- Positional traps: both copy a neighbour, and neither says so on the card. + j_blueprint = 'dead in the rightmost slot', + j_brainstorm = 'dead in the leftmost slot', + j_riff_raff = 'needs free joker slots', + + -- Does nothing on its own: Mime retriggers held-card abilities, so with no + -- Steel/Gold cards and no Baron/Shoot the Moon it retriggers nothing. + j_mime = 'dead without held-card payoffs', + + -- Board-wide side effects the card text buries. + j_burglar = 'wipes ALL discards each blind', + j_vampire = 'permanently eats enhancements', + j_obelisk = 'resets on your most played hand', + j_stuntman = 'costs you 2 hand size', + + -- Decay: the numbers are exact (chips 100 / chip_mod 5, mult 20 / extra 4, + -- h_size 5 / h_mod 1, odds 6 -- all from game.lua). + j_ice_cream = 'melts to nothing in 20 hands', + j_popcorn = 'decays to nothing in 5 rounds', + j_turtle_bean = 'hand size shrinks back each round', + j_gros_michel = '1 in 6 to self-destruct each round', } -- How to phrase a tag link in the tooltip, from the partner's perspective: