#đ»ă»modding-dev
1 messages · Page 346 of 1
I think somethingcom might have just been mistaken
because they run it bu wrapping it in a function
this is if you're just running it on its own
they make a function called err and run it
f but yes
yeah you can see here that the () is how to get the function to actually execute still
god cryptid is so complicated
legacy code be like that
extremely technical explanation
SMODS.load_fileis a mere wrapper to aloadfile-like interface, and just likeloadfileit returns a function and an error codefrefers to the function. lua scripts can return a value that will be the return value that the function provides. usually seen in require statements likelocal foo = require "bar"which getsbar.luaand returns the return value of that tofooerris the error code.nil(or just 0?) when there is none. usually done for error checking before callingfto prevent a hard nil value reference crash
And lots of people use it as their reference đ
it depends on what you want to do
recreate the description of a joker without loc_vars
hmm can you elaborate a bit more? I'm pretty sure you don't need generate_ui to do something like that
i use G.P_centers rn, but that includes info_queue of the joker in that center
i used key, set thing but that crashes the game
yeah I would imagine that's the way to do it
what's the crash?
im making a joker that sets your entire played hand to a random suit, this seems to work fine visually but the hand proceeds as if the suits were unchanged (when playing a diamond flush, even if turned into spades, greedy joker will activate on the scoring cards), afterwards it works fine.
Could someone tell me how to make the game take into account the new suit instead of the old one?
Don't use an event for this
It'll trigger after scoring happens if you do
I see
thanks!
kind of a shame tho since without the event it all happens as the cards are moving :(
common_events.lua:2789 local 'ability' (a nil value)
can i see the code
Let me find my code
Just set card.base.suit = newsuit outside the event
i will try to see what the issue is but if it is your own joker you can also go to sncury_mostand's loc_vars and do
if not card.fake_card then
-- info_queue stuff
end
thanks!
that can exclude the stuff the stuff i don't wanna be shown when in G.P_CENTER?
right?
yes
aight, i'll try in a moment
also i think the issue is that you need a config table here
i love when defender randomly kills lovley
What rarity should this be?
wait, i put that IN loc_vars? i'm pretty sure that doesn't have card variable
so there can be card.fake_card
yep that crashed
global 'card' (nil)
Because youâre using the jank cryptid loc vars definition that uses center instead of card
thank you
what version of smods did cryptid start on? The answer to that question probably exmplains the jank
I think it was just a stylistic choice
Perhaps, but cryptid /is/ quite old
not the perfect comparison because I misremebered the cryptid first commit date
but real close
being accurate to the actual last bump version makes it look so much worse though
lol
I guess there was no 0.8.x of smods, or it was extremelhy short lived
is there a quick way to make only certain boss blinds available in a specific ante
but variable naming isn't a required thing, it's almost certainly a stylistic choice
yeah, very true
I guess I was meaning the zeitghesit too
what was the 'done thing'
old smods conventions tended to be a lot more heavily inspired by thunk's code even cosmetically I've noticed
idk if that applies here
though I have no clue where 'slug' came from instead of key
back in the early days
which of these do you think looks better?
right but depends
depends on?
if they'll get a body or something at bottom
no, it's just a bust like the normal jokers
i see
i'd say right
but what do i know
left may look a bit more "comical", but the arms are still just thin thin
tried to give a deck the negative shader and for some reason did this to the screen lol
How can I check if I have two diffrent number cards in the hand, i know about context.other_card:get_id(), but im not sure if adding an And statment will work
Iterate over G.hand.cards and check the id.
ah, okay, thank you
I was trying to make a dynamic text a la misprint but it's not working at all, did i do anything wrong here?
loc_vars = function(self, info_queue, card)
return {
main_start = {{n=G.UIT.O, config={object = DynaText({string = string.gsub(string.format("%.2f", tostring(30-(G.TIMERS.REAL - card.ability.start)*card.ability.inblind)), "%.", ":"),pop_in_rate = 9999999, silent = true, pop_delay = 0.5, scale = 0.32, min_cycle_time = 0})}}},
}
end,
number cards as in not face cards?
Im checking if the played hand has both an Ace and Nine
oh ok
ââââââââ
Base Difficulty
just to be sure, is this how you check a cards ID?
if card.get_id() == 14 then
No, card:get_id() == 14
you can use ref_value and ref_table instead if you need to it update in real time
I see, i'll try it asap then
Would something like this work or am i over complicating it
calculate = function(self, card, context)
if context.joker_main then
local found = {}
for _, card in ipairs(G.hand.cards) do
found[card:get_id()] = true
end
if found[14] and found[9] then
end
end
end
yeah that makes sense
is there a way to detect probabilites fail occuring?
like a hook 1 - odds when a pseudorandom is done?
no
it only seems to work when there is only one of each
with the code you posted it should work when there are multiple
i wish it was doing that lol
heres the most recent code, its also crashing when i play an ace and a nine
calculate = function(self, card, context)
if context.joker_main then
local found = {}
for _, card in ipairs(G.hand.cards) do
found[card:get_id()] = true
end
if found[14] and found[9] then
card.ability.extra.mult = card.ability.extra.mult * 1.99
return {
xmult = card.ability.extra.xmult
}
end
end
end
you use mult in one line and xmult in the other
also i just tested this and it works with multiple of each
is it the same code?
i pasted this and added the print
like two aces and two nines?
tested with two ace and a nine and two nines and an ace
i dont see how it would be different
okay, ill see if its something on my end
it seems to be triggering when you just have the cards in hand
plus it still crashes
ill try redoing the code
if played hand has an Ace and Nine, give 1.99x mult
ohhh G.hand is held in hand
oh my god
context.scoring_hand
i am so dumb
would i necessarily need to manually check for each probability in game, from jokers, tarot and playing cards ?
so just replace G.hand with context.scoring_hand
yes, you would need to patch all of them and also it would not work with other mods
yeah
yeah hard coded
Okay sweet, it still crashes but at least it detects it now
YES, IT FINALLY WORKS
can someone help me out here? i'm trying to add an image to my mod's config tab, that being my mod's icon, but i keep getting a crash
this is my code
SMODS.Atlas {
key = "modicon",
path = "modicon.png",
px = 34,
py = 34
}
...
function SMODS.current_mod.config_tab()
local sprite = Sprite(34, 34, 34, 34, "modicon")
local config_nodes = {n=G.UIT.ROOT, config = {align = "cm", colour = G.C.L_BLACK}, nodes = {}}
config_nodes.nodes[1] = {n = G.UIT.O, object = sprite}
return config_nodes
end
the fifth argument is an atlas not a string
are tags considered consumeables? as in, im trying to see how to track how many have been used during the run, and looking at fortune teller it uses G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.tarot
you mean the SMODS.Atlas object?
No.
how could i track them then?
G.ASSET_ATLAS["modprefix_modicon"]
You'll probably have to increment a variable in the function where tags get used maybe?
tag:yep()?
so in a hook?
Yes.
alrighty
now it's just giving me this, everything is the same except that "modicon" is G.ASSET_ATLAS["lcb_modicon"]
what is the difference between the x,y and w,h values in the Sprite()?
Hello
I had a very silly idea of a deck that only gets added into the game at the weekend but like how would I do that
config={object = sprite}
i'm stupid, i forgot to put the object thingy inside the config
yea i figured that out now xD
os.date("*t").wday == 6 or os.date("*t").wday == 7 maybe?
Sunday is 1 for some god forsaken reason
when a tag is used, the print does increment but the game stops working (i mean cant select a blind, or skip, can only use menu ui)
local tag_used = 0
function Tag:yep()
tag_used = tag_used + 1
print(tag_used)
end```
You need to hook it not overwrite it.
Also you want to put it in G.GAME
im not sure i understand the difference ^^;
hook means keeping the old function overwrite means remove the old function completely, the game was trying to activate the tag but you got rid of the old function.
anyone seen these logs in their build?
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
INFO - [G] Error unpacking string: [string "return {["BLIND"]={["chips"]=0,["dbsk"]={},["..."]:1: attempt to perform arithmetic on global 'inf' (a nil value)
logs without stopping on the deck selection screen
how do i turn my thing into a hook?
im not sure i understand the structure difference
local oldtagyep = Tag.yep
function Tag:yep(message, _colour, func)
-- code
return oldtagyep(self, message, _colour, func)
end
Hi guys, what does the weighting mean? I am guessing higher == more chance to see
yeah, exactly
wrote G.GAME.context.vdr_tag_used or 0 in loc vars, crashes, have i miscalled the context?
G.GAME.context does not exist, so you are indexing a nil value.
how can i use the context's returned value of how many tags have been used as the joker's current chips?
Just put it in G.GAME.vdr_tags_used
ahh no context needed?
G.GAME.contextdoes not exist?
is there a way i can replace the locked deck sprite
in malverk etc
tryna convert my texture mod to actual mod format
cringe so the superior format for this mod is still straight file replacement
Is there a context window for "and this hand will win", i.e. the flaming effect is happening?
returns nil (but doens't crash)
the hook's : lua local oldtagyep = Tag.yep local tag_used = 0 function Tag:yep(message, _colour, func) tag_used = tag_used + 1 SMODS.calculate_context({vdr_tag_used = tag_used}) return oldtagyep(self, message, _colour, func) end
when i print context.vdr_tag_used though it does return tag_used correctly
I said put in G.GAME.vdr_tags_used?
No context?
im confused
no the superior format is malverk by a signicant margin, you just can't replace the locked sprite easily
What effect are you looking for?
if i cannot complete my mod in malverk then it is not superior
for joker chips to be equal to an amount * nb of tags used this run
im trying to recreate shit i already did by dragging a file into my balatro exe in less than 10 seconds
local oldtagyep = Tag.yep
local tag_used = 0
function Tag:yep(message, _colour, func)
tag_used = tag_used + 1
SMODS.calculate_context({vdr_tag_used = tag_used})
return oldtagyep(self, message, _colour, func)
end
--Hang Tag R
SMODS.Joker {
key = 'hang_tag',
loc_txt = {
name = 'Hang Tag',
text = {
"This Joker gains {C:chips}+#1#{} Chips",
"per {C:attention}Tag{} used this run",
"{C:inactive} (Currently {C:chips}+#2#{C:inactive} Chips)"
}
},
atlas = 'Jokers',
pos = {
x = 1,
y = 1
},
blueprint_compat = true,
perishable_compat = true,
eternal_compat = true,
rarity = 1,
cost = 4,
config = {
extra = {
chipsmod = 35
}
},
loc_vars = function(self, info_queue, card)
return {
vars = {card.ability.extra.chipsmod, G.GAME.vdr_tag_used or 0}
}
end,
calculate = function(self, card, context)
if context.vdr_tag_used then
print(G.GAME.vdr_tag_used)
card_eval_status_text(card, 'extra', nil, nil, nil, { message = localize('k_upgrade_ex'), colour = G.C.CHIPS})
end
if context.joker_main then
return{
chips = G.GAME.vdr_tag_used or 0
}
end
end
}```
Then put the number of tags in G.GAME.vdr_tags_used
No calling contexts.
the context is only used for the card_eval though
how do i define G.GAME? in hook?
G.GAME.vdr_tags_used = G.GAME.vdr_tags_used + 1?
ok so replacing the tag_used and no needing to local define it before the hook?
Yes.
hi guys
I was trying to play a sound effect within a hand but I have the issue of the sound being played when the cards are selected,not when they are played. Has anyone tried something similar?
When are you playing the sound?
am i able to give texture atlases offsets
I'm playing the sound within a custom hand's definition
I think that is the wrogn approach, I am going to rethink this
That triggers every time the game tries to calculate the hand?
Yes, that is not what I wanted to happen so it was playing a TON
whats the function to change the shop size? i used SMODS.change_booster_limit(1) and SMODS.change_voucher_limit(1) for vouchers and that works, but SMODS.change_shop_size(1) doesnt work, neither does removing the SMODS prefix
change_shop_size() is a vanilla function
I'm trying to kind of make a midas mask that has a 1 in 4 chance to add polychrome instead (though I have yet to swap out gold for polychrome in the code), and I get this error, anyone know why?
loc_vars = function(self, info_queue, card)
return { vars = { (G.GAME.probabilities.normal or 1), 4 } }
end,
calculate = function(self, card, context)
if context.cardarea == G.play and pseudorandom('Child Vance') < G.GAME.probabilities.normal / 4 then
local faces = {}
for k, v in ipairs(context.scoring_hand) do
if v:is_face() then
faces[#faces+1] = v
v:set_ability(G.P_CENTERS.m_gold, nil, true)
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end
}))
end
end
if #faces > 0 then
return {
message = localize('k_gold'),
colour = G.C.GOLD,
card = self
}
end
end
end
delete card = self
can texture atlases have offsets
Right, I remember that now, thanks!
how do i make it so my enhancement doesnt spawn natually?
alright, back at it again, anyone know why my joker isnt triggering when a light card is triggered?
Put ```lua
in_pool = function(self)
return false
end
thank you
?
you're setting the enhancement as G.P_CENTERS.glimmering, but it needs to be like G.P_CENTERS.m_prefix_glimmering
@wintry solar any idea why none of the params except x_mult works here
(this is blind calc)
?
needs a message
buh
just to be sure, is this how i set up first_hand_drawn?
calculate = function(self, card, context)
G.E_MANAGER:add_event(Event({
func = function()
if context.first_hand_drawn then
print("HAI :3")
end
end}))
end
}
that's annoying
auto messages dont take custom stuff
ty
okay, that clearly didnt work
oh wait
i gotta return True
i hate how i have to ask multiple times before i get an answer
thats just how support chats work
You also should check for the context outside of the event.
idk why it doesnt work but you could try
for i = 1, #context.scoring_hand do
if context.scoring_hand[i].config.center.key == "m_cry_light" then
return {
xmult = card.ability.extra.Xmult,
card = card
}
end
end
I dont understand, how come?
You don't want to clog the event queue with empty events.
it uh. does not override the auto message
lol
and the card = ... param doesnt work
No, just check for the context then run the event.
you dont get an auto message if you use xmult_mod iirc
What is this type?
3hi?
if i have to use xmult_mod instead of x_mult i'm actually going to end it all
talisman
nope, did i do it right?
you need to keep the if context.individual and context.cardarea == G.play then
?
ye
still nothing
what did i do wrong here why does it crash if i start a new run??
SMODS.Voucher {
key = 'Dumpster',
loc_txt = {
name = 'Dumpster Diving',
text = { '{C:green}#1# in #2#{} chance to spawn a random consumable at {C:attention}end of round{}', '{C:inactive}(No need to have room)'}
},
atlas = 'Jokers',
pos = {
x = 0,
y = 32,
},
config = {
extra = {
odds = 3,
}
},
loc_vars = function(self, info_queue, card)
local stg = card.ability.extra
return {
vars = { G.GAME.probabilities.normal, stg.odds }
}
end,
calculate = function(self, card, context)
if context.end_of_round and not context.repetition and not context.individual then
if pseudorandom('trash') < (G.GAME.probabilities.normal / card.ability.extra.odds) then
local new_card = create_card('Consumeables', G.consumeables)
new_card:add_to_deck()
G.consumeables:emplace(new_card)
if config.sfx ~= false then
play_sound("fn_trash")
end
end
end
end
}
SMODS.Voucher {
key = 'Dumpster2',
loc_txt = {
name = 'Trash Tycoon',
text = { 'Spawn a random consumable at {C:attention}end of round{}', '{C:inactive}(No need to have room)'}
},
atlas = 'Jokers',
requires = 'v_fn_Dumpster',
pos = {
x = 1,
y = 32,
},
calculate = function(self, card, context)
if context.end_of_round and not context.repetition and not context.individual then
local new_card = create_card('Consumeables', G.consumeables)
new_card:add_to_deck()
G.consumeables:emplace(new_card)
if config.sfx ~= false then
play_sound("fn_trash")
end
end
end
}
how can i find the key of a booster pack?
bro
my best guess then is that you're using the wrong key? are you sure the prefix is cry and the enhancement key is light
its from cryptid, the prefix is cry, and i'm pretty sure the enhancement key is light
i checked and thats what it said
could try something similar to this joker it gets the gold cards and retriggers them
SMODS.Joker({
key = "Kane",
loc_txt = {
name = "Fletcher Kane",
text = {
"Retriggers every {C:money}Gold{} card {C:attention}#1#{} times",
}
},
rarity = 2,
atlas = "Jokers",
pos = { x = 0, y = 15 },
cost = 6,
unlocked = true,
discovered = false,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
config = { extra = { repetitions = 1 } },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.m_gold
info_queue[#info_queue + 1] = G.P_CENTERS.e_cry_gold
info_queue[#info_queue + 1] = G.P_SEALS.Gold
return { vars = { card.ability.extra.repetitions } }
end,
calculate = function(self, card, context)
-- Check if a Gold Card is played or in hand
if context.repetition and context.cardarea == G.play then
if context.other_card and context.other_card.ability.name == 'Gold Card' or context.other_card.edition and context.other_card.edition.key == 'e_cry_gold' or context.other_card.seal == 'Gold' then
return {
repetitions = card.ability.extra.repetitions,
message = localize('k_again_ex'),
card = card
}
end
end
-- Handle Gold cards in hand
if context.cardarea == G.hand then
for i = 1, #G.hand.cards do
if context.other_card and context.other_card.ability.name == 'Gold Card' then
return {
repetitions = card.ability.extra.repetitions,
message = localize('k_again_ex'),
card = card
}
end
end
end
end
})
that's for editions though
context.other_card.edition.key == 'e_cry_gold'
yeah it retriggers all forms of gold seals, edition, and enhancement
ohhh
i'm not looking to retrigger though, i want it to add x2 mult when a light card is triggered
yo whattup can you give an atlas an offset
then rather than a return you'd do
card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_add
that should work i'd think
what context should i use for creating a booster when entering the shop? couldnt find one for entering the shop
where would that go?
it'd be something like this
calculate = function(self, card, context)
-- Check if a Light Card is played or in hand
if context.repetition and context.cardarea == G.play then
if context.other_card and context.other_card.ability.name == 'Light Card'
card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_add
end
end
if context.joker_main then
return {
message = localize{type='variable', key='a_xmult', vars={card.ability.extra.Xmult}},
Xmult_mod = card.ability.extra.Xmult,
}
end
end
}
you'd probably remove the repetition actually since no repetition
why are we checking if its held in my hand? they get triggered when played
bump
that doesn't the original code i had for fletcher kane did since gold cards in hand have an effect to retrigger (the $3 they give you for holding them)
ohhh
Why do I get an error nil value on extra in what would be line 4 here?
config = { extra = { odds = 4 } },
loc_vars = function(self, info_queue, card)
return { vars = { (G.GAME.probabilities.normal or 1), card.ability.extra.odds } }
end,
if G.GAME.current_round.hands_left == 1 then?
Where is the code that makes the boss blind outline and inner color of the UI (the color that mimics the blind)
im trying to have it apply after the player beats the score requirement
still nothing
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 2
}
},
loc_vars = function(self, info_queue, center)
return { vars = { center.ability.extra.Xmult } }
end,
calculate = function(self, card, context)
-- Check if a Light Card is played or in hand
if context.cardarea == G.play then
if context.other_card and context.other_card.ability.name == 'Light Card'
card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_add
end
end
if context.joker_main then
return {
message = localize{type='variable', key='a_xmult', vars={card.ability.extra.Xmult}},
Xmult_mod = card.ability.extra.Xmult,
}
end
end
}```
have it apply after the round is won? you can use context.end_of_round for that
in blinds you can define boss_colour = HEX(ffffff)
you need an Xmult_add in your extra+locvars for it to add however much its adding
I may be able to use that for what I'm trying to do, albeit in a roundabout way.
to make sure it doesnt happen multiple times do if context.end_of_round and not context.repetition and not context.individual then
how does one get to read this code
instead of repetition and individual you can do context.main_eval
like this? because this didnt work
really? didnt know that haha gonna try that now
so something like this?
if context.end_of_round and context.main_eval then
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.0,
func = (function()
print("BAI! :3")
return true
end)}))
end
or should it be not context.main_eval
like that yeah just tested it, just saying context.main_eval is good
oh, that did seem to work
thanks
now i gotta find out how to randomly add my enhacement
all this feels like near gibberish
i wish i knew what i was doing
learn lua then ig
ive learned lua in the past but switched to python lol
i feel like if you find the base code for randomly doing negative youll find how to do that
add it to what? you can use the set_ability function to set the enhancement
bump
to a random card chosen
i need to figure out how to pull a randon card
python feels so much more readable than this
try (G.GAME and G.GAME.probabilities.normal or 1) instead of G.GAME.probabilities.normal or 1)?
Same thing.
pseudorandom_element(G.P_CARDS, pseudoseed('seed') will return a random card in your deck i think
ok yeah that didn't work but this works
SMODS.Joker {
key = 'ash',
loc_txt = {
name = 'Ash Baby',
text = {
"This Joker Gains {X:mult,C:white}X#1#{} Mult",
"When a Light Card is played",
}
},
rarity = 1,
atlas = "ashbaby",
pos = { x = 0, y = 0 },
cost = 5,
unlocked = true,
discovered = false,
eternal_compat = true,
blueprint_compat = true,
perishable_compat = false,
config = {
extra = {
Xmult_add = 1,
Xmult = 2
}
},
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.Xmult_add,
card.ability.extra.Xmult
}
}
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
for _, played_card in ipairs(G.play.cards) do
-- Check if the card is light
if played_card.config.center == G.P_CENTERS.m_cry_light then
card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_add
return {
message = localize('k_upgrade_ex'),
colour = G.C.Mult,
card = card
}
end
end
end
if context.joker_main then
return {
message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.Xmult}},
Xmult_mod = card.ability.extra.Xmult,
}
end
end
}
oh
lmao
i misunderstood that
What data type is a hi? I am seeing numbers that are formatted as 2hi or 3hi. I'm trying to parse hi into a number
does Xmult_add add times mult or an x amout of mult
can someone tell me how to get localized text in a proper ui table because this does nothing
loc_vars = function(self, info_queue, card)
local main_end = {}
if G.jokers and G.jokers.cards then
for k, v in ipairs(G.jokers.cards) do
if (v.ability and v.ability.eternal) then
main_end = {}
localize({type = "text", set = 'Other', key = 'o_af_removes_eternal', nodes = main_end, vars = {}})
main_end = main_end[1]
break
end
end
end
return {
main_end = main_end
}
end,
i havent seen balatros source code myself and its kinda unreliable to make those assumptions (i know from experience looking through other games code)
Understandable
trying to figure out why my deckskin crashes the game. here's the crash log and the main.lua
It's going to be the tiniest thing, I swear. Anyone?
Ok I found my answer, here is how you can parse a table number value!
tonumber(format_ui_value(G.GAME.hands["HandName"].level))
It takes a hi value and gives you a regular lua number
SMODS.Joker {
key = 'ash',
loc_txt = {
name = 'Ash Baby',
text = {
"Played Light Cards each give {X:mult,C:white}X#1#{} Mult when scored",
}
},
rarity = 1,
atlas = "ashbaby",
pos = { x = 0, y = 0 },
cost = 5,
unlocked = true,
discovered = false,
eternal_compat = true,
blueprint_compat = true,
perishable_compat = false,
config = {
extra = {
Xmult = 2 -- Mult per light card
}
},
loc_vars = function(self, info_queue, card)
return {
vars = { card.ability.extra.Xmult }
}
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
for _, played_card in ipairs(G.play.cards) do
if played_card.config.center == G.P_CENTERS.m_cry_light then
return {
x_mult = card.ability.extra.Xmult, -- Apply multiplier to the current card
card = card
}
end
end
end
end
}
bump
bump
stole my idea :( /j
lol
you sure because that worked for me??
oh wait i might have fucked up pasting it oops
can someone please inform me on how to read balas code so i can get some knowledge in before i sleep as its 00:43 and i want to ignore the fact i have assesments to work on tmmr
yeah no it still didnt work
This looks correct to me, I tested it myself
Send the full error code?
thats the fun part, you gotta decode it basically
wha
its fucking something
you can unzip the game executable
what does that even mean
wait, do you mean reading it or extracting the code
that is like telling a todler to do astrophysics
reading
okay then maybe you should learn said astrophysics
i dont know how to get that pulled up
do you not have the source code on hand right now
wtf that works on my end
no
you can take Balatro.exe it's actually a zip file
i will try to
hang on i'll dm you the whole thing, i probably fucked up somewhere
you mean to tell me this bitch is a zip
yea
yes you can open with 7zip or winrar
open it with 7zip and extract it
yeah
THE FUCK
zip files are a cursed file format
[patches.pattern]
target = '=[SMODS _ "src/crash_handler.lua"]'
pattern = "table.insert(err, sanitizedmsg)"
position = "before"
payload = "sendDebugMessage(tprint(sanitizedmsg))"
match_indent = true```
trying to lovely patch smods so that the game can tell people that they need to update it for cardsauce and i dont understand for the life of me why this lovely patch doesnt work
flower pot's works
HOW THE SHIT CAN SOMETHING BE A ZIP FILE AND EXECUTABLE AT THE SAME TIME
they hold the power to everything but make no sense, like quantum mechanics
imagine you have a pc, the stuff in the pc is what you have in the game, the game files, and the pc is what runs those files
does that help at all
technically balatro is a .love file, which is a .zip file in disguise
so thats 3 filetypes
time to download the unlimited free trial app
to get technical the main bits of data needed to be a valid zip file come at the end of file
i've been playing a little bit of nnf and i had a kind of funny idea for a joker:
Nubby: Rare
At the end of scoring, force-trigger the joker to the right
how possible do you think this would be
force-triggering is a nnf thing - triggering a joker regardless of whether it usually would be
reallypainful
use 7zip, its completely free
for example, force-triggering hanging chad would go back and trigger the first card scoring (but nubby wouldn't activate afterwards)
you could hijack cryptid's demicolon stuff
so is winrar
unfamiliar with demicolon
doesn't that use talisman
it's forcetrigger but during scoring
yeah but 7zip doesn't pester you
and i personally prefer the books
ideally they would pull the forcetriggers out into a separate library mod
7zip also just leaves aa bad taste in my mouth due to prior experiences with it
how can i get a list of cards in hand that arent enhanced?
the console doesnt even say that this patch failed it just doesnt get applied at all
super weird
I was going through the love documentation and was so surprised to see that balatro.exe was literally love.exe concatenated with the balatro zip file
how can i edit this so it tells me the rank and suit of the card instead of printing its tables?
mac by any chance?
nope, windows
Hey can anyone help me out and guide me how I could turn some of the changes into smods I hv a txt file
weird, not sure then
i am in the middle of attempting to switch from using one lovely patch file to several seperated ones in a lovely folder
it wouldnt like
prevent the folder ones from loading if i have a central one, would it?
i'm guessing this has something to do with how i tried to stop glass cards from being destroyed but i have no idea what the fuck is going on
-- makes kori block shattering
local shatterVanilla = Card.shatter
function Card:shatter()
local kori = false
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].ability.name == "Korihas" then
kori = true
break
end
end
if not kori then shatterVanilla(self) end
end
It would
ah that explains it then
It either looks at lovely.toml or the lovely folder
ok well i moved my core patches to the folder
but now its still not loading?
i mean all my other patches seem to be loading but this smods one in particular just
lovely refuses to acknowledge that it exists
Can you screenshot your folder structure?
Bump
loc vars is uh,
very funny
i use self.config.extra instead and it works
Donât do that
thats probably not good but eh
Bill can you screenshot the code?
haven't done vouchers before cause the coding i see on like all of them is very confusing but why does this crash if i ever try to start a new run after getting this voucher?
wtf are you meant to do then
Should be ((G.GAME and ' '..G.GAME.probabilities.normal) or 1)
That doesn't change anything.
And what are you experiencing?
can anyone tell why this crashes on end of round?
Boosters dont exist at end of round, maybe try context.starting_shop
Have you started a new run?
oh i didnt see that context on the mod page..
I haven't, would that fix it?
If you continue a run it will keep the old values so yes try a new run
Ah, that fixed it, I'm just stupid. At least I know for next time.
Is this the right code to add polychrome to a playing card?
v:set_edition(G.P_CENTERS.e_polychrome, nil, true)
Just âe_polychromeâ as the first argument
Okay, got it.
its super confusing cause im following pretty much the exact same formatting as this patch from flower pot (even using the same priority value) and this patch works on my end. but for some reason the patch i made doesnt
Does it work if you change the file name?
Try typing it out again from fresh
wdym?
Hello good people. Question: Is there a way to figure out if any given card has a seal? (basically where are seals stored.)
card.seal?
It's a blessing when things are on the nose like that
I swear enhancements, editions and seals are eo extra fucked up.
It is not when there is no order whatsoever.
Type it out as a new patch
iirc seal keys are properly stored in card.ability.seal.key
card.ability.seal does not seem to exist.
wait
oh wtf is that now?
Copy of such.
how does idol choose a random rank?
card.seal for identifying current seal, card.ability.seal for using a given value of config from seal.
still nothing
Yeah I was expecting smth like that
is there something im missing when it comes to lovely patching smods?
@woven stratus hii :3
yall, is there a way to layer multiple deck skins on top of each other
hi!
like
for example, one skin provides just aces, but another provides all cards, and i want to use both
like minecraft resource packs
not unless you merge them yourself
for gimp, after i have made my images and saved them, how can I mass export into pngs?
Does anyone see why this card woul not proc? It says 'AGAIN', but the action doesn't take place at all
if context.individual and context.cardarea == G.play then
local hand_name = "Fox_shungokusatsu"
local retrigger = tonumber(format_ui_value(G.GAME.hands[hand_name].level))
card.ability.extra = retrigger
local otherCard = context.other_card
local cardInfo = getValueNilSafe(otherCard.base.value)
sendInfoMessage("Played Card " .. cardInfo, card.key)
if cardInfo == 10 or cardInfo == "10" then
sendInfoMessage("Played Card " .. cardInfo .. " is a ten, retriggering " .. retrigger .. " times", card.key)
if FoxModConfig.playSounds then
return {
message = localize('k_again_ex'),
repetitions = card.ability.extra,
card = card,
sound = "Fox_metsu"
}
else
return {
message = localize('k_again_ex'),
repetitions = card.ability.extra,
card = card
}
end
end
Debugplus gives me this and playing a card gives a message saying "ERROR" on both the card and joker, here's the code, why's it happening?
config = { extra = { odds = 4 } },
loc_vars = function(self, info_queue, card)
return { vars = { (G.GAME.probabilities.normal or 1), card.ability.extra.odds } }
end,
calculate = function(self, card, context)
if context.cardarea == G.play and pseudorandom('Child Vance') < G.GAME.probabilities.normal / card.ability.extra.odds then
local faces = {}
for k, v in ipairs(context.scoring_hand) do
if v:is_face() then
faces[#faces+1] = v
v:set_edition(e_polychrome, nil, true)
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end
}))
end
end
if #faces > 0 then
return {
message = localize('k_poly'),
colour = G.C.POLYCHROME,
card = card
}
end
end
end
is there a way to make 6 card hands and above playable?
#1329150573479596032 does 6 card hands
Cryptid can do anything but is probably jank
repetitions need to be in context.repetitions afaik
also you dont need the again message, it does it automatically
How do i put a value above cash to display a value? UI is hurting my head
wait for the next smods release
dosent the cryptid mod have that feature?
yes but if you copy it, it will break in the next smods release
whens the next smods release?
Bump
Ah, that's right, thanks!
--[[
G.UIT.R: Row assortment.
G.UIT.C: Column assortment.
G.UIT.ROOT: Root node. Every UI element needs a root node.
It's, generally speaking, good practice to alternate between rows and columns.
--]]
--
function risk_menu_test_func(menu_name)
return {
n = G.UIT.ROOT,
config = { align = "cm" },
nodes = {
{
n = G.UIT.R,
config = { align = "cm" },
nodes = {
{
n = G.UIT.C,
config = { align = "cm" },
nodes = {
{ n = G.UIT.T, config = { text = menu_name, colour = HEX("000000"), scale = -1.5 } },
},
},
},
},
},
}
end
local my_menu = UIBox({
definition = risk_menu_test_func("I Am menu"),
config = { type = "cm", ... },
})
function create_UIBox_HUD()
local contents = original_hud()
local stupid_fucking_box = my_menu
table.insert(contents.nodes[1].nodes[1].nodes[4].nodes[1].nodes, stupid_fucking_box)
return contents
end
crashes stating 'attempted to index field 'colour' ( a nil value)
why is scale -1.5??
i fixed it but that didnt change anything
btw i dont intend for this to look good i just wanna get it working
its very confusing but I had that happen sometimes when I was mixing up things that expect a list of nodes and things that expect a node
not saying it is I dont know enough UI to diagnose it from that snippet
i changed it to 'stupid_fucking_box.nodes'
is there a way to make a different window just for a certain type of enhancement?
I do not like tables and lists being conflated in lua because of crap like this
Now, good(er) people. Where can I find if a card is rental, eternal and stuff?
I think it's just a field on card.ability
For each
If I'm remembering correctly
I'll check
what localization entry does SMODS.deck_skin take?
how can i check when the boss blind is defeated?
check for G.GAME.blind and G.GAME.blind.boss i think
look at how campfire did it in the base game
https://github.com/TheOneGoofAli/TOGAPackBalatro/blob/main/localization/default.lua
https://github.com/TheOneGoofAli/TOGAPackBalatro/blob/main/items/deckskin.lua
Maybe such will help?
bump
how do i modify the game's UI
I want to make a food joker that gives extra discards each round but changes the amount of extra by -1 each round, how should i do that?
i found https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua and it says
Extra note, having the config as something like
config = {d_size = 3, h_size = -1, extra = {whatever variables you put}}
automatically applies these changes.
However, these values outside of the extra table are constants, so they aren't good for jokers with values that change.
You can find a fuller list of them at card.lua:275.
]]```
which makes sense but i'm not sure what i should use instead
it also uses `G.GAME.round_resets.discards = G.GAME.round_resets.discards + card.ability.extra.discard_size` but that seems like it wouldnt work well if the number of discards changes either unless im wrong?
you'd want to use ease_discards(), which takes a number and modifies (NOT SETS) the amount of discards by it, and have a variable in your config which decreases by one at the end of the round
bump
new to modding, is there a best way to do chance other than just doing it with regular lua code, and how would i make the 'Nope!' text show up if the chance fails
use psuedorandom() which takes a seed (string) and returns a number from 0 to 1
can anyone explain to me why my deckskin isn't working?? (excluding the localization)
wdym
noit sure tho
i have all of the images in my /assets/ folder
but at the top of the code, did you specify the paths?
yeah, atlases use /assets/ by default
why does it do it like this, what is the actual benefit to relooping over all centers this just seems wasteful
am i stupid or
i have this line
in_pool = function(self)
return false
end,```
to take the joker off the pools of joker creations like judgement or riff raff, but now it stopped appearing in shop or boosters, is there a way to fix it?
the center should already contain the centers key this just feels like extra steps for no reason
-# It was simpler for me, tbh. Plus... that's how Cardsauce did theirs. :p
bump
oh wait this isnt vanilla i thought this was vanilla
you should be able to just access center.key instead of doing it like this unless issues pop up
i mean it almost doesnt matter
unless a lot of cards are created at once
idk what cardsauces deal is tbh
ÂŻ_(ă)_/ÂŻ
hihi, two questions
hello
hai :3
when would i call ease_discard()?
first: i have a modded, secret hand called Junk, and a Joker that depends on it
how can i check if Junk is unlocked, in the Joker's in_pool function?
G.GAME.hands[handkey].visible
the second layer would be the "enhanc" thing right?
second: said Joker has this code
swapped atlas_lc.key out for a full string but the atlases i defined don't exist? even though i just defined them above?
it works, but i'm worried that future localisations will break it
soul_pos here would be the floating sprite and pos would be the actual card unless you want to invert that functionality
check for text instead of disp_text
is there a better way that doesn't rely on the player playing in- ah thanks ^^
testing ^^
i want the pos to be the "enhanc" with background and soul_pos to be the "enhanc" thing that is blank in the middle
then yes this is correct
you'd probably need to fiddle with floating_sprite and drawsteps to get exactly what you want
oh wait, nvm i misread
for some reason it is duplicating the last one in the second colum of images
bump
try printing text to find the exact key cause you might be checking wrong
but text is the hand index in G.GAME.hands which exists for all hands incl modded ones
and also doesnt depend on localization
ya i had phanta_Junk đ thanks! changed it to phanta_junk
what about this? is there a function that finds a hand, based on key?
gonna post the art here too :3 meet Binman!
should be something like return G.GAME.hands["phanta_junk"].visible
or G.GAME.hands.phanta_junk.visible would work too
what could possibly be the reason for the crash in engine/sprite.lua???
the issue is that the atlas provided is nil but idk what the root cause of that is
for some reason anything i put into soul_pos turns into that one
Gibo
yeah, i'm not sure because i define the atlases literally right above the deckskin
is there another way to put more layers to a consumable isntead of soul_pos?
youll have to mess with some things that i dont remember to do that
but its possible
show that part of the code
cause atlases need to be mod prefixed in some specific places
iirc
wtf đ
hm
its like consumable keys and stuff
the prefix is automatically added sometimes but not everywhere
let me try and prefix
idk if this is the specific issue here but it might be
did not fix it
you might want to inspect G.ASSET_ATLAS if you get into the game
before you crash
and see if you can find your atlas key
it's luckily not crashing anymore but the cards are just blank
it IS there but.. for some reason the cards are blank
bump
when should i call ease_discard() to make a joker that gives extra discards per round based on a variable?
?????? so it is registered with the right atlas
--[[
Risk is a mechanic for astropulvis that I want to add, but problem is, I have not a clue what to start with. Oh well, here we go!
]]
local original_hud = create_UIBox_HUD
Risk = 0.00 -- Risk is measured between 0.00 and 1.00. Higher means more chance of bad things happening.
-- ALSOOOOO... make globals start with uppercase letters. Good practice or whatever.
Risk_manip_table = { risk = Risk }
--Some kind of UI element? gotta figure out how to do that.
--[[
G.UIT.R: Row assortment.
G.UIT.C: Column assortment.
G.UIT.ROOT: Root node. Every UI element needs a root node.
It's, generally speaking, good practice to alternate between rows and columns.
--]]
--
function risk_menu_test_func(menu_name)
local spacing = 0.13
local scale = 0.4
return {
n = G.UIT.R,
config = { align = "cm" },
nodes = {
{
n = G.UIT.C,
config = {
align = "cm",
padding = 0.05,
minw = 1.45 * 2 + spacing,
minh = 1.15,
colour = HEX("ffffff"),
emboss = 0.05,
r = 0.1,
},
nodes = {
{
n = G.UIT.R,
config = { align = "cm" },
nodes = {
{
n = G.UIT.C,
config = { align = "cm", r = 0.1, minw = 1.2, colour = HEX("000000") },
nodes = {
{
n = G.UIT.O,
config = {
object = DynaText({
string = { { ref_table = Risk_manip_table, ref_value = "risk" } },
font = G.LANGUAGES["en-us"].font,
colours = { G.C.RED },
shadow = true,
scale = 2 * scale,
}),
id = "astropulvis_risk_UI_shit",
},
},
},
},
},
},
},
},
},
}
end
local my_menu = UIBox({
definition = risk_menu_test_func("I Am menu"),
config = { type = "cm", ... },
})
function create_UIBox_HUD()
local contents = original_hud()
local stupid_fucking_box = my_menu
table.insert(contents.nodes[1].nodes[1].nodes[5].nodes[2].nodes, stupid_fucking_box.nodes)
return contents
end
can someone explain to me why this ui element only shows up during the inital startup animation, and not during the run like I want it to.
you should probably just make the element in Game:start_run and attach it in G.HUD from there
is there a context on destroying cards?
ive probably done something else here that messed stuff up but it seems like psuedorandom doesnt exist and or im just silly and i cant set it to 1-10 like other random things
you miswrote pseudorandom
pseudorandom
thaat makes sense lawl
elaborate?
also the first argument takes in a seed name
tryna make flush six bla bla bla, this doesnt work, whenever i make a flush it considers it a flush six
i mean i guess you have this but theres no real context on a joker being destroyed (though only that knife joker does it right?)
i think removed stores whatever card was destroyed
yeah there's none for destroying jokers
but i want a joker that does something when a card is destryoed, including consumables and playing cards
isnt there a remove_card context?
no
got it working by setting pos_style = 'rank', but can someone please explain why my loc_txt isn't displaying
how would i do this? the example i looked at attached it when the game was building the ui
bump 2
what variable
i'm trying to just save it in self.ability.extra.discard_size but idk if that works?
what about one on destroying consumables?
rather, what's the effect?
well it's meant to be a food joker, so it just gives self.ability.extra.discard_size discards each round, but the value of that also goes down by 1 each round
nope, there's one for using them
I just found out that Extra Credit users lovely patches for their "changes each round" jokers that act on suits and ranks, abs hard codes them to only use the vanilla ones instead of in_pool
That's insane, right?
so there isnt a way to get it to activate then?
I think i have the logic for it going down working, but cant test cause it's just crashing where i'm trying to put ease_discard() rn
local elements = { ui elements... }
G.HUD:add_child(elements, node)
except on destroying playing card
actually no you probably don't need to do this
but i dont think theres any way to remove playing cards without destroying them
you have to patch for easy global variables
create_UIBox_HUD does not make a uibox- it creates the definition for it
meaning its a raw table of elements
i had a "card changes each round" joker that did a little bit of patching
some mods implement their own destroy card context but it's not as straightforward as it could be because there's no in-game difference between destroy/use/sell
mhm..
you don't need to make a UIBox to attach elements to it
well there a context on selling cards
bump, loc_txt is incomprehensible
It's the hard coding the options that really gets me
yeah that part's a little strange
so i should just add the function for the definition
of the uibox
rather than the ui box
yep
you can put ease_discard anywhere, you might be calling it wrong
yeah but selling a card also removes it and not vice versa
bump bump localization is hell
doesn't loc_txt just take in a single string here
like just loc_txt = "THE NAME IS HERE"
that would suck if it does but let me check
the game rendering a table would mean its trying to create a representation of that table as a string
i mean i guess there's not too much to localize anyways for the name of a game
maybe, do you know what the arguments are for it cause i cant find those online
i just copypasted burglar (because that's the only instance of it that i could find) and changed the first argument so now i have ease_discard(self.ability.extra.discard_size, nil, true)
yea
just use a localization file if you want multiple languages
you really shouldn't be using loc_txt if you're planning for that
god damn it đ
card.ability.extra instead of self
yeah i know
there's no docs on what set deckskins use
so i just gave up
that looks good btw !!!! diamonds is my second favorite suit besides spades
all the other suits SUCK
I WIN!!!
I WINNNN!!!!!
I WIN I WIN I WIN
I WIN I WIN I WIN
i might have it disp like hands, discards, ante and round
its still crashing when i call it
crash log pls
r
ive tried calling it in some different spots and all of them crash
also the calculate part is just taken from popcorn
dont use self, use card pls
oh i missed that part i see
trying to think of how to shuffle played cards back into the deck
not sure how that would go
should playing card be yellow? idk which text to make yellow
i should probably add a separate hud element for pyrox and money now that i think about it
would it be as simple as taking note of played cards (that a variable applies to) and throwing them back into G.deck or something similar?
im currently lovely patching it rn its not great
How do I make tooltips?
its still crashing, where are the crash logs saved?
How do they work?
this is intended to give +1 hand size, why doesn't this work properly?
oh i found it
Steamodded wiki isn't helpful
nvm
There's an example in the wiki, which part do you need help with?
what's cry_ante_base_mod?
the cry_ prefix is usually for Cryptid stuff
i assume it's a cryptid thing that's called every frame?
how do you keep an effect constantly active again?
i'm not entirely sure, what should i use instead?
set_blind
how do i find this? or should i just take a screenshot of the crash window?
is it still self, dt or is it something else
ctrl-c that window or find it in lovely/logs
Do you mean the loc_vars example?
yes
Sorry again, i just tried this and now the textbox just has an empty space
one of your add_event is missing the :
in info_queue it says to use G.P_CENTERS.<key>
but in another mod it does it differently
oh ty
Do I also need anything else outside of loc_vars to make the tooltip work?
okay that is way too much hand size what happened
ref_value = "time"
it gave +3 instead of +1
i tried it both ways with no luck
If you're referencing another center you just do the G.P_CENTERS thing
You can also do {set = set, key = key} to reference something in the localization
have you tried giving it a color
anything on the wiki under SMODS.Center
nope, let me check
Well unfortunately I need to reference a seal
replace P_CENTERS for P_SEALS
bump
And seal keys are just modprefix_sealkey?
not sure on that one
I will try
this should only give +1 hand size, right?
and see how that goes
Yes.
thank you seals on everything creator
That was it, thank you so much for the help
This truly is a Seals On Everything creator moment
you can either manually exclude it from judgement and riff raff or manually include it in shop and boosters but checking args.source
im not sure how to do it, tried but it instead either ban it from everywhere, either not
yes, i dont know if you need to manually draw tho
i thought the G.FUNCS was to manually draw
if you want it to include it manually in boosters and the shop do return args and (args.source == 'sho' or args.source == 'buf') (this will exclude it from other modded packs tho)
yeah thats what i said, i dont know if you need to do that
ah i see
can anyone tell why my f6 doesnt work? my 6oak works fine but the game now things ANY hand no matter what is a f6
what is the context for retrigger?
Playing cards or jokers?
playing cards!
context.repetition
tyty!
Is there any way to make the upgrade text display after the card finishes scoring? It's being handled by an enhancement
The code is being ran in the main_scoring context
does this work for 1 in 4 chance for retrigger?
make it be final_scoring_step
i think
I believe you return a table with a repetitions variable set to the number of retriggers you want
oh so then return = {1}?
No return {repetitions = 1}
repetitions = 1
}```
oh, gotcha, tyty both!
That worked ty!
yw!
How to correctly spell rarity in localization
where is the code for the serpent wtf
That's really funny
Its handled in the draw_from_deck_to_hand function in state_events.lua
how would i check for if a hand contains a certain poker hand like jolly joker for example?
and probably the harder part of what im trying to do, is there a way to check if all cards scored are a specific suit?
use context.poker_hands['Hand'] in a calculate function, replace Hand with the specific name of the hand you want
Eg. 'Two Pair'
Hi folks, how do I set the default state of a config toggle? For bran new users of my mod, a toggle is unchecked, which can lead to a crash
or just store the suit of the first card and if the suit of any subsequent card is different set false and break
in the in pool?
this is probably stupid but what do i use to check a specific card scored and is there anywhere on the smods docs that has all the special globals and stuff balatro uses that arent generally in lua? im trying to use the docs as much as i can but its difficult finding specific stuff
context.individual and context.cardarea == G.play should ignore any non-scoring cards
Then context.other_card is the current card the joker is calculating on
No, you want to do it before scoring?
context.scoring_hand
You don't have to activate effects yet.
Wait
I misinterepted
It depends on how the joker works, if the joker activates once, you can activate its effect in context.joker_main and store variables in context.individual
If it activates per card, then yes, do it before scoring
i tried to add a rarity and a joker with that rarity, but it's crashing on load, can anyone help
key = 'fusion',
loc_txt = {name='Fusion'},
badge_colour = '009900'
}```
I have `rarity = "m_eodmod_fusion"` in the joker code, where my mod prefix is eodmod
what's failing here? now it's turning blinds specified in this function into bl_ast_iboss when it's only supposed to turn blinds that aren't specified here into it
activates once, essentially droll joker only for heart flushes is what im trying to do
No, Iâm pretty sure doing it before scoring is more efficient in both ways.
hi all, How could I totally reset progress for my mod? I want to see how a new user would experience it
double blind
Doing it in context.individual is one less for loop
Unless you want to show a message on the cards?
Create a new profile
Why?
delete system 64
Calculate runs on every joker you have, every time a card is calculated
ive literally tried completely rewriting this in like 5 different ways and it STILL doesn't work, how do i do this?
Yes, I donât see the issue?
Ah, this kind of comment takes me back
A for loop is not going to nuke your frames.
idea, is it possible to just check if any of the cards in hand are a speciifc suit (in this case hearts) because a; would probably balance nicer in the thing im trying to make and b; all flushes will be all the same suit anyway
It's not really an issue, but it is easier to write
Same way we just talked about
Btw if you don't know how to check for a suit, it's card:is_suit('Hearts', true)
Obviously Hearts can be a different suit if needed
yes
Whatâs the true for?
Not entirely sure, copied it from flower pot
Oh. It's if the check should bypass debuff
badge_colour: Colour of the rarity's badge.
how is this formatted? i tried to use a hex code but it isnt working, seems like other mods use G.C.[color name] but i'm not sure how to find a list of built in colors like that
not to be that person who just asks it to be done for them but my brain is like melting trying to figure out how to put these pieces together
What did I do wrong?
Are you using the HEX function on it?
Not exactly
context.joker_main and context.individual should be seperate
đŠ < have a random raccoon emoji I had in my text box for some reason
What did I do wrong?
bumpistan
also hello modding chat
modding dev
that fixed it ty
Yw!
What did I do wrong?
card:set_eternal(true)
tyty!
this doesnt give the sticker tho right?
just gives the eternal abilityi?
Eternal is the sticker?
i mean like the ability like eternal, so it cant be take out
You have to put the sticker on it.
isnt there another way?
Why?
because the idea is a enhancement that works like eternal
You didnât say you were talking about playing cards?
obsidian enhancement, gives X2 mult and cant be solt or destroyed
Thatâs a lot different.
oh sorry sorry
how do i do it?
You would have to patch where smods calculates destroyed cards, and you would also have to hook start dissolve and shatter.
Perhaps we take a step back
We can do it in all the same context, context.joker_main
Instead of setting a variable, you iterate through cards through for \_, card in ipairs(context.scoring_hand) do
You can then check if the card is hearts and return your 15 mult
What happened to the formatting of the third line...?
im not sure i follow
Oh funny it was 'cause of the underline
Pretend the slash before it doesn't exist
I have some code about it here: https://github.com/Somethingcom515/SealsOnJokers/blob/main/lovely/others.toml
if context.cardarea == G.play and context.main_scoring then
if next(context.poker_hands['Flush']) and context.other_card:is_suit("Hearts") then
return {
mult = 15
}```
i think
tyty!
what is wrong here?
it's supposed to be setting non specified blinds to the generic one
but its setting EVERY blind to the generic one
even small and big?
only boss blinds
thank you!! :D i will see if it works
yeah the last condition basically says that if it's a boss it gets replaced
i thought elseif was only supposed to run if none of the previous conditions are true
I believe that will trigger on every card.....
The intent is for it to trigger after scoring is done
What did I do wrong?
yes, if it's not any of the other blinds it goes to the elseif
but the elseif says "if you're in blind and it's a boss and it's not this specific blind then change it"
how does one go about adding your mod to the balatro mod manager
as in, uploading it to be downloaded by others
it also runs in every context
how would i fix this then without specifying every boss twice
ok so i add the patch thing to my code and then do what?
how do you make a joker count a round going by?
it looks correct, maybe the keys are off? You should probably try printing them
the keys should be fine
ooh then just change context.main_scoring to context.final_scoring_step probably?
oh, i get it now sorry
it's probably because it runs in every context like eremel said
what should i do?
run it in setting_blind?
it didnt seem to work at first so ill try doing that
add 1 to a counter in context.end_of_round
There is one problem with that too...... other_card won't exist
Yes, but you need to modify it to check for your enhancement instead of eternal.
still doesnt work
yeah still nothing @_@ not even a crash like id expect just the joker not doing anything
if you remove the elseif does it work?
if i remove the last one all the previous ones work yes
What did I do wrong?
maybe you need to manually check for the other ast_i blinds in the elseif too
thats what i was trying to avoid
It should be like
if context.final_scoring_step and next(context.poker_hands['Flush']) then
for k, card in ipairs(context.scoring_hand) do
if card:is_suit('Hearts', true) then
return { mult = 15 }
end
end
end
maybe in context.first_hand_drawn? if not then that's the only solution i can think of
how do i check if the player has a certain joker?
next(SMODS.find_card("key"))
ty
first_hand_drawn should work
thank you!!!! as far as i can test this works amazingly
wrote it like that but doesnt spawn at all, have i understood it wrong?
in_pool = function(self)
return args and (args.source == 'sho' or args.source == 'buf')
end,```
id rather not use first_hand_drawn since some boss blinds effects begin before first_hand_drawn, it's fine though im gonna try specifying every blind in the final elseif
you're missing args in the arguments
wdym? i dont know what args is đ
got this crash
can example cards for poker hands have enhancements?
oh wait nvm ik why
no
i PRd smods about that today
wait really no? how does cryptid do it?
you can copy the lovely patch in that pr
no as in not normally, you can patch it
im a slow typer
how much does this break other mods
would this work?
idk if they're even going to accept it lol
makes sense to me
yeah that'll get merged
wake up balatro cheating just got inventedđ„
no but really i love this concept totally will play with your mod when i have the time
i need to pr the mod ui customization in a bit too
yeah I looked over that briefly
its not working?
also tried with the enhancement key
Use SMODS.has_enhancement
Code?
also tried without the v and without the "
How are you testing?
using hanged man in the card with enhancement
No, try with sixth sense.
crash
how do i give a certain joker to the player?
I notice riff-raff does local card = create_card('Joker', G.jokers, nil, 0, nil, nil, nil, 'rif') but idk what all of those arguments do and I can't find it on the wiki
says table index is nil when i use it while selecting a card
v does not exist change it back to card.
Oh hey, I looked into this before https://discord.com/channels/1334988047229653042/1349144537846648886
also how are the keys for vanilla jokers formatted
yeah i PRd because i saw that got no attention lol
Put these 2 hooks somewhere in your code; https://github.com/Somethingcom515/SealsOnJokers/blob/main/main.lua#L2281
tyyy!
Change it to check for your enhancement as well.
crashed
Code?
Itâs self not card
oh okok, ty
bump
Do you want a specific joker?
tyyy!! totally working now
yes, it's from my mod, the key would be j_eodmod_green_candy i think
SMODS.add_card({key = âj_eodmod_green_candyâ})
Just found out this also affects non-playing cards. Is there an easy way I can prevent that??
Couldnât you just check if the set is equal to âDefaultâ?
Y'know you're right 
Been trying to explore how to hide certain elements of the ui for challenge functionality, where can I find the reference to the Skip Ante button? Iâve already figured out how to flat out remove/hide specific blinds but Iâd want to prevent skipping in another challenge
Try looking at cryptid.
Honestly been putting off looking at cryptic purely because of how much content it has, so Iâll look into it soon
Only other thing would be how would I mark a boss to not increase the ante? Iâm thinking of having a challenge that has a 50% chance to replace the Big Blind with a set of certain bosses