#💻・modding-dev
1 messages · Page 175 of 1
Is there a reference to the 'overscore' or whatever that happens? Like when you reach the blind in a single hand and the fire appears in the ui? I want to reward players for being able to score that much in a single hand, but not just the first hand being noticed, just if they manage to do it in any hand
did you start a new run
yea
still nothing
did you notice you spelled calculate wrong
calcualte = function(self, card, context)
that'd certainly do it
._.
indeed, i was surprised you didnt catch it
it's the first time i've seen that
next time i'll have to look out for misspellings too
it's all a learning process, don't work yourself up about it
my stupid ass types stupid so ill often add or swap letters
so i always gotta look
lmfao
thats fair, one day i should organize my things and make a localization file too, but i just cant be bothered to
everything is in one file
eh, it works and user has no reason to be in the code so its not really an issue i think
the most localization does in my eyes is appearances
And makes it easier for other people to translate your mod
ever since we implemented a loc file in paperback we got a portuguese and french translation
i've never made a mod before do any of u know how I would go about adding my own images over balatro's jokers
i find it unlikely for others to use my shit much lmfao
so im not too worried about other languages
you do you, but i still stand by it being a bad habit
like having all your books thrown on the ground instead of a bookcase
maybe, either way itll be a bridge i cross later
context.other_card................
guhhhfhfhhfuhfuifhisdfnilawsfjmiv aewebriuo weihtgnmb wesiuotmb4joswrietpmbjswet
key = "millicent",
loc_txt = {
name = "Millicent",
text = {
"Played {C:attention}Steel Cards{}",
"give {C:mult}+#1#{} mult when",
"scored"
}
},
config = { extra = {mult = 4} },
blueprint_compat = true,
rarity = 1,
atlas = "dilatro",
pos = {x = 0, y = 0},
cost = 4,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult } }
end,
calculate = function(self, card, context) --
if context.individual and context.cardarea == G.play then
if SMODS.has_enhancement(context.other_card, 'm_steel') then
return {
mult = card.ability.extra.mult
}
end
end
end
}```
this is working when i ran it now
change the atlas to yours obv
i had to use mine to see
everybody starts somewhere its all good
i really gotta seperate my main.lua
just started coding and i have no clue whats going on, im basically just copying the code from SixSuits since im adding 4 more suits and when i checked to see if the first suit would show up in the option this crash came up
heres my code this far
thanks
trying to make a joker for cardsauce that does negative mult, and it works in calculation but i noticed that if the mult counter goes below 0 it becomes blank. anyone know a mod that has a fix for that?
what's the context for a card being destroyed?
could it literally just be "card_destroyed"?
hold on i'm seeing "cards_destroyed" imma go with that
destroying_card
What happens if two different mods extend the same vanilla-game function in different ways, like the image
will both execute based on priority or will only the one with higher priority execute
for some reason, after a hand is scored, this isn't resetting or playing the reset message
G.jokers instead of G.play
it will be in the order mods are loaded I think
so first based on each mod's specified priority, and then in whatever order the filesystem finds them
I believe is how it works
and all hooks will apply
that's indeed how that works, so long as no one does destructive overrides
-# that's if you're not steamodded and aren't lovely patching the override
laughing rn because i thought this would add +4 mult when a card (be it a playing card or Joker) is destroyed
instead
it triggers on each card played and destroys them instead
so turns out doing this was super easy
Is there a way to make my joker change Glass Cards probability to get destroyed, without modifying any other probability?
you can just pass mult to the return table in joker_main and it'll make the message for you
as for your desired effect, there's no smods context for destroying jokers, but you can use remove_playing_cards for playing cards, and all the destroyed cards will be in context.removed
so i can get rid of the message line?
yes
that seems like it'll need lovely patches to accomplish
what's the exact effect of your joker?
I want my joker to make it so Glass Cards can’t shatter by themselves.
The Joker will have a 1 in 100 chance to get destroyed at the end of rounds.
trying to make a joker that permanently adds chips to played cards like hiker, what am I doing wrong in this calculate function?
i think the first effect will need to be done through a lovely patch
hiker adds to perma_bonus iirc
the game keeps crashing and it shows that "Atlas flip_cards" cannot either find or use the image file for the asset and i dont understand why heres my code and files o show im not going mad
as for this
it works as intended
however
no mult ding when used
and it only counts once when two cards are destroyed
I’m still pretty new to modding this game so I don’t know yet how to work with lovely patches. Guess I’ll work on some other Jokers for now.
yes, that context is not executed once for every card, it's executed one time for all destroyed cards, which are in context.removed
you have each file in assets/1x and assets/2x respectively right
where are those image files located?
in my assets folder under 2x since i dont have scaled down versions for 1x (its a long story)
thx, ill fix up the files later
does anyone know why it's saying this file doesn't exist when it clearly does?
Is there any consumable and booster packs example mod?
I mean i could see any mod source code but im looking something easy and beginner friendly
So I'm not sure what's going on with the deck here
It's not supposed to have the other ranks in the booster packs
if G.GAME.selected_back and (G.GAME.selected_back.effect.center.key == "b_SCB_AltSuit" or G.GAME.selected_back.effect.center.key == "b_SCB_EveryDeck") then return true end
end```
I have it as this for in_pool
I'm thinking it's something to do with Talisman possibly
because I disabled my other mods
when i went to check if the suits were working and was jumpscared with this mess
oh
dunt know why its called that or how to fix it
Thats a nice Ace of ERROR
you could make it a joker as an easter egg
"All aces are considered kings and viceversa"
ill write that down
thoughts? i'm not 100% on the card art but it works for now
Been wanting to get into making mods for a while, hoping to get some general help with programming modded jokers mainly, but figuring out how to make card skins (like the Cyberpunk spades) and how to add them to the skin list would be nice to figure out too. All help would be appreciated 🙏
Card looks sick, plus i'd probably use that with erratic deck early game 
Strange, I can't seem to recreate the bug. I loaded talisman and nothing happened
Lemme try re-adding Cryptid
It's something with Cryptid
how can i delete a ui box
Mini-Immolate each round? Sign me up
oh hi
yea that's p much it
just gotta make sure you don't play your good cards up`front
Oh youre here
I want to thank you
Canio's code worked excelent
Nice to hear
alright the logic is all working right, but how do I make the joker itself juice up when the "Upgrade!" message pops up? currently it happens as soon as the joker triggers which is too early
hiker only does the animation once the upgrade message appears on the other card
I grabbed pieces of the code to basically trim it down assuming that the ability name was "Caino"
So that if you were to add it with SMODS, the resulting code would be what you would put in the calculate
And then re-indented it because that's much easier to read like that
okay, ill add learn to do that to my todo list
Use message on its own, not extra
ah, I see, I just looked at what hiker was doing
return {
message = localize('k_upgrade_ex'),
colour = G.C.CHIPS,
card = context.other_card
}
If you're using SMODS this should work too
I mean, it was working already and this works exactly the same
Are there any consumable and booster packs example mod?
I mean i could see any mod source code but im looking something easy and beginner friendly
my issue is that the joker itself isn't doing the animation at the same time like hiker does, only the affected card
As for juicing up the joker itself at the same time as the message I'm not sure?
I've had similar issues of doing things at the same time as the message, and have a patch that enables an unused feature that allows you to do that
# card_eval_status_text()
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "local extrafunc = nil"
position = "at"
payload = "local extrafunc = extra and extra.extrafunc"
match_indent = true
You can then use extrafunc in the return table like func. It will be executed at the same time the message gets displayed
(Small update regarding that: you can delete the first if. It's never called in-game)
(Keep only context.remove_playing_cards and it should still work fine)
structured like this?
No
extrafunc = function()
card:juice_up(0.8, 0.5)
end
yeah, i cleaned the code
and changed the messages
Me when The Needle
Cards get destroyed after scoring so you should be fine
If "losing your best hand" could be considered fine
Oh if it's specified to do this then
All destroy jokers happen after scoring
See Sixth Sense (and I assume Alrex implemented it the same way)
Guys, the mod manager is out now: https://discord.com/channels/1116389027176787968/1339375696254074942
YAY!
bump
preference for these 3 buttons?
buttons is the wrong word
They're like little pins
cursed.
i personally like the one with the drop shadow the most, also are those like blind enhancements or challenges or something different
is there a way to just get the number of cards inside G.consumeables (or any other cardarea) or do I just have to loop over them all
they're little blind challenges based on spectrals
they get applied to every single blind on a certain deck
#G.consumeables.cards
cool, and by the one with the drop shadow i meant the third one btw
is there a way to get the price of shop items like boosters packs such as a value I can use elsewhere?
Hey, So I used the code from the example joker that gives +4 mult and changed it for chips, it continues to crash when I play a hand with it there, over "Attempt to index field 'vars' [a number value]"
What should I do?
what does your code look like
I'll grab it rq
Based on the error I'd assume you did return { vars = 4 } in loc_vars which is incorrect
Or something of that kind
how do I get an enhancement/joker/etc that references something that doesn't exist yet to stop crashing when hovered in the collection if you're on the title screen
like, my joker that references the number of consumable cards you have crashes if you hover it on the menu because the consumable area doesn't exist yet, I assume
set a default value if it doesn't exist
That's pretty similar, I wrote
loc_vars = function(self, info_queue, card) Return { vars = { card.ability.extra.chips} } end
that looks fine
do local amt = G.consumeables and #G.consumeables.cards or 0 for example
if consumeables exists it'll get the amount of cards, otherwise 0
will need to see the code for that
Well it gave me a different issue this time, so that's nice ig
I'll grab the code
SMODS.Joker { key = 'PotatoChip', loc_txt ={ name = 'Potato Chip', text = { '{C:chips}+#1#{} Chip' } }, config = { extra = { chips = 21 } }, loc_vars = function(self, info_queue, card) return { vars = { card.ability.extra.chips} } end rarity = 1, atlas = 'Jokers', pos = {x = 0, y = 0}, cost = 0, calculate = function(self, card, context) if context.joker_main then return { chips_mod = card.ability.extra.chips, message = localize { type = 'variable', key = 'a_chips', vars = card.ability.extra.chips } } end end }
I wasn't sure what you needed to see, so I just grabbed all of it
the actual issue here is in your localize call in your return statement
vars should be a table
Ah
but you don't need to specify the message, just pass chips = card.ability.extra.chips and steamodded will do it for you
Ooh thank you
May I know what that'd look like, I'm not the greatest at Lua
Thank you so much mate!
No
because if G.consumeables is nil, it cannot access cards
that's why in the example i sent before I did G.consumeables and before
I see
how can i move a card area
Ayo, what the heck did i do?
something sick looking damn
Still trying to play around with it
ayo im just getting in to modding this game, is there any way i can get VSCode autocomplete stuff with Steamodded, so i can see the different properties?
It's mostly just the ionized shader but i need to play more to see what happens
Also uh, new here but I've been trying to add a planet card to the game for a while and it isn't showing up. What exactly do I need for steamodded to add a card? I have already added jokers to the game and can't figure this out. (this is just for me to learn stuff, basing it on cryptid) (Also I know it's cut off, there's just ends and close brackets below the screenshot.)
how to move/remove card areas
how to use the atlas system?
why isnt it displaying the negative consumable
Ah damn, so this works if I put it into the file my jokers are in, so the better question is, how do I load extra files then?
(also changed from SMODS.Planet to SMODS.Consumable)
try {key = 'e_negative_consumable', set = 'Edition', config = {extra = 1}}
in place of what?
oh i got it
thank you wise one for gracing me with your genius
yw i literally just looked up e_negative_consumable in the game's code
i was just confused because G.P_CENTERS.e_negative works but not when i add consumable
because it's not in P_CENTERS, don't ask me why
ah
rather I think I know why but idk why it's considered an edition in the localization
assert(SMODS.load_file("your_file.lua"))()
Is there a way to remove a suit from the pool so it doesn't get added to the decks, but allow it to show up in card packs? Or is that a default thing that I'd also have to disable if i wanted it disabled?
I just put this in my main file?
yes
is there a way to check how many hands are left?
G.GAME.current_round.hands_left I'm pretty sure
how does the legendary joker atlas work?
Like I have the back and the joker isolated, but how do I put them together in the code?
soul_pos = {x = yeah, y = sure}
and I assume thats for the isolated joker?
yeah
and final question about it, for x and y do I put the size of a normal card or just the size of the joker?
neither you put the atlas position of it
I have no clue what you mean by that
Ballot is x = 1 , y = 0
that's all that soul_pos is
art for one of my decks and its corresponding gimmick
I see, so y = column, x = row?
so 5th joker on 4th column is x = 5 , y = 4?
Also thank you so much, is there documentation for Steamodded somewhere so I can go look there first before asking questions?
yes
thank you
Almost, is: x = 4 , y = 3
no
so I start at 0,0?
lua arrays start on a 1 count
ah you're a godsend thank you.
x = 5, y = 4 is correct
Wait really? cuz my code isn't that way
atlas starts at 0 as far as I know
That's what I've been doing
oh good, I thought I was crazy (which wouldn't be a shock tbh)
yeah, this is what I get for not starting at 0,0
do I specifiy atlas key anywhere?
same atlas
wdym? I put it IN my SMODS.Atlas?
no
it should be on the same image file your other jokers are on, thus you do not need to specify the atlas key again, as you do that to get the Joker sprite anyways
I see, thank you
does anyone have a list of the fonts used in the balatro jokers?
how do i get the number of spectral cards held in consumable slots
Loop through G.consumeables.cards, check if <card>.set == "Spectral"
may be card.ability.set
I don’t need it yet, but do you guys think there’s anyone in here who would be willing to help out with pixel art for card designs if I were to ask for it at a later point?
G.E_MANAGER:add_event(Event({
func = function()
G.consumeables.config.card_limit = G.consumeables.config.card_limit - card.ability.extra.con_slots
G.hand:change_size(card.ability.extra.hand_size)
return true
end
}))
if #G.consumeables.cards > 0 then
local cards_to_destroy = math.min(2, #G.consumeables.cards)
G.E_MANAGER:add_event(Event({
func = function()
for i = 1, cards_to_destroy do
local destroyed = pseudorandom_element(G.consumeables.cards, pseudoseed('jochinator'))
destroyed.T.r = -0.2
destroyed:juice_up(0.3, 0.4)
destroyed.states.drag.is = true
destroyed.children.center.pinch.x = true
destroyed:start_dissolve()
return true
end
end
}))
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4,
func = function()
play_sound('tarot1')
return true
end
}))
end
end
}``` I'm trying to have an effect where if the joker is destroyed or disabled, it destroys two consumeable cards. I works except for some reason it only ever deletes 1. Before I had the for loop right below local card_to_destroy, but sometimes then it only deleted 1, I assumed it was because the same card was picked twice?
how would i have one atlas come after the other? because i'm adding in a separate atlas for all the legendaries in my mod and they show up before my main atlas in the collection
The jokers show up in collection in the order you loaded them in your code
has nothing to do with atlas
ohhhh wait then i think i know why then
it's cause the file comes before the main atlas in alphabetical order
if you're loading a folder with NFS then yeah
also how would i have it so that a joker gives you +1 discard per round
A permanent discard or one given at start of blind like burglar
"permanent" being for as long as your joker exists ofc
a permanent discard like drunkard i believe
in your joker, define add_to_deck where you ease_discards(1), on remove_from_deck do ease_discards(-1)
so ima ask again does anyone know how to move card areas to off screen
i wonder if I'd be able to delete cards that are held in hand through context.destroy_card 🤔
i also don't know the key for jupiter specifically as a card
oh wait its c_jupiter
is the way I'm doing this just not good for what I'm trying to do? I'm taking code from toby the corgi and riff raff and probably using it wrong
key = 'consumeable_destroyer',
loc_txt = {
name = 'Reckless Gambler',
text = {
"If {C:attention}destroyed{} or {C:attention}disabled{},",
"{C:red}destroys 2 unique consumable cards{}."
}
},
config = {
extra = {
consumeables_destroyed = 2
}
},
rarity = 3,
atlas = 'youratlashere',
pos = { x = 2, y = 1 },
cost = 7,
remove_from_deck = function(self, card, from_debuff)
print("[DEBUG] Reckless Gambler removed. Destroying consumables...")
local available_consumables = {}
for _, v in ipairs(G.consumeables.cards) do
table.insert(available_consumables, v)
end
if #available_consumables > 0 then
local cards_to_destroy = math.min(self.config.extra.consumeables_destroyed, #available_consumables)
local destroyed_cards = {}
G.E_MANAGER:add_event(Event({
func = function()
for i = 1, cards_to_destroy do
if #available_consumables == 0 then break end
local destroyed = pseudorandom_element(available_consumables, pseudoseed('reckless_gambler'))
if destroyed then
for index, v in ipairs(available_consumables) do
if v == destroyed then
table.remove(available_consumables, index)
break
end
end
table.insert(destroyed_cards, destroyed)
print("[DEBUG] Destroying consumable:", destroyed.ability.name)
destroyed.T.r = -0.2
destroyed:juice_up(0.3, 0.4)
destroyed.states.drag.is = true
destroyed.children.center.pinch.x = true
destroyed:start_dissolve()
end
end
return true
end
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('tarot1')
return true
end
}))
end
end
}
i tested this and this worked for me, at least on sale anyway, youll have to see if it does on debuff
it was picking the same one so just making it so it cant pick the same one solves that issue
this is my first time I'm using lua or any coding at all and i literally just learned how for loops and math.min works, and I don't really understand what ipairs is doing, I saw that in the immolate code and other places
ipairs by my understand is to loop over an array, itll return an index and value
so in this case its looping through all consumjables in g.consumeables.cards, then we insert whats available into a table
then we see what was destroyed, return a list, and go for a card that was not destroyed
ok that makes sense why it's in the immolate code then
tysm I'll try to wrap my head around this
no worries, just get use to beating your head against the wall in the beginning =]
lmk if what i posted works for your desires
i attempted this and it is safe to say that i still have no idea what im doing
what does your attempt look like
beware this is probably complete nonsense
is there a context similar to end of round but only after the boss blind?
the incorrect parts are card.consumeable.ability.set[i] should be swapped to G.consumeables.cards[i].ability.set, and if you return inside a for loop you will only evaluate one element
context.end_of_round and G.GAME.blind.boss
how would i make it so that each played card gives 1 dollar when scored?
if context.individual and context.cardarea == G.play then return { dollars = 1 } end
this seems top trigger multiple times, how can I make it trigger once?
add and context.main_eval
nothing happens now
are you on the latest steamodded
does anyone know what the context card played function is? like I don't know how to do this properly
im just trying to add multi whenever a heart card is played ^^
I also don't know if the color name is correct because I saw that the example joker had this color and I don't know how to do it for the multi color instead
just updated, works now
Behold my jonklers
why is Canio a diamond?
Ramiel joker???
Finally updated my steammodded
Went from 1326a to 1413 good lord they were cruising
Your jokers are on that Bhutanese shadow garden grown dark evil pack 🗣️ 🔥
Yes ramiel
Ill change the name later
Would it be great to have all the Evangelion angels as jokers? Yes
Do i want to sprite every Evangelion angel? No
I want to round up the effect of this jonkler, ive seen a function to round up in the wiki but i cant make it work
any help on what must i do with the variable that keeps the money taken out to round it up?
math.floor(number) - always rounds down
math.ceil(number) - always rounds up
@past forge
you can't just use that as a function on its own line
you have to use it as a variable
card.ability.extra.mult = card.ability.extra.mult + math.ceil(taken_dollars)
is there any way to detect when a joker is being destroyed specifically?
something like banana or you want another joker to detect if any specific joker is being destroyed?
if second option, i gues you could use the joker id
like
jokers being destroyed through stuff like Madness, Sacrificial Dagger, etc.
besides
the current issue for me is trying to find a way to detect when any cards at all are being removed
is remove_from_deck it's own function or do I put it in the calculate function?
This is canios code
it helped me yesterday to make the guillotine joker that i was working on
doesnt this apply?
its still the original balatro source code being posted openly
i mean I have no problem on deleting it but i thought i could post it here
yeah i wouldnt risk it tbh
wait a second, in that case ill send you my code
I think rule 7 more so applies to redistributing the entire source code
A lot of modded ressembles vanilla code reshapen slightly
thats what i was thinking
And things like SMODS directly interact with source code, so discussing it is kinda necessary
it must be in the calculate
Basically imo, as long as you can't have someone take the code and rezip it into a working Balatro without having to have paid for it, you should be fine
Also as I told you yesterday you can remove the context.cards_destroyed code
It's never triggered in the game
Is it possible to add a second card to the main menu? I'm trying with this but the sorting function is causing a crash for some reason
what is it suppose to be then?

yeah the code's there to catch shattering glass i think?
It's never run
mhm
If you search for "cards_destroyed" in the entire codebase, it's never used inside a context as a flag
remove_playing_cards handles glass breaking
ok slight issues
it sort of works
but there's no mult ding when it adds mult to a hand and even when multiple cards are destroyed at once, it only increments by one
For the latter that's by design
It doesn't trigger once for each card, but once for each group of cards being destroyed, so it increments once by the amount of cards destroyed
For the former, does it actually add the mult?
yes
That's odd
ok but the thing is
i want it to count each individual card
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain * destroyedcards
i get efficiency but it works
You do you
oh wait that's probably why it wasn't registering
it automatically does mult, but it doesn't automatically do mult_mod
does this include xchips too now?
Afaik it was recently added, yeah
It does do mult mod it’s just not recommended to use it
mult_mod is what is used internally, mult is added and handled by SMODS, correct?
that makes a lot of sense
Thunk used mult and mult_mod in different calculation steps
(Regarding xchips support)
So using either now works anywhere, just plain mult does all the auto messaging for you
:(
oh a question, does it differentiate between adding mult/chips to the score and adding to the joker's scaling
Those returns only add to score. For scaling you need to toy with the ability, and handle the messages yourself
I could maybe add support for returning upgrade = true for the standard messaging
this is the code for one of my scaling jokers
(it scales every time you play a hand with an unscoring card, but it resets if all cards score)
Neat
maybe also reset = true because that's used on a few Jinkies as well
guess I'll keep it like this
btw I like to use config rather than flat values because that makes balancing changes real simple
you don't have to go in and change a bunch of numbers, you just change one number once
Yeah that’s a good habit to get into
That's the standard way of doing it, even the base game does it
And allows more flexibility and compatibility with stuff like whatever Cryptid is doing
The base game doesn’t do it for everything iirc
this is for a joker that activates if you've scored more than 60% already
although idk if its entirely necessary to always put it in extra or if I can just put it outside in config
thought it was common knowledge
Only extra is copied
is there a context for when a hand is levelled up?
Alongside a few other base values in the config
Yeah I believe only certain things in the main config are copied
Or saved maybe
yeah
example: mr bones
Unless it was changed at some point
Last time I checked ability was created by cherrypicking things from config, not copied wholesale
I can't check the code right now, not at my computer
ive used random keys inside the root config all over strange pencil with no issues
I followed what the SMODS wiki says on the matter
i really like how simple it is to add talisman support
asking again
i dont think so?
no but you can make one
Wait you need a to_number failsafe too now?
to_big didn't work in this very specific function
Oh
oo? how?
hook/patch the function to call the smods function that calculates a context
the function being SMODS.calculate_context({something = true})
Damn, the Pokermon patches
exposed for my crimes
when compared to other cryptid jokers, is this too powerful for epic or not powerful enough?
i feel like this should be more Exotic
also make sure to include the "negative" infobox
im stupid, how do i do that again?
should be in the Perkeo example code
in this file
loc_vars = function(self, info_queue, card)
-- This is the way to add an info_queue, which is extra information about other cards
-- usually, like Stone Cards on Marble/Stone Jokers, Steel Cards on Steel Joker, and
-- in this case, information about negative editions on Perkeo.
info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
end,```
mhm
although I still don't exactly know how this works to create unique ones
so to clarify there should be a helpful hook that sort of achieves what I want here, right?
what
no this is the hard part theres no helpful anything you're wrangling this nightmare of a codebase to your bidding
yeah but its really easy
thx guys, idk if i should create a pull request cuz this is a bit low effort
if you really wanna break the game,
X1.5 mult, gains x1.5 mult for each copy
so if you have 2, rather than doing 1.5 x 1.5, it does 3.0 x 3.0
crikey
Why not push it further and make them retrigger the other copies
is that truer to the cryptid experience
it already takes like 0.1s to calculate amount of time with 40 copies, so making them iterate over all jokers for each copy would take a lot longer
its cryptid, taking a long time to calculate is part of the mod
okay so if i essentially want something that triggers when a hand is levelled up through any means (space joker, black hole, relevant planet cards, etc.)
how would i structure it
would the retriggers retrigger the retriggers?
would it also include being levelled down by that one boss
yes!
nahhh fuck the arm
perhaps retrigger all jokers (mitosis copies) to the right so it doesn't go forever?
If you code it right, no
You can filter out the retriggers iirc
no infinite retriggers 😢
-# literally 1984
It does mean if you code it wrong, then yes
The Mario joker from Cryptid could be one you could look at
hook or patch the level_up_hand function
you would need an edge case for The Arm though
since that uses level_up_hand() but negative instead
yeah
you can check if its positive
better to have the context be generic and have specific effects check positive/negative
maybe under the arm, you could do calculate_context({arm_level_down = true})
so you can do if context.level_up and not context.arm_level_down
no like you just pass info about the level up in context.level_up
if you add the new context here you can pass {upgrade_hand = (amount > = 1) } possibly
SMODS.calculate_context(upgrade_hand = (amount > = 1))
And in the joker calc
if context.upgrade_hand then
like context.level_up.handname, context.level_up.amount etc
i'm sort of mystified rn because the example they use in the examplejokers mod is for Castle
Well just put it alongside in the context, and keep level_up_hand as a flag
That's the way all other contexts work
{
level_up_hand = true,
amount = amount,
hand = hand,
other_card = card
}
igo?
function Game:init_game_object()
local ret = igo(self)
ret.current_round.castle2_card = { suit = 'Spades' }
return ret
end```
(taken from the ExampleJokersMod)
I'd personally use a patch, I don't have experience with that
i don't have experience with that either-
Patch a
SMODS.calculate_context({ level_up_hand = true, amount = amount, hand = hand, other_card = card })
at the end of the level_up_hand function
You can look into SMODS for inspiration ("lovely" folder). Patches are really simple, they just look for strings inside existing code and either add new code before or after, or replace it entirely
This could work (Using hooks)
That is a possibility
Too context dependent
if its easily doable, hooks, otherwise patches
Some stuff can only be done with hooks, some stuff can only be done with patches (more often the latter)
for me
duly noted
But yes hooks are probably easier
yk Im going to keep this now, might come in handy
what can a hook do that a patch can't? can you give an example?
Hooks are cleaner when you have multiple mods modifying the same thing, patches might enter conflicts more easily
Hooks can be simpler to perform. Even #💻・modding-dev message is done via hook.
Patches are more powerful but more blunt
Individually though patches can do anything a hook can do, yes. It's in a wider context that differences show up
hooks can add at the start/end of a function, patches in the middle as well (in short)
i will probably come to prefer Hooks because I like keeping in my current code and don't like using an entirely separate file and coding format
hooks can also cause subtle compatibility issues fwiw, depending on the hooks in question
ok thanks for the neat hook
how would i make it work
Like this
what does ~= stand for in Lua?
not equal
because i refuse to think is aproximetaly
I used to think that too
why not go for the standard !=
every other language uses != but lua loves to be unique
why not go for the standard <> /nj
If the hook overrides the arguments then yes, if it just adds functionnality it's much less likely
like i think i dont even have that key in this laptop keyboard
Like triggering a context in this instance
real, my keyboard doesnt even have the tilde so I have to copy paste it
balatro mod coded in brainfuck
a pain
One of many reasons I subtly despise Lua
The first one is 1-indexing
not (a == b) my beloved
true
The third is using then/do end and not { }
so i just use the context.joker_main?
the fourth is not having a .contains()
a ~= b
That's what we were discussing
all I dislike is how picky it is with commas
no the context is the one you added in the hook (upgrade_hand in the picture)
should I take this as a challenge? no. will I? maybe
so it should be written as
if context.original_level_up_hand then
-- code runs here
end
end```
like this
wdym
the function is already being hooked
you just do what you want your joker to do
which is... upgrade the hand being upgraded again
well then thats different
you can still intercept the function and increase amount by 1 if the joker is held
@_@
local thunk = function() end
so this wouldn't even need a calculate function?
correct
heya, what's the simplest way to change the colour of the menu? i tried it a few days ago but i couldnt get the thing spinning
like the colours were there but the animation just didnt
it doesn't work
and
i'd rather it have an animation on the joker to indicate that it is doing something
i used Pluto and Black Hole to test
maybe it's because the code doesn't call the function
what's your code like?
return {
message = localize('k_upgrade_ex')
}```
here's all the code relevant to the joker
maybe it's because i referred to it as "j_starwish" instead of "starwish"
also yeah you should add in your mod prefix
rolo's code had it as a comment 😭
j_[prefix]_starwish
How to get the color of the text depending on the suit?
i guess maybe using the same variables
are C:diamonds, C:hearts, C:spades and C:clubs valid colors?
Got it to work
Yuhhh!! thx!!
just send me the code whenever
local original_level_up_hand = level_up_hand
function level_up_hand(card, hand, instant, amount)
local level_by = amount or 1
if SMODS.find_card('j_prefix_name')[1] and level_by > 0 then
card_eval_status_text(SMODS.find_card('j_prefix_name')[1], 'extra', nil, nil, nil, {message = 'Double Upgrade!', colour = G.C.RED})
level_by = level_by + 1
end
original_level_up_hand(card, hand, instant, level_by)
end```
Still no need for the calc function in the Joker itself
Another doubt, how do i make the card randomly select a suit? must I just use localize(G.GAME.current_round.castle_card.suit, 'suits_singular') or the ancient joker suit?
cool joker it works with space as well
should work with Burnt too
do you want it to upgrade it by the amount of that joker you have or just +1
yea i want it to be blueprint compatible
i'd imagine it'd do a similar ding to how space joker and burnt joker levels up hands
you know
instead of "double upgrade!"
it'd add another level
understandable
but that sounds a bit more complicated, you should just use the "amount" the function gives you
local original_level_up_hand = level_up_hand
function level_up_hand(card, hand, instant, amount)
level_by = amount or 1
SMODS.calculate_context( {upgrade_hand = (level_by > 0)} )
original_level_up_hand(card, hand, instant, level_by)
end```
```lua
calculate = function (self, card, context)
if context.upgrade_hand then
level_by = level_by + 1
return {
card = card,
message = '+1 Level'
}
end
end
Something like this can work
@obtuse silo
I'd consider making this rare or legendary lol
So, this is supposed to set the enhancement of all cards in hand to Stone cards but I feel Im missing smth here:
Nvm I figured it out!
i get this error and i assume it happens when im trying to get the color of the random suit i got
its probably because its looking for the colors that go in here
It should also be V:1 and V:2
i see
Can someone tell if theres a way to get rid of this wierd visual bug related to stone cards?
cards are turning blank for a moment before becoming stone cards
that's like very not clean
What do you use to turn them into stone? There might be an immediate argument
Ig im using no argument?
should I just plug it in above func?
third argument in set_ability is delay_sprites, try just removing the last two arguments
so remove nil, true
Worked like a charm!
Thanks kind stranger
Done, thank you so much
a very strong common joker
is not going to be common
Is there an easy way to identify non-scoring cards?
So I wanna make a function that checks how many stone cards in your hand and do X thing per each in hand. Am I doing this correctly?
what do you need it for
to give player money for each stone card in hand
5$
when?
Ive made a code for transforming all cards in your hand into stone cards on use
for a spectral card
now I need it to identify how many were turned into stone
and give 5$ for each transformed
in one total sum
is it a different Joker that gives money for each stone card
Ive done the first part of the effect
now I need to figure out how to make the 2nd
Does this check if hand is or if hand contains?
I think it'll be quite complicated for me to make a code which would track which cards were turned into stones and which not
whats your consumable code
object_type = "Consumable",
set = "Spectral",
name = "Petrify",
key = "pertify",
order = 1,
cost = 4,
atlas = "Consumables",
pos = { x = 3, y = 0 },
loc_vars = function(self, info_queue, card)
end,
can_use = function(self, card)
return #G.hand.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local chosen_card = pseudorandom_element(G.hand.cards, pseudoseed("cry_replica_choice"))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.hand.cards do
local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("card1", percent)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
for i = 1, #G.hand.cards do
if not G.hand.cards[i].ability.eternal then
G.E_MANAGER:add_event(Event({
func = function()
G.hand.cards[i]: set_ability(G.P_CENTERS.m_stone)
return true
end,
}))
end
end
for i = 1, #G.hand.cards do
local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("tarot2", percent, 0.6)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.5)
end,
calculate = function(self, card, context)
if context.cardarea == G.hand then
local stones = {}
for k, v in ipairs(context.cardarea == G.hand) do
if v:is_stone() then
stones[#stones + 1] = v
}```
can you put it between the code brackets
Put what exactly?
the code
whats the symbol
You can put it between
```lua
```
to format it with syntax highlighting
Thanks!
the calculate doesnt have return or end
Add a variable to count the number of stoned cards
In the second loop, only apply the effect to non-stoned cards and increment that variable
Gain money based on that variable
because I do not know what to calcute
I dont know how
to be precise
You won't need calculate here
I need to give money only for cards that werent initially Stone cards
Calculate is used to modify effects/do stuff when other stuff happens. This is a consumeable, so the only thing you should worry about is use
Yes, hence the check in the second loop
Probably something like if not G.hand.cards[i].ability.eternal and G.hand.cards[i].ability.name ~= 'm_stone' then
possibly
Yep, what I described, just without the "already a stone" check
yep they should add that check as well
shouldnt you be checking by center
bump
contains
if you want it to be hand is, then you're looking for something like poker hand == "hand name"
idk never done it
I assume this doesnt check if card was initially Stone?
I'm not sure, so most likely
codex added the check here
(Not guaranteed to be correct, I recommend you check similar code)
but the real question is why are you checking if playing cards are eternal
for the record
Compatibility I guess?
i'm pretty sure it is better to check it with
card.config.center == G.P_CENTERS.m_stone rather than card.ability_name == "Stone Card"
i don't know why it's better
but I was told it is better
It checks based on a variable rather than a hardcoded value, so it's more robust
makes sense
havent even finished my first mod and im already brainstorming a second one based on my ocs i think im a bit autistic 😭
I'll need some time to digest how this works haha
just for understanding purposes
Kim is very similar to Canio, just with built-in destroy
Sasha might be a bit complicated to implement
Otherwise neat, is Zach/Zoey a trans character?
Yeah lemme just get home, I'll implement it then
ya zoey is trans :3
Where do I even find something like this?
i also somehow forgot canio exists when thinking of kims ability
Source code of Balatro
You can access it by just unzipping the .exe
Iirc you can check the Immolate code, it checks if cards are glass to shatter them instead of dissolving them
oh wow
Or things like Stone Joker which should have a check for Stone cards
But this should work
This is how Stone Joker checks for stone cards in the deck
I though it just gives you 20$ to f off and thats all to it
lol
in terms of code
That's pretty much what it does, but the destroy code has an explicit check to shatter glass cards
Because Glass Joker and visual/sound effects I guess
Yep
Sorry, wasn't able to find much by searching but is there a template repo or getting started guide available somewhere?
Thank you!
I've got a pair of UI boxes, is there a way to send a variable output from one to another as an input?
works with custom enhancements too (but you need to specify the prefix)
Uhm... My flip animation doesn't look right. 🤔
How do i concat strings in Lua?
.. instead of +
okey
Change the set ability to be in an event and not delayed
my pc takes some time to take the screenshots so when i do it it ss my screen like 5 seconds sgo
Wouldnt this just go off only once and set turned_cards to 1 from 0 and thats it?
Uncommon or Rare?
No?
0.1%
I think it’s weak even as an uncommon
If 1 in 100 instead?
What is the rate of Polychrome when the wheel of F hit the 1 in 7?
If it hits the 1 in 4 a polychrome is 15%
Wait, when did it become 1 in 4?
I thought it was 1 in 7?
Edit: I just checked the wiki, it does say 1 in 4.
Hi chat, I have a question. By default, a negative to played cards gives +1 hand size?
Yes
Thx, I'm going to create jokers on negative cards.
So that make it 3.75% per WoF, or 1 in 26.67 chance.
I'll prob make mine 1 in 30.
But how can I tweak it so it would check your hand instead of deck?🤔
use G.hand.cards in brackets?
why in brackets?
What’s the effect again?
Turn all cards in hand into stone cards, earn 5$ for each turned
From a consumable?
immolate but bad 
local converted = 0
for _, handcard in pairs(G.hand.cards) do
if handcard.config.center_key ~= ‘m_stone’ then
— set to stone
converted = converted + 1
end
end
ease_dollars(converted * 5)
Like that
But obviously done properly and not types badly on mobile
Quotation marks will need changing thanks iOS
you can hold the ' key to get straight apostrophes
could've sworn we had a runner emoji
but this does work because reasons
For some reason game gives me 180$ ???
I overcooked this, did I
You iterate over G.hand.cards twice
i think you dont need the second for loop in there
since the first for loop already does what the second loop does, so its pretty unnecessary
Remove the outer for loop
And move the eternal check inside the second for loop
And change G.hand.cards[i] to handcard
local converted = 0
for i = 1, #G.hand.cards do
local other_card = G.hand.cards[i]
if not other_card.ability.eternal and other_card.config.center_key ~= 'm_stone' then
other_card:set_ability(G.P_CENTERS.m_stone)
converted = converted + 1
end
end
ease_dollars(converted * 5)
probably that
This version doesn't increment converted
oh yeah i forgot
(Also please indent your code)
im typing it on discord, and i didnt really want to manually space the lines out, so sorry 😭
You can use tab to add two spaces
And it works for indenting/unindenting multiple lines if you select multiple ones
thats new
Like this?
What causes cards to instantly transform before flipping?
local used_consumable = copier or card
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.hand.cards do
local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("card1", percent)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
local converted = 0
for _, handcard in pairs(G.hand.cards) do
if handcard.config.center_key ~= 'm_stone' and not handcard.ability.eternal then
handcard:set_ability(G.P_CENTERS.m_stone)
converted = converted + 1
end
end
ease_dollars(converted * 5)
for i = 1, #G.hand.cards do
local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("tarot2", percent, 0.6)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
end```
The event occurs after the delay but anything after occurs instantly
The set ability line remove the nil and true
the flip is delayed, but the set_ability isnt
the timing is like this, you can see how the cards will turn into stone immediately while others r delayed
why?
Isn't delay is just animation speed?
Well I tested it and it ran only once. I set ease dollars to the turned cards and it was giving me 1$
It doesn't seem to change anything.
no, delay is the time until next event can occur
resend your code
Wierd because I just recently played around with it and only thing it did was how fast cards were flipping
I already adjusted it multiple times it's not the same anymore:(
yes, the unflipping is the "next" event in this case
Wait so if I don't set ANY delay then the action would occur immediately and not in order?
if you send it again we may see what you are doing
You mean what I have now?
Here^^^
It seems correct, 40$ in total
Yeah, it's correct now
5$x8
^^^
thats the same thing
except not in an event so that might have been it
(ease dollars was not in one so it occurred before the count finished)
is everything working correctly now?
immediately, in order
is there a way to get the price of shop items like boosters packs and ect. as a value I can use elsewhere?
the default cost should be in G.P_CENTERS[object_key].cost and the current cost should be in object.cost
this is from the top of my head so it might be wrong
thanks
Can I make non-scoring cards be added to the scoring hand?
Yeah I want to add some actual smods side support for non scoring cards at some point
So?
Im not really sure how to input a delay here
if its an event I just use delay = 0.15
but what do I do here?
@violet void
You can do it with some lovey patches but there’s no supported methods for altering them right now, you can look how splash functions and inject into the same place
Put thet entire block inside an event
In which file is the function for Splash?
state events
like this?
And the ease dollars
hihi, how do you check if a card has a particular seal?
this code doesn't seem to worklua if context.individual and context.cardarea == G.hand and context.other_card.seal == "Blue" then if context.other_card.debuff then return { message = localize('k_debuffed'), colour = G.C.RED, card = card, } else return { x_mult = card.ability.extra.given_xmult, card = card } end end
I now get 180$ on use
if it's the same issue with other_card being garbage-collected i will cry 😭
Then you put it in the wrong place
oh shoot I put it inside the loop
my bad
Probably just the wrong key value for the seal, I don’t remember how vanilla seals are called
when i check to see if the added suit works everything does except for the name of the suit being error even though everything looks to be fine whe comparing it to SixSuits
key = 'Flowers',
card_key = 'FLOWER',
hc_atlas = 'cards',
lc_atlas = 'cards',
hc_ui_atlas = 'ui',
lc_ui_atlas = 'ui',
hc_colour = HEX('d020db'),
lc_colour = HEX('d020db'),
pos = { y = 0 },
ui_pos = { x = 0, y = 0 },
in_pool = allow_suits
}```
am I missing something?
made my best joker yet
HALLELUYA
thanks everyone for helping me out with this one
its basically a different ability for each tarot
juices up any tarot you hold
for example
it uses fool? two negative copies of your last tarot
🗣️
thats a ton of work for one effect
sounds very inappropriate in italian
wow
ikr but it's incredibly fun
i'm almost done with all the tarots
i need to do strenght and the suit changers
okay fixed it! just had to check for seals in the first place ^^
Isnt it a bit contradictory to Balo game desing philosophy?
(such complex effects)
well the effect basically is always what you expect of the tarot it uses
but buffed
Oh, so some sort of number amplification?
nice 👍🏽
perhaps you can prevent existing stone cards from flipping too
thats sounds straightfoward
mm no not really, more like a buffed version of their ability
oh no I just noticed
like emperor giving a mega arcana pack instead of just two random cards (still 2 cards, but now you have choice)
quick question, can the joker target modded tarot cards?
yes, but it would need to have compatibility code written for them to have an effect
nice
im thinking of having a list of the buffed effects somewhere, but i don't know where i would put it
could add the respective buffs to the tarots' tooltip
mm is there a way to have conditional tooltips?
like for them to appear only when you have the scopacane joker
ok thats perfect
is it possible to remove info queue
info queue i believe (the thingies that appear on the side of the cards, i haven't really used it before)
like the extra info they give you
you can put them in a conditional to show/not show them
not sure if you need take_ownership to affect vanilla tarots tho
-# if thats even a thing
i have no clue
im pretty sure you can edit vanilla tarots
You can just inject them
If you don’t want to take ownership
I’m guessing you already do though for your use effects?
you could create different cards with different art?
and then set those cards to never appear in the shop or elsewhere
no they're triggered by the joker itself
and then destroy one held tarot, and create one of your new cards
mmm you're saying to create a new set altogether
mhm
that would make sense
might be too much for one single joker
but that would be an insane amount of work
yea exactly
Oh I didn’t read the effect properly
Is it possible to give a card a cost that would be a random value chosen at the start of the run?
push, since I really have no clue how to fix the issue
ye you could hook Game:init_game_object() and add a randomized variable then just use that with your joker
Does that require a lovely patch?
i don't think soù
is there a way a joker can do multiple things?
this code doesn't work
if context.joker_main then
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
G.E_MANAGER:add_event(Event({
func = function()
return { mult = card.ability.extra.given_mult }
end}))
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
G.E_MANAGER:add_event(Event({
func = function()
return { x_mult = card.ability.extra.given_xmult }
end}))
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
G.E_MANAGER:add_event(Event({
func = function()
return { chips = card.ability.extra.given_chips }
end}))
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
ease_dollars(card.ability.extra.given_money)
G.E_MANAGER:add_event(Event({
func = function()
return {
message = localize('$')..card.ability.extra.given_money,
colour = G.C.MONEY,
delay = 0.45,
remove = true,
card = card
}
end,
}))
end
end```
(ignore the comma after the third-last end)
i was wrong, i think take_ownership does not work on vanilla tarots
you gotta do it all in one return
and you can't return calc from an event
create a table that you then add entries to using randomness
ooh okay!
money might be tougher, you might need a manual evaluation call
I'd recommend checking out how other money jokers do it
like rough gem
yeah you're just setting the fields but inside your if statements so you can split it up
happy to help
hmm, so Rough Gem does a return
anyone knows of any way to add info_queue to base game tarots?
should be grand
then try adding it to the table
mhm
I suppose lovely patches
hmm, so the money works, but not the other three
new code:
if context.joker_main then
local outcome = {}
local index = 1
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
outcome[index] = { mult = card.ability.extra.given_mult}
index = index + 1
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
outcome[index] = { mult = card.ability.extra.given_xmult}
index = index + 1
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
outcome[index] = { mult = card.ability.extra.given_chips}
index = index + 1
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
ease_dollars(card.ability.extra.given_money)
G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.given_money
G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)}))
outcome[index] = { dollars = G.GAME.dollar_buffer }
index = index + 1
end
return outcome
end```
Don't put them in an array, put them all in the same table
you're creating a table that looks like this
outcome = {
[1] = {mult = ...},
[2] = {mult = ...},
[3] = {dollars = ...},
}
outcome = {}
outcome.mult = card.ability.extra.given_mult
outcome.Xmult = card.ability.extra.given_xmult
outcome.chips = card.ability.extra.given_chips
outcome.dollars = card.ability.extra.given_money
cant you just use take ownership in this case?
The rest should be handled by SMODS, in particular messages and easing
Lua is extremely permissive
^^^ strongly typed programmer
Also arrays and tables are technically the same object like in JS
made a function to clean up a string
But to an even more extreme degree
It's so bad in Lua I'd argue it doesn't even have arrays lmao
just tables in a trench coat
exactly lmao
(And nothing prevents you from having one with both string and number keys)
(Which gets fun on whether you use ipairs or pairs to iterate it)
"would you like to shoot yourself in the foot" speedrun edition
Lua is definitely not my favorite language
But it works
And it's popular thanks to that permissivity
And the fact it's, at the end of the day, fairly easy to learn and doesn't have that many advanced stuff in it
Once you get metatables you basically have hit the skill ceiling of Lua in terms of language knowledge
imagine if someone can make c++ compatible with balatro somehow lol
where do i put lovely patches?
create a folder in your mod named "lovely"
then put it there
either lovely/<name>.toml or lovely.toml
they said it didnt work
oh i see
You can definitely take ownership of a tarot
@minor magnet
i tried, didn't work, did i mess something up?
it seems intuitive you could do it but it doesn't seem to work
Show code
used stone as a test since i havent made custom info_queues yet
I think the key should be a string too
Good catch
a question I have about taking ownership, what happens if multiple mods do that for the same item
life savers
Priority will determine the order
so is it always one who takes ownership or all of them
All of them
interesting