#💻・modding-dev
1 messages · Page 642 of 1
Yeah I think it’s catching itself
ah
Add a and context.card ~= card
okii
game is crashing when switching save files, never happened before i added a localization file to my mod
is there something i overlooked about how to load in loc files or something
localization files just need to be put in the correct folder with the correct structure, you don't need to load them or anything
what's the crash
are you sure it's not a problem with deck creator
something is trying to parse multi box descriptions as single box
seems like it is from the log
aw heck
so any recommendation for testing tools
i usually just use it to make a deck where you start with a joker i wanna test
debugplus
I screenshotted my message and didnt forward it because... idk
Ima eat dinner now, so i most likely wont respond immediately
how would i make a challenge's joker start with a modded sticker
how do pseudoseeds work how do i just get a random item from a table i'm looking at other mods' code for reference do i need to constantly change what pseudoseed i'm using? what do i even put in pseudoseed()
you dont need to use pseudoseed anymore, you can just put a plain string to any of the pseudorandom functions and itll automatically use pseudoseed
use pseudorandom_element(table, seed) to get a random table element
How do I check whether a card is in a pool in the function Card:set_cost() if I have a pool like this one
SMODS.ObjectType({
key = "Interest_Vouchers",
default = "v_seed_money",
cards = {
v_seed_money = true,
v_money_tree = true
}
})
(setting the cost to a voucher in another way would too be appreciated)
i notice that when i change the pixel_size of jokers they're no longer centered, do i need them to be in the top-left of their position in the atlas? or the center?
it would appear to be the case
if (self.config.center.pools or {}).Interest_Vouchers then
local scoring = {}
for _, card in pairs(hand) do
scoring[#scoring + 1] = card
end
return scoring
end,```
HOW TF DO I JUST MAKE ALL THE CARDS SCORE
return { hand }?
only first card scores
oh wait im just stupid
works now lol
ty
thing is thats not my actual code and i want only the specific cards in the hand to score
yo guys i'm kinda new to modding in general, i know some lua but it's difficult for me to find the variables i need to do certain things, i wanted to make a simple joker: each stone cart discarded gives +3 to mult
calculate = function(self, card, context)
if context.on_discard_card then
if card.base and card.base.type == 'STONE' then
context.mult = (context.mult or 0) + card.ability.extra.mult
return {
message = 'Upgraded!',
color = G.C.RED
}
end
if context.joker_main then
return {
mult = card.ability.extra.mult
}
end
end
end
i tried a lot of things and this is the one that got me the nearest
it just needs to be a table of all card combinations
idk how that got you nearest because on_discard_card and base.type don't exist afaik
it doesnt
your base mult might be 3 already so the joker_main part is scoring
anyway have you checked green joker
oh damn thanks, i was searching for this type of snippets
you would move what's in context.before to the discard part
the base problem was that i couldn't find the right variables from the source code
thanks
that's why i made that repo ;3
you can also check stone joker for the stone card part
I edited the low contrast deck version sprites, how can I edit the high constrast version now?
i have no idea with that format, i would recommend switching to the modern way of doing this
https://github.com/Steamodded/examples/tree/master/Mods/DeckSkinTemplate
random question
where the fuck is the documentation for smods.font
Can you help me with it? I want to change the face cards plus Ace sprites in both low and high contrast versions. I have the pngs already I just didn´t understand what to do with the code.
there isn't one merged but there's one in the wiki PRs iirc
i dont have much idea about this, i would recommend just changing the images in that repository
there s no deck pngs tho, its just icons and numbers
the numbers are the cards
uh is there any video or step by step documentation for each command? the smods one is a bit chaotic
not really
there's a video but it's kinda outdated and basic
damn, alr maybe this is a rushed start. What si the most basic thing i can make? Simple +4 joker?
yeah
let's roll
should'nt this work? its not working
you're only defining the atlas objects there, not the skin
whats an atlas object
im trying to think how to do it with those hints
or will you get mad if I didnt understand what im supposed to do?
i literally sent you the code 😭
ohhh
you're missing this part
https://github.com/Steamodded/examples/blob/d43316d97bc927f3de431dd84c0283d41e69761a/Mods/DeckSkinTemplate/DeckSkinTemplate.lua#L29
remove the 3 suit_icon lines if you're not going to use icons
Is there somewhere to find the ids of every vanilla joker? I tried looking on the wiki but can't find anything
maybe they re id are they number?
i mean keys mb
that also works ig
Ik what you did
I think
Where it says atlas = atlas_lc.key
Shouldn’t it be the key of your lc atlas
ty!!!!!!
that's what atlas_lc.key is
did you check the friends of jimbo menu
Well I suck at Lua then lol
yep
that's the same thing here yeah
no clue then
check hearts
yeah the "Spades", ... is not going to do anything
The primate way was working LOL 😭
i remove it? i Added it
yeah
let me test stuff myself
oh where is this file
do you have a .json
you need to add that
and copy paste the lua stuff?
check the one in the repository
aight
no its a different thing
Does its name needs to be DeckSkinTemplate?
i can be whatever you want, usually the name of the mod
check if it loads now, you should see it in the mod menu
oh wait
i didnt even tried to check the mods menu, i thought i was modifying the game's files itself 😭
Ima name it my mod name now, right?
uhh it has an error it seems
ah yeah the main_file should point to your lua
that's good it means it loaded
yeah theres a syntax error somewhere
is it the same crash
aight
these
That is what code is like
Then you realise you missed like one letter or something and it just works
Which is why I love code
lmao
you're missing a } before SMODS.DeckSkin
with space?
not necessary
Ohh yeah i see
What did I say
😭
what not using a code editor does to someone
LMAO
again, check hearts
not there too
yeah it's probably going to be the wrong one
so this adds a deck instead of retexturing it?
yeah
Ok, well that’s good that it works
Only in hearts tho
now you need to add an SMODS.DeckSkin for each suit
When you create a seal, where is the calculate function stored? Can't find it in shared_seals or SMODS.Seals.
yes
any of SMODS.Seals, SMODS.Seal.obj_buffer or G.P_SEALS
it should be in SMODS.Seals.key.calculate
SMODS.Seal.obj_buffer is number indexed though so probably dont use that
i added the different suits
not showing
am I doing smoething wrong?
Ok thanks!
ok now i understand somethings, i did some base jokers tests and the all worked, now I just need to get the enhanchment thing
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.m_stone
return {vars = {card.ability.extra.d_mult, card.ability.extra.h_mult}}
end,
--I DID THIS BASICALLY RANDOM
calculate = function(self, card, context)
if context.discard and SMODS.has_enhancement(playing_card, 'm_stone') then
return {
d_mult = card.ability.extra.d_mult,
}
end
end,
give it a different key
like what? the same key for every suit?
oh wait
make it like this?
liek key = "example" should be different for each
key1 for hearts. key2 for spades etc...
okay got it
done
got it
all working
dont ask lol
what if I want to change the rest of the deck what do I add to the code? (Ace card)
i think the code already changes all the cards
oh okay
but its set to show the face cards in the preview
so just editing the texture?
yeah
I know some mods can change what ante the game is won at, is there a way to make a blind unable to appear in the ante before the final one (even if a mod changes what that is)
Would it be possible to make a joker trigger when a playing card is modified? The closest I can find is when a consumable card is used, but that wouldn't apply when, for example, midas mask or vampire modify a card
i think that's the default for showdowns but im not sure
there's context.setting_ability for enhancements
for the rest of the modifications you need hooks i think
I can only edit badge colour in the json file
I only want it to not appear in the ante exactly one below the final ante (including if that value is changed), it should be able to appear in every other non-showdown ante
The specific one I'm looking at is any suit change, so I'll look into using hooks, thank you
thanks
ah
hmm you can just check the ante in in_pool then
in assets? the png file
ah wait no, there's a context for modifying suits
check the wiki i dont recall the name
right now I've got this:
in_pool = function(self)
local ante = G.GAME.round_resets.ante
if G.GAME.round_resets.ante = 7 or G.GAME.round_resets.ante <= 2 then
return false
else
return true
end
end
which would work in most situations, but if the final ante is changed, it obviously wouldn't change that
pretty much, I just need that minus 1
G.GAME.win_ante
I'm having trouble finding this, do you mean the balatromodded wiki or balatrowiki?
ah awesome thanks, I'll test it out
how do i make a suitless rank
(can form 3oak, but not flushes)
Ah, a third wiki, thank you !
this should be your main one
I even have that one open but I didn't think of it as a wiki
I guess it's just github in my mind first
I am pretty new to this
the steamodded wiki is so unhelpful sometimes ;-;
no idea but you can check Aikoyori's mod, it has that
aight
Ok now the things changed, 2 problems:
1 - Sometimes crashes when cards are pulled from deck (probably cause of enhancement)
2- The stone discard activates but crashes the game whenever an enhanced card is discarded (any enhance)
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.m_stone
return {vars = {card.ability.extra.d_mult, card.ability.extra.h_mult}}
end,
--I DID THIS BASICALLY RANDOM
calculate = function(self, card, context)
if context.discard and SMODS.has_enhancement(playing_card, 'm_stone') then
return {
d_mult = card.ability.extra.d_mult,
}
end
end,
playing_card is nothing
where do i declare it?
i tought that the variables names in loc_vars didn't matter, my bad
oh ok, ty
here's is an example of how to scale a card
https://github.com/Steamodded/smods/wiki/Calculate-Functions#step-2-logiceffects
how do you hook a function but like put something in the middle of it
It works, thanks man
lovely patches
are they as hard to make as they look
no formatting is literally going to kill me
everything is the same colour
well if you need highlights just code in the dump and then move it to a patch
guys, may I ask for new help?
local xiferp_up_another_step = SMODS.poll_enhancement({guaranteed = true, type_key = 'shuffletheseed'})
card:set_ability(xiferp_up_another_step, nil, true)
end```
This isn't enhancing any cards
SMODS.Consumable {
key = "flynnine",
set = "xiferp_Element",
atlas = "Golden_Brick_Road",
cost = 3,
pos = { x = 14, y = 6 },
unlocked = true,
discovered = true,
config = { extra = { element_no = 103, odds = 3, yes_is_no = false }},
keep_on_use = function(self, card)
return true
end,
can_use = function(self, card)
if card.ability.extra.yes_is_no == false then
return true
end
end,
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 2, card.ability.extra.odds, 'c_xiferp_flynnine')
return { vars = { numerator, denominator } }
end,
use = function(self, card, area)
card.ability.extra.yes_is_no = true
end,
loc_txt = {
name = 'Flynnine',
text = {
'Adds x5 mult to your next hand',
'and enhances all held cards',
'(2/3 chance to radioactively decay)',
},
},
calculate = function(self, card, context)
if card.ability.extra.yes_is_no == true then
if context.individual and context.cardarea == G.play then
G.GAME.xiferp_rowseven_xmult = (G.GAME.xiferp_rowseven_xmult or 0) + 5
SMODS.destroy_cards(card, nil, nil, true)
for _, card in ipairs(G.hand.cards) do
local xiferp_up_another_step = SMODS.poll_enhancement({guaranteed = true, type_key = 'shuffletheseed'})
card:set_ability(xiferp_up_another_step, nil, true)
end
end
end
if context.individual and context.cardarea == G.play then
if SMODS.pseudorandom_probability(card, 'c_xiferp_flynnine', 2, card.ability.extra.odds) then
SMODS.destroy_cards(card, nil, nil, true)
SMODS.add_card({ key = 'c_xiferp_xenon' })
end
end
end
}```
here is it in context
you should probably check card.ability.extra.yes_is_no after checking for context.individual
i dont see any issues with the snippet though, make sure the code is being reached in the first place with a print or something
thank you
also oops won't affect your joker's description (still affects the chance)
+the description is unclear about when that chance is rolled
doesn't seem to work
by that do you mean the code isnt being reached?
code's not reached, yea
check if the destroying code is reached
also the timing at which it enhances is a little weird?
me personally id put it in context.before
wait no thats held in hand nvm
this would still have issues with something like cryptid's None though so i still recommend using context.before
how does a vanilla blind debuff a card
SMODS.Blind {
key = "club",
dollars = 5,
mult = 2,
debuff = { suit = "Clubs" },
pos = { x = 0, y = 4 },
boss = { min = 1 },
boss_colour = HEX("b9cb92")
}```
Here's how the boss blind "The Club" does it
why do you care about vanilla implementations we have smods
what function does a vanilla blind use to debuff a card
how do you change ante scaling on a specific deck?
alter G.GAME.modifiers.scaling (its what Green and Purple stake use)
alright
both stakes increase it by 1
so card:set_debuff...
yes
I have an error in the following line:
G.GAME.card.Joker.display_size.h = 0.7 * G.GAME.card.Joker.display_size.h
It's supposed to squash all jokers by 70%
because that line is non sensical
Well, how would I do it?
dunno
id hook update
the line's supposed to read the joker's display size and shrink it like how the Wee Joker does it
if whatever condition is satisfied loop through G.I.CARD every frame and squash every unflagged card, then add a flag to the card so you dont further squash it next frame
G.GAME.xiferp_lineseven_xmult = (G.GAME.xiferp_lineseven_xmult or 0) + 5
G.E_MANAGER:add_event(Event({
trigger = 'after',
func = function()
G.GAME.card.Joker.display_size.h = 0.7 * G.GAME.card.Joker.display_size.h
return true
end
}))
end,```
Here's the line's context
can i ask why your xmult scaling starts at 0
whats with the G.GAME.xiferp_lineseven_xmult or 0 defaulting to 0 then
copy-paste thing
in the event you would want to set a flag in G.GAME
then hook update and check for it every frame: if its true, loop through G.I.CARD and squash every unflagged card, then add a flag to the card so you dont further squash it next frame
also check to make sure the card is a joker
Anything a bit simpler? One that just starts with the jokers?
i mean theoretically you could loop through G.I.CARD in the event if you dont want it to apply to any future jokers
but also i dont think any of that is that complicated? G.I.CARD is a table containing every currently visible card
you have to loop through it with pairs
huh
i should just set it to like 0.smth then right
"Steamodded (>=1.0.0~BETA)" i think
i just set it to the exact one "Steamodded (>=1.0.0~BETA-0624a)"
ok it's working now
how do you make blinds "score at least as low as:"
what do you mean
like blind requirement is -300
and you need to score that much or lower
Assuming you already have a way to decrease score, probably just make the blind itself compare scores and trigger a win if it's correct
I think it has a calculate function
ive been having trouble getting these consumables to appear correctly
they are 64 x 64 pixel squares but ive tried setting their px and py, defining pixel size and display size, and theyre always stretched into the default dimensions
does changing these values work for consumables or just jokers?
(spoilers for blue prince)
I'd imagine spacing them out in your atlas while pretending they're the size of normal joker cards (71*95) would work
though I guess they'd be off-centre
that works!
i just moved them to be in the center
i guess the only issue is you can still grab it from that 71 x 95 zone but im ok with that for now
alright pixel_size fixed that issue huzzah
i don't have can use set, why isnt it usable?
answered your own question
you don't have a can use function
i was out here thinking it would just be usable at any time
how should use select card as a function anyway
i got a attempt to compare number with table on
if G.GAME.hands[G.handlist[i]].level > 0 and G.handlist[i] ~= card.config.extra.poker_hand then
wait
to_big(G.GAME.hands[G.handlist[i]].level) > to_big(0)
you only need field select_card = CardArea
im trying to prevent a situation where you use it but the targeted hand isnt visible yet
what are you trying to do
trying to make a legendary consumable that sacrifices everything in exchange for supercharging a poker hand
doesnt matter because i got wrong number of arguments to insert over
table.insert{todestroy, G.playing_cards[i]}
that does "everything" mean in this context
Aka. "Dying Neutron Star"
Trades all your enhanced cards, jokers, and hand levels for levels on a hand determined the moment the card generates.```
wait a mminute
-# that was another bug, still at large is the main elephant in the room
you wrapped the values in curvy brackets, not regular ones
lua treats that as a single table
i feel like the entire circus rn.
why does times negative 1 no llonger work for flipping
you need to multiply harder
atp ima just use the method that works every time
y'all is there an easier way to do custom boxes for tooltips?
because istg having to define them from scratch, then hook UIE functions to see the custom tooltip just feels off
yea
in localization, do this
return {
descriptions = {
...
Other = {
custom_tooltip = {
name = "Something",
text = {
"This is a custom tooltip"
}
},
...
and then in the loc_vars function for the object you want the custom tooltip, do this
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = { set = "Other", key = "custom_tooltip" }
...
end
the key of the tooltip doesn't require a mod prefix but it's probably a good idea to set it anyway
do you guys know a good way to stack cards in a cardarea vertically?
ah - not quite what i mean, apologies. I mean doing smth like this
a
my bad lol
yea idk balatro ui is jank
you ever pour your heart and soul into a feature and forget to do micro-commits?
how do i use timers
edit: I figured it out
I forget the exact reasoning but iirc it's because it would require Thunk to endorse a third-party modding library which he does not want to do
ur wrong, it works now it was just a typo in my code
ah no worries haha ^^
I assumed you saw my pre-edited message somehow
Looking for ideas of twitch commands for the twitch mod if you could have the ability to control a streamers run what would you want to control
give the player a random negative, eternal, rental joker, it would be funny if it was just jimbo too
Had an idea for a random joker command
So yeah might do that instead
My favorite working command so far is the fake soul card
Gives you a soul that just makes a fart sound
And says pranked

A more ragebait version of the Win tarot from Yahimod
Love it.
another silly one, if in a shop, forces them to move on, if selecting a blind, forces them to skip it, if in a blind, forces them to play a hand
Anyways, code no work and don't know why. No crash or anything.
Can u show the whole code
I'm not very smort but I think I might know
If not someone will correct me
Xmult_mod and Xchips_mod needs to be a config value or apart of a message
depends on your goal
Just do the xChips and xMult as determined in the config
Ok, now it's saying xnil. What is wrong with it where it's not triggering?
and it's not the Xmult_mod needing to be in a config, there are other Jokers in my mod that use the same method to do xMult
I think I know this what does the very top of the code look like
Had very similar thing when working on the monkey joker
I think xchips_mod should just be x_chips
Same for xmult_mod
If I'm not mistaken
I'm still learning this stuff as I go but I think that's how I fixed mine
You need a context check.
do I need to chuck context.joker_main in?
Yes, that would replace context.cardarea == G.play
The legend has drooped in 
Yeah, still not triggering at all.
you're not returning
this is acrobat form vanillaremade, this should be a good example
I was looking at Dusk. I forgot Acrobat even existed, that would have been faster.
lol
How is this not triggering? I'm wasting all my hands except the last one and nothing.
reread the structure of this
check what it is returning
Oh my god. I just checked the return.
I am terrified of people who code with non-monospaced fonts
It is a hell.
FINALLY WORKS
When does set_sprites gets called?
And is front in set_sprites(self, card, front) a bool
I figured it out
Seems like front is not bool
how do you check for a specific deck? i do this but it doesnt seem to work
no errors btw, it just does nothing
the key should be b_[mod prefix]_[deck key]
im so smart and intelligent how do i keep on forgetting this
your inteligence is taking up too much space in your brain, you have to become stupid to remeber /j
nope still nothing
i took these patches from VR and replaced the next(smods.find_card()) parts with IsEffectDeck
use the mod prefix
wait no I cant read
excuse my dumbassery
wait
how does vr smeared joker work?
it does this but i dont see it patch the actual smeared_check
and the smeared_check fails automatically because it doesnt have the actual smeared joker
or wait does find_joker just do it by name and im stupid
Yes, but VanillaRemade Smeared Joker doesn't have name set.
Does anyone know how to force skip a pack?
I admire your persistence on these
is it possible to make jokers take up 2 slots?
because i tried incrementing all joker values and it seems to have made the jokers take up 2 slots
yes, card.ability.extra_slots_used
ty
How to add your own poker hands
Like a poker hand named junk which is half a high card score
i did e_bootleg and ttv_e_bootleg
and keep getting this crash telling me i'm missing the e_ prefix
Is there a built in functions for selecting and deselecting a card?
slightly updated
but this probably what i'm going for when I mentioned the idea of temu jokers
card.area:add_to_highlighted(card) and card.area:remove_from_highlighted(card)
im trying to make an idol-like joker but for some reason it's crashing when i hover over it in my collection while a run is open, and not outside of it
{
key = "search_and_find",
atlas = "jokers",
pos = {
x = 5,
y = 2
},
unlocked = true,
discovered = false,
rarity = 1, -- Common
cost = 6,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
-------------------------
loc_vars = function(self, info_queue, card)
return {
vars = {
localize(G.GAME.current_round.j_o_y_search_find_card.rank, "ranks"),
localize(G.GAME.current_round.j_o_y_search_find_card.suit, "suits_plural"),
colours = { G.C.SUITS[G.GAME.current_round.j_o_y_search_find_card.suit] }
}
}
end,
calculate = function(self, card, context)
end
}
-- im gonna be real this is mostly just copy-pasted code, i have a decent understanding on how it works tho
-- here i save this game function so i dont completely overwrite it
local igo = Game.init_game_object
--we make a new function with the same name that will run the old function
function Game:init_game_object()
-- this is where the old function is run, any code before or after it will "add" that code to it
local ret = igo(self)
ret.current_round.j_o_y_search_find_card = { rank = "Ace", suit = "Spades" }
return ret
end
-- and this is where the card's rank and suit to find changes between runs and rounds like Idol does, no need to put it inside the SMODS.Joker
function SMODS.current_mod.reset_game_globals(run_start)
G.GAME.current_round.j_o_y_search_find_card = { rank = "Ace", suit = "Spades" }
local valid_saf_cards = {}
for _, v in ipairs(G.playing_cards) do
if not SMODS.has_no_suit(v) and not SMODS.has_no_rank(v) then
valid_saf_cards[#valid_saf_cards + 1] = v
end
end
if valid_saf_cards[1] then
local saf_card = pseudorandom_element(valid_saf_cards, pseudoseed("j_o_y_search_and_find"))
G.GAME.current_round.j_o_y_search_find_card.rank = saf_card.base.rank
G.GAME.current_round.j_o_y_search_find_card.suit = saf_card.base.suit
end
end```
i followed it exactly as it tells me in ExampleMods
the answer is that it wasn't there when I wrote the code, and i never noticed it changed
https://github.com/Steamodded/smods/commit/b2f59512e9878f316e3da48338200cf7072af2c3
i dont like this change because you can't hook the function but whatever
i dont really see the issue but you can check the implementation in vanillaremade to compare
i did some things different that i didn't like in the examples
how important is appending G.GAME.round_resets.ante to the seed btw?
ah i think i see what went wrong
not very in terms of making it work but it is good for randomization and not being able to manipulate the rng
G.FUNCS.skip_booster()
ehh, I tried like that, right after the open() with skip_booster(e) or end_consumeable(...), but to no avail. I achieved my desired functionality with dissolving the cards in the pack right after they emplace (it forces the player to manually skip, and I am ok with that)
that was way more helpful, thank you
this works for me
ooh, manager, ofc
made an accidental discovery
ghost card
happens when there are 2 or more references to the same card
that face-down darkened card is supposed to be in deck, not drawn yet, and way below
or in discard pile
but the second reference forces the card to be in hand
thus it tells Lua to "draw" (both ways!) the card to hand, with its state still intact
randomly my mod is crashing at line 8 and line 14 in my current code
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95,
}
SMODS.Joker{
key = 'mrsexy',
loc_txt = {
name = 'Mr. Sexy',
text = {"{C:blue,s:1.1}+#1#{} Chips"}
}
atlas = 'Jokers',
rarity = 1,
cost = 2,
unlocked = true,
discovered = true,
blueprint_compat = true,
perishable_compat = false,
pos = {x=0, y=0},
config = {extra = { chips = 69}},
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.chips}}
end,
calculate = function(self, card, context)
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
end,
}
it should be:
SMODS.Joker = {
wtf because when i made it like 6 months ago it worked without it
nope still same errors
and is the name of your image for jokers called Jokers.png
oh...
yes it is but i dont have it in my folder yet
you need it in your mod
it is looking for Jokers.png
if that isnt in your mod
well... I dont think I need to explain
it crashes after having the image in my folder
Do you have it in a 1x and 2x folder
local RanJoker = {"j_gros_michel", "j_egg", "j_ice_cream", "j_diet_cola"}
local RanSelect = math.random(#RanJoker)
local RanCreate = RanJoker[RanSelect]
if is_on_cooldown then
math.randomseed(os.time())
if G.STAGE ~= G.STAGES.RUN or not G.GAME then return end
local card = SMODS.add_card({key = RanCreate})
card:add_to_deck()
end
end```
which both of those folders being in an assets folder
or is just manually adding the jokers the best way lmao
ah ok
hmmm
i have this as my loading main file:
SMODS.load_file("src/jokers.lua")()
SMODS.load_file("src/pokerhands.lua")()
also is there like a list of every j_ name
so I don't have to dig through balatros lua to find them all
????
Wait wha
you might as well do G = nil
Mb
its my formatting that is wrong
you were missing a comma
where
there
@red flower can you please send me a layout template
when i add it is still give me the error
can i see your current code
there are a couple of problems: math.random doesnt respect seeds and add_card already does add_to_deck so you're doing it twice
local random_joker_key = pseudorandom_element({"j_gros_michel", "j_egg", "j_ice_cream", "j_diet_cola"}, "seed")
SMODS.add_card{key = random_joker_key}
you can also make a pool and use that as the set for add_card, there's an example in vremade wiki of how to make a pool with food jokers
my current code is fixed
well the plan is to make any joker havea chance
if i'm making a pool does it really matter
i just didnt copy it from where its located
i dont understand the question
working on a command that can pick any joker in the game to spawn
i have a 2x png that is unsupported lmao
SMODS.add_card{set = "Joker"}?
didn't work crashed the game
seems making a table is the way to go lol
post the log, this is literally a basic command lol
functions/common_events.lua:2172: bad argument #1 to 'ipairs' (table expected, got nil)
Development version of Steamodded detected! If you are not actively developing a mod, please try using the latest release instead.
Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-1229a-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.8.0
Platform: Windows
Steamodded Mods:
1: Twitch Integration by chowder908, JackMacWindows, Mossloth [ID: twitchintegration, Version: 1.0.0]
2: DebugPlus by WilsontheWolf [ID: DebugPlus, Version: 1.5.1, Uses Lovely]
3: SystemClock by Breezebuilder [ID: SystemClock, Priority: 100000, Version: 1.7.1, Uses Lovely]
4: JokerDisplay by nh6574 [ID: JokerDisplay, Priority: -1000000000, Version: 1.8.8.5]
Lovely Mods:
Stack Traceback
===============
(3) LÖVE function at file 'boot.lua:352' (best guess)
Local variables:
errhand = Lua function '(LÖVE Function)' (defined at line 605 of chunk [lovely debugplus.console "debugplus/console.lua"])
handler = Lua function '(LÖVE Function)' (defined at line 605 of chunk [lovely debugplus.console "debugplus/console.lua"])
(4) global C function 'ipairs'
(5) Lua global 'get_current_pool' at file 'functions/common_events.lua:2172'
Local variables:
_type = string: "joker"
_rarity = nil
_legendary = nil
_append = nil
_pool = table: 0x13b9a628 {}
_starting_pool = nil
_pool_key = string: "joker"
_pool_size = number: 0
(6) Lua global 'create_card' at file 'functions/common_events.lua:2338'
Local variables:
_type = string: "joker"
area = nil
legendary = nil
_rarity = nil
skip_materialize = nil
soulable = nil
forced_key = nil
key_append = nil
area = table: 0x03ea29a8 {click_offset:table: 0x0b2d5c58, static_rotation:false, shuffle_amt:0, T:table: 0x13a273c8, offset:table: 0x03e9a278, role:table: 0x03cd19d8, last_aligned:-1 (more...)}
center = table: 0x04533b10 {order:1, _d:true, set:Back, stake:1, key:b_red, discovered:true, alerted:true, pos:table: 0x04533c00, unlocked:true, _u:true, _discovered_unlocked_overwritten:true (more...)}
(7) Lua field 'create_card' at Steamodded file 'src/utils.lua:383'
Local variables:
t = table: 0x13b9a5c8 {set:joker}
(8) Lua field 'add_card' at Steamodded file 'src/utils.lua:405'
Local variables:
t = table: 0x13b9a5c8 {set:joker}
(9) Lua function '?' at file 'commands.lua:196' (from mod with id twitchintegration) (best guess)
Local variables:
modifier = string: ""
RanEdit = table: 0x13b9a558 {1:nil, 2:e_foil, 3:e_polychrome, 4:e_holo, 5:e_negative}
RanSelect2 = number: 4
RanCreate2 = string: "e_holo"
(10) Lua method 'update' at file 'main.lua:118' (from mod with id twitchintegration)
Local variables:
self = table: 0x03ace6b0 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x0e89e888, F_ENGLISH_ONLY:false, viewed_stake:8, HUD:table: 0x0e806690 (more...)}
dt = number: 0.00606091
line = string: ":chowder9o8!chowder9o8@chowder9o8.tmi.twitch.tv PRIVMSG #chowder9o8 :!randomjoker"
err = nil
user = string: "chowder9o8"
msg = string: "!randomjoker"
command = string: "randomjoker"
arg = string: ""
(11) Lua field 'update' at file 'main.lua:1011'
Local variables:
dt = number: 0.00606091
(12) Lua function '?' at file 'main.lua:950' (best guess)
(13) global C function 'xpcall'
(14) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 921 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])```
Joker uppercase
I got the editions working
I just need to figure out how to havea chance at it being a normal joker
jokers added thorugh that command already have a chance for editions btw
you dont need to add them
oh
this is why it's imporant to look at documentation before you try things lol
I'm a if it works it works guy
"As long as it works"
🧨
if is_on_cooldown then
math.randomseed(os.time())
if G.STAGE ~= G.STAGES.RUN or not G.GAME then return end
end
local card = SMODS.add_card{set = 'Joker'}
card:add_to_deck()
card:juice_up(0.3, 0.5)
play_sound('card1', 1)
end```
well i dont agree with that philosophy
stop doing add_to_deck!!
SMODS.add_card{set = "Joker"} isn't really random sadly
it just creates the next card in seed
it's only random if u never play a seeded run
I guess it can work for now then whenever I get free time i'll figure something out
it gives the joker you type after the =
so if you type baron it will give you baron
the point of the command is to be a random joker given to u
idk how
i havent tried making that
well using the table i made from the original version is actually random
then use it if you can convert it to smods
add a key_append
if you want it truly random then yeah you can use math.random
I mean this is ok for now
like I said i'll probably swap back to table method later
well it's still random
enough
it's just the randomness is seed just like the joker pool
but the jokers aren't the same in the shop so it's good
you can give it a key_append based on the time for more randomness
i had made a reverse tooth blind as joker before i lost my mod progress i had made
it had knave which basically was a baron for jacks, while i had made a baron but instead of 1.5x mult for kings it gave +1.5 mult
i don't remember if this is the way to do itlua if context.post_joker or (context.main_scoring and context.cardarea == G.play) then return { hypermult = {self.config.hyper, self.config.mult} } end
for an edition
looks fine to me
why does none of my stuff work
you dont believe in it
you have to believe in the heart of the cards
ok uh chat
i have no idea how to make this sticker a reality
SMODS.Sticker {
key = "burdened",
badge_colour = HEX '3abd4c',
pos = { x = 0, y = 0 },
atlas = 'CustomStickers',
should_apply = function(self, card, center, area, bypass_roll)
return G.GAME.modifiers.enable_burden_in_shop and card.config.center.burden_compat
end,
}
local smods_is_eternal_ref = SMODS.is_eternal
function SMODS.is_eternal(card, trigger)
return card.ability.vremade_eternal or smods_is_eternal_ref(card, trigger)
end
this is the code i got from the eternal stickers thing
and i edited some of it to have "burden"
but like
i dont know what i am doing
afaik thee stickers must be defined somewhere else
maybe i apply some sort of hook?
the role is this: every burdened joker takes up 2 joker slots instead of 1
you should start by cutting the eternal ref
you just need an apply function in the sticker to set extra_slots_used
here's the code I wrote for a sticker in starspace that does the exact same thing
when apply is called with val set to true, it's applying the sticker, and with val set to false, it's removing it
oke, ill give that a shot later
yeah im getting rid of that
why is the c_base check there? is it for the collection or something else
ya the outer if statement just skips the extra_slots_used stuff if it's being applied to a dummy card in the collection, because the tooltip that smods adds ends up being treated as the card's primary description instead of the sticker's tooltip
oh thats weird
I'd love to actually fix that but idk where to start in terms of the code for that
ideally thered just be a way to suppress the tooltip
or at least some amount of it, so if a different source adds some itll still show
true but in general I'd like to be able to have other tooltips
like if there was a sticker in entropy that did something with ascension power, I'd like the ascension power tutorial tooltip to pop up in the collection without also clobbering the sticker tooltip
true
oh also I just remembered
I was looking at morefluff code recently and I think colour cards could do with an smods.consumable:extend to define some common behavior. would make crossmod colour cards far less tedious
oh yeah thatd probably be a decent idea
I can probably write up a PR for that if you'd like
thatd be lovely
Last night I discovered Tags do not have sprite manipulation and it makes me sad 😭
like for animation?
No, like for changing sprites on the fly
why does my cards dont show ?
For whatever reason Tags make their sprites and add functions to them on the fly instead of drawing thru update
local ovch = {}
for k, i in pairs(SMODS.Stickers) do
if Giga.is_overcharge(k) then
ovch[k] = i
end
end
return SMODS.card_collection_UIBox(ovch, { 5, 5 }, {
snap_back = true,
hide_single_page = true,
collapse_single_page = true,
center = 'c_base',
h_mod = 1.18,
back_func = 'your_collection_other_gameobjects',
modify_card = function(card, center)
card.ignore_pinned = true
center:apply(card, true)
end
})
end
G.FUNCS.your_collection_giga_overcharges = function()
G.SETTINGS.paused = true
G.FUNCS.overlay_menu {
definition = ovch_ui_collection()
}
end
local function wrap_without_overcharges(func)
local dump = {}
for k, i in pairs(SMODS.Stickers) do
if Giga.is_overcharge(k) then
dump[k] = i
SMODS.Stickers[k] = nil
end
end
local ret = func()
for k, i in pairs(dump) do
SMODS.Stickers[k] = i
end
return ret
end
local stickers_ui_ref = create_UIBox_your_collection_stickers
create_UIBox_your_collection_stickers = function()
return wrap_without_overcharges(stickers_ui_ref)
end
local other_objects_ref = create_UIBox_Other_GameObjects
create_UIBox_Other_GameObjects = function()
return wrap_without_overcharges(other_objects_ref)
end``` heres the code
what does Giga.is_overcharge do
this looks very similar to the code that paperback uses to give paperclips their own category and hide them from the stickers category, so yes I assume the issue is with that function's behavior
I have two questions. Just got into modding today and need a teensy help already (big surprise, I know).
- How do I import Steammodded into Visual Studio so I can see the functions?
- How come the description text doesn't show "X10" and instead only shows "X"? (I mean for the bottom line of text, not the temp text)
there should be a lsp def folder in your smods folder
if there is, copy and paste it into your workspace
also, make the last x on that line another #
oh, whoops
I.... don't understand
im not very technical when it comes to file formatting and such
im trying to go over to Visual Studio for this reason
i switched over to it, Im just not familiar with how VS works either
youll first want to open the folder of your mod in File > open folder
so you just see everything
well you have your folder open so now you should see all the contents of the mod folder on the left
youll probably want to install the lua extension by sumneko from the extensions tab too
alright, done and done
then you should hit F1 and search for Preferences: Open Workspace Settings (JSON)
and in the file it will create you should add the code snippet in the link i sent
youll then just want to replace the two file paths with the actual steamodded and lovely dump file paths
so just open up file explorer, go to those folders and then copy the file path from the top into the settings file
if youre on windows youll have to replace all the slashes because it uses backslashes in file paths for some reason
if you did it right it should eventually show SMODS and balatro functions
Its is checking if the card has an overcharge its like a new thing that can be add on a card
could you post the code for the function
@keen atlas why does frost utils cause like half the lovely dump to stop dumping
actually i should probably test frost utils on its own before i pin the blame on it, i was using it in a big modpack for reasons
it loads the prepatched version for most of vanilla files so it doesn't get patched afterwards
except for when it's patching due to empty cache / modified modlist
the dump is there
ahh ok
it's a bit inconvenient tbh, but i can just disable the mod for debugging and whatnot
how would i adapt my legendary jokers in shop code to uhhh not do this
-- 1 in 20 chance for shop Jokers to be Legendary
local gcp_hook = get_current_pool
function get_current_pool(_type, _rarity, _legendary, _append)
if #SMODS.find_card("v_elle_breakthrough")>0 and _type == 'Joker' and _append == 'sho' and pseudorandom('ellerar'..G.GAME.round_resets.ante.._append, 1, 20)==1 then _legendary = true end
return gcp_hook(_type, _rarity, _legendary, _append)
end```
what does the code look like tho?
it could be the issue since the ui seems to be working
When hovering over a deck like Magic or Zodiac, certain UI boxes appear referring to the vouchers/tarots. Does anyone know how to achieve such boxes in a custom deck?
thanks
this is gonna sound really really really stupid so bare with me here, if i'm on jokerforge, how would i make a joker that resets its mult at end of round? i know i'm missing something obvious.
i'm a novice doing this for the first time
you should probably ask the joker forge thread or discord for this
i wonder who that is
im pretty sure familiar is a spectral card
why does this crash
local edition = G.P_CENTERS["e_MDJ_corrupted"]
local aura_card = G.jokers.highlighted[i]
aura_card:set_edition(edition, true)
---@param key string
---@return boolean
function Giga.is_overcharge(key)
for i, _ in ipairs(Giga.POOLS.Overcharges) do
if i == key then
return true
end
end
return false
end
--- Check if a card has an overcharge.
---@param card table
---@return string | nil
function Giga.has_overcharge(card)
for i, k in pairs(card and card.ability or {}) do
if Giga.is_overcharge(i) then
return i
end
end
return nil
end
--- Delete overcherge on a card
---@param card table
function Giga.delete_overcharge(card)
for i, _ in pairs(card and card.ability or {}) do
if Giga.is_overcharge(i) then
card.ability[i] = nil
end
end
end
--- Add an Overcharge to a card
---@param card table
---@param key string
function Giga.set_overcharge(card, key)
if card and Giga.is_overcharge(key) then
Giga.delete_overcharge(card)
SMODS.Stickers[key]:apply(card, true)
end
end
```thats the code my bad for the delay I got an important call
in the is_overcharge function you're comparing the key to a number
since ipairs only goes over consecutive indices starting from 1
that looks like you have a non existent function name in a ui element
but i'm not sure
oh Idk what I have done but just a CTRL + Z and now it work
but is it possible to add a sticker to a card with like a command or something
I mean you have it on your code, SMODS.Stickers[key]:apply(card, true)
with debugplus console
and in debugplus, dp.hovered is the card object for whatever card you're currently hovering over
you can also just use your own function, eval Giga.set_overcharge(dp.hovered, key)
ok it work fine now but I want to make the sprite change dynamicly
card.children.center:set_sprite_pos{ x = 1, y = 0 }
ui is hard to explain, did you look at the smods wiki guide?
in the sticker itself ?
That just made me even more confused
yes
well it is hard
intermediate i would say at least
yea I’m cooked
I wanna make the top card always be a steel card if there's one in the deck but I'm very confused on what to do because i ain't the smartest at code
G.deck.cards is a list of cards in the deck where the card at index 1 is the one at the bottom of the deck
what you want to do is sort the list so that the steel cards are closer to G.deck.cards[#G.deck.cards]
so like...
G.deck.cards[1] = SMODS.has_enhancement(playing_card, 'm_steel')
I dont think its working
i wouldn't know how to format a card like that cause nothing in vanilla works like that
ah wait you want to change the sticker, right? i read it wrong lol
yeah that's what i mean
you want to do that but with the stickers sprite object
let me look up where it is
like its supposed to be different during boss blind
G.shared_stickers["modprefix_key"]:set_sprite_pos{...} i think
no, first of all what I meant is that [1] is the bottom of the deck so that would be the last card
SMODS.has_enhancement returns a boolean not a card so the statement doesn't make sense, you want to swap cards in G.deck.cards
I would maybe recommend doing easier stuff until you get a bigger grasp on coding
right ok
is there a way to get a cards description as a table from localize
if not how else would be best to do so
Does anyone know any jokers that shrink cards?
wdym by shrink cards
like physically shrink the visual size of the card?
you know any?
for wee size, set card.T.w = card.T.w * 0.7 and card.T.h = card.T.h * 0.7 on the card you want to shrink
this won't save if you back out to the main menu tho, and i'm not sure if there's any better way to do it
Is it permanent for the run or for as long as it's onscreen?
i tested and it does persist across the rest of the run, just not if you quit out and load the save back up
you can probably set a variable to true in the card's ability table, and then hook the load function to re-apply the size scaling if the card has that variable set
eh, so long as it shrinks the height of jokers, it's good with me
card.T.w = card.T.w * 0.7
end)```
Implemented, should it look like this?
don't forget card.T.h = card.T.h * 0.7
also do you want it on the jokers or the cards held in hand? because G.hand.cards is the cards held in hand
I'll replace it with G.jokers.card in the code
Okay, it works
Next challenge
(find jokers of rarity_statarity - 1, and randomly get two)```
how do I get two jokers of the next rarity down from a random joker?
(ping if you have an answer)
assuming the rarity is a vanilla rarity, you can just call SMODS.add_card { set = "Joker", rarity = x } where x is the number of the rarity (common = 1, uncommon = 2, rare = 3) and it'll automatically create a random joker of that rarity for you
if the rarity is a modded rarity, you'll have to manually define what "the next rarity down" means, but once you know that you can pass that into SMODS.add_card just the same (rarity can also be a string, for modded rarities)
@unkempt bronze
thank you!
hm
this line has an issue with = not being near a then
if context.yes_is_no = true then
it should be == true, but really it should just be if context.yes_is_no then
you don't need to have == true for any if checks
unless you're trying to make sure that it's specifically a boolean and not some other thing that just counts as true, which is a rather niche case
how do it tell what object type a card is/if its a voucher
local is_voucher = card.ability.set == "Voucher"
vanilla remade wiki is helpful for questions like this
i wonder who wrote it
where am i
i'm trying to get my joker to retrigger held steel cards, but i have no earthly idea why it isn't retriggering
Remove the and context.end_of_round
And you should use SMODS.has_enhancement(context.other_card, 'm_steel') instead of SMODS.get_enhancements(context.other_card)["m_steel"] == true
ah thanks
you already got an answer but just as a tip: not a == b is almost always incorrect since that evaluates not a first so it will mostly result in false == b
you want a ~= b or not (a == b)
yeah that tracks
i'm trying to learn this code by making the joker in jokerforge and then editing the code myself which is why a lot of this is really sloppy
honestly a pretty bad idea
jokerforge generated code is usually not a good reference, because there's usually a lot of extra syntax junk to account for every possible option (and also a lot of it is just bad even for generated code). might be worse than writing the code from scratch, because otherwise you'll constantly have to be unlearning bad habits
i guess, but i'm definitely trying to learn more from the vanilla reforged than i am from jokerforge
vanillaremade is right there for you
great reference of well-written code reimplementing basically all the vanilla content, including non-jokers
whoops i meant vanillaremade
i am looking at that yes
looking at reforged would be completely redundant lol
i'm tripping , why won't sound and colour register```lua
return {
hypermult = {self.config.hyper, self.config.mult},
sound = "busterb_Thunder1",
colour = SMODS.Gradients["busterb_Thomasgradient"]
}
alright, this is supposed to unlock a joker if the joker itself gets destroyed it's definitely not working
Is it that the Joker is being called incorrectly? Maybe you need j_MODPREFIX__JOKERKEY (Remove 2nd underscore between prefix and key.)
Also, maybe remove the G.P_CENTERS from that?
yeah still doesn't work... this entire thing of code needs to be redone i think but i am absolutely not sure how
i don't think they work unless you set a custom message, standard calculation effects like hypermult automatically provide all the message data (including sound and color)
also yeah crucify me it's jokerforge but this is a joker i made before you said that and i'm trying to code jokers from scratch now
by taping together a bunch of vanillaremade code
it is not working in the slightest
god i hate modding
context.remove_playing_cards only runs when a playing card is destroyed
to check in a joker's own code for if the joker itself being destroyed, check if context.joker_type_destroyed and context.card == card then
You'll need to also specify hypermult_message iirc.
like this?
I've tried context.after and context.final_scoring_step, but it still keeps on adding the 10% before ANY scoring is done. Why is this being difficult with me?
hypermult_message = "text string"?
no need to put anything in a return statement, literally just
if context.joker_type_destroyed and context.card == card then
unlock_card("j_stinky_crucible")
end
(to be clear, the intended effect is "if this joker is destroyed, unlock the Crucible joker"?)
-# It also occurred to me I am doing the math wrong here.
it didn't work...
echip_message = {message = localize{ type = "variable", key = "toga_Echip", vars = { card.ability.extra.heldechip } }, colour = G.C.DARK_EDITION, sound = "talisman_echip"}
Snippet from my Michael Rosen return.
and yes, the name of the card is spelled right
i'm seeing usually that unlock conditions are in the jokers themselves and not really in other jokers
maybe that's the problem
but then the code would be entirely different and i am tired
wait is it supposed to be outside of the calculate
do i need to make a localize?
i don't use any localization files
You can just give it a raw string.
Ok, now it's just straight up not adding anything.
G.GAME.chips doesn't actually update its value until after context.after
return {
hypermult = {self.config.hyper, self.config.mult},
hypermult_message = {message = "^^^^ "..self.config.mult, colour = SMODS.Gradients["busterb_Thomasgradient"], sound = "busterb_Thunder1"}
}
you'll need to do G.GAME.chips = G.GAME.chips + ((G.GAME.chips + SMODS.calculate_round_score()) / card.ability.extra.score) i think?
is there a G that hold every card discarded, I tried G.discard and G.discard.cards and it doesnt seems to work
nevermind i don't think ifs can be put outside of calculates
G.discard.cards should be every card that's been discarded and played by the player in previous hands this round
so why thats not working
is it like this?
Should work, although I am not familiar with hypermult specific strings.
where'd you get the strings?
when is this code being run
elseif eval_type == 'hyper_mult' then
sound = 'talisman_eeemult'
text = (amt[1] > 5 and ('{' .. tostring(amt[1]) .. '}') or string.rep('^', amt[1])) .. tostring(amt[2]) .. ' ' .. localize('k_mult')
amt = amt[2]
colour = G.C.MULT
config.type = 'fade'
config.scale = 0.7
so it's eeemult_message?
The sound is.
why can vanilla cards move their multipliers straight into the config table without worry, but modded ones have to use extra as a table
Theoretically the entire scoring loop is calculated when you press play, so this happens instantly. Maybe try putting it in an event?
can i just throw a entire table that belongs to a card into set ability and make a carbon copy?
you can use the copy_card function for copying
Why
(only happens when adding and removing cards on the winning hand)
You should be using SMODS.destroy_cards instead of Card:start_dissolve
also, don't use create_playing_card, use SMODS.add_card
there's a lot of extra work you have to do that SMODS.add_card will handle for you
in fact it'll automate some of the stuff you're currently doing manually
SMODS.add_card { set = "Playing Card", suit = "Clubs", area = G.hand } is all you have to do to create a random Clubs card and put it in your hand
You can put your own stuff directly in the config table, but it might get picked up by some of the automatic handling of stuff that vanilla uses, and there are some weird remnants with things not resetting or loading properly when you change/copy the card iirc. The entire extra table was always given the correct behaviour, AND allows you to control exactly how you want the card to calculate, so that’s always been the recommended place to store your values
made this to make it easier to make new boosterpacks in a semi vanilla style. its intresting to see how the location of the text differs between versions as these are made from the vanilla bufoon packs.
Why are my jokers showing up with the wrong texture
Code?
How do I spawn joker with custom name? (For example spawn photograph with name "Joker")
Hook generate_card_ui
Thanks
Blame joker forge devs for fucking up textures again
why is that? is it fine to use start_dissolve for a joker to self-destruct?
cuz vanilla remade mr. bones uses it
oh i should change that
i mean start_dissolve works too
it's just that it's recommended to use destroy_cards
because it handles more logic
anyway for the case somethingcom was saying it's important to use destroy cards to destroy playing cards during scoring
where does SMODS relocate observatory behaviour to? its not in the normal vanilla place of Card:calculate_joker, but there also isnt any take_ownership done for Observatory either
src/game_object.lua
wicked ty, sry for not explaining correctly
-- 3. Logica di valutazione della mano (fuori dalla definizione)
local evaluate_poker_hand_ref = evaluate_poker_hand
function evaluate_poker_hand(cards)
-- Controlla se possiedi il joker (usa il prefisso corretto se necessario)
local has_trinity = next(SMODS.find_card("j_trinity"))
if has_trinity then
local original_ids = {}
for i, card in ipairs(cards) do
original_ids[card] = card.base.id
-- Se è J, Q o K, trattalo come un 11 (Jack)
if card:is_face() then
card.base.id = 11
end
end
local ret = evaluate_poker_hand_ref(cards)
-- Ripristina i valori originali per non rompere Baron/Shoot the Moon
for i, card in ipairs(cards) do
card.base.id = original_ids[card]
end
return ret
else
return evaluate_poker_hand_ref(cards)
end
end
Yo guys, i'm trying to make a "Joker Fluid" card like, what's wrong?
At first i tought about making every face card the same ID, but that would prevent the cards from activating upon jokers that work with specific faces, so i changed it to only when played hand
You mean you want every face card to be counted as every face rank but only for poker hands?
why does only orange deck break and nothing else
ok it might have to do with the card trying to reference a variable when it physically cannot
ok that's what was happening lol
wait, does {T:key} work only for decks and not jokers' formatting?
it doesnt work for jokers, T:key is for tooltips on hover which you can only do with decks
for tooltips with jokers (and other objects) see how info_queue is used in vanillaremade
well some jokers too achieve tooltips, like diet cola, I thought surely they work the same
they use info_queue
because they're not on hovering the word like decks
@red flower has anyone told you you are the goat
Maybe I should put galdurs infoqueue adaptation for those into smods
hey guys, i just ran into an issue in my mod that hasn't been there in the past.
My mod uses function SMODS.debuff_card(card, debuff, source) in src/utils.lua line 417 to debuff jokers, which works fine while in a blind, but I also want to have some jokers debuffed in the main menu (in the collection or when the card burns). If you call it however, it will eventually run into G.GAME.blind:debuff_card(card) which crashes because blind is nil in the main menu.
is there a workaround for this? I mean i could just call card:set_debuff(true) but then it could fuck with the blind specific logic.
main reason im reporting this is because i dont think debuffing a card while not being in a game is that unreasonable, so it could be good to have a nil check or whatever in steamodded
if G.STAGE == G.STAGES.RUN then SMODS.debuff_card(card, true, 'source') else card:set_debuff(true) end
Ok i guess ill use the workaround then, thx for replying
Yeah, so that you could do pairs even with K-Q or K-J, vice-versa for the other combos
how would i change the order that the cardareas are scored?
Hook SMODS.get_card_areas
ty
time to come back to moddin gafter like a ear of inactivity
wooooooooooooo babyyyyyyyy
can the message_card value of a calculate function's return table be an array of multiple cards to display the message on each one in the array?
its under nothing
its just a card property
card.debuff
ok thanks
no
you have to use extra to return multiple messages or use SMODS.calculate_effect
SMODS.Edition {
key = 'bootleg',
shader = 'holo',
prefix_config = {
-- This allows using the vanilla shader
-- Not needed when using your own
shader = false
},
config = {
extra = {
odds = 4
}
},
in_shop = true,
apply_to_float = false,
sound = { sound = "ttv_fart_sound1", per = 1.2, vol = 0.4 },
disable_shadow = false,
disable_base_shader = false,
loc_txt = {
name = 'Bootleg',
label = 'Bootleg',
text = {
[1] = '{C:green}1 in 2{} chance to fail'
}
},
unlocked = true,
discovered = true,
no_collection = false,
get_weight = function(self)
return G.GAME.edition_rate * self.weight
end,
loc_vars = function(self, info_queue, card)
local new_numerator, new_denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'e_ttv_bootleg')
return {vars = {new_numerator, new_denominator}}
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.hand then
return card.debuff
end
end
}```
trying to give the bootleg edition the chance to debuff
doesn't seem to crash so I can't really figure out where to look at
for SMODS.calculate_effect is the table passed as the effect argument set up the same as a calculate's return table then, or is that table something different entirely?
Yes, it is, but you should always use a return if possible.
it's the same, yes but instead of using message_card is better to pass the card as the second argument calculate_effect({message = "text"}, card)
what's the exact effect? returning card.debuff won't do anthing, calculate has a specific set of returns for each contexty you can't just return whatever
also for editions you want to use context.main_scoring
they're trying to set debuff based on a probability
card.debuff is the actual debuff property
but obviously returning it doesn't do anything
if i ask someone something to help them i want them to answer thanks
they did
read the message
lmfao
i did not add new information
they did what? I asked for the exact effect. What does chance to debuff mean? When? Why do they want to debuff?
its called bootleg figure it out ig
ok then i wont help
i just asked a question I didn't expect mom and dad to argue over dinner
i already had them ignored anyway idk why i clicked on show
no trying to be mean but that is just pointless arguing
i'm gonna try giving the context change an try
see if that works
getting ragebaited by nothing
local new_numerator, new_denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'e_ttv_bootleg')
curious if it's related to this
with e_ttv_booleg being defined
since it's not a card but a edition being called lol
what do you mean
SMODS.Edition {
key = 'bootleg',
shader = 'holo',
prefix_config = {
-- This allows using the vanilla shader
-- Not needed when using your own
shader = false
},
config = {
extra = {
odds = 4
}
},
in_shop = true,
apply_to_float = false,
sound = { sound = "ttv_fart_sound1", per = 1.2, vol = 0.4 },
disable_shadow = false,
disable_base_shader = false,
loc_txt = {
name = 'Bootleg',
label = 'Bootleg',
text = {
[1] = '{C:green}#1# in #2#{} chance to fail'
}
},
unlocked = true,
discovered = true,
no_collection = false,
get_weight = function(self)
return G.GAME.edition_rate * self.weight
end,
loc_vars = function(self, info_queue, card)
local new_numerator, new_denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'e_ttv_bootleg')
return {vars = {new_numerator, new_denominator}}
end,
calculate = function(self, card, context)
if context.cardarea == G.play and context.main_scoring
if SMODS.pseudorandom_probability(self, 'e_ttv_bootleg', 1, card.ability.extra.odds) then
card:set_debuff(true)
else
card:set_debuff(false)
end
end
end
}
the problem with the code you showed is that it doesn't make sense
this is almost there
but i'm fairly sure that it needs a different context
since i THINK editions run after
would have to double check
i'll slap it in see what it does
i don't have much context but main_scoring only works with playing cards, and is correct for editions on playing cards
if bootleg is intended to appear on jokers, you'll also need the same behavior in context.pre_joker
also self should be card
u forgor a then
after main_scoring lol
