#đ»ă»modding-dev
1 messages · Page 630 of 1
ali and eris are both correct
make keep_on_use return true, make the use function set a variable in its config, make its can_use function only return true when that variable isn't set, and then use the calculate function to check for the context + if the variable is set
i do the exact same thing in High Roller, although the code is a little bit spread out because i did some stuff to avoid having a bunch of copy/pasted code in each die's definition
https://github.com/MetaNite64/High-Roller/tree/dev
(the can_use and keep_on_use functions are in lib/dice.lua, the use function has a bunch of visual work and most of it is offloaded to a separate function in lib/functions.lua, and the calculate function is in each individual die in content/Dice/dX.lua)
Just a quick question
is it possible to get mp4s to play
and how would I go about doing that?
How would I go about subtracting money from the player on a joker? I wanna subtract $3 after you win a blind and on the evaluation screen I wanna show if you win any from doing that (the joker is like slots lol)
calc_dollar_bonus = function(self, card)
return -3
end
That one's on the evaluation screen though, I want it before that pops up
If thats possible of course
I know this might be a stupid question but is there any way to set the rank of a card on deck generation? I tried looking through the VanillaRemade, Balatro code (or thats what my vscode says), and SMODS docs (including SMODS#change_base). Can anyone help me?
if context.end_of_round and context.main_eval then return {dollars = -3} end
Could anyone say why my game keeps on crashing when I try to add anything to main_end? I'm going off of VanillaRemade's code for the Invisible Joker.
main_end = {}
localize {
type = 'other',
key = 'm_lapsems_uranium_destroy',
nodes = main_end,
vars = {
card.ability.extra.cards_to_destroy
}
}
return {
main_end = main_end,
vars = {
card.ability.extra.blind_handicap,
}
}
-- Here's the localization bits:
m_lapsems_uranium = {
name = "Uranium Card",
text = {
"{X:attention,C:white}X#1#{} {C:attention}Blind{} amount",
"no rank or suit",
}
}
m_lapsems_uranium_destroy = {
name = "u",
text = {
"Destroy {C:attention}#1#{} random",
"card in hand",
},
}
Oops! The game crashed:
engine/ui.lua:693: attempt to index field 'colour' (a nil value)
@marble flint WHEN I GET MY HANDS ON YOU
this is such a fucking dumb idea /pos i love it
Is there a way to play a sound in calc_dollar_bonus?
yep
LOL
although the intermediate step needs to get rendered with an e
significantly funnier is that 101 goes to 20.22
also if you wanna uh
bit of a shameless plug but
if you wanna fit the whole code on there I Have A Font that you could mess with
idk if it's worth it tbh
fair
Anyone got any pointers for me?
i mean, at some point i think like, 10001 would go to 2000 then 20002 because i don't think decimals display above 1000 i might be wrong tho
that is correct but it actually happens after you've won with vanilla balance
How would I correctly delay a consumable effect when used, for instance how cards are all flipped at a short delay when a suit changer or enhancing tarot was used?
You're gonna hafta use event managers for that. If you need more information, check out VanillaRemade which explains how the various cards are coded.
G.E_MANAGER:add_event(Event({
trigger = 'after', --or 'before'
delay = 0.15, --That's 0.15 seconds
func = function()
-- whatever you please
end
}))
Alright
guys
is there a way to make sure that specific jokers cant appear in shops, packs and consumables
look into in_pool for that
so under the right circumstances this is a ^10 Mult joker
i did
and i tried
but i didnt do it right
Show us what you did.
What do "jud", "sho" and "buf" signify?
judgement, shop and buffoon
return not args or (args.source ~= 'jud' and args.source ~= 'sho' and args.source ~= 'buf')
Now that there's a lull in the action, could someone please take a look at this problem?
Something's not being properly added in the main_end nodes. That specific crash occurs because there's either an empty node or the arrangement of the nodes are misaligned
The localize call looks correct to me
So I think it has to do with the structure of the returned main_end
Not sure if this solves it tho
-- Here's how I tried to implement mine.
local main_end = {}
localize {
type = 'other',
key = 'm_lapsems_uranium_destroy',
nodes = main_end,
vars = {
card.ability.extra.cards_to_destroy
}
}
-- Here's what VanillaRemade did for Invisible Joker, which I used as a guide.
main_end = {}
localize {
type = 'other',
key = 'remove_negative',
nodes = main_end,
vars = {}
}
-- Both ended with this in their return calls:
return {
main_end = main_end
}
Can you show the localization entry for m_lapsems_uranium_destroy
-- Here's what both of them look like:
m_lapsems_uranium = {
name = "Uranium Card",
text = {
"{X:attention,C:white}X#1#{} {C:attention}Blind{} amount",
"no rank or suit",
}
}
m_lapsems_uranium_destroy = {
name = "u",
text = {
"Destroy {C:attention}#1#{} random",
"card in hand",
},
}
The 2nd one should be in the set "Other"
Changed from "other" to "Other", but it doesn't show up. Keep in mind, it's supposed to display it unless Hazmat Joker is present, which ensures that Uranium Cards don't destroy cards held in hand.
The localize call should be "other", I meant in your localization file, the m_lapsems_uranium_destroy key should be under the "Other" category, not "Joker" or anything else
-- loading videos
Comedy_video_dont_ever_do_that_again = Comedy_loadVideo('dont_ever_do_that_again')
-- in utils.lua
function Comedy_loadVideo(name)
local path = (ComedyGold.path .. "assets/videos/" .. name .. ".ogv")
ComedyGold.videos[name] = assert(love.graphics.newVideo(path))
ComedyGold.show_vid[name] = false
return ComedyGold.videos[name]
end
i dont get it. The video is there. What's causing this?
m_lapsems_uranium_destroy is listed under Other, and the localize call features type = 'Other'.
do main_end = main_end[1] that's what vanilla remade actually has
idk where you got it has main_end = main_end
It still doesn't show up. It appears identical to my previous posted image.
What does your loc_vars code look like now
Here's the full loc_vars call.
loc_vars = function(self, info_queue, card)
local main_end
local hazmat_joker = false
if G.jokers and G.jokers.cards then
for _, joker in ipairs(G.jokers.cards) do
if joker.config.center.key == 'j_lapsems_hazmat' then
hazmat_joker = true
break
end
end
end
if not hazmat_joker then
main_end = {}
localize {
type = 'Other',
key = 'm_lapsems_uranium_destroy',
nodes = main_end,
vars = {
card.ability.extra.cards_to_destroy -- 1
}
}
end
return {
main_end = main_end[1],
vars = {
card.ability.extra.blind_handicap,
}
}
end
okay, I said the localize type should be "other"
Also in your case specifically you want to check whether main_end exists in the first place, so do main_end = main_end and main_end[1]
It's gone half right.
Must I split the lines among separate localization-signifiers?
uhhh, if I had to guess the main_end[1] is what's causing only the first line to show
Do you have any experience with adding multiple lines with main_end? 'Cause Invisible Joker didn't have to deal with this.
Also, I ran main_end[2] and that did add only the second line.
try
main_end = main_end and {
n = G.UIT.C,
nodes = main_end
}
that's all I can think of
actually nvm, that's wrong too, as you can see I have no experience lol
question: is there a way for a boss blind to debuff cards with a certain enhancement
if context.debuff_card and SMODS.has_enhancement(context.debuff_card, 'm_modprefix_key') then return {debuff = true} end
Bump, I have a solution rn but I know its not the best one
if SMODS.pseudorandom_probability(card, "JACKPOT_WIN", 1, card.ability.jack_odds, "JACKPOT_WIN") then
return card.ability.extra.jack_dollars - card.ability.extra.gamble_cost,
play_sound('DRY_GambleJackpot')
thanks
Is it possible for a jokerâs xmult message to have custom colours and sounds?
Yes. Use message = "Your Message", colour = G.C.YOURCOLOUR, sound = "Your Sound", remove_default_message = true in the return
Anyone got any idea, why it shows --5 in the mult message? I only see 1 -, in the return
key = "curse",
config = { mult = 5 },
shader = "cstorm_curseShader",
in_shop = false,
weight = 2,
extra_cost = 5,
badge_colour = HEX("8000CC"),
--sound = { sound = "cstorm_curse1", vol = 0.7 },
calculate = function (self, card, context)
if context.post_joker or (context.main_scoring and context.cardarea == G.play) then
return{
mult = -card.edition.mult
}
end
end,
in_pool = function (self, args)
return false
end,
loc_vars = function (self, info_queue, card)
return { vars = { card.edition.mult }, key = self.key }
end
}```
Yeah I did that, though if I put x_mult in then the message turns red and has the default sound
Code?
SMODS.Sound ({
key = 'gourdy_ability',
path = 'dw_gourdy_ability.ogg',
pitch = 1,
})
SMODS.Sound ({
key = 'gourdy',
path = 'dw_gourdy.ogg',
pitch = 1,
})
SMODS.Joker{
key = "gourdy",
atlas = 'dandysworld',
pos = { x = 7, y = 9},
soul_pos=nil,
rarity = 3,
cost = 10,
config = { extra = {chips = 50, mult = 10, x_mult = 1.5} },
blueprint_compat=true,
eternal_compat=true,
perishable_compat=true,
unlocked = true,
discovered = true,
calculate = function(self,card,context)
if context.joker_main then
local effects = {
{
message = localize("dw_gourdy_ability"),
sound = "dandy_gourdy_ability",
colour = G.C.FILTER
}
}
for _,v in ipairs(G.jokers.cards) do
if v ~= card then
local vEffectType = pseudorandom('dw_gourdy', 1, 3)
local vEffect = {}
if vEffectType == 1 then
vEffect.x_mult = card.ability.extra.x_mult
elseif vEffectType == 2 then
vEffect.mult = card.ability.extra.mult
elseif vEffectType == 3 then
vEffect.chips = card.ability.extra.chips
end
vEffect.sound = "dandy_gourdy"
vEffect.colour = G.C.FILTER
vEffect.message_card = v
effects[#effects+1] = vEffect
end
end
return SMODS.merge_effects(effects)
end
end,
loc_vars = function(self, info_queue, card)
return { vars = {card.ability.extra.chips, card.ability.extra.mult, card.ability.extra.x_mult}, key = self.key }
end
}```
Why do you put the custom stuff into a table?
trying to get video loading to work.
-- video loader
video = nil
game_volume = 0
function Comedy_play_video(name)
local path = SMODS.Mods["ComedyGold"].path.."assets/videos/" .. name .. ".ogv"
love.filesystem.write("temp.ogv", path)
video = love.graphics.newVideo('temp.ogv')
-- mute the game until finished
game_volume = G.SETTINGS.SOUND.volume
G.SETTINGS.SOUND.volume = 0
video:play()
end
-- love2d hooks
loveUpdateHook = love.update
function love.update(dt)
loveUpdateHook(dt)
if video and not video:isPlaying() then
video:release()
video = nil
G.SETTINGS.SOUND.volume = game_volume
end
end
loveDrawHook = love.draw
function love.draw()
loveDrawHook()
if video then
local xScale = love.graphics.getWidth() / 1920
local yScale = love.graphics.getHeight() / 1080
love.graphics.draw(video, 0, 0, 0, xScale, yScale)
end
end
got this error
it also says "file not found" even though the file does in fact exist
how do I fix this?
this is the other error I keep getting
(same issue, btw)
this code is probably incorrect, what am i doing wrong?
Change G.hand.cards[playing_card] to playing_card
k
Also context.individual and context.joker_main don't happen at the same time.
doesnt do the function, what am i doing wrong?
context.cardarea is never G.hand in context.joker_main
this returns the message for everyone (placeholder) but it doesn't actually turn them gold
whats wrong?
again this
i have the boolean as greater than just to test
if context.before and to_big(G.GAME.dollars) <= to_big(card.ability.extra.dollars) then
for k, v in pairs(G.hand.cards) do
v:set_ability('m_gold', nil, true)
end
end
works
â
how would i draw something (le sprite) below a card
i guess i would just have to do drawstep jank
ive never used it before though
What is going on, I selected a 3 of clubs
how does cryptid make its own variables i wonder
G.GAME.code_rate
im tryna do the same for my set
-# if you do answer please ping
This is an example of setting a ConsumableType rate, specifically for Code Cards. Hereâs the wiki documentation of using that
return not next(SMODS.find_card('j_modprefix_key'))
tried to open the balatro sounds folder and it crashed file explorer. i love windows 11
put that in the in_pool for each joker
can it work with a joker group?
what are you trying to do
what are your specs đ
im tryna make a joker that can transform and then after it transforms the base form cant appear anymore (as long as the transformed one exists)
so just put the in_pool into the base form
make an objecttype
that all your transformations have
and then loop through joker slots and check for jokers with that objecttype
return true if nothing is found
i want to add an attention_text that displays just above where the deck lives but i have no idea how to do that
attention_text({
text = localize('k_reset'),
scale = 1.3,
hold = 1.4,
backdrop_colour = G.C.SECONDARY_SET.Joker,
align = 'br',
offset = {x = 0, y = 0},
silent = true
})
right now what this is doing is flying across the screen
Set major to the deck?
i dont get it
what part dont you get
Check set_ability
the loopy thing
you want it to check
every jonkler slot
for if the joker (or a transformation of it) exists
and if it does then return true
where's the pos stored in a card
card.config.center.pos
last question, how do i get a pseduorandom number (from the game's seed of course) đ
Vanillaremade wiki prob has something on that Idk the exact formula and cant check rn
do you mean like. a for loop
https://www.lua.org/pil/4.3.5.html
i know how loops work
what do you mean the loopy thing then
did you not read the entire thing
I did
lua allows you to make for loops of the form for x, y in pairs(z), where y represents an element in the table z and x represents the label of that element in z
each element of G.jokers.cards is a joker
You want to check every joker slot for if the joker or a transformation of it exists
also you should probably be checking SMODS.Showman for each as well
how do you tell what cards are about to be discarded in pre_discard context
G.hand.highlighted afaik
if context.pre_discard and context.cardarea == G.play then
{
cardarea = G.jokers, -- G.hand, (G.deck and G.discard optionally enabled)
full_hand = G.hand.highlighted,
pre_discard = true,
hook = hook -- true when 'The Hook' discards cards
}
gathered that while i was coding just now but
im trying to compare if the card im evaluating is inside of g.hand.highlighted
by iterating through all of the cards in the highlighted hand
and comparing
but i cant just use ==
so how would i tell if a card is the same card im looking at
is there something like full deck position or
What's the effect?
applying enhancements of discarded cards in the first hand
to a random non-discarded, unenhanced card in hand
problem is that it can apply it to ones that are part of the discard
i want to grab the inverse of g.hand.highlighted to pick from basically
cards individually store their highlighted state in card.highlighted
so iterate over G.hand.cards and grab all the cards where card.highlighted is false, and then pick a random one from that subset
Does anyone know if its possible to make a key combo? (like ctrl + k + r)
^
Ty! (also very cute cat pic :D)
context.pseudorandom_result and not context.result
hey yâall, is there a context for doing something before a hand is scored but before context.before? like how the tooth takes your money after your cards are moved to the play area but before the cards move up slightly for scoring
context.press_play
i tried that, but i canât access the played cards because that context doesnât have context.full_hand, and i need that
oh full hand is just G.play.cards
maybe
letâs see
doesnât seem to be working, plus it happens the instant you press play and not after the cards are moved to be played
iâm looking at the tooth in vanilla remade and it uses events with delays
maybe itâs just that and there isnât a context specifically for this?
probably then yeah
@marble flint bakery bug with stickyfingers: charms go in the consumable slot when bought through the added buy area
they also do this when spawned from debug
(playing with drawing pen)
Is there a way I can change the color of the hand/discard number to something else
yea just hook into functions/UI_definitions
unless you mean also on jokers then no not without changing everything else thats red and blue
Why does this hook crash my game?
function eval_card(card, context)
if card.edition.key == "e_cstorm_glitch" then
print("Glitched :O")
end
local ret = eval_card_ref(card, context)
return ret
end```
if card.edition and card.edition.cstorm_glitch
I still get this crash when I have a card with that edition
local ret, post = eval_card_ref(card, context)
return ret, post
It works now, thank you :3
What was the problem though? Did it give 2 things and I only returned one?
Yes.
Okay, how do I make the card not trigger with the odds in the edition's config? I'm struggling...
function eval_card(card, context)
if card.edition and card.edition.cstorm_glitch then
local RNGesus = pseudorandom("cstorm_glitch", 1, card.edition.denominator)
if RNGesus <= card.edition.numerator then
return
end
end
local ret, post = eval_card_ref(card, context)
return ret, post
end```
This crashes my game... It also rerolls the number every frame instead of once when the card would score
Wait, only thing that I don't understand is how I stop the card from scoring
Now the Joker never triggers at all...
key = "glitch",
config = { numerator = 1, denominator = 4, already_rolled = true },
shader = "cstorm_glitchShader",
in_shop = false,
weight = 2,
extra_cost = 5,
badge_colour = SMODS.Gradients["cstorm_glitchGradient"],
sound = { sound = "cstorm_glitch1", vol = 0.7 },
calculate = function (self, card, context)
if (card.ability.set == "Joker" and context.pre_joker) or
((card.ability.set == "Default" or card.ability.set == "Enhanced") and context.main_scoring and context.cardarea == G.play) then
print("Runnt")
card.edition.already_rolled = false
end
end,
in_pool = function (self, args)
return false
end
}
local eval_card_ref = eval_card
function eval_card(card, context)
if card.edition and card.edition.cstorm_glitch and card.edition.already_rolled == false then
print(card.edition.already_rolled)
local RNGesus = pseudorandom("cstorm_glitch", 1, card.edition.denominator)
card.edition.already_rolled = true
if RNGesus <= card.edition.numerator then
card.edition.already_rolled = false
print("Glitch activated! Card skipped.")
return {}, {}
end
print("Glitch check passed: " .. RNGesus)
card.edition.already_rolled = false
end
local ret, post = eval_card_ref(card, context)
return ret, post
end```
i'm confused as to how the aura code works (i need to use the random edition thing). what is info_queue?
the code is
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.e_foil
info_queue[#info_queue + 1] = G.P_CENTERS.e_holo
info_queue[#info_queue + 1] = G.P_CENTERS.e_polychrome
return { vars = { card.ability.max_highlighted } }
end,
it's irrelevant to the actual behavior of the card
adding an entry to info_queue adds an extra little pop-up box next to the card's description box that explains a related thing (in Aura's case, it has 3 pop-up boxes with the descriptions for Foil, Holographic, and Polychrome)
Bump
just starting to get into balatro modding (ive done mostly python and JS development as well as some light roblox lua programming), besides following the beginner guide and looking at examples any advice on making my first mod?
any advice would be appreciated but would also like advice about what IDE's are best for balatro/lua development as well as build scripts/extensions
just have fun, and any ide works, personally i use the most popular vsc, the lua plugin on it is quite useful, theres also alot of help you can get from vanilla remade (by our god n'), usually you should think of a theme, or you can just do anything to do with you, balatro modding should be smth you find fun
anyway with the actual question, I'd suggest either a basic joker that does flat mult or flat chips, but you can also do a scaling joker, so smth like
gains +1 mult per stone card played
(currently +0 mult)
its also very important you start with doing a localization folder when adding text to your jokers if you any bit serious with your mod, since its less messy and will help when you just wanna change 1 word in all jokers to something specific
hope this helped
can SMODS.blueprint_effect copy multiple cards or is it restricted to only one target?
i believe you can do SMODS.merge_effects(SMODS.blueprint_effect(whatever), SMODS.blueprint_effect(whatever2))
i don't know the args of the blueprint effect function so ig figure it out
appreciate the advice. currently looking through vanilla remade and just trying to get things working đ
is there a way to use that to blueprint_effect cards in a table? like all copies of a card in SMODS.find_card?
local rets = {}
for i, joker in ipairs(SMODS.find_card("whatever")) do
local ret = SMODS.blueprint_effect(whatever_the_card_that_is_copying_is, joker, context)
if ret then
rets[#rets+1] = ret
end
end
if #rets > 0 then
return SMODS.merge_effects(unpack(rets))
end
obviously didn't test this
and ofc replace the whatever placeholders
in order it:
- makes a list of all of the effects that the targeted jokers have given
- if there is any effects, then:
- it provides each one as an arg to merge_effects, using unpack to do so
- returns the combined effect
it works!
is there a way to have a ternary result from pseudorandom_probability
probably
do you mean like
pick one out of 3 options
yea like
true false evil third bool
(which techincally could be nil depending on how you look at it)
true fruse false
question: how do i do an operation (i.e. division) on the score of a hand played
what is the goal tho
to increase a number by 0, -1, or 1
just use pseudorandom with a range of -1 to 1 then right
rather than pseudorandom probability
example?
yea lol
local value = pseudorandom("seed", -1, 1)
[something] = something + value
^
^
^
^
v
v
if you pass the second and third arguments to pseudorandom, it returns only integers
i actually forget if it's inclusive on both the lower and the upper bound or not
but i think it is
god i hope so
all my homies hate exclusive randoms
like say if a hand scores like uh 300 it becomes 150 (score is divided by 2)
how'd i do that
it is
wait meta
ur literally the dice girl
how the fuck do u not know if its inclusive
đ
i haven't looked at the actual dice rolling code in a while
i am a sweet and soft catdog girlthing
actually that's a lie i have the lua file open right now, but i was looking at specifically the calculate_context stuff i did for it to help sleepy
im crine
i am a soulware ($0 ruby)
anyway if you needed to do something more complicated than just adding one of three random values to another variable, here's something cool you can do: define a table containing three functions, each one runs the behavior of one of the options. then just use pseudorandom_element on that table and call whatever function you get out of it :3
:3
what fucking usage would i get out of that
cryptid chocolate die
Chocolate Die is an Effect Joker. When the Boss blind is defeated, this Joker will start 1 of 10 events at random until the next Boss Blind.
ok that makes sense
but im just adding to a value đ
(and the actual value of it matters)
ya i know, i was just giving some general advice for anyone (it's what i was gonna send before you mentioned your specific use case)
makes sense đ
that's why you always ask for the goal
how do i move a joker to a specific slot
(specific goal: move a just created joker to a slot that i know should exist due to the addition of the joker)
By swapping their positions, example swapping the 1st joker with the 2nd joker
local swapped_joker = G.jokers.cards[1]
G.jokers.cards[1] = G.jokers.cards[2]
G.jokers.cards[2] = swapped_joker
wait i can move cards just by changing indexes!?
pretty sure this could just be done in one line with G.jokers.cards[1], G.jokers.cards[2] = G.jokers.cards[2], G.jokers.cards[1]
if i remember correctly anyways
at least in the jokers area yes
dunno how this works internally, so maybe, you'd have to try
still looking for answers to this
could you give a example
trying to set a floor on player money, but it's not quite working
i have this so far
calculate = function(self, card, context)
if context.main_scoring and context.cardarea == G.play and G.GAME.dollars < card.base.nominal then
return { dollars = card.base.nominal - G.GAME.dollars }
end
end
it doesn't work because G.GAME.dollars isn't updated immediately
any ways i could get it to work?
G.GAME.dollar_buffer gets updated in real time whilst scoring occurs, so i believe you could do return { dollars = card.base.nominal - ( G.GAME.dollars + (G.GAME.dollar_buffer or 0) ) }
how do i delete or move a UIBOX? i have the following functions to define and draw it:
function G.UIDEF.suika_main()
return {n = G.UIT.ROOT, config = {r = 0.1, minw = 7, minh = 10, align = "tm", padding = 0.2, colour = G.C.UI.TRANSPARENT_DARK }, nodes = {
}}
end
function SuikaLatro.f.drawBG()
return UIBox{
definition = G.UIDEF.suika_main(),
config = {align='cm', offset = {x=0,y=G.ROOM.T.y + 2}, major = G.ROOM_ATTACH, bond = 'Weak'}
}
end
not working, (a card was destroyed before the card was moved btw)
for j = 1, #jokers do
if j == created_card then
if jokers[i + 1] then
local temp_joker = jokers[i + 1]
jokers[i + 1] = jokers[j]
jokers[j] = temp_joker
end
end
end
wait didn't reply ping
@normal crest
seems to require manual updating
what is jokers
G.jokers.cards
and what is created_card
is it not obvious
i mean you're comparing it to a number
?
so it could be either a number or you incorrectly are comparing it to a number
to delete it you need to store a reference to it and do box:remove()
also in vanilla it always does box = nil afterwards
dunno if that matters at all
probably for memory mangement despite lua having a garbage collector
like say if a hand scores like uh 300 it becomes 150 (score is divided by 2)
at the end of the scoring after every joker deck etc gave their stuff? Or at start
end
just do x_mult=0.5
x_mult_message="/2"
remove_x_mult_message=true
on context.final_scoring_step
...this is for a blind lmao
-# i forgor to specify that fml
theres a blind that does that
u could check it on blinds.lua
...the flint does it on the base, not the end result
I think theres calculate functions for blinds too
u could use that and context.final_scoring_step
i know
then It's the same thing here
resources/textures/1x or 2x depending on resolution
save and replace the original png inside the exe using 7 zip
what
do you know
what you are talking about
badge colour
talks about sprites
?????????????????????????????????????????
@lime iron grindset
> enter the server
> tells me to replace sprites using 7zip
> leaves
absolute blunder
I asked this in modding chat but here is more appropriate.
is there a way to track when you draw the last card you have of a certain rank (or any rank)
the first way i can think of is to loop over G.deck.cards every time a card is drawn, and check if there are any other cards of the same rank as the drawn card in G.deck.cards (that card area is only for cards that haven't yet been drawn)
a more complicated way that might still end up being more efficient than looping over a giant table like G.deck.cards would be to have a table that tracks how many cards of each rank you have in total, update that table whenever playing cards are added or destroyed, have a second table that tracks how many cards of each rank you have left in the deck, and update that table every time playing cards are added to specifically the deck, destroyed from specifically the deck, drawn to hand, and then reset it to the state of the first table at the end of the round (after any end-of-round card destroying/adding of course)
52 elements
are you referring to the first method or the second
because you are correct on the first one, but the second one would only have 15 elements unless you have mods that add more ranks
haha sometimes
okay, this won't be simple but thank you for the methods!!!
loc_vars = function(self, info_queue, blind)
return { vars = { G.GAME.dollars } }
end,
local prestige_money = {}
calculate = function(self, blind, context)
if context.setting_blind then
prestige_money = G.GAME.dollars
end
if context.money_altered and G.GAME.dollars ~= prestige_money then
local diff = G.GAME.dollars - prestige_money
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
ease_dollars(-diff, true)
blind:wiggle()
return true
end
}))
delay(0.6)
end
end
Alright so i did tried out, putting the prestige_money in local didn't worked out and would constantly apply the dollar change even if it should not
I did tried setting outside of the calculate function but it it wouldn't work and directly crash my game, so i would like to know if there's a config setting that can work out similar like card.ability.extra.prestige_money but for blinds ? Should i make something like self.ability.extra.prestige_money or is there a different way to do it ?
Would appreciate the help thanks
what's the color key in G.C for balancing (the color behind the message on plasma deck)?
idk if it's there, but it's { 0.8, 0.45, 0.85, 1 }
Generally you shouldn't put code without a context check
In calculate
First think about when you want this effect to happen
well i want it to happen whenever the money change (from Tarot, Joker, etc) but i guess to make it safe i can just put a context.main_eval
Uh I don't remember if there's an SMODS context for that
I'll just use context.main_eval, i think this should work out that way as a safe way, that or simply use things like consumable used or triggered joker
whatever that works without breaking
right now my issue is to store the amount of money the player got when setting the blind, since i don't think i can simply do a card.ability.extra.prestige_money like how you could do with a Joker
and using a local might work but with what i tried to do, it either make the function constantly run or crash my game directly upon starting
context.money_altered
use context.money_altered
here's all the documentation on it
was it from a recent version of SMODS ? i don't think i did saw that context before
but thanks again
yea latest release
Ah that make sense
context documentation is sadly in need of a lot of work still
yeah i feel like the wiki misses a lot of important things and makes it hard to search what you need, i rely a lot on Vanilla Remade since the exemples helps A LOT
..I still need to manage how to make the blind store the money it got when setting the blind, trying local wouldn't work as i wished it would and well, i could try a config but i don't know that works out since blinds in general doesn't use the config function
Does, anyone know how i could do it please ?
blind.effect.prestige_money = G.GAME.dollars
thanks
should i then just make a config with prestige money like config = { prestige_money = 0 } ?
how do you replace in a lovely patch
position = "?"
at
thx
I dont remember the exact keys (currently afk), but whats the point in having both x_mult and perma_x_mult in Card.ability? (Same with h_x_mult and perma_h_x_mult)
I'm implementing similar "bonuses" for the custom scoring parameters in a mod im developing
Consider not answering if you don't have a serious one.
Values without perma don't show up automatically on playing cards.
...huh
Now I'm wondering why that would even be needed - like wouldn't it be better to like see those values always, gameplay-wise?
what's the context (combo) that is at the end of the round, but the scoring_hand is still existant
context.after and (blind score + hand score > required score) is the closest iirc
how do i keep the game from discardiing the cards if the effect isn't done yet
jonkler code:
if (context.after) or context.forcetrigger then
-- stolen vanillaremade code
for i = 1, #context.scoring_hand do
local percent = 1.15 - (i - 0.999) / (#context.scoring_hand - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.15,
func = function()
context.scoring_hand[i]:flip()
play_sound('card1', percent)
context.scoring_hand[i]:juice_up(0.3, 0.3)
return true
end
}))
end
delay(0.2)
for i = 1, #G.hand.highlighted do
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.1,
func = function()
-- SMODS.modify_rank will increment/decrement a given card's rank by a given amount
if context.scoring_hand[i]:get_id() == 14 then
elseif context.scoring_hand[i]:get_id() == 2 then
assert(SMODS.modify_rank(context.scoring_hand[i], 12))
else
assert(SMODS.modify_rank(context.scoring_hand[i], card.ability.extra.decrease))
end
return true
end
}))
end
end
end```
how can I change the desc of vanilla consumables?
https://github.com/GitNether/balagay
Have a look at this, It changes the descriptions of a few things, including consumables
english only tho
nvm I figured it out
k
SMODS.Blind {
name = "bos_prestige",
key = "bos_prestige",
atlas = "pseudoblinds",
mult = 2,
pos = { y = 2 },
dollars = 5,
boss = { min = 1, max = 3 },
boss_colour = HEX('b55e9e'),
config = { prestige_money = 0 },
loc_vars = function(self, blind)
if G.GAME.dollars < 0 then
local key
key = self.key .. '_alt'
else
key = self.key
end
return {key = key, vars = { G.GAME.dollars or 0, } }
end,
calculate = function(self, blind, context)
if context.setting_blind and context.main_eval then
if G.GAME.dollars > 0 then
--blind.effect.prestige_money = G.GAME.dollars
self.prestige_money = G.GAME.dollars
ease_dollars(-G.GAME.dollars, true)
elseif G.GAME.dollars < 0 then
self.prestige_money = -G.GAME.dollars
end
end
end,
disable = function(self)
ease_dollars(blind.effect.prestige_money, true)
end,
defeat = function(self)
if G.GAME.current_round.hands_left > 0 then
ease_dollars(self.prestige_money, true)
end
end,
} ```
so i wanted to try to change the blind's text depending on either you have money or are in debt but got that error, is there a work around for this ?
Do you have Talisman installed?
oh wait yeah it's on
lemme disable it
I forgot Talisman fucks up some of the calculations
Yeah it works now thanks
how to control the temperance value bc I removed the limit and it is still showing 50 dollars even though the self.ability.money is higher than 50
here is what my patch looks like
if G.GAME.no_limit then
self.ability.money = self.ability.money
else
self.ability.money = math.min(self.ability.money, self.ability.extra)
end
found the value
?
...no that's for mult not the score
add_to_deck = function(self, card, from_debuff)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.5,
func = function()
SMODS.add_card{ set = "Joker" }
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 8.5,
func = function()
SMODS.destroy_cards({card}, nil, nil, true)
message = "Goodbye !"
return true
end
}))
return true
end
}))
end,
}```
Hi again sorry but i wanted to know how do i make the joker do the message once it autodestroy itself (like Gros Michel), tried to do a return message outside, didn't worked out and inside doesn't either
sorry if i disturb anyone but what would i have to do to make this stake apply gold and everything below, since apparently {"gold"} still doesnt work đ„
you could try applying orange instead and then re-add the effects of gold yourself
tho did you tried first if
applied_stakes = { "gold" },
wouldn't work ?
Yea I did, I tried it a few times but it would not emplace it correctly
not sure what to add, cryptid does have gold applied so unless there's a smods to fix that, you might as well look at toher code or recode gold yourself
https://github.com/SpectralPack/Cryptid/blob/952f6e44234a21a52f2d35497e3873734c44325d/items/stake.lua#L348
I did reference cryptid for this but I'll try build it off orange and copy the gold stake code
yeah seems the easiest workaround right now
you need prefix_config = {applied_stakes = {mod = false}}
In SMODS.Stake?
yes
You should word it as {C:red}-1{} hand size
It did something, showing Applied Gold Stake, should I leave that be?
Alr I'll change it in a sec
it should be working then
Alright thanks a lot you all
đ
That's 0.5 X mult at the end of scoring which is literally /2 the score which is what u asked for
or did u want it to be /2 chips too
nvm i found a way
...which was to MAKE AN ENTIRE NEW FUCKING FUNCTION TO USE FOR THE SCORING OF THAT SPECIFIC BLIND đ
smods should probably have a context for between score being totaled and it being added to round score so modifying hand score at all isnt scoring calculation hell
fr
bump
bump
technically because multiplication is commutative this does actually divide the score by 2
Making a joker that gives an investment tag, but the info queue shows the dollar value as nil (and shows the normal $25 when you actually have the tag). Is there a potential fix for this?
Nothing is changed from vanilla in regards to the tag.
what does the info_queue look like?
actually no
just add config = G.P_TAGS.tag_investment.config to the info_queue thing for it i think
I replaced { key = 'tag_investment', set = 'Tag' } with G.P_TAGS.tag_investment and everything seems to be working as intended now
oh okay
is there a way for me to set a jokerâs default sell value ala the cost property? or do i need to make an add_to_deck function that sets its sell value?
Hook Card:set_cost
Also sell value is always half of the cost so if the cost doesnt matter just make it double the sell value
it seems easier to just double the sell value lol
The "+1 Tarot" and "+1 Spectral" messages do not appear. What am I doing wrong here?
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 2
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = (function()
SMODS.add_card {
set = 'Tarot',
key_append = 'witch_hunter'
}
G.GAME.consumeable_buffer = 1
return {
message = localize('k_plus_tarot'),
colour = G.C.SECONDARY_SET.TAROT
}
end)
}))
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = (function()
SMODS.add_card {
set = 'Spectral',
key_append = 'witch_hunter'
}
G.GAME.consumeable_buffer = 0
return {
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.SPECTRAL
}
end)
}))
nether of those returns are actually being returned as a result of a calculate function
you can use SMODS.calculate_effect on those tables instead of returning them, with a second argument that is the joker/consumable/card that is creating these
for example:
SMODS.calculate_effect({
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.SPECTRAL
}, card)
Like this?
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = (function()
SMODS.add_card {
set = 'Spectral',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 1
SMODS.calculate_effect({
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.SPECTRAL
}, card)
end)
}))
yes
and similar for the other one
and of course make sure card is actually the card running the effect
(it may be named something else after all)
The messages still don't show up, but now it fills up the consumable slots indefinitely.
if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 2
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = (function()
SMODS.add_card {
set = 'Tarot',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 1
SMODS.calculate_effect({
message = localize('k_plus_tarot'),
colour = G.C.SECONDARY_SET.TAROT
}, card)
end)
}))
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = (function()
SMODS.add_card {
set = 'Spectral',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 0
SMODS.calculate_effect({
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.SPECTRAL
}, card)
end)
}))
end
However, I'm about to head out for a little while, so I can't stay and chat.
events run until the function inside them returns true
so you have to return true at some point
The messages still don't show up, though.
Is there a way to make the text of the blind requirement wiggle too ?
Like when i want for exemple the requirement to change, it could wiggle to show it's changing
how do I make this work?
what are you trying to do
making a new variable for profiles.
for a mod
either by hooks or lovely patch
I'm trying to see if I can do a hook method.
you could probably hook Game:load_profile
how do i start making balatro mods
https://github.com/Steamodded/smods/wiki
have a look at this
https://github.com/nh6574/VanillaRemade
This link is also helpful, as its every vanilla thing
Thank you
calculate = function(self, card, context)
if context.joker_main then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
G.GAME.blind.chips = G.GAME.blind.chips * 0.97
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
G.GAME.blind.chip_text:wiggle()
return true
end
}))
delay(0.6)
return {
message = "-3%"
}
end
end
}```
Hi again, just trying to make my joker do a little shaking effect when the score changes but i got this error despite during blinds this wouldn't happen, could i have some help to know if there's a way to make the blind requiremenet text wiggle or not ?
interesting thing when I was trying to do the loc_txt. for some reason I believe that inside the code still contains the "{C:voucher}" for blank.
However when I try to make "voucher" a custom color despite it never exists.
The color shows.
You mean you simply made C:voucher and it just..worked ?
NEVERMIND I FIGURED IT OUT ITS G.hand_text_area.blind_chips:juice_up()
Yeah.
Wouldn't that just be a re-added feature of SMODS ?
Honestly I'm rather shocked that in the code it actually had "[C:Voucher}"
unless maybe, localthunk just left that somewhere hidden in the code
Honestly, I don't get to see the reason why he get rid of that function. thought would be interesting since obviously how on earth would modders would use an unlock feature where you just tells you that it's a voucher by it's own color text.
Just like how Planets, Tarots and also Spectrical had their color in text.
I feel like it was ever since in the demos probably.
maybe since it's close to C:attention he just, didn't see the use of C:voucher, but kept it in case
Probably, but yeah it's really interesting to find it like that.
This Joker's "+1 Tarot" and "+1 Spectral" messages don't show up, and I sought help in this channel a few hours ago, to no avail. What am I doing wrong?
if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card {
set = 'Tarot',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 0
SMODS.calculate_effect({
message = localize('k_plus_tarot'),
colour = G.C.SECONDARY_SET.TAROT
}, card)
return true
end)
}))
delay(0.2)
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card {
set = 'Spectral',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 0
SMODS.calculate_effect({
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.SPECTRAL
}, card)
return true
end)
}))
end
what the heck!?
Hello I am currently trying to make malverk crossmod textures and add them to my mod does anyone have any resources or something similar or if someone's already done this before that i could look at?
trying to think of how to make editions trigger when held in hand
questioning if it's worth it
taking ownership probably wouldn't be the route considering modded editions will do nothing
augh
Hook Game:splash_screen() or patch right before if G.SETTINGS.skip_splash == 'Yes' then. 
how do i make a misprint like description
so when i tell the game to run doom it doenst owkr
can someone hel[p
i used c++
check vanillaremade
i am
but its so weird
as the card itself doesnt have a description
yea everything is in the loc_vars function
yeah
the description is found in localization
but i wanna do that for xmult and chips
misprint is silly
wtf LMAO
everything's in the main_start in loc_vars
it makes me want to misprint myself
because it's dynatext
i figured it'd have some sort of translation
it does
it calls the localize function for "k_mult"
the rest of it is just numbers pretty much
that's the only text that needs to be shown since. its only +mult
is there even a thing called
k_xmult
or something
or k_chips
i fricked up
nvm
i fricked up
its only jumping from 1.5 to 2.5
does anyone know where i could find the code for k_mult
send the joker's code
oh wait
for i = card.ability.extra.xmult_min, card.ability.extra.xmult_max do
r_xmults[#r_xmults + 1] = tostring(i)
end
local loc_xmult = ' ' .. (localize('k_mult')) .. ' '
main_start = {
{ n = G.UIT.T, config = { text = ' X', colour = G.C.MULT, scale = 0.32 } },
{ n = G.UIT.O, config = { object = DynaText({ string = r_xmults, colours = { G.C.RED }, pop_in_rate = 9999999, silent = true, random_element = true, pop_delay = 0.5, scale = 0.32, min_cycle_time = 0 }) } },
{
n = G.UIT.O,
config = {
object = DynaText({
string = {
{ string = 'rand()', colour = G.C.JOKER_GREY }, { string = "#@" .. (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11) .. (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.suit:sub(1, 1) or 'D'), colour = G.C.RED },
loc_xmult, loc_xmult, loc_xmult, loc_xmult, loc_xmult, loc_xmult, loc_xmult,
loc_xmult, loc_xmult, loc_xmult, loc_xmult },
colours = { G.C.UI.TEXT_DARK },
pop_in_rate = 9999999,
silent = true,
random_element = true,
pop_delay = 0.2011,
scale = 0.32,
min_cycle_time = 0
})
}
},
}
return { main_start = main_start }
end,```
How do I check if a certain mod is active (Like Cryptid) in my mod?
Nvm found it
You use swift SMODS.find_mod(id)
ye
how do i get specially unscored cards?
Any pointers, @harsh belfry and @normal crest?
Is there a function to make a Joker move to a specific slot position?
hey guys uh
i wanna like
start modding
uh
i just wanna like
add more suits and ranks
how can i do that
No.
Here's a guide about starting your first Mod: https://github.com/Steamodded/smods/wiki/Your-First-Mod
And this is specifically for adding Suits and Ranks: https://github.com/Steamodded/smods/wiki/SMODS.Rank-and-SMODS.Suit
Thank you so much!
I would yap to y'all about my ideas, but that'd be in #âă»modding-general + I don't think people would even wanna hear that lol
can you show the entire calculate function
is it possible to re-use an in-game sprite for something else? i wanna reuse ancient joker's sprite for a deck sprite
please help idk why this isnt working
atlas = 'Joker',
prefix_config = {atlas = false},
pos = G.P_CENTERS.j_ancient.pos,
thank you my glorious king
what does the error say?
theres no error it just doesnt do anything
Tags do not have joker contexts.
ah
what should i do then
get patching the scoring loop buddy
check tag.lua
or card.lua
you could do on discard like burned joker
You could use the mod calculate.
there isnt a context.type for discarding either
whats that
if context.discard then
i used it in my rebaloed mod
tags dont do contexts the same way otherwise my code would have worked
SMODS.current_mod.calculate = function(self, context)
end
Theyâre gotten a bit better, especially documentation-wise
how do i make something that affects the LAST played card
what is the G.P_CENTERS equivalent of poker hands?
SMODS.PokerHands
im not sure if this is the correct channel to ask since im no longer in the developing part of things but
i now have a mod that works and im happy with, whats next? where do i upload the mod, etc, and does it really need a github if its 37 lines that can be contained within a screenshot or is that overkill for something that small scale
yes upload the mod to github
its more trustworthy when you can see the code
secondly you can upload it in the modding forum here or in a couple other servers
and if you want you can make an entry on the wiki
wait what wiki
https://github.com/dervorce/Keke-s-Ancient-Deck is this good enough?
Adds Keke's Ancient Deck suggestion made in the official balatro discord server - dervorce/Keke-s-Ancient-Deck
yep
@wispy falcon
(the positions need to exist)
And?
Don't be a smart ass
Say "There's not a function, but there's a way."
is there a function for checking if a card has an edition (in general)? backreading tells me SMODS.has_edition isn't a thing
it's not a function, you just check if card.edition exists
https://github.com/nh6574/VanillaRemade/wiki#how-do-i-get-if-a-card-has-a-specific-editionenhancementsealsticker
guys i dont understand what this part means, im assuming it means i can automate the version number so i dont have to keep on changing it manually but i dont really get it
ok i mean i understand the most part but idk if it would work for my project because i have a git containing multiple mods instead of just one
Omg, thank you! :D
question: how do i make a blind trigger its effect if the hand played does not contain a certain rank
is the effect "this hand does not score" (i.e. it just throws away the cards like psychic) or something else
smth else
like setting money to a certain amount
gotcha
i haven't done much with blinds but i'm pretty sure this should work
in the blind's calculate function, you'll want to do this
if not blind.disabled and context.before then
local flag = false
for i, v in ipairs context.full_hand do
if v:get_id() == (the ID of whatever rank) then
flag = true
break
end
end
if not flag then
-- do whatever
end
end
ah ok thanks
so if the mod i published to the mod manager links back to a specific folder within a git instead of the whole repository, would automatic-version-check still work or not?
uhh
SMODS.Blind {
key = "peach",
atlas = 'wacleblinds',
dollars = 5,
mult = 2,
pos = { x = 0, y = 4 },
boss = { min = 1 },
boss_colour = HEX("46a4f7"),
calculate = function(self, blind, context)
if not blind.disabled and context.before then
local triggered = false
for i, v in ipairs context.full_hand do
if v:get_id() == 14 then
triggered = true
break
end
end
if not triggered then
ease_dollars(-G.GAME.dollars+11, true)
end
end
end
}
-# ok nvm theres some stuff i forgot to change hold on
-# yep still that
update: i forgor to add parentheses đ
it works now
Here's the relevant bit.
if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card {
set = 'Tarot',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 0
SMODS.calculate_effect({
message = localize('k_plus_tarot'),
colour = G.C.SECONDARY_SET.TAROT
}, card)
return true
end)
}))
delay(0.2)
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card {
set = 'Spectral',
key_append = 'j_lapsems_witch_hunter'
}
G.GAME.consumeable_buffer = 0
SMODS.calculate_effect({
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.SPECTRAL
}, card)
return true
end)
}))
end
yes that's what you already sent, I meant the entirety of the function
The only other thing in there is the bit which triples the base Boss Blind size at the beginning of the round, which has no bearing on the card generation, so I thought I'd leave it out.
seems like it's the fault of whoever rewrote the entire implementation of scoring parameters without asking me
the code you sent looks correct to me, so I'm looking for the issue elsewhere
amount is being set to -naneinf
It won't let me.
But here's the only other thing in calculate():
if context.setting_blind and G.GAME.blind.boss then
return {
message = 'X'..card.ability.extra.boss_blind_size,
func = function()
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blockable = true,
blocking = false,
ref_table = G.GAME.blind,
ref_value = 'chips',
ease_to = G.GAME.blind['chips'] * card.ability.extra.boss_blind_size,
delay = 0.6,
func = (function(t) G.GAME.blind.chip_text = number_format(t); return t end)
}))
end
}
end
to be clear, the only thing not working are the calculate_effectcalls right
and card is the 2nd parameter of your function
Of which, calculate()? It is the second parameter of that.
calculate = function(self, card, context)
-- ...
end
Oh wait, might be the color, it's Spectral not SPECTRAL
Same with Tarot
Changed the names, but the messages still didn't show up.
Maybe just remove the color entirely...
try going to a game, get 1 joker and do eval SMODS.calculate_effect({ message = "hi" }, G.jokers.cards[1])
That does produce a message from my first Joker, but removing the colors in Witch Hunter's calculate() function changed nothing.
you are modifying the right file and saving it, right
The src/jokers.lua file which contains all Joker information, Witch Hunter included? Yes!
guess I'm gonna try your code in my pc and see what goes
The messages show up for me, they don't show up at the right time but they show up for sure
When do they show up?
After the consumables spawn
But your issue was that they don't show up at all right
genuinely don't know why it doesn't work for you
@marble flint i got it working kind of!
it works until it hits hash notation. omeganum doesn't know how to parse hash notation
..nor do i
elseif n:arraySize() < 8 then
--e12#34#56#78
local r = (n.sign == -1 and "-e" or "e")..e_ify(math.floor(n.array[1]*10^places+0.5)/10^places).."#"..e_ify(n.array[2] or 1)
for i = 3, n:arraySize() do
r = r.."#"..e_ify((n.array[i] or 0)+1)
end
return r
else
--e12#34##5678
return (n.sign == -1 and "-e" or "e")..e_ify(math.floor(n.array[1]*10^places+0.5)/10^places).."#"..e_ify(n.array[n:arraySize()] or 0).."##"..e_ify(n:arraySize()-2)
end
time to write a parser for this
hash notation is sbiis saibian's Hyper-E Notation
this is a bit of a dry read, but the original definition should cover pretty much the rest of what omeganum is capable of (you can ignore the extended definition section)
https://googology.miraheze.org/wiki/Hyper-E_notation
Not to be confused with Δ function.
Hyper-E Notation (E# for short) is a notation for large numbers devised by Sbiis Saibian. It was first introduced on his Web book One to Infinity: A Finite Journey on November 19, 2011, and was generalized to Extended Hyper-E Notation (xE# for short). Hyper-E Notation is a refined version of a notation Sbiis ...
so i just need to write a parser for that then
ya
here's a bit of demonstration to help you get started
e6.79#9 = e(e6.79#8) = e(e(6.79#7)) = ...
e3#3#3 = e3#(e3#3#2) = ...
i mean
i don't need to make the number i need to make the bignum
which means i can num.array[i] =
true,,,
nice
question: how do i make a blind have multiple effects and activate one of those effects randomly each after each hand
calculate function and context.after
function parse_hyper_e(num)
local split_array = num:sub(2)
local arr = {}
local current_run = 0
local i = 1
for _, str in ipairs(Split(split_array, "#")) do
current_run = current_run + 1
if #str ~= 0 then
if current_run > 1 then error("currently unimplemented") end
current_run = 0
local val = tonumber(str)
if i > 2 then val = val - 1 end
arr[i] = val
end
i = i + 1
end
return setmetatable({array = arr, sign = 1}, OmegaMeta)
end
what i've got so far
works round trip for everything without a ## in it
how do those ##'s work
E3##5 = E3#3#3#3#3 (there are 5 3's)
Ea##b = Ea#a#a#...#a (there are b a's)
that expansion can happen whenever the ## is the rightmost separator
@frosty rampart tysm
i'm Not doing triple # btw that sounds like a fucking headache
function parse_hyper_e(num)
local split_array = num:sub(2)
local arr = {}
local current_run = 0
local i = 1
for _, str in ipairs(Split(split_array, "#")) do
current_run = current_run + 1
if #str ~= 0 then
local val = tonumber(str)
if current_run == 1 then
if i > 2 then val = val - 1 end
arr[i] = val
elseif current_run == 2 then
local last = arr[i-1]
for _ = 1, val do
arr[i] = last
i = i + 1
end
else
print("Extended Hyper-E notation for # > 3 is currently unsupported. Returning Infinity.")
return math.huge, true
end
current_run = 0
i = i + 1
end
end
return setmetatable({array = arr, sign = 1}, OmegaMeta)
end
triple # is basically the same as double # but it expands to a bunch of double #s
but yea you don't need to do it for balatro purposes because that's far beyond what omeganum is capable of
i = i + 1
if i > 4000 then
-- This number is way too big. Bail.
return math.huge, true
end
is there a way to add ban your own items for vanilla challenges?
i would like to add my mod's tags to the list of banned tags in Jokerless
@marble flint i got lua joker up to e10#10##10000, aka 10{10000}10
wait. mutual servers. something something why are you also at the devils sacrament
I will gladly take a PR so you can be credited in the commit history :3
Im trying to do Crossmod stuff and i believe i did something wrong could anyone help me?
stop using the comment steamodded helper
make a .json file
please
first off, why the old header,
second off, whatâs the issue
Is there a way to make it so a Joker's rarity depends on settings?
i want to make a crossmod for my malverk mod and all in jest and it keeps giving me an error when i try to start balatro that im missing a }
also the old header because i used a similar mod as a base and the mod was older
rarity = (next(SMODS.find_mod('Cryptid')) and 'cry_epic') or (dandysworld.config.epic and 'dandy_epic') or 3
I'm trying to look into doing talisman compatibility against my better judgement, what exactly do you need to use the to_big() function for? Just any value that could contribute to scoring?
i fixed the {} issue but i did something wrong with my Compats/Crossmods as it keeps giving me attempting to call a nil value error
why does it crash
Remove everything after context in the function inputs.
still persists
SMODS.Blind {
key = "knife",
atlas = 'wacleblinds',
dollars = 5,
mult = 2,
pos = { x = 0, y = 21 },
boss = { min = 1 },
boss_colour = HEX("A391CE"),
calculate = function(self, blind, context)
if not blind.disabled then
if context.modify_hand then
blind.triggered = true
mult = mod_mult(math.max(math.floor(mult - G.GAME.hands[text].played), 1))
update_hand_text({ sound = 'chips2', modded = true }, { mult = mult })
end
end
end
}
Yes, it would be context.scoring_name not text
Aaaaughh, been at this for HOURS trying to figure out why a sound wont trigger, finally gonna ask for help.
Oops! The game crashed:
Thread error (Thread: 0x020ddab161f0)
Could not open file resources/sounds/Key:Nuke_Boom.ogg. Does not exist.
stack traceback:
[C]: at 0x7fff57e558a0
[C]: in function 'newSource'
engine/sound_manager.lua:63: in function 'PLAY_SOUND'
engine/sound_manager.lua:197: in main chunk
BRUH
like in game or just the sprite because i dont know how to do it in game but if you wanna make the sprite (more detailed) bigger just double the sprite dimensions in the code so where its like x= and y= double those
It's modprefix_soundkey
Could you elaborate a little more?
play_sound 'modprefix_soundkey'
Like this, right?
No, play_sound 'junk_Nuke_Boom'
I used px = 68 and py = 68 which is just ignored here
Itâs used in collection and blind selection screen but not here
Bump
But yeah thatâs why I was annoyed
ah thanks
:catplant:
do you know what a string is
if not then https://lua.org/pil/contents.html please read this. up until the end of chapter 16
My bad gang, incredibly new to coding đ
you need to know lua to use lua
read up
end of chapter 16 is a good stopping point
but also read 19 and 20
thats alright, just read up a bit on it
honestly might not be a half bsd idea to have https://lua.org/pil/contents.html pinned
Anyone know how to fix this? I used px and py
if thats not supported then i bet it's a big hassle snd you[re better of downscaling (or better, redrawing at a lower scale) the blind texture
path of least resistance
is something off here? i can't for the life of me figure out why i can't use this consumable on a joker with the fused rarity
can_use = function(self, card)
local highlighted = G.jokers.highlighted or {}
if #highlighted < 1 or #highlighted > card.ability.extra.max_highlighted then
return false
end
local joker = highlighted[1]
return joker.rarity == "bfs_fused"
end,
return joker:is_rarity('bfs_fused')
â
Is there a way to make the Blind reward have custom text instead of money?
Cos I made it so if you defeat that Blind, you get a very good Joker as a reward
SMODS.Tag {
key = "dyle",
pos = { x = 0, y = 2 },
apply = function(self, tag, context)
if context.type == 'new_blind_choice' then
local lock = tag.ID
G.CONTROLLER.locks[lock] = true
tag:yep('+', G.C.GREEN, function()
G.from_boss_tag = true
G.FUNCS.reroll_boss()
G.E_MANAGER:add_event(Event({
func = function()
G.E_MANAGER:add_event(Event({
func = function()
G.CONTROLLER.locks[lock] = nil
return true
end
}))
return true
end
}))
return true
end)
tag.triggered = true
return true
end
end
}```
Anyone know how to make it so the reroll always lands on a specific Boss Blind?
Figured it out, I just do G.GAME.perscribed_bosses[1] = 'bl_dandy_dyle'
Bump
NVM it doesn't work sometimes...
I'll replace the 1 with G.GAME.round_resets.ante and see how that works tomorrow
canât you just
OH WAIT
IM FUCKING STUPID
No, G.FORCE_BOSS = 'bl_modprefix_key'
Oh thx
lol
Oh shit a dandyâs world fan!
chat i got a really weird issue to fix
one of my jokers is unaffected by the eternal sticker when I apply it
as in it can be sold or destroyed by other jokers as if it didn't have eternal
even though i used the same method as i did on several other jokers its just this one that breaks it
wait i'm stupid no I didn't
i used the wrong method to apply it
ok its fine
nevermind that it has decided not to apply the sticker now
ok the issue appears to actually be that the joker doesn't like stickers being put on it
i can't even give it one with debugplus
i figured it out
it had eternal compat off oops
my insane ramblings cannot be accompanied by gifs for they are blocked
I was thinking that and was like "Nah she couldn't have forgotten that"
why does this lovely patch doesn't work? the print function doesn't show up at all
oh i couldve (i did)
what is this what am I doing wrong now?
question: what's the set name for stickers
I was trying to make a save system about times played things
There isnât one (why are we yelling?!)
hit up the steamodded ui page
and besides that theres like nothing
figure it out from other mods ig đ€·
i'm trying to create a system where the joker tracks if you've play a flush or a straight, after doing both you get a spectral card, a rework of seance.
dose someone know why my flush_done and straight_done parts of my code aren't functioning the way i'm intending? it gives the spectral card without having checked if the other poker hand has been played.
uhm you're using {} in your condition
presumably they're meant to be parenthesis
@loud citrus
would this work for destroying cards of x rank before the scoring happens
No, context.destroy_card and context.before don't happen at the same time.
OH SHOOT, thank you so much... Time to test
ahh okay so how would i go approaching that
Use context.before and put the cards you want to destroy into SMODS.destroy_cards
kayyy thanks eremel
iam trying to make a joker that flips the base and chips mult, context.before changes it back and context.modify_hand makes the blind icon spin around, what would be the correct solution to this?
but on what context check
because context.before doesnt work(instantly swaps it back)
and modify_hand makes the blind icon spin for some reason
context.initial_scoring_step
Anyone know how to make a Joker debuff a random card in your hand when played?
SMODS.Joker{
key = "shrimpo",
atlas = 'dwJoker',
pos = { x = 0, y = 6},
soul_pos=nil,
rarity = 1,
cost = 1,
config = { extra = {} },
blueprint_compat=true,
eternal_compat=true,
perishable_compat=true,
unlocked = true,
discovered = true,
calculate = function(self,card,context)
if context.before then
local scored_card = pseudorandom_element(context.scoring_hand, "dw_shrimpo")
G.E_MANAGER:add_event(Event({
func = function()
scored_card:juice_up()
scored_card:set_debuff(true)
return true
end
}))
return {
message = localize('k_debuffed'),
colour = G.C.RED,
sound = "tarot2",
}
end
end,
}```
I have this code which makes the card display work, but the scoring treats the debuffed card as if it wasn't debuffed.
i think you have to move the set debuff call out of the event
although that might mess with the timing of some visuals
First time coding a tag - the effect works normally, but it softlocks the game after adding the cards; anyone knows why?
how do i get the cardarea of a card
card.area
how do i send a card to a specific card area
draw_card(from, to, 90, 'up')
i don't remember what the 90 or 'up' are for
they may not even be necessary
nah it's just a global function, I think if you want to move a specific card there's an additional parameter
Don't have the source code available rn so you'll have to check yourself
but that function is from cardarea to cardarea
I don't think you need the controller locks
oh bruh ty, that makes sense lol idk how that slipped me
Also you might be able to replace your creating card logic with local _card = SMODS.create_card { set = "Base", enhancement = "m_gold", edition = "e_bstuck_paradox" }
So I've noticed music plays slower than the given file. How would I go about making my music play regularly? Either through code or modifying the file itself, I just don't want it to be giga slow lol
At first I thought it was playing at half the speed but it's not the case it's faster than that
edit: nvm found my answer, just set pitch and volume to 1
I need help.
I'm making a quick/shitty sprite sheet for my mod im making that way i can test and learn how to write my content. I have 4 cards in the 1x format done. What is the best method to convert it to 2x???
Im using Krita at the moment.
What you can do is Image > Scale Image to New Size, and it'll let you resize the sheet into any given number
to make a 2x version, you should set the px move to %, meaning if you type in 200 instead of 100, the image will double in size
IMPORTANT: Keep the filter to Nearest Neighbor, so that there's no blurring or blending between the pixels!
then you can export the 2x image, and then CTRL + Z to undo the image resizing
Dude you're a life saver
is there a context for beating blinds in first hand?
what's the final context before the hand's score gets added
probably context.final_scoring_step or context.after depending on what you are looking for
â
is there a way to check what position card is being scored currently
local pos = 0
for k, v in pairs(card.area) do
if card == v then pos = k end
end
how do i get the current chips/mult?
hand_chips and mult
No, it's just hand_chips and mult
ok
im a bit confused would this go inside a context call?
To make a shader deform a card like this, would I need to draw the shader on the layer of the card, that is the white in the background or how would I make that?
It would go where you want to check the position of the card.
yknow what, actually, is there just a way to run code every time a card gets retriggered, or to just check for card retriggers
excluding joker retriggers
actually no it would be better to make this work, when I add it to my code it always returns 0 though
Code?
trying to get this latch to work with retriggers, so the joker only triggers on the first card but it will trigger twice on a retrigger
latch prevents it from retriggering
my thought was like reset the latch if you're scoring the same position card twice in a row
@unkempt thicket you said i can borrow your martellino code, right? how do i change it to fit a consumable card?
SMODS.Consumable {
key = 'mugen',
set = 'Spectral',
atlas = "atlas_Slumber",
pos = { x = 0, y = 0 },
soul_rate = 0.1,
can_repeat_soul = true,
soul_set = 'Spectral',
loc_txt = {
name = "MUGEN",
text = {"Create a joker of {V:1}your choice{}."}
},
loc_vars = function(self, info_queue, card)
return { vars = { colours = {SMODS.Gradients["busterb_Epileptic"]} } }
end,
use = function(self, card, area, copier)
local eval = function(card) return (card.ability.loyalty_remaining == 0) and not G.RESET_JIGGLES end
juice_card_until(cardd, eval, true)
if #G.jokers.cards <= G.jokers.config.card_limit then
G.SETTINGS.paused = true
G.FUNCS.overlay_menu{
config = {no_esc = true},
definition = SMODS.jest_no_back_card_collection_UIBox(
G.P_CENTER_POOLS.Joker,
{5,5,5},
{
no_materialize = true,
modify_card = function(card, center)
card.sticker = get_joker_win_sticker(center)
if card.config.center.discovered then
jest_create_select_card_ui(card, G.jokers)
end
end,
h_mod = 1.05,
}
),
}
end
end
}
To get a Consumable instead of a Joker? if so look at Morio
no like assuming i'm not using all in jest
I mean morio's code
morio?
you want a consumable that can spawn jokers from a menu
reference paperback's apostle of wands
(it also uses all in jest code)
without limitation
it shouldn't be hard to pick through the code and find what hides legendary+ jokers from the menu
what's PB.UTIL
Did you also grab the UI code for it?
the global table that contains all the paperback-related functions and tables
bump
yea
Is its name SMODS.jest_no_back_card_collection_UIBox ?
It probably be better to change the prefix, did you also add jest_create_select_card_ui?
aij
If its not the latter thats probably the problem
i'm using marty's code
Try copying the UI functions and change the prefix.
what's loyalty
No, its called SMODS.jest_no_back_card_collection_UIBox and jest_create_select_card_ui, Its probably in the UI file.
Yea line 263
So line 263-439 and line 529-547 in Utils/UI
line 263?
this? ```lua
return true
end
}))
end
end
G.FUNCS.jest_gold_tags = function(e)
if G.GAME.jest_upgrade_tab then
G.GAME.jest_upgrade_tab = false
else
G.GAME.jest_upgrade_tab = true
end
end
function jest_create_select_card_ui(card, area, extra_data)
extra_data = extra_data or {}
extra_data.copies = extra_data.copies or 1
local t2 = {n=G.UIT.ROOT, config = {ref_table = card, minw = 0.6, maxw = 1, padding = 0.1, align = 'bm', colour = G.C.GREEN, shadow = true, r = 0.08, minh = 0.3, one_press = true, button = 'jest_select', data = {area, extra_data}, hover = true}, nodes={
{n=G.UIT.T, config={text = "Select",colour = G.C.WHITE, scale = 0.5}}
}}
card.children.select_button = UIBox{
definition = t2,
config = {
align="bm",
offset = {x=-0,y=-0.15},
major = card,
bond = 'Weak',
parent = card
}
}
end
function jest_create_select_playing_card_ui(card, area, extra_data)
extra_data.times = extra_data.times or 0
extra_data.copies = extra_data.copies or 1
local t2 = {n=G.UIT.ROOT, config = {ref_table = card, minw = 0.6, maxw = 1, padding = 0.1, align = 'bm', colour = G.C.GREEN, shadow = true, r = 0.08, minh = 0.3, one_press = true, button = 'jest_continue_select', data = {area, extra_data}, hover = true}, nodes={
{n=G.UIT.T, config={text = "Select",colour = G.C.WHITE, scale = 0.5}}
}}
card.children.select_button = UIBox{
definition = t2,
config = {
align="bm",
offset = {x=-0,y=-0.15},
major = card,
bond = 'Weak',
parent = card
}
}
end
line 263 is blank
Should this work?lua SMODS.Consumable { key = 'mugen', set = 'Spectral', atlas = "atlas_Slumber", pos = { x = 0, y = 0 }, soul_rate = 0.1, can_repeat_soul = true, soul_set = 'Spectral', loc_txt = { name = "MUGEN", text = {"Create a joker of {V:1}your choice{}."} }, loc_vars = function(self, info_queue, card) return { vars = { colours = {SMODS.Gradients["busterb_Epileptic"]} } } end, use = function(self, card, area, copier) if #G.jokers.cards <= G.jokers.config.card_limit then G.SETTINGS.paused = true G.FUNCS.overlay_menu{ config = {no_esc = true}, definition = SMODS.busterb_no_back_card_collection_UIBox( G.P_CENTER_POOLS.Joker, {5,5,5}, { no_materialize = true, modify_card = function(card, center) card.sticker = get_joker_win_sticker(center) if card.config.center.discovered then busterb_create_select_card_ui(card, G.jokers) end end, h_mod = 1.05, } ), } end end }
Do I really need to borrow all this just to make a spectral card?
Ah my Ui might be a little updated, and yes since thats what makes the UI.
It works but then I canât play a hand.
Just copy the functions with these names SMODS.jest_no_back_card_collection_UIBox, G.FUNCS.jest_select, jest_create_select_card_ui
it still does not let me play a hand
I'm not sure why, if you have all the UI functions it should be working.
this is the file i'm using.
Do you have any other mods enabled? Everything you have seems to be right.
I just found out they have exclusive funcs for apostle of wands so i'm using that instead. how do i use it tho?```lua
can_use = function(self, card)
return #G.jokers.cards < G.jokers.config.card_limit
end,
use = function(self, card, area, copier)
if #G.jokers.cards < G.jokers.config.card_limit then
G.SETTINGS.paused = true
G.FUNCS.overlay_menu {
config = { no_esc = true },
definition = mugen_apostle_of_wands_collection_UIBox(
selectable_jokers,
{ 5, 5, 5 },
{
no_materialize = true,
modify_card = function(other_card, center)
other_card.sticker = get_joker_win_sticker(center)
busterb_create_select_card_ui(other_card, G.jokers)
end,
h_mod = 1.05,
}
),
}
end
end
ok this shit keeps happening, i can't make a move anytime i use the card.
IT WORKS
the game keeps crashing because my loc_vars is invalid... i don't know what i'm doing lol
Log?
is there a way to detect if any joker gets added or removed in general?
if context.card_added and context.card.ability.set == 'Joker'
and the opposite is just context.card_removed?
No, it's (context.selling_card or context.joker_type_destroyed)
can i borrow from apostle of wands
i need to legally ask first
hmmm I'm having to do someting to specifically retrigger seal effects, I'm sure I can find a specific way to do this universally
Something like this......
the error says "attempt to index upvalue chosen_joker"
use = function(self, card, area, copier)
local applicable_jokers = {}
for _, joker in pairs(G.jokers.cards) do
if not card.edition == nil then applicable_jokers[#applicable_jokers + 1] = joker end
end
local chosen_joker = pseudorandom_element(applicable_jokers, 'ang_choice')
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
local random_edition = poll_edition("ijsj_ang", nil, true, true)
chosen_joker:set_edition(random_edition, true)
card:juice_up(0.3, 0.5)
return true
end
}))
end,
Change if not card.edition == nil to if joker.edition
ah
also is poll_edition automatically seed-dependent?
is there a way to make a joker that does something only if the current hand's mult is higher than x?
nvm i got it
y'all know how context.card_added works? never knew about it before and thought it would be super helpful but it's not triggering the upgrade rn
wait i'm stupid
i think i may have outdone myself here
aand it works now
wait it also counts consumables
eh i'll change the text and call it a feature
You can filter by doing and context.card.ability.set == "Joker" for example
ohh sweet thanks!
paperback is licensed under MIT so yeah you can
Iâm gonna license mine under GPL3
-- Makes all 7s be treated as Steel and Gold
if context.check_enhancement and context.other_card.base.value == "7" then
return {
m_gold = true,
m_steel = true
}
end
Guys what does this code actually do? does it give the enhancement abilities?
guys
is there a way to check if held in hand cards have a certain enhancement
it uses the quantum enhancements feature from smods
figured it out
how do you add a soul over a card?
soul_pos
but what about like setting the atlas and such
so i put my soul sprite in the jokers.png?
yeah
Running SMODS.add_card(G.hand.cards[1]) doesn't produce the card that I expected to produce. What do I do to ensure that I'm picking the right card?
you shouldnt be using add_card to copy a card regardless
use copy_card
see vanillaremade dna
Rouge Rose uses SMODS.add_card(), Cryptid uses copy_card().
That is because rouge rose does not copy any cards
Chat how do i make the core lua file load stuff from a different lua?
Like i have a Joker.lua file but it dosen't load stuff, it only loads them from the main lua file
oh alright, thanks!
assert(SMODS.load_file('/yourpathrelativetothemodfolder.lua'))()
--[[
  WARNING!!!!
  MESSING WITH THE INTERNAL
  FIELDS OF THIS STRUCT
  THAT ARE NOT EXPOSED USING METHODS
  MAY CAUSE UNDEFINED BEHAVIOR
  AND / OR SEGFAULTS.
  BE RESPONSIBLE.
]]
local ffi = require "ffi"
ffi.cdef [[
  typedef double Layer[2];
  typedef struct {
    size_t arrayCapacity;Â
    size_t arrayLength;
    size_t layer;
    int sign;
    Layer * arrayBuffer;
  } ExpantaNum_t;
]]
chat am i cooking or am i cooked
something something ffi.metatype
if this does end up getting finished then people might start seeing "error: attempted to compare number with cdata" instead of "error: attempted to compare number with table" (but hopefully not)
cdataman? in my talisman? it's more likely than you think
i love malloc
a talisman fork for adding support for number-"table" comparison - frostice482/amulet
idk if you have Observed
i've seen this
this is omeganum
i want higher.
i mean like
cdata comparison metamethods work w numbers
also you can probably just make the stuff that has invariants private
or just the entire struct
How would I utilise dotted characters for SMODS.Language, since so far it doesn't seem to be working as intended unless there is some workaround
you need to use an SMODS.Font for any characters not supported by the base balatro font, just like the vanilla languages that use a non-roman alphabet
Hi, I'm new to modding and I've been trying to get a Joker to recognise, which card has been destroyed/added if it happens, but I only got gibberish as an output. Can someone with a higher understanding explain to me, what I'm doing wrong?
current calculate function of the joker:
calculate = function(self, card, context)
if context.remove_playing_cards and not context.discard then
sendInfoMessage("removed playing card", "MyInfoLogger")
sendInfoMessage(tableToString(context.removed), "MyInfoLogger")
end
if context.playing_card_added then
sendInfoMessage("added playing card", "MyInfoLogger")
sendInfoMessage(tableToString(context.cards), "MyInfoLogger")
end
end
output (I destroyed a 2 of Diamonds with hanged man, and copied a 5 of clubs with cryptid):
2025-12-09 19:42:39 :: INFO :: MyInfoLogger :: removed playing card
2025-12-09 19:42:39 :: INFO :: MyInfoLogger :: {1 = table: 0x1b27a5a8, }
2025-12-09 19:44:01 :: INFO :: MyInfoLogger :: added playing card
2025-12-09 19:44:01 :: INFO :: MyInfoLogger :: {1 = table: 0x1adf60b8, 2 = table: 0x1abb49d0, }
the tableToString function (I stole from https://luascripts.com/lua-table-to-string):
function tableToString(tbl)
local result = "{"
for k, v in pairs(tbl) do
result = result .. tostring(k) .. " = " .. tostring(v) .. ", "
end
result = result .. "}"
return result
end
cards are tables
theresfore it simply prints out the table into the logger, which is just a memory adress
using print while having debugplus installed would actually expand the card table to show contents
well, I do have debug++ installed, but how do this?
do I just replace it with print(tableToString(context.removed)) and do I need to do anything in debug++?
No, print(context.removed)
trying to make a joker which removes reroll cost scaling for non-free rerolls
thinking of using add_to_deck and remove_from_deck methods for this, but I don't know what I would call to prevent the reroll cost from incrementing
in other words
how do i get/set the current reroll cost
how can i interrupt the reroll cost increment
Hook calculate_reroll_cost
is this as simple as redefining the function within an SMODS.joker object or might i have to do some more here
wait can't I just hook calculate_reroll_cost(skip_increment) where skip_increment is true
couldn't i just
calculate
shop reroll and not blueprint
calculate_reroll_cost(true)
hmm i'll have to try that
No, that would do nothing.
yeah i have no clue how to hook here
local oldcalculatererollcost = calculate_reroll_cost
function calculate_reroll_cost(skip_increment)
if conditions then
return oldcalculatererollcost(true)
end
return oldcalculatererollcost(skip_increment)
end
Also you would put it outside of the joker.