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>
This commit is contained in:
+308
@@ -0,0 +1,308 @@
|
||||
--- Synergy database for Joker Combo Advisor.
|
||||
--- Each joker lists tags it GIVES (capabilities it adds to a build) and tags
|
||||
--- it WANTS (capabilities that make it stronger). The scorer matches one
|
||||
--- joker's gives against another's wants, in both directions.
|
||||
---
|
||||
--- Tag glossary:
|
||||
--- mult / chips / xmult engine roles (also used for the generic
|
||||
--- "scaler + multiplier" complement rule)
|
||||
--- money earns money; money = wants money (econ payoffs)
|
||||
--- faces makes cards count as face cards / wants face cards
|
||||
--- retrig_scoring retriggers (or multiplies triggers of) played cards
|
||||
--- retrig_held retriggers cards held in hand
|
||||
--- hand_size / hands_up / discards_up resource increases
|
||||
--- probability improves listed probabilities / cares about them
|
||||
--- tarot_gen / spectral_gen / planet consumable economies
|
||||
--- stone_gen / gold_gen / enhance_gen / card_gen deck modification
|
||||
--- joker_gen / sell_value sell-fodder economies
|
||||
--- copy_target a strong effect worth copying (for Blueprint et al.)
|
||||
--- pair, two_pair, three_kind, four_kind, straight, flush hand-type
|
||||
--- clusters (jokers keying the same hand reinforce
|
||||
--- each other; enablers like Four Fingers give these)
|
||||
--- hearts, diamonds, spades, clubs, suit_flex suit clusters
|
||||
---
|
||||
--- Jokers not in this table (e.g. from other mods) simply score 0.
|
||||
|
||||
local J = {}
|
||||
local function j(key, gives, wants)
|
||||
J[key] = { gives = gives or {}, wants = wants or {} }
|
||||
end
|
||||
|
||||
-- Common jokers ------------------------------------------------------------
|
||||
j('j_joker', {'mult'})
|
||||
j('j_greedy_joker', {'mult','diamonds'}, {'diamonds','suit_flex'})
|
||||
j('j_lusty_joker', {'mult','hearts'}, {'hearts','suit_flex'})
|
||||
j('j_wrathful_joker', {'mult','spades'}, {'spades','suit_flex'})
|
||||
j('j_gluttenous_joker', {'mult','clubs'}, {'clubs','suit_flex'})
|
||||
j('j_jolly', {'mult','pair'}, {'pair'})
|
||||
j('j_zany', {'mult','three_kind'}, {'three_kind'})
|
||||
j('j_mad', {'mult','two_pair'}, {'two_pair'})
|
||||
j('j_crazy', {'mult','straight'}, {'straight'})
|
||||
j('j_droll', {'mult','flush'}, {'flush'})
|
||||
j('j_sly', {'chips','pair'}, {'pair'})
|
||||
j('j_wily', {'chips','three_kind'}, {'three_kind'})
|
||||
j('j_clever', {'chips','two_pair'}, {'two_pair'})
|
||||
j('j_devious', {'chips','straight'}, {'straight'})
|
||||
j('j_crafty', {'chips','flush'}, {'flush'})
|
||||
j('j_half', {'mult'})
|
||||
j('j_credit_card', {})
|
||||
j('j_banner', {'chips'}, {'discards_up'})
|
||||
j('j_mystic_summit', {'mult'})
|
||||
j('j_8_ball', {'tarot_gen'}, {'probability'})
|
||||
j('j_misprint', {'mult'})
|
||||
j('j_raised_fist', {'mult'}, {'retrig_held','hand_size'})
|
||||
j('j_chaos', {})
|
||||
j('j_scary_face', {'chips'}, {'faces','retrig_scoring'})
|
||||
j('j_abstract', {'mult'})
|
||||
j('j_delayed_grat', {'money'})
|
||||
j('j_gros_michel', {'mult'})
|
||||
j('j_even_steven', {'mult'}, {'retrig_scoring'})
|
||||
j('j_odd_todd', {'chips'}, {'retrig_scoring'})
|
||||
j('j_scholar', {'chips','mult'}, {'retrig_scoring'})
|
||||
j('j_business', {'money'}, {'faces','probability','retrig_scoring'})
|
||||
j('j_supernova', {'mult'})
|
||||
j('j_ride_the_bus', {'mult'})
|
||||
j('j_egg', {'sell_value'})
|
||||
j('j_runner', {'chips','straight'}, {'straight'})
|
||||
j('j_ice_cream', {'chips'})
|
||||
j('j_splash', {'retrig_scoring'}) -- makes every played card score
|
||||
j('j_blue_joker', {'chips'})
|
||||
j('j_faceless', {'money'}, {'faces','discards_up'})
|
||||
j('j_green_joker', {'mult'})
|
||||
j('j_superposition', {'tarot_gen','straight'}, {'straight'})
|
||||
j('j_todo_list', {'money'})
|
||||
j('j_cavendish', {'xmult'})
|
||||
j('j_red_card', {'mult'})
|
||||
j('j_square', {'chips'})
|
||||
j('j_riff_raff', {'joker_gen'})
|
||||
j('j_shortcut', {'straight'})
|
||||
j('j_vagabond', {'tarot_gen'})
|
||||
j('j_cloud_9', {'money'})
|
||||
j('j_rocket', {'money'})
|
||||
j('j_luchador', {})
|
||||
j('j_gift', {'sell_value'})
|
||||
j('j_turtle_bean', {'hand_size'})
|
||||
j('j_erosion', {'mult'})
|
||||
j('j_reserved_parking', {'money'}, {'faces','retrig_held','probability','hand_size'})
|
||||
j('j_mail', {'money'}, {'discards_up'})
|
||||
j('j_to_the_moon', {'money'}, {'money'})
|
||||
j('j_hallucination', {'tarot_gen'}, {'probability'})
|
||||
j('j_fortune_teller', {'mult'}, {'tarot_gen'})
|
||||
j('j_juggler', {'hand_size'})
|
||||
j('j_drunkard', {'discards_up'})
|
||||
j('j_golden', {'money'})
|
||||
j('j_popcorn', {'mult'})
|
||||
j('j_walkie_talkie', {'chips','mult'}, {'retrig_scoring'})
|
||||
j('j_smiley', {'mult'}, {'faces'})
|
||||
j('j_ticket', {'money'}, {'gold_gen'})
|
||||
j('j_swashbuckler', {'mult'}, {'sell_value','joker_gen'})
|
||||
j('j_hanging_chad', {'retrig_scoring'})
|
||||
j('j_shoot_the_moon', {'mult'}, {'retrig_held','hand_size'})
|
||||
|
||||
-- Uncommon jokers ----------------------------------------------------------
|
||||
j('j_stencil', {'xmult'})
|
||||
j('j_four_fingers', {'straight','flush'})
|
||||
j('j_mime', {'retrig_held','copy_target'})
|
||||
j('j_ceremonial', {'mult'})
|
||||
j('j_marble', {'stone_gen','card_gen','enhance_gen'})
|
||||
j('j_loyalty_card', {'xmult'})
|
||||
j('j_dusk', {'retrig_scoring'})
|
||||
j('j_fibonacci', {'mult'}, {'retrig_scoring'})
|
||||
j('j_steel_joker', {'xmult'})
|
||||
j('j_hack', {'retrig_scoring'})
|
||||
j('j_pareidolia', {'faces'})
|
||||
j('j_space', {'hand_level'}, {'probability'})
|
||||
j('j_burglar', {'hands_up'})
|
||||
j('j_blackboard', {'xmult'}, {'spades','clubs'})
|
||||
j('j_sixth_sense', {'spectral_gen'}, {'spectral_gen'})
|
||||
j('j_constellation', {'xmult','planet'}, {'planet'})
|
||||
j('j_hiker', {'chips'}, {'retrig_scoring'})
|
||||
j('j_card_sharp', {'xmult'})
|
||||
j('j_madness', {'xmult','copy_target'})
|
||||
j('j_seance', {'spectral_gen'}, {'straight','flush','spectral_gen'})
|
||||
j('j_vampire', {'xmult'}, {'enhance_gen'})
|
||||
j('j_hologram', {'xmult','copy_target'}, {'card_gen'})
|
||||
j('j_cartomancer', {'tarot_gen'})
|
||||
j('j_astronomer', {'planet'}, {'planet'})
|
||||
j('j_burnt', {'hand_level'}, {'discards_up'})
|
||||
j('j_bootstraps', {'mult'}, {'money'})
|
||||
j('j_dna', {'card_gen'})
|
||||
j('j_midas_mask', {'gold_gen','enhance_gen'}, {'faces'})
|
||||
j('j_photograph', {'xmult','copy_target'}, {'faces','retrig_scoring'})
|
||||
j('j_stone', {'chips'}, {'stone_gen'})
|
||||
j('j_lucky_cat', {'xmult'}, {'probability'})
|
||||
j('j_baseball', {'xmult'})
|
||||
j('j_bull', {'chips'}, {'money'})
|
||||
j('j_diet_cola', {})
|
||||
j('j_trading', {'money'}, {'discards_up'})
|
||||
j('j_flash', {'mult'})
|
||||
j('j_trousers', {'mult','two_pair'}, {'two_pair'})
|
||||
j('j_ramen', {'xmult'})
|
||||
j('j_selzer', {'retrig_scoring'})
|
||||
j('j_castle', {'chips'}, {'discards_up'})
|
||||
j('j_mr_bones', {})
|
||||
j('j_acrobat', {'xmult'}, {'hands_up'})
|
||||
j('j_sock_and_buskin', {'retrig_scoring'}, {'faces'})
|
||||
j('j_troubadour', {'hand_size'})
|
||||
j('j_certificate', {'card_gen'})
|
||||
j('j_smeared', {'flush','suit_flex'})
|
||||
j('j_throwback', {'xmult'})
|
||||
j('j_rough_gem', {'money','diamonds'}, {'retrig_scoring','diamonds','suit_flex'})
|
||||
j('j_bloodstone', {'xmult','hearts'}, {'retrig_scoring','hearts','suit_flex','probability'})
|
||||
j('j_arrowhead', {'chips','spades'}, {'retrig_scoring','spades','suit_flex'})
|
||||
j('j_onyx_agate', {'mult','clubs'}, {'retrig_scoring','clubs','suit_flex'})
|
||||
j('j_glass', {'xmult'})
|
||||
j('j_ring_master', {})
|
||||
j('j_flower_pot', {'xmult'}, {'suit_flex'})
|
||||
j('j_merry_andy', {'discards_up'})
|
||||
j('j_oops', {'probability'})
|
||||
j('j_idol', {'xmult','copy_target'}, {'retrig_scoring'})
|
||||
j('j_seeing_double', {'xmult','clubs'}, {'clubs','suit_flex'})
|
||||
j('j_matador', {'money'})
|
||||
j('j_hit_the_road', {'xmult'}, {'discards_up'})
|
||||
j('j_satellite', {'money','planet'}, {'planet'})
|
||||
|
||||
-- Rare jokers ---------------------------------------------------------------
|
||||
j('j_obelisk', {'xmult'})
|
||||
j('j_ancient', {'xmult'}, {'suit_flex'})
|
||||
j('j_campfire', {'xmult'}, {'joker_gen','sell_value'})
|
||||
j('j_baron', {'xmult','copy_target'}, {'retrig_held','hand_size'})
|
||||
j('j_duo', {'xmult','pair'}, {'pair'})
|
||||
j('j_trio', {'xmult','three_kind'}, {'three_kind'})
|
||||
j('j_family', {'xmult','four_kind'}, {'four_kind'})
|
||||
j('j_order', {'xmult','straight'}, {'straight'})
|
||||
j('j_tribe', {'xmult','flush'}, {'flush'})
|
||||
j('j_stuntman', {'chips'})
|
||||
j('j_invisible', {})
|
||||
j('j_blueprint', {}, {'copy_target'})
|
||||
j('j_brainstorm', {}, {'copy_target'})
|
||||
j('j_drivers_license', {'xmult'}, {'enhance_gen'})
|
||||
j('j_wee', {'chips'}, {'retrig_scoring'})
|
||||
|
||||
-- Legendary jokers ----------------------------------------------------------
|
||||
j('j_caino', {'xmult','copy_target'}, {'faces'})
|
||||
j('j_triboulet', {'xmult','copy_target'}, {'retrig_scoring'})
|
||||
j('j_yorick', {'xmult','copy_target'}, {'discards_up'})
|
||||
j('j_chicot', {})
|
||||
j('j_perkeo', {'tarot_gen'}, {'tarot_gen'})
|
||||
|
||||
-- Famous explicit combos (flat bonus on top of tag matching), each with a
|
||||
-- short "why it works" line shown in the tooltip. Keep blurbs under ~34
|
||||
-- characters so a name + blurb fits on one tooltip row.
|
||||
local PAIRS = {
|
||||
{'j_baron', 'j_mime', 'held Kings trigger twice'},
|
||||
{'j_baron', 'j_shoot_the_moon', 'Kings and Queens pay in hand'},
|
||||
{'j_burglar', 'j_mystic_summit', 'zero discards, max Mult'},
|
||||
{'j_burglar', 'j_acrobat', 'more hands, big final hand'},
|
||||
{'j_hack', 'j_wee', 'retriggered 2s grow Wee fast'},
|
||||
{'j_hanging_chad', 'j_photograph', 'first face scores three times'},
|
||||
{'j_pareidolia', 'j_sock_and_buskin', 'every card is a face to retrigger'},
|
||||
{'j_pareidolia', 'j_photograph', 'any first card is the face'},
|
||||
{'j_pareidolia', 'j_midas_mask', 'every played card turns Gold'},
|
||||
{'j_midas_mask', 'j_ticket', 'Gold cards feed Golden Ticket'},
|
||||
{'j_midas_mask', 'j_vampire', 'eats the new Gold for xMult'},
|
||||
{'j_dna', 'j_hologram', 'copied cards grow Hologram'},
|
||||
{'j_constellation', 'j_astronomer', 'cheap Planets stack xMult'},
|
||||
{'j_fortune_teller','j_cartomancer', 'free Tarots grow the Mult'},
|
||||
{'j_egg', 'j_swashbuckler', 'growing sell value becomes Mult'},
|
||||
{'j_gift', 'j_swashbuckler', 'inflated sell values become Mult'},
|
||||
{'j_four_fingers', 'j_square', 'four-card hands suit them both'},
|
||||
{'j_marble', 'j_stone', 'adds Stones that pay chips'},
|
||||
{'j_oops', 'j_lucky_cat', 'better odds, more Lucky payoffs'},
|
||||
}
|
||||
|
||||
-- How to phrase a tag link in the tooltip, from the partner's perspective:
|
||||
-- `give` when the partner provides the tag, `want` when the partner consumes
|
||||
-- it, `both` for cluster tags where the pair simply shares the theme.
|
||||
-- Every tag that appears in the joker table must have an entry here.
|
||||
local TAG_TEXT = {
|
||||
faces = {give = 'turns cards into faces', want = 'pays off face cards'},
|
||||
retrig_scoring = {give = 'retriggers scored cards', want = 'pays per extra trigger'},
|
||||
retrig_held = {give = 'retriggers cards in hand', want = 'pays off held-card triggers'},
|
||||
hand_size = {give = 'adds hand size', want = 'wants a big hand'},
|
||||
hands_up = {give = 'grants extra hands', want = 'uses the extra hands'},
|
||||
discards_up = {give = 'grants extra discards', want = 'feeds on discards'},
|
||||
probability = {give = 'improves listed odds', want = 'relies on listed odds'},
|
||||
money = {give = 'earns money', want = 'scales with your money'},
|
||||
hand_level = {give = 'levels up poker hands', want = 'rewards hand levels'},
|
||||
tarot_gen = {give = 'creates Tarot cards', want = 'rewards Tarot use'},
|
||||
planet = {both = 'shares the Planet economy'},
|
||||
spectral_gen = {both = 'shares the Spectral theme'},
|
||||
gold_gen = {give = 'creates Gold cards', want = 'pays off Gold cards'},
|
||||
stone_gen = {give = 'adds Stone cards', want = 'pays off Stone cards'},
|
||||
enhance_gen = {give = 'enhances cards', want = 'feeds on enhancements'},
|
||||
card_gen = {give = 'adds cards to the deck', want = 'grows as the deck grows'},
|
||||
joker_gen = {give = 'creates spare Jokers', want = 'profits when Jokers sell'},
|
||||
sell_value = {give = 'raises sell values', want = 'turns sell value into Mult'},
|
||||
copy_target = {give = 'is a prime copy target', want = 'copies your best Joker'},
|
||||
suit_flex = {give = 'makes suits count as others', want = 'cares which suits score'},
|
||||
pair = {both = 'both reward Pairs'},
|
||||
two_pair = {both = 'both reward Two Pair'},
|
||||
three_kind = {both = 'both reward Three of a Kind'},
|
||||
four_kind = {both = 'both reward Four of a Kind'},
|
||||
straight = {both = 'both reward Straights'},
|
||||
flush = {both = 'both reward Flushes'},
|
||||
hearts = {both = 'both love Hearts'},
|
||||
diamonds = {both = 'both love Diamonds'},
|
||||
spades = {both = 'both love Spades'},
|
||||
clubs = {both = 'both love Clubs'},
|
||||
}
|
||||
|
||||
-- Order in which tags are considered when picking the one reason to show;
|
||||
-- most specific mechanics first, broad engine roles last.
|
||||
local TAG_ORDER = {
|
||||
'retrig_held', 'retrig_scoring', 'faces',
|
||||
'gold_gen', 'stone_gen', 'enhance_gen', 'card_gen',
|
||||
'tarot_gen', 'spectral_gen', 'planet',
|
||||
'probability', 'discards_up', 'hands_up', 'hand_size', 'hand_level',
|
||||
'money', 'sell_value', 'joker_gen',
|
||||
'hearts', 'diamonds', 'spades', 'clubs',
|
||||
'pair', 'two_pair', 'three_kind', 'four_kind', 'straight', 'flush',
|
||||
'copy_target', 'suit_flex',
|
||||
}
|
||||
|
||||
-- One-sentence mechanic explainers shown at the top of each catalog theme
|
||||
-- page. Teaching voice: explain how the mechanic works, not what to buy.
|
||||
-- Every tag listed in main.lua's THEME_TABS needs an entry (max ~90 chars).
|
||||
local THEME_INFO = {
|
||||
faces = 'Face cards trigger these effects; makers like Pareidolia turn every card into one.',
|
||||
retrig_scoring = 'Retriggers make each scored card count again, so per-card payoffs double up.',
|
||||
retrig_held = 'Some jokers pay for cards sitting in hand; retriggering the hand pays them again.',
|
||||
copy_target = 'Blueprint and Brainstorm mirror a joker - the stronger the target, the better.',
|
||||
probability = 'Listed "1 in X" odds are dice rolls; odds boosters make gambling jokers hit more.',
|
||||
hand_size = 'A bigger hand holds more Kings, steel and gold - held-card builds love the space.',
|
||||
hands_up = 'Extra hands per round are fuel for jokers that reward or count hands played.',
|
||||
discards_up = 'Extra discards are fuel: several jokers grow or pay out each time you discard.',
|
||||
money = 'Money is an engine too - some jokers earn it, others turn savings into power.',
|
||||
sell_value = 'Sell value can be inflated first, then cashed in as Mult or a big sale.',
|
||||
joker_gen = 'Spare jokers are fodder: sell them for profit or feed them to scaling jokers.',
|
||||
tarot_gen = 'Free Tarot cards fix your deck and feed the jokers that count Tarot use.',
|
||||
planet = 'Planets level up poker hands; this crew makes them cheaper and rewards each one.',
|
||||
spectral_gen = 'Spectral cards warp the deck; these jokers create or lean on that chaos.',
|
||||
gold_gen = 'Gold cards pay while held - creators supply them, payoffs cash them in.',
|
||||
stone_gen = 'Stone cards are pure chips; add them, then pay off the heavier deck.',
|
||||
enhance_gen = 'Enhanced cards (gold, steel, stone...) power the jokers that eat or count them.',
|
||||
card_gen = 'Adding cards grows the deck - and the jokers that scale with its size.',
|
||||
pair = 'These all fire on a Pair, so one played hand triggers the whole set at once.',
|
||||
two_pair = 'Two Pair sets off every one of these together - stack them and replay it.',
|
||||
three_kind = 'Three of a Kind triggers all of these in a single played hand.',
|
||||
four_kind = 'Four of a Kind is rare but sets off this whole crew at once.',
|
||||
straight = 'Straights trigger all of these; enablers make gaps and 4-card runs count.',
|
||||
flush = 'Flushes trigger all of these; enablers make them far easier to assemble.',
|
||||
suit_flex = 'Suit benders make cards count as two suits, unlocking every suit joker.',
|
||||
hearts = 'Hearts pay these jokers when scored - suit benders widen the supply.',
|
||||
diamonds = 'Diamonds pay these jokers when scored - suit benders widen the supply.',
|
||||
spades = 'Spades pay these jokers when scored - suit benders widen the supply.',
|
||||
clubs = 'Clubs pay these jokers when scored - suit benders widen the supply.',
|
||||
}
|
||||
|
||||
-- Convert gives/wants arrays into sets for fast lookup.
|
||||
for _, entry in pairs(J) do
|
||||
local g, w = {}, {}
|
||||
for _, t in ipairs(entry.gives) do g[t] = true end
|
||||
for _, t in ipairs(entry.wants) do w[t] = true end
|
||||
entry.gives, entry.wants = g, w
|
||||
end
|
||||
|
||||
return { jokers = J, pairs = PAIRS, tag_text = TAG_TEXT, tag_order = TAG_ORDER,
|
||||
theme_info = THEME_INFO }
|
||||
Reference in New Issue
Block a user