#💻・modding-dev
1 messages · Page 262 of 1
ig that might be it
something involving adding to the game’s own files (i know like nothing don’t ask me 😭)
chat how does this look
oh my god i made it
Shader uniform 'shader_here' does not exist Can anyone help me understand this shader error? I copied the shader example, changed the rbg values around to carry an average that I want, and it gives that error
tex.r = average;
tex.g = average;
tex.b = average;```
For reference, this is all I changed, added the average number and changed the tex r, g, and b to the average
i have made a severe lapse in my judgement when making this
is that an exposed nerve ending
i heard you like em young
this is currently giving the default sell value of the card not the increased one,
is there a way i can get it to give double the current sell value when selling?
hey is there a way to force a joker you modded in to show up? to test it's effects
you can use DebugPlus
where would one find that
for me its just the order i have them in my list
It's not like that for me
could you send a screenshot of the discard part, easier to see on mobile
They're all in their own seperate files so that prolly affects it
what’s the check for if cards have been played before? like say i wanted to check if a certain few cards were played, and i wanted to do it under a context.after
calculate = function(self, card, context)
if context.joker_main and card.ability.extra.chip > 0 then
return {
chips = card.ability.extra.chip
}
end
if context.discard then
local face_cards = 0
for k, v in ipairs(context.full_hand) do
if v:is_face() then
face_cards = face_cards + 1
end
end
if face_cards >= card.ability.extra.faces and not context.blueprint then
card.ability.extra.chip = card.ability.extra.chip + card.ability.extra.chip_mod
return {
message = 'Upgraded!',
color = G.C.CHIPS,
card = card
}
end
end
end
Why does this upgrade the joker 5 times instead of once?
i already fixed it but ty regardless, now im dealing w a different issue
just follows this order for me
ah
i can try help if you need
I just have it like this
and its not appearing in the order of the load table either
i was using that before and i didnt notice any consistency with the order they loaded, i'd add a new joker and they would all get shuffled
better explanation, say i played at least one 2 and one King during a blind. if i wanted a joker to do something once a 2 and a King were played at some point during that blind, what would i have the joker check for?
context.other_card:get_id() == 2 and context.other_card:get_id() == 13
im not sure how you'd get it for any point during a blind though
save played cards in a table
yeah that’s the part i n—come again
this is a joker
oh
save played cards in a var of that joker
card.ability.extra.played_cards or something
then in context.after, do smt like
local played2, playedK = false, false
for _,v in ipairs(card.ability.extra.played_cards) do
if v:get_id() == 2 then
played2 = true
elseif v:get_id() == 13 then
playedK = true
end
if played2 and playedK then break end
end
--if played2 and playedK == true then blah blah
the issue here is that when this is triggered, it crashes, saying 'base' is a nil value (highlighted on line 285)
ok i’m stuck here :) how would i save multiple values to it
tables
card.ability.extra.played_cards = {}
would it be base_value?
then whenever a card is played:
table.insert(card.ability.extra.played_cards, context.other_card)
i use base_value elsewhere and it works fine is what is messing me up
oh real?
yeah
let me workshop something rq
you can put tables in there
and i want the value not the id, because i would like it to read ace instead of 14
hold on imma download the thing and look through it properly
i dont understand why it works here, highlighted, but not there
probably have made some updates, heres this
ah ok cool
does anyone know how i could make this dynatext object (inside of a uibox) square the chips instead of just showing [chipsvalue^2]
config = {
object = DynaText({
string = { { ref_table = G.GAME.blind, ref_value = "chips", prefix = "Overscoring enabled at [", suffix = "^2] chips." } },
colours = { G.C.UI.TEXT_LIGHT },
shadow = true,
float = true,
scale = 0.4,
y_offset = -4,
}),
id = "ante_overscoreText",
},
im not sure how i could actually get the value so i could do math with it
is it not working because it's a for i = 1, n do function nested within a for i, v in ipairs() do function?
do they have a context for a scoring CARD? i know they do for a scoring hand (actually can’t i just run it in scoring hand now that i think about it)
you dont need that
just run a for loop through context.scoring_hand
and it will return each scoring card
i think that could be it, if all your other ones are working and aren't nested that would be the first thing i'd think
You'd have to calculate it elsewhere, store the squared value in a table, and pass that ref_table and ref_value instead. Make sure to recalculate as necessary whenever chips might change
could i just put a different variable for for i = 1 then?
the issue with that is, the uibox this is (boss blind) is made right before the blind chips are actually set properly, so if i try to do it beforehand, it just says the chips are 0
or for for i, v in ipairs() for that matter
ur saving every card in ur deck :3
im cooked
because if they both require i to work then fuckkkk
if context.before and context.cardarea == G.jokers then
for i,v in ipairs(context.scoring_hand) do
...
end
end
thus is what i meant
just change playing_cards to the context- yeah
OH SHOOT I WAS RUNNING IT IN THE SCORING HAND 😭 im foolish
let me try something actually hold on
Create the temporary table first and pass it to the DynaText, then calculate and set that table value when you can. The DynaText will automatically update with the latest value if you're using the ref_table correctly
chat what am i doing wrong
isnt there a way to specefically call like "max_highlighted" or something so i can avoid the can use if statement?
its crashing on the len(G.hand.highlighted) < card.ability.hold then
Can someone tell me why the enhancement takes effect after flipping back over? I have the abilty set inbetween the flips
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function()
play_sound('tarot1')
card:juice_up(0.3, 0.5)
return true end }))
for i=1, #G.hand.highlighted do
local percent = 1.15 - (i-0.999)/(#G.hand.highlighted-0.998)*0.3
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.15,func = function() G.hand.highlighted[i]:flip();play_sound('card1', percent);G.hand.highlighted[i]:juice_up(0.3, 0.3);return true end }))
end
delay(0.2)
local rightmost = G.hand.highlighted[1]
local leftmost = G.hand.highlighted[1]
for i=1, #G.hand.highlighted do if G.hand.highlighted[i].T.x > rightmost.T.x then rightmost = G.hand.highlighted[i] end end
for i=1, #G.hand.highlighted do if G.hand.highlighted[i].T.x < leftmost.T.x then leftmost = G.hand.highlighted[i] end end
for i=1, #G.hand.highlighted do
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.1,func = function()
if G.hand.highlighted[i] ~= rightmost then
rightmost:set_ability(G.P_CENTERS[leftmost.config.center.key],nil,true)
end
return true end }))
end
for i=1, #G.hand.highlighted do
local percent = 0.85 + (i-0.999)/(#G.hand.highlighted-0.998)*0.3
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.15,func = function() G.hand.highlighted[i]:flip();play_sound('tarot2', percent, 0.6);G.hand.highlighted[i]:juice_up(0.3, 0.3);return true end }))
end
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2,func = function() G.hand:unhighlight_all(); return true end }))
delay(0.5)
i think they do have to be different
put j in
like this
fun coding idea
yeah same error
works now, tysm 🙏
LMAO
ok well its not gonna hurt keeping it as j, that means its a problem with the logic OR
theres a typo
considering i copy-pasted from the working one i do not think theres a typo
hey so what's a break end for? i havent had to use it yet so i possess no knowledge
would it be easier if i annotated it gel\
i get the gist but it would be helpful yeah
break exits the for loop
oh it’s literal
the end is just from the if
i mean i had a GUESS i didn’t expect it to be exactly that though
Got all my spectrals finished!!
any idea? 😭
context.discard is called once for every card discarded
so the table insert gave me an index error when i tried to score one of the cards
what context should i be using to check for atleast 3 face cards being discarded?
i am looping through every card discarded to increment a local variable that counts each face card so i think i do need context.discard?
but i need to only upgrade the joker once
Art looks fantastic. Stone Mask and Mood Indigo seem super useful, the other two... less so. Do you have other mechanics for making Perishable and Rental useful?
ichor seems useful
here's what i have in the configuration, did i mess up setting the table up? was i also supposed to add brackets to the return?
how often is it able to trigger?
wdym? like the joker?
yeah
isnt "card" the joker itself though
ill do it again so you can see the error
the idea is that joker adds +variable amount of chips to every hand and gets upgraded by 20 chips everytime 3 or more face cards are discarded at once
try pre_discard
will it loop over every card to increment my variable?
ohh i see
pre_discard looks like it's called once before discarding
with the hand to be discarded in context.full_hand
Part of the benefit of perishable is that it allows you to remove an Eternal Joker if you need. Adding Polychrome is useful just because Polychrome is super good late game
so try it out
okok checking
whats "card" here?
Otherwise the Perishable/Foil combo is definitely the weakest, and we've considered swapping to Eternal/Foil and Perishable/Holographic
if "card" refers to the playing card, then card.ability.extra... no longer refers to the joker config
ohhhhh
WAIT THAT WORKED THANK YOU SO MUCH
w!
Personally I think Foil is better mid-game than Holographic is, which is why I associated it with Perishable (which is slightly more of a downgrade than Eternal)
wait then how the heck do i get the joker ability in there
i cut out everything before calculate because it isnt necessary to understand the process
ill take a gander
just
refer to the playing card as something else
like, "v" or smt
whats the entire code?
is there any documentation on balatro modding or do i just have to skim source code to find out how to do what i want?
if context.before and context.cardarea == G.jokers then
for _, card in ipairs(G.playing_cards) do
if card:get_id() == 2 or card:get_id() == 3 or card:get_id() == 4 or card:get_id() == 5 then
table.insert(card.ability.extra.played_cards, card)
end
end
end
thankyou!
yeah uh
use for _,v instead
or just anything else that isnt card
.
wait
you are supposed to run the loop through context.scoring_hand...
OH, it deletes Eternals. That's possibly even more useful than Stone Mask, then. Awesome
Yeah it overwrites Eternal since Perishable and Eternal technically can't (or aren't supposed to) coexist
i forgot to…. change it….
I wish there was a better way to ensure support for modded stickers, but without any property clarifying the positioning/space of a sticker other than the atlas, for now it just supports vanilla stickers
if context.before and context.cardarea == G.jokers then
for _, kard in ipairs(context.scoring_hand) do
if kard:get_id() == 2 or kard:get_id() == 3 or kard:get_id() == 4 or kard:get_id() == 5 then
table.insert(card.ability.extra.played_cards, kard)
end
end
end
I SAID IGNORE IT YOU
Guess I needed to add a delay(0.2) after applying the enhancement
am i right in understanding that the last two things are essentially updating the card list visually based on what was removed?
moment of truth 2
thats right
in here just put 1 and see what it outputs
same crash, trying to index on line 294 table.insert(combination, card.ability.extra.card_list[j].base.value)
nil value?
mhm
np :D
what i AM able to do is putting table.concat (table.remove(card.ability.extra.ranks [...] rather than card.ability.extra.combination = table.concat(combination without any error EXCEPT that it displays 14 instead of ace
i tried using some math functions to make it return 1 instead of ace but math functions dont work on tables like that of course
i'd honestly just exclude ace for that reason which, goes against the theme a little but it isnt quite a 1 anyway
had to add you in the credits atp with how much youve saved my ass
^ might be a very dumb question but sometimes those solve things lmao
wait omg true
ohhh thats because the config variable is different from the local variable, the former being a value and the latter being a table
oohhh
yeah ok i give up lmfao im just excluding aces n calling it a day
one more potentially stupid question
yeah?
is it removing the value from the list or is it removing the list bc, if theres no list then that would explain it giving a nil value
but ik youve done that in other places so
probably not that
its removing the value in position i
ohhh its the name then pos i see
instead of resetting it then adding the remaining could you remove removed?
maybe not if they dont exist but worth suggesting
that wouldnt work i dont think because extra.combination is a value not a table
i could rework it to have the combination read out a table instead of turning a table into a variable but
its midnight
and i got a functional joker
less that its late and more that ive been at this for like 8 hours straight now
fair enough lol gn!
gn and tysm for the help
np, im not all that knowledgeable but bouncing ideas can help
I'm trying to make a reverse strength that decreases card ranks but I don't know how to get it to wrap around for 2s
margret thatcher joker
Ding dong
go back to Aces
Beeppiiisss
hi dilly :3
How goes life
do you play maimai
I'm so cooked
I'm getting cooked
I did so little development wise today so I feel a little guilty about that but otherwise I'm living life well
i just asked someone if they played maimai i think I'm actually cooked
development resumes tomorrow
I did my talisman compat the last couple of days so I've just been vibing
:3 does playing a ripoff version of maimai count
I've still gotta make some stuff work with and without talisman though
But that's a problem for tomorrow me
what the fuck
icic, u should prioritize your life quality over everything, so its good to know that :3
i couldn't even 100%
im into a lot of music types :3
rhythm arcade game
Kyuu Kurarin
I can clear just about every guitar hero song ever on medium though 😎
guitar hero looks cool, theres an arcade ripoff of that in my supermarket
but i have never seen it being turned on before
;(
i do play maimai!!!
where can i find the different value that "context" can be?
i tried playing maimai im bad at it
i’m really good at it
the calculate section in smods documentation
thank you
after scoring i want to randomly pick one pair to destroy while the other is copied to the deck, but im not sure how
rn all it does is copy every card in the two pair immediately after scoring
omg how do people get good at this
I'm cooked i can't
how is this kind of small text added?
{s:0.5}text{}
ty!
you can add multiple uhh thingies, like
{s:0.5,C:inactive}this text is gray and small{}
I'm cooked
any idea why this tag isnt triggering? it should trigger before scoring happens after playing a hand
if context.before then
tag:yep("+", G.C.Mult, function(self)
return {
mult = card.ability.extra.mult
}
end )
tag.trigger = true
end
end```
How could one make a joker not shake when giving xmult for a card?
Hmm I'm wondering how best to order this
Off the top of their heads, does anyone know when gold seals give money for playing cards? Is it before they score their chips or after?
I'm not at my computer and just finding footage of gold seals is Not Easy apparently
After the card scores its chips.
Ugh, damn
I have a joker that makes it so Blue and Purple seals trigger on scoring, but the way it's set up now results in them activating before the card's chip score, which bugs me
I haven't looked at tags, so maybe there's something weird with names or tags don't have a calculate, but I'd say it's likely because that's an apply function, not a calculate function.
Which context are you using?
sadly not the case
context.individual and context.cardarea == G.play
context.main_scoring and context.cardarea == G.play is what you should use there i think
No, use other_card, let me double check which context I'm thinking of,
Ideally, I'd want this effect to run after every other regular chip/mult/money effect scoring (since there's no precedent for it in vanilla)
But it's the same thing as the +3 mult suit jokers, that'd work, right?
If you want that, then you'd want to use a context.after check and iterate through the cards yourself.
But that would be after the entire effect table for the entire hand, not just after per card scoring
I think it'd be best to just have it as the jokers, that should be the right context, can you show the full bit of code?
But yeah you're right, this is primarily used for enhancement effects
Also, as I'm unfamiliar with tags, give me a few minutes to read up and I'll get to you if I figure something out.
thank you
i hope it works out
It seems to be because tags use a different context system, you can see the types of tags in P_TAGS under Game:init_item_prototype in game.lua, it uses :apply_to_run to call tags, but shares that with decks, so you can search it, but you'll have to double check to see if it's being called on a tag or a back - other than that, you can search up the types present in P_TAGS and see where those are and if any of those work; else, write a lovely patch for a new tag:apply_to_run context.
anyone happen to know why this isnt working? its supposed to turn a card held in hand into a steel card after you win with a fire score
ahhh i see, i was really hoping to not have to learn lovely
ig thats what im doing tho
how can i check if someone elses mod is installed without setting it as a dependency?
Logic seems fine to me, maybe sprinkle in some sendDebugMessage()s to figure out where it's getting cut off at and figure out what's going on with the values.
will try that out
It's easy, still just lua, find a target line that's unique in the file you want to change, decide if you want your code to come before, after, or replace it with "at", and then put your code in the payload.
one of my fav arts for this mod too
SMODS.find_mod(modid)
thx
ok it seems like this line isnt triggering for whatever reason then hm
is it that i cant just say "rand_card" to check if it exists?
If it's the second debug message, print out sendDebugMessage(hand_chips) and repeat that for the other variables you're checking for to see which one has an issue.
You'll probably need to throw rand_card into a tostring() as it's a table, or you could use inspect or inspectDepth to see it list every contained value.
im p confident that part should work but ill double check
where should it be a string?
It'd be sendDebugMessage(tostring(rand_card)).
gotcha
can I info_queue a boss blind like
info_queue[#info_queue+1] = G.P_CENTERS.bl_watsau_final_distorted_fate
or do i need to make a tooltip?
Remove the return in the thing where it sets the rand_card.
still nil
could it be because im declaring the rand_card outside of that block?
hm
Set local rand_card = {}.
imma test that hypothesis first rq
It's not, if you declare a local, then it's local to the block - and if you have the local inside of the if block, then it can't be used outside of it.
yeah its resetting when it shifts code blocks
because i set the local first thing in the calculate block
so i think the calculate block runs again and resets it
Ah, right, very obvious, it's getting set to blank every single time calculate is called. Store it in your joker's config so it doesn't get overwritten.
already on it
thanks for the help though
(assuming it doesnt immediately crash right after i do this)
I think I've seen it done before, I don't remember where, but, I think @zealous glen has a bit more experience than me when it comes to info_queues.
so im injecting code with lovely, it should go right after if context.before then in card.lua. right now im just injecting print('runs') to test if its working properly but it isnt printing anything
Can you send the lovely file?
version = "1.0.0"
dump_lua = true
priority = 0
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = "if context.before then"
position = "after"
payload = '''
print('runs')
'''
match_indent = true
overwrite = false```
That appears to be located in "card:calculate_joker", which is a weird place for it,
im not really sure where else would work
functions/state_events.lua, there's a nice -- TARGET: effects before scoring starts line for you to set as your pattern, and you can look it in the code - it's the part that actually send the calculate call.
i completely forgot to check the files that arent in the main directory 🤦
Just in case, the -- TARGET: effects before scoring starts is only in the lovely/dump files, you won't be able to search for it if you're only using the unmodified source code.
Oh, also, should probably just be payload = '''print('runs')'''.
yea at the time it was right after an if statement so i wasnt sure if it needed to be indented or not
The match_indent usually takes care of that setting, but if you had three lines, then it'd be like,
payload = '''if a then
print('b')
end'''
the changes i make should appear in lovely/dump after i run balatro right?
Correct, and it'll say in the console if it couldn't find the target line.
it works now, thank you so much for the help
How does one check if a joker is rental?
I think it's just stored in card.ability.rental unless SMODS changes something?
that shit looks heat (queer)
i can get a tag to trigger before any cards scoring after playing a hand, but i have no idea how to make it actually change the current mult or chips
I did a similar thing in Bakery, lemme check how i did it rq
oh right i did a bunch of hot trash
ive added a custom context for the tags, and it works, so i added the tag into tag.lua where it checks and runs the tags, which also works. but i have no idea how to make the code in tag.lua change the current scoring values
elseif _context.type == 'before' then
print('runs')
if self.name == 'Lesser Mult Tag' then
self:yep('+', G.C.Mult, function()
return true
end)
self.triggered = true
return {
mult = self.config.extra.mult
}
end```
this thing with the return doesnt work here
what i'm doing is not this, but you might be able to SMODS.calculate_effect() it at the appropriate moment
omg thats it
its always some command that was mentioned once extremely briefly i swear
my current method is changing the return value of the boss blind's modifications which is not correct and i should change it kjlasdhgkladsfg
but it works, so
version = "1.0.0"
dump_lua = true
priority = 0
#triggering custom tags
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
mult, hand_chips = mod_mult(mult), mod_chips(hand_chips)
'''
position = "after"
payload = '''
for i = 1, #G.GAME.tags do
G.GAME.tags[i]:apply_to_run({type = 'before'})
end
'''
match_indent = true
overwrite = false
#adding customm tags functions
[[patches]]
[patches.pattern]
target = "tag.lua"
pattern = "elseif _context.type == 'immediate' then "
position = "before"
payload = '''
elseif _context.type == 'before' then
print('runs')
if self.name == 'Lesser Mult Tag' then
self:yep('+', G.C.Mult, function()
return true
end)
self.triggered = true
SMODS.calculate_effect({mult = self.config.extra.mult}, self)
return true
end
'''
match_indent = true
overwrite = false```
this is what i used if you think it'd help you
just replace "Lesser Mult Tag" with your tags name
That feature has been implemented, by Baliame IIRC, but it just displays name and text like other tooltips. I had previously manually implemented a Boss Blind tooltip directly
i prefer my own approach which lets me just write a calculate function on the smods definition
fair
in my mod it'd just be this:
SMODS.Tag {
key = "LesserMultTag",
config = {
mult = 5
},
loc_vars = function(self, info_queue, tag)
return {
vars = {self.config.mult}
}
end,
apply = function(self, tag, context)
if not tag.triggered and context.type == 'Bakery_play_hand_early' then
return {
mult = self.config.mult,
after = function()
tag:yep('X', G.C.RED, function()
return true
end)
end
}
end
end
}
(and my mod can be used as a dependency to do it like this)
What do you guys think
If a debuffed card is played, score it anyway and +10 mult
If a card is played, debuff it for the rest of the round
good morning everyone
Hello sir
probably too underwhelming when its a staple of the build
like, the moment you sell that joker, all the debuffed cards cant be used
i suggest going for the XMult/XChips instead
Okay then
Thanks for the suggestion
Also is there any good resources to read about draw step other than documentation and source code
mhm
They are so confusin
Rest of round? How does this work? You score it, then it's considered played, and then you can't use it because you played it that round, so it's no longer in your deck?
probably check mods which use DrawStep, i think Victin's issac-inspired joker uses it
Oh right
Thanks
I didn't think about that
Thank youu
I hope i can finish my soulpos thing today
also, i think this joker should also have some benefits on its own too, like
If a card is played, debuff it, and increase Mult by +10
(Currently: +0 Mult)
else it has no other purposes if you aren't going for the joker above, and risky if you don't already have it
np :3
@manic rune how would I add third layer of soul position
Victin did that for their joker
idk how myself
check their mod's code, and see how its done
we normalize the silliness of :3 around here :3
Been reading other people's code but I cant figure nothing
Wait which one
Im checking it right now
Ahh lagg
It's so laggy
My discord just had a insane lag spike
the joker which is based on the binding of issac, i don't remember its exact name sorry
Okay
how can i add custom tags to the info queue on a card?
I chekc the github code
There's nothing about the drawstep things
In the isaac joker thing
oh, really?
Yea sadly
it uses multiple soul layers, so i thought it uses drawstep
There isn't any soulpos on it too
-# huh
The joker's atlas doesn't even contain the sprite too
So maybe it's just old code but Idk where the new one is
.
Ok im going to do this
Ok I found the new one
Hello everyone, just started getting into modding balatro and have been told the discord was the best place for this :)
Have fun modding
thank you!
hii, i suggest checking #1349064230825103441 if thats the case! :3
@manic rune
soul_pos = { x = 0, y = 1 },
set_ability = function(self, card, initial, delay_sprites)
if self.discovered or card.bypass_discovery_center then
card.T.w = card.T.w * (custom_width / 71)
card.children.floating_sprite.T.w = card.children.floating_sprite.T.w * (custom_width / 71)
end
end,
set_sprites = function(self, card, front)
if self.discovered or card.bypass_discovery_center then
card.children.center.scale.x = card.children.center.scale.x
card.children.floating_sprite.scale.x = card.children.floating_sprite.scale.x --* (custom_width / 71)
end
end,
load = function(self, card, card_table, other_card)
if self.discovered or card.bypass_discovery_center then
card.T.w = card.T.w * (custom_width / 71)
--card.children.floating_sprite.T.w = card.children.floating_sprite.T.w * (custom_width / 71)
end
end,
I have found victins code
nice :D
returning true on the debuff_hand function in the blind on the newest version of steamodded crashes the game, is there a reason for this?
mhm
main.lua:1837: functions/state_events.lua:798: attempt to compare table with number
Stack Traceback
===============
(1) Lua upvalue 'orig' at file 'main.lua:612'
Local variables:
msg = string: "main.lua:1837: functions/state_events.lua:798: attempt to compare table with number"
(*temporary) = Lua function '?' (defined at line 31 of chunk [SMODS _ "src/logging.lua"])
(*temporary) = string: "Oops! The game crashed\
"
(2) Lua local 'handler' at file 'debugplus/console.lua:576' (from lovely module debugplus.console)
Local variables:
msg = string: "main.lua:1837: functions/state_events.lua:798: attempt to compare table with number"
heya! so I have this code for a Joker that's supposed to give you Xmult if you have a certain amount of unique Jokers
but for some reason it just is not working, and always displays as 0 even when I've accumulated a number of unique Jokers in a run
can someone help with this?
How would I go about making an enhancement unable to be overridden by jokers or tarot cards without just straight up editing the code of the jokers or tarot cards?
chat is this good
I'm using an enhancement to consider a card sleeved, which destroys it at the end of the round, and if you change the enhancement mid-blind it doesn't destroy the card, which is an issue
I feel like the pink-ish red is way too saturated
And I say that as a huge fan of that specific color
i hear you but it needs to be that specific colour
Why does it need to be?
Also, how do I add new colors for descriptions and effects? If I can
i just added a separate tally
idk why # didn't work anymore though
How do I make it so when I get this Joker in the shop or booster packs, it's always Foil?
I currently use the code
set_ability = function(self, card, initial, delay_sprites)
card:set_edition({foil = true}, true)
end```
It only applies in the Collection view, but not the actual game. What should I add or change?
does anybody know all the steamodded colors for formatting?
didn't find those specified anywhere
{C:attention} 🟡 Yellow Used for important keywords
{C:money} 🟢 Green Used for dollar amounts ($)
{C:mult} 🔴 Red Used for multipliers (x2, x5)
{C:chips} 🔵 Blue Used for chip values
{C:red} 🔴 Red Generic red text
{C:green} 🟢 Green Generic green text
{C:blue} 🔵 Blue Generic blue text
{C:dark_edition} 🟣 Purple Used for special card editions
{C:spectral} ⚪ White (or glowing effect) Used for spectral-related effects
{C:clovers} 🍀 Green Used for Clover buffs
{C:voucher} 🟠 Orange Used for Voucher-related text
{C:stars} ✨ Gold Used for celestial-related bonuses
these should be real but im not sure
at least most of them 🔥
tysm! is this such a common thing that everybody has this message ready on command LOL
Ctrl + F the source code
nope more complicated way
also search color in #💻・modding-dev
thats why i said im not 100% sure
Some are wrong 😬
what's a star? can you eat it?
no idea smh
thanks for these, though!
Can you make your own colors?
pretty sure you can just type in hex values
set_ability = function(self, card, initial, delay_sprites)
G.E_MANAGER:add_event(Event({
func = function()
card:set_edition({ foil = true }, true)
return true
end
}))
end,```
@vagrant moth try this out
Is it just straight up putting in hex or do I need to run a function?
im pretty new to this, so i wouldn't ask myself
but probably
boop found the message
you can do G.ARGS.LOC_COLOURS["whatever"] = HEX("123fff") i'm pretty sure
bump
so
{C:red}
{C:mult}
{C:blue}
{C:chips}
{C:green}
{C:money}
{C:gold}
{C:attention}
{C:purple}
{C:white}
{C:inactive}
{C:spades}
{C:hearts}
{C:clubs}
{C:diamonds}
{C:tarot}
{C:planet}
{C:spectral}
{C:edition}
{C:dark_edition}
{C:legendary}
{C:enhanced}
does anybody know where the smods source code contains the code that adds the sticker page in collection?
yup! cool shit
are you ok
2 lab classes in one day
physics an chemistry
I see
at least i am done with physics one this week so
I think engineering physics lab classes involved measuring a table dozens of times
nevermind actually
ill work a bit on math deck and collapse on my bed tonight
i have to do tritration for chem lab next week
This happens when I do that
no
uh
i was gonna reply earlier but i accidentally quit discord and had to repatch the thing
yo this new Discord UI sucks 🔥 🔥 🔥 🔥 🔥 🔥
I just put this in my main lua file, do I need to do anything more to make it work?
Yay new shit UI update no one ever asked 🔥 🔥 🔥 🔥 🔥 🔥
this just gives me claustrophobia
Do I gotta put this shit in a while #G.ARGS.LOC_COLOURS <= 0?
in any case
i was gonna say
to put simply
you drop shit with exact concentration in another shit of unknown concentration
and look at when colour changes
then do a bunch of calculation n shit
i hate it
you need to do it like this
https://github.com/nh6574/JoyousSpring/blob/3769cadd5829031a465db2ff24fe69e2c881129a/src/globals.lua#L28
take a shot
Thank god I don't drink
wheres my mod...
THE MIST IS COMING
for the sake of it
I treat this like having billion of tabs in browser 
IT WORKS THANK YOU
bump Again!
Looked up how to create hooks in lua, seems like this worked
any way to give existing jokers stickers?
card.ability.eternal = true
card.ability.perishable = true
etc etc
oh wait hey astrapboy

rental actually
card.ability.rental = true
i assume it's just card.ability.rental yeah
Heya guys, ran into my first issue. during the before step, I want a joker to lose 1 mult for each card played. I've tried a few ways but they all seem pretty not work or crash the game lol
I tried making a different check for each handsize context but that didnt work, is there maybe a way to have a var set to the handsize?
can u show me the code? i can probably help with that
how does the code look like rn
-# do note that i barely worked with blinds, so no guarantee i can solve ur issue :(
Still wanna find a solution to this
Sorry its nightmarish
dear god
Hey, in my defense I joined an hour ago
card.ability.extra.sub_mult = #context.full_hand [=
Please for the love of god
card.ability.extra.sub_mult = #G.play.cards
You can make contexts into numbers?
its a table
yes
I didnt know that sorry
# returns how many keys the table has
length of table is #table
sorry
This would be held in hand
Play doesn't include all played I don't believe
it does
Only scored
works perfectly fine and the preview does too until you press Play Hand, and only crashes if it returns true
-# fyi im adding exclusive content to my mod for compatible content mods which is why im using some of aikos stuff since that's the current mod im working on
local w = ""
for _,c in pairs(hand) do
w=w..string.lower(c.ability.aikoyori_letters_stickers)
end
for _,uw in pairs(KMOD.played_words) do
if uw==w then
return true
end
end
return false
Gods appeased?
G.play.cards is the same as context.full_hand
Okay so it'd be context.full_hand, good to know
Thank you all so much, it works
doesnt recalc_debuff run through every single card though?
i dont think you need a table
-# wait, forgot ur using debuff_hand, let me check
yeah uh, its not the return true thats wrong, its the uw == w part
i dont have any knowledge regarding what those are, but one of them is a table while the other is a number
as long as you fix that, it should work
w is a string and KMOD.played_words is a table of strings
can you try printing "w" and "uw" separately
im pretty sure uw is still a table (and a card too)
calc hook code btw
local calc_hook = SMODS.calculate_context
function SMODS.calculate_context(context, return_table)
local x = calc_hook(context, return_table)
if G.GAME.letters_enabled and G.GAME.aiko_current_word then
local word = G.GAME.aiko_current_word
if not word then return {} end
word = string.lower(word)
local lowerword = string.lower(word)
word = string.gsub(" " .. word, "%W%l", string.upper):sub(2)
if context.before then
table.insert(KMOD.played_words, string.lower(word))
end
end
return x
end
im assuming the first one is "w" while the second one is "uw"?
...hm
ah, but also, remember to use ipairs for the (hand) for loop
just for safety, i still have memories about for pairs loop going through the keys randomly in luau, i heard its not the same in lua butttt better be safe than sorry :3
nothing changed
yeah its not supposed to fix the crash itself
just to make sure "w" is added properly
aaaaaa
hi baliame
?
a aaa
aaa aaa
aa aaa
like, if the keys r chosen randomly
if you play A C E, "w" can return E A C
yea but they're the same? how would this fix the crash?
like i said - thats just to make sure when the crash is fixed, it will work properly
im confused though, why is it that "w" is seen as a number
here's the code that the error mentions btw, i don't get how this would still brick the game though
actually, just realized something wrong with this
if not word then return {} end i think that will completely stop SMODS.calculate_effect from running too
oh
i didn't notice that
take it with a grain of salt though, im not that good with hooks but it does look like so
still bricks the game
and uhhh, whats with
word = string.gsub(""..word,... smt smt?
copied from aikos mod
from the maxwells notebook joker
:3 god im bad at working with mod-exclusive stuff
can you replace uw == w with true rq, i want to make sure its the comparison thats breaking
nah that's not the problem it crashes even if it is always true
:3 damn
probably not the blind's code itself then
i should probably ask aikoyori themselves for this
meh still stops you from playing the hand anyways so it works in my book 👍
change it to "Repeated words will crash your game", problem solved ❤️
I'm fucking crying
are you making a cross mod content for my mod
yea
i think there's a G.GAME.current_word
this?
I'm exhausted today
i saw it in the maxwells notebook code
yeah
still crashes the game which is why i changed it but i was too lazy to change it back
i spent half an hour troubleshooting
a nested mod folder problem
have you updated the release
the release of aikos tomfoolery or smokemodded?
mine
you good?
nope
no
{C:dark_edition} will make ur text change color like Negative
i am especially not okay today
oh okay, thanks!
transferring my energy to u through bluetooth 🖐️
hope you're gonna be doing especially okay (and above okay if possible) tommorow, then!
getting well resumes tomorrow
I'm so fucking done I want to just somersault my way back to my room
-# ur computer is not in ur room?
I'm outside, bepis
now this shit does nothing
did you change the current_word/aikoyori_letters_stickers api?
yes
ohhhhh
i changed it
i thought u r on ur computer rn, sorry
LIAR
balatro modders CANNOT go outside
which one or both?
api or docs?
😭
doing good, ty. how about you?
alr
ima hit the sack and try to fix my shitty code in the morning
i wouldn't be surprised if it was just smods and not aikos frolicsomeness
-# crazy thesaurus pull
Very tired
idk what part of the smods api you think is shitty 💀
the majority of it
(blinds to be specific because returning true CRASHES MY GAME 😡)
wha-
video of it here
-# john "aure" smods will rememberthis.
sushang :3
sus hang !!!
how can i check if i have more than one consumable?
if #G.consumeables.cards > 1 then
i'm either using the steamodded wiki wrong or it's super hard to find stuff there
LOL
so what is #G, anyway?
you know what # does already, right?
mmmmmaybe
G.consumeables refers to the consumeables area
G.consumeables.cards refers to the table containing the actual consumables
putting # behind a table will refer to how many keys the table has, basically
no yeah i get it, just like, is G the base balatro values object?
ye, kind of
so the array length, makes sense
yup
so is there a way to see all of the keys the "G" contains?
can be inconsistent with his coding, so dont count too much on that
for i,_ in pairs(G) do
print(i)
end
thank you, i'll check these out
np :D
i don't trust my instincts when im working in lua...
oh yeah wait thats not how random works
thought so lol
HELP
as in? sorry im kind of new to this
it's a balatro specific function that determine stuff based on seed
ohh
I'm so tired
by the way, is there some better way to debug this type of stuff?
as in, right now im just opening the game and trying to find this card in a spectral pack
WTF the balatro modders are so cool
if only i was cool :3
then there's me about to collapse in taco bell
Wait
So every other language uses 0
average balatro modder
lua is the only language i know that indices start at 1
I actually coded roblox games for a couple of years
Lua is the only thing I know and love
no yeah im pretty sure that uses lua as well
Yea
Some others do too, but languages that index at 1 are generally geared towards non-programmers
you might experience ascension once you try anything but lua
but you will have a hard time trying to understand it
I'm forced to do python
At school
like... i can't really rely on my coding instincts when coding in lua due to its nature being different at its core
isn't pythong cool...
So I'm still getting used to python different sytaxes
i guess its nice that you know both lua and non-lua structure
thats like the best thing ever
Not quite
lua is nice because i can easily write highly illegal code, i.e. it makes the kind of metaprogramming i like easy, and in fact encourages it
Illegal?
Julia indexes from 1, right?
Not familiar with Julia, but I know R and Matlab do
- hooks
- metatables for stuff like the lazy part of LuaFunctional
- lovely patches but that's less of lua's fault
statisticians and anyone doing anything with statistics. It's taught to linguists as well
I love metatables
chat
ye
I'm trying to come up with a good system to convert a letter deck into letter+number deck
no adding cards
no removing them either
I only learned about metatables last week and I really wanna learn how to use them now, because they sound like they can make for some pretty interesting things
A -> 1, etc.?
Idk what a metatable is
letter + number
It's a table that can be interpreted as a not table
so it will be mix of letter and number
Tables but cool
oh also lua's iterator (for loop) model is very nice
Just do it for the first 10 letters
are letters and numbers implemented the same way? They're both stickers on cards, right?
How so?
we also have + - * / ()
very powerful, flexible, and easy to use in exactly the way that makes me happy
Seriously you could keep letters used as variables but not the rest
yeah but how do i do the part for converting letters deck to letter+number cards deck
So maybe like
Well i also love how Lua does it
Wait how did i suddenly forget how to do it
I have many hundreds of hours on lua
ABCEFGHIJKPQRSUVWXYZ?
💀
Maybe not SPQR
My gut tells me it might be the most interesting to just set up a good 52 card division for which numbers and operators you want to appear, and randomly assign them to cards when you start 🤔
actually do you understand what i mean by converting into number+letter deck
No
so
the fact that you're asking makes me think I don't 😛
you will be able to buy vouchers that enable math in letter deck runs
the question is
how do I change existing deck to be as fair to the player as possible while adding at least one of the numbers and symbols
Oh the Voucher changes the deck?
i guess I'll just have to add 20 cards to the deck 😔
Why a Voucher though
how else would you allow the player to play numbers in other decks
Consumables
Newborn sacrifice
like how would you enable it
still pretty sure this is wrong..
stapling squirrels to John balatros wife to anger god
you never add the card to your hand, it's just created
I'm pretty sure it is pseudorandom_element(G.consumeables.cards, pseudoseed('seed'))
gang, how do u get download link of file? Like this one 'https://github.com/MathIsFun0/Trance/archive/refs/heads/main.zip'
checking
Right click the "Download ZIP" in the green Code button of the github page
download link 💔
? Yea right click it to get the link
Is there a way one could do this?
im going to try to read cryptid mod soruce code again
I think if you return xmult_mod, it won't
hey, so i'm trying to print out a big table yet it just makes it small and says +x more values
is there a way i can avoid that?
the debugger has a specific function for that, i think
btw tysm! works perfectly
lm check
https://github.com/Steamodded/smods/wiki/Utility the inspectdepth function goes up to a depth of 5, but should get every value
nice but where did it print it out...
In the lovely console
-# whats inspectDepth
the cool brother of print
Try sendDebugMessage(inspect(G.consumeables.cards))
the cooler daniel
with DebugPlus you can just call print on a table btw
:3 just use print instead dawg
the problem with using print is just
and by "you can" I mean that the output isn't fucking useless
and by fucking useless I mean table: 0xdeadbeef
it abbreviates when there is way too much lines in the value
welp..
how can i check how many jokers there are in the joker area, similar to what abstract does?
#G.jokers.cards
this is just a value i can use?
im learning
...thats a new one
yep! It'll give you the length of the array as a number
can i call this anywhere or only in the calculate functioin
sorry im new to this
anywhere will work
@native zinc ah yeah, the SMODS.calculate_effect, alright. I can't recall, does that actually work with retriggers?
edit: just tested, doesn't seem like it?
alright
Consumables
as in the game rule
What do you mean
where the hell is this end connected to :3
you know how buying alphabet soup voucher enables letters and words mechanics
No
isnt it the first function
I thought they granted Mult
now i get to pray that my code works
which one?
is there a similar way to pull current mult?
calculateDOT
honestly, no clue
oh, no
i'll test it
how would i check if something is negative?
the end for calculateDOT is all the way like 100 lines below that
oh
is it in .ability?
or should i be more concerned about the fact this comment can be collapsed and vice versa
😭
what the fuck is going on in my code
yeah i was going to say that
if (card.edition and card.edition.negative)
thanks!
works with hanging chad
well wait that's weird
wait, are you sure? for me it just says "again" and doesn't even retrigger
-# what the fuck is going on with my file
hm
I don't think SMODS.calculate_effect handles retriggers properly (one of those special cases I was talking about haha)
am i being debuffed
Kind of just seems like indentation stuff, even if it's not, double check your indentation to make it clearer. Or format it automatically if you can.
is the code fucking gatekeeping me from reading it
yeah probably just auto-format it
retriggers are handled above the scope of calculate_joker, so it needs to be returned out
however retriggers also don't work properly with extra tables
😭
shouldn't be too bad to fix though, but I can't send it through SMODS.trigger_effects as that would show the retrigger messages at a bad timing
fixing which part? 🤔
repetitions not respecting extra tables
i see
oh yeah I tried myself too
okay i'll try with other stuff
there's a bit of ambiguity on how the returns should be handled in such a case
return {
repetitions = 1,
extra = {
repetitions = 1,
message = 'abc',
}
}
what should this do
I tried changing
if value.repetitions and key ~= 'retriggers' then
for h=1, value.repetitions do
value.card = value.card or _card
value.message = value.message or (not value.remove_default_message and localize('k_again_ex'))
reps[#reps+1] = {key = value}
end
end
to
while value.repetitions and key ~= 'retriggers' then
for h=1, value.repetitions do
value.card = value.card or _card
value.message = value.message or (not value.remove_default_message and localize('k_again_ex'))
reps[#reps+1] = {key = value}
end
value = value.extra or {}
end
which worked math-wise, but duplicated the "again" message
Whats up with the "14 and 2" in this line of code for Strength? Seems like it just takes the math.min so whats the point?
local rank_suffix = card.base.id == 14 and 2 or math.min(card.base.id+1, 14)
if the rank is 14 (an ace) turns it to 2
if card.base.id == 14 then turn to 2, basically :3
return {
repetitions = 1,
message = localize('k_again_ex'),
extra = {
message = 'something else',
}
}
as opposed to this
that code is completely overridden by steamodded actually
but it wraps aces around to 2s instead of just going back to themselves
Oh wow
read as if card.base.id == 14 then 2 else math.min(card.base.id+1, 14) end
yea the syntax was throwing me off
it's a ternary operator in disguise
it reads weird the first time you see it haha
first one would be 2 retriggers, second one would be 1 retrigger?
or is that not what you meant?
would you expect the retrigger of the second one to have two messages?
I'd expect "again" -> retrigger -> "something else"
uh huh, retrigger messages are usually always before a retrigger and don't exist "on their own"
so that seems unnatural
my point is this
if the message from the extra table is displayed along the one retrigger but doesn't if the extra table has retriggers attached to itself, that seems confusing
I'm confused
am i witnessing the conversation between two gods
isn't this "again" -> retrigger -> "abc" -> retrigger?
💔
yeah that's what I'd expect
however that suggest that the extra table is ignored when evaluating the effect table on the first retrigger
Ah so you're saying that it starts handling the extra table inconsistently?
that's what I'm afraid would need to happen
hey gods 👋
don't make me smite you john lovely
i can't smite you back but I do have a cattle prod
I'm thinking I can just ignore extra tables altogether in triggering effects, which would mean extra tables with no repetitions attached would just do nothing
can i offer a
:3
which I guess is consistent if you consider extra tables with no repetitions to have an implicit repetitions = 0
which means the 'something else' here is ignored
I mean, kinda
so would that mean that
return {
repetitions = 1,
extra = {
mult = 2,
}
}
only gives 1 repetition and no mult then?
oh and ```lua
return {
repetitions = 1,
extra = {
repetitions = 1,
message = 'abc',
}
}
fair enough
I would argue repetition checks aren't the right time to give mult
if you want the mult alongside the repetition, you can either have it in the first table or use a func
king you dropped this
same for multiple messages on a repetition
Oh are we unscuffing repetition and retrigger logic a bit
considering to
return {
repetitions = 1,
message = '1',
extra = {
message = '2',
extra = {
repetitions = 1,
message = '3'
}
}
}
I would see this as one repetition with "1" and one with "3", with the "2" in the middle being ignored due to having zero repetitions
Yeah that seems reasonable
that seems relatively pain-free to implement
though it would probably be nice for steamodded to give a warning or similar saying "hey your extra table is empty"?
or... "considered" empty
alternatively just doc it
I guess that can be a warning as it'd rarely be intentional