#💻・modding-dev
1 messages · Page 622 of 1
i thought you were better than this
ehh better safe than sorry
not really for myself honestly
what would you even train it off of
Not people’s mods I hope
nvm actually i abstain from this discussion
Buddy you don’t have permission to do that
wait what
Not on vanillaremade
but its for myself
I’d ping mods but they’d end up banning me with the moderation here
The pinned message
;u;
it's probably legal according to licenses but you'll be ostracized from the community here if you decide to train AI off people's mods
I advise you stop the AI stuff immediately
ok maybe not that one
it is legal according to gpl i believe
welp this is unfortunate
Is there a possible way to replace the splash screen entirely?
anyways bye get blocked
what?
not you
😭
for @umbral spire
What did he do?
something that shouldnt be metioned here
AI that they wanted to train on other people’s mods
i said not that one
chat the pinned is also about discussion on the topic
we're all getting banned 😭
weeelll on another note, im thinking of adding a seal that makes editions and enhancements still go off when held in hand (ex. polychrome acting like steel), is that possible?
just asking yes or no tbh cuz idk anything abt code lol
lol
Should be
Help me pls T-T
awesome
Calculate edition and enhancement with context.individual
@wind steppe could u help me out? should be pretty easy for u
And seal
Wait
What
No
Huh
Oh this is modding dev
lol
Fixed it
you could just show snippets of your code and ask a question, and note your goal.
i have like twice now lol, keeps crashing while only running steamodded and tailsmain
I thibk
i also tried the other channel and no one wants to respond to it
what talisman version
newest, let me get the exact version, one sec
How can I make the "ERROR" say something else?
modprefix_key = 'Label' in Localization > misc > labels
in context.before in a joker's calculation function, how would i check if there is a 2 or 3?
played
How would I move the blind select ui down when I set the game state to shop?
Theres method in smods that let you check the id
See Shoot the Moon code or something like this
label = 'Label'
👍
local passed = false
for k, v in pairs(context.full_hand) do
if v:get_id() == 2 or v:get_id() == 3 then
passed = true
end
end
if passed then
end
ok ty
No, it's card.ability[self.key].extra.xmult
just [self.key] ?
Yes.
oh wait i need another context for jokers
X0.9 mult
doesnt that lower the score?
yes
lolll
i dont play with them, i like to see big number go bigger
well yeah they are meant to be a debuff to your run, for harder difficulties
like black stake, orange and gold
yup
is it out?
not many ideas
what is it adding exept stickers?
not all of the enhancements have code either
mm
Ive got the art covered on some of it tho
art is really the one thing im ok at T-T
it depends
k
damn, wish I was able to draw like that, I have so many ideas yet without a good art everything just wouldn't feel right
thx
well, if you want I could try make some
im low on ideas most of the time
that would be really cool, I don't want to insist too much so one seal would be the best
ok well, dm me on more of this then
How would I optimally be able to have the shop appear when a blind is skipped, since my approach seems to be a bit rough with booster pack tags :>
if this would help, I know a joker in one mod that does precisely that, you can look at "Dizzard" code from All in Jest
Alright
these look awesome
ts bricking me
ok bro
uhh, can you do me a favour in a sec?
probably not im not at my PC and won't be for over an hour
but if it doesn't require that then maybe
done
and this
this is high contrast
oh wait @umbral zodiac i forgor i could do this
here is the shit
i’m lily !
she's lily
you are
i did say I was going to make a better one
thats up to interpretaion
but i did unique art for each suit
looks peak to me
im just thinking is it better that what is in valk arleady
yeah im never giving a compliment again 🥀
my bad 😭
im sorry i hate myself and my art
oh shit i forgot something
@umbral zodiac I didnt paint bucket you mouth for queen diamonds
i will add these when i’m home
hi home im cg
does anyone know how i can force the shop to be skipped?
ive tried 2 different ways and its given me 2 different crashes
Hook G.FUNCS.toggle_shop
thanks
Is there a way to not use recursive scripts to reduce lag? This script is just detecting the highest possible hand type to be played but it's very laggy 🥲
What do you mean the highest possible hand type?
As in Flush Five > Straight Flush > Straight > Two Pair...
The order of poker hands
Also I just realized is your pfp polybridge?
Yes.
just do G.FUNCS.get_poker_hand_info(G.hand.cards)
that'll give you the theoretical best hand you can play
yeah why are you trying to recreate something that already exists in the game?
The problem being it could say striaght flush, but I can't really play both straight and flush at the same time
I tested it but I'm pretty sure it doesn't work
Like all the cards together fulfill that req but 5 cards cannot
that'll probably be because of how the game decides what a straight flush is
in that a straight exists and a flush exists rather than them containing the same cards
because of four fingers
what, you disagree with balatro's definition of straight flush being a hand containing both a flush and a straight?
Nono, it's because I'm detecting 8(hand size) cards at once and the ones that make a straight don't make a flush (with 5 cards played)
Same with some of the secret hands
What's the reason for doing this, anyway?
Oh just a blind effect
get_poker_hand_info should be giving poker hands, not poker hand parts
Unless I forgot
a straight hand is quite literally a hand that contains both a straight and a flush
if the minimum length for a straight and a flush is less than the number of cards played, the straight and flush don't have to fully overlap
you can see this in vanilla with four fingers
Yeah that's how balatro defines a straight flush
like Meta said, you can see this with 4 fingers
nah I tested and xstep is correct
i assume xstep wants to have some blind effect when you play the best possible poker hand in your drawn hand, but it shouldn't count a straight flush if you can't actually play that straight flush
if there exists a straight and a flush, even if they don't overlap, the function says straight flush
Is that not how balatro defines it?
yeah it is
yeah but that only works because vanilla never expects more than 5 cards
that is correct
the issue here is that an 8-card hand can count as a straight flush without necessarily containing a 5-card straight flush
and xstep wants to find the best possible 5-card hand (or whatever the selection limit is) within your drawn 8-card hand (or whatever the hand size is)
very true
the problem comes from running it on more than 5 cards
the straight flush detection should probably be altered here imo
to at least an overlap between the straight and flush supposedly?
I think the total number of unique cards should check to see if it's less than the play limit
do you guys know any useful resources that i can use to make my own mods
great
how do I make a consumable that spawns jokers spawn any joker, even if u own it already
any joker from a specific pool*
i think add_card has an allow_duplicates field
(i dont remember if it got merged)
looking at the github this is indeed the case, i assume it's in the latest release?
anyway add allow_duplicates = true as an argument to the table in your add_card call
showman consumable?
nah just a thing for my legendaries
How do I check for what deck the player is on? I want to check if they're on painted deck
G.GAME.selected_back iirc
Thank you!
Why the crash?
code for the consumable
use = function(self, card, area, copier)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('timpani')
SMODS.add_card({ set = 'BitterJokers', allow_duplicates = true })
card:juice_up(0.3, 0.5)
return true
end
}))
delay(0.6)
end,
the image is of a joker iwth the thingy
Did you create the SMODS.ObjectType?
ima die
bump
what animation is used for a card when it "triggers"? (e.g. a joker giving mult, a card scoring...)
is it card:juice_up()? or some other function?
also, how do I add the little diamond that pops up saying what happened?
is there a function for making that appear
SMODS.calculate_effect({message = 'message'}, card)
it is juice_up for the first thing
depending on the animation it might have some parameters
okay im gonna need a refresher on lua string manipulation for putting a variable inside of said message
is it like some other languages where i can just use addition
'message' .. var .. ' more message'
'string1'..variable..'string2'
is there a parameter for the color?
it's called concatenation btw if you ever need to look it up
kitty! 🐱
code no worky
if not blind.disabled then
if context.cardarea == G.jokers and context.joker_main then
if true then
if SMODS.pseudorandom_probability(blind, 'vremade_gun', 1, 6) then
local destructable_jokers = {}
for i, joker in ipairs(G.jokers.cards) do
if joker ~= card and not SMODS.is_eternal(joker) and not joker.getting_sliced then
table.insert(destructable_jokers, joker)
end
end
local target_joker = #destructable_jokers > 0 and pseudorandom_element(destructable_jokers, pseudoseed('destroy_joker')) or nil
if target_joker then
target_joker.getting_sliced = true
G.E_MANAGER:add_event(Event({
func = function()
target_joker:start_dissolve({G.C.RED}, nil, 1.6)
return true
end
}))
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "Destroyed!", colour = G.C.RED})
end
end
end
end
end
end
}```
trying to make a boss blind that has a 1 in 6 chance to destroy a random joker
ok decided to redo the code and got a new error
i might just scrap the gun tbh
wait i think ive figure d it out
nvm idk what im doing
it doesnt destroy a single joker sobs
any of yall know how to make a specific joker have a different font
Blinds don't have context.joker_main
o
ok i did that and it still deosnt destroy the joker
calculate = function(self, blind, context)
if context.cardarea == G.jokers then
if true then
if SMODS.pseudorandom_probability(blind, 'vremade_gun', 1, 6) then
local destructable_jokers = {}
for i, joker in ipairs(G.jokers.cards) do
if joker ~= hand and not SMODS.is_eternal(joker) and not joker.getting_sliced then
table.insert(destructable_jokers, joker)
end
end
local target_joker = #destructable_jokers > 0 and pseudorandom_element(destructable_jokers, pseudoseed('destroy_joker')) or nil
if target_joker then
target_joker.getting_sliced = true
G.E_MANAGER:add_event(Event({
func = function()
target_joker:start_dissolve({G.C.RED}, nil, 1.6)
return true
end
}))
card_eval_status_text(context.blueprint_card or blind, 'extra', nil, nil, nil, {message = "Destroyed!", colour = G.C.RED})
end
end
end
end
end
}
idk what im doing wrong here
if context.before
No, remove the second if
it work!! thankes
i wanna make this a different font, how would I do that
sorry, i don't think I explained it entirely correctly
What Zamazenta does is level up every other poker hand that isn't the most played poker hand
How would I go about doing that?
losing my fucking mind im convinced this function was actually designed to troll me or something
local neg_chips = hand_chips * -1
update_hand_text({ sound = 'chips2', modded = true }, { chips = 'wawa'..neg_chips})
end
else update_hand_text({ sound = 'chips2', modded = true }, { chips = hand_chips})```
this, will correctly display wawa[number] at the chips.
**however**.
if i change the text to '-'
it suddenly stops working
however however
if i literally just have chips = '-wawa' it.
does work?????
i've also been able to eval it with debugplus to say a minus sign and then a number, but never with actual code?????
fig.1: chips = 'wawa'..neg_chips
fig.2: chips = '-wawa'
fig.3: chips = '-'..neg_chips
fig.4 debugplus eval being able to set it correctly though??????
what the actual heck is going on here.
local most_played, played = nil, -math.huge
for k, v in pairs(G.GAME.hands) do
if v.played > played then
played = v.played
most_played = k
end
end
for k, v in pairs(G.GAME.hands) do
if k ~= most_played and v.played ~= played then
SMODS.smart_level_up_hand(card, k)
end
end
fig.5 chips = '-'..'wawa'
??????????????????????????????????
why???
does it just hate a negative sign in particular being concatenated to a variable??????
i am losing my mind why does everything except for what i specifically want to do work
i mean no criticism in this but why is the chips wawa
Have you tried tostring('-'..neg_chips)?
wawa
didn't think about it that way
doesn't work
does the same as figure 3, just makes the chips box blank
zero clue why this specific action and none other does this
Hi hi hello friends
im working on a new poker hand that only works if you have a certain joker
right now im stuck on making the description, here's the code
key = "franklin",
mult = 8,
chips = 101,
l_mult = 16,
l_chips = 200,
example = {
{ 'S_K', true },
{ 'S_9', true },
{ 'D_9', true},
{ 'H_6', true },
{ 'D_3', true }
},
evaluate = function(parts, hand)
return parts._highest
end,
loc_txt = {
name = 'The Franklin',
descriptions = {
misc = {
poker_hand_descriptions = {
["clo_franklin"] = 'See?' },
poker_hands = {
["clo_franklin"] = 'The Franklin' },
}
}
}
}```
right now it crashes when you try to hover over it, with the error that 'line' is a nil value
which im confused about because line isnt mentioned here
any advice?
what happens if you do eval '-10' + 1
is the box just hardcoded to hate anything resembling a negative number or something
It hates the total score being negative afaik but besides that i dont think it does
-9
new tactic add a zero width space
Aw man, they turned off threads
this game/language is cursed i still do not understand this at all
i want help badly i am losing my mind
what if you use an em dash
that basically does it, but is there a way to optimize it? like how black hole levels all of them up at the same time?
You mean you don't want it to play the animation for every hand?
I do want it to play the animation, but in practice it's leveling up all of them one at a time, and that takes way too long. Is there a way to mimic how Black Hole does it?
what does eval G.GAME.current_round.current_hand print out when it works when you use debugplus to set it to '-100'
Yes, that's what I meant.
I mean before you set it to -100
but when doing so actually works
then yes. just one
ok the lua coding language is fucking with me
chips = '-' .. '100' works
but chips = '-' .. tostring(neg_chips) doesn't
i can not see an explanation for this im just being psychologically tortured
these should be doing the exact same thing why is only one of the two working
and its not the variable either because wawaneg_chips worked
is that with debugplus
Do you have Talisman installed?
usually im pretty bad at pixel art and art in general but i like this a lot
nope!
no talisman
are you not able to reproduce?
SMODS.Font is funny
ive got debug prints and neg_chips is always a positive integer here too
EVIL joker
not to be pushy, but are you still going to help me optimize the leveling?
guys how do i fix it
Yes, add true to the third input of SMODS.smart_level_up_hand
Did you start a new run?
now it's not playing the animations at all.
Yes, you have to do that manually.
i got bad news
the game does not even render the em dash
it displays the number though ?????
so like. how do i do this
actually how
i feel so close yet so far at the same time
okay
local neg_chips = hand_chips * -1
local neg_chips2 = '-'..tostring(neg_chips)
print(neg_chips2)
update_hand_text({ sound = 'chips2', modded = true }, { chips = neg_chips2})
this doesn't work either.
but the print does.
but '-'..'100' does work
why
so how would i do them manually?
why is it like this i am actually losing my sanity trying to figure out what is going on with this function
Does anyone know why this isn't working? I would presume the way to "Back(G.P_CENTERS.b_painted)" is wrong but I'm not sure how to refer to the painted deck otherwise
oh i was just looking at this lol
if G.GAME.selected_back.effect.center.key == 'b_painted'
how do i set play card limit back to 5
im running code that does SMODS.change_play_limit(-1)
but i want it so that after you defeat a blind, it resets to 5
SMODS.change_play_limit((-G.GAME.starting_params.play_limit)+5)
oke
That worked, thank you!
it work, thankies
somethin wrong
you can always look at what the function is doing
You're missing the c_ prefix.
a
here is what the function is doing.
local delta = (type(vals.chips) == 'number' and type(G.GAME.current_round.current_hand.chips) == 'number') and (vals.chips - G.GAME.current_round.current_hand.chips) or 0
if delta < 0 then delta = ''..delta; col = G.C.RED
uh
i think you have to code the behavior for that yourself
:o how
i'm not sure
what is your code for it
there's a line below that explicitly checks whether it's a string, so that part shouldn't matter i think
not really sure what this is.. doing
type(vals.chips) == 'string' then delta = vals.chips
yeah okay
so then whys it breaking with a minus sign in the string
the parameter that you're using is currently called card in the function, try just renaming it to blind
do i really need to do something stupid like inserting a zero width space
to make it not parsed as a number
or some shit
i'm not sure if the string being parsed as a number is actually the issue
then what is?
because '-'..'100' works perfectly fine
so literally
what could it possibly be
i mean that would still be parsed as a number
which is why I don't think it's the issue
Getting a crash that looks like this. Only things I have installed are steamodded, talisman, and cryptid
Anyone got any idea what's happening?
can you send the full code of whatever it is that wants to do this
Was sent here from #⚙・modding-general
ok guys
this channel is for asking for help when you are developing a mod, so you were incorrectly sent here, but does the game launch without talisman and cryptid?
It does! Also: What channel should I head to for help with mod-related crashes in the future
Narrows it to either cryptid or talisman, but that doesn't rly help fix the issue
since it's an issue related to those mods, probably the discord servers related to that, that said do you have the latest releases of both mods
gonna modify some things for the simplest way to replicate
if hand_chips < 0 then
local neg_chips = hand_chips * -1
local neg_chips2 = '-'..tostring(neg_chips)
update_hand_text({ sound = 'chips2', modded = true }, { chips = '-'..tostring(neg_chips)})
end
else update_hand_text({ sound = 'chips2', modded = true }, { chips = hand_chips})```
i can not send the full code, sorry
When are you running this code
under a calculate function?
if this says something like indexing a nil value (i’m on mobile and can’t tell) that’s my bad
yeah a blind's calculate
and if so, under what context
context.modify_hand
To my knowledge yes. Though so that im not taking up the wrong channel, I'll slide back over
nobody reviewed my pr to see if it worked fresh so i just merged it and i guess it didn’t work
yea it says that
yeah sorry about that
you can solve it by downloading a slightly older version of talisman
damn, you eated the nil :(
i’ll fix it when i get home
gotcha
How to modding on MacBook?
This is one of the notifications of all time
i'm testing rn
as always, theres a relevant xkcd https://xkcd.com/583/
what is your full context check for this effect
if context.modify_hand then
the strangest part to me is how whenever i do a debug print statement it prints every variable i have perfectly fine
and also how my test of doing anything except for a - added to the number, doesn't cause issues
ok
make sure to use a hand worth less than 20 base chips (e.g high card) for the test
so it actually goes negative
wait fuck i wrote this wrong its adding two minuses
oh wait no its actually just skipping negchips2 completely
ok it should still be fine its just redundant
hi again gang
im trying to create a hand that only is playable if a certain joker is there
i have found some mods that do this, but they all do it in different ways and none of them seem to work
here is my code for both the joker and the poker hand:
key = "franklinjoker",
loc_txt = { name = 'Benjamin Franklin',
text = { 'Invents a move called',
'{C:attention}The Franklin{}'}
},
pos = { x = 2, y = 3 },
atlas = 'franklinjoker',
blueprint_compat = true,
rarity = 1,
cost = 3,
}
SMODS.PokerHand {
key = "franklin",
mult = 8,
chips = 100,
l_mult = 16,
l_chips = 200,
example = {
{ 'S_K', true },
{ 'S_9', true },
{ 'D_9', true },
{ 'H_6', true },
{ 'D_3', true }
},
evaluate = function(parts, hand)
if next(SMODS.find_card("clo_franklinjoker")) then --- This part checks if the player has the joker
if jokers and #jokers > 0 then
return parts._5
end
return false
end
end,
loc_txt = {
name = "The Franklin",
description = {
"Any five cards"
}
}
}```
The game cant seem to find this joker, can anyone help me out here?
return next(SMODS.find_card("j_clo_franklinjoker")) and parts._5 or nil
Hello all, Im new here. Hoping to find some help. I am having what I hope to be a simple issue with trying to run the talisman mod. When it is enabled the game crashes during start. It is the only one that does this. When disabled the game launches normally. If anyone can help let me know what information you need. Thanks.
j_space
@umbral zodiac
it broke it
update:
i did this and it 'fixed' it.
yay????
honestly. good enough. i can deal with a zero width space
i fucking know
ive been told this like
6 times already
and i above said that i was going to fix it when i could
and guess why i have balatro open right now
update: i think it just doesnt like using parts._5 because i switched it to parts._highest and it worked fine
now to benjamin franklin planet.
@lofty tree @lean prism talisman crash has been fixed, youre free to download latest commit now [even though you should probably be downloading latest release unless you know what youre doing]
Thank you. Just updated and all is well.
wdym?
What is the goal?
i gave up, i don't get it either
but 2 probabilities
you can make edition extra costs negative right
Yes.
Is there code that can level up all hands?
for k, v in pairs(G.GAME.hands) do
SMODS.smart_level_up_hand(card, k)
end
how do you get the selected joker
G.jokers.highlighted[1]
so to create the joker i'd do like smods.add_card with that right
You mean you want to copy the selected joker or create a joker of the same key as the selected joker?
copy the selected joker with an edition
local copy = copy_card(G.jokers.highlighted[1])
G.jokers.highlighted[1].area:emplace(copy)
copy:add_to_deck()
copy:set_edition('e_modprefix_key')
Does anybody have a way to remove vanilla joker of the game on my mod ? I saw a pokemon do that, but it been 10h and I couldnt see a way to do it
how do you check if you actually have a joker selected
if G.jokers.highlighted[1]
for k, v in pairs(G.P_CENTERS) do
if v.set == 'Joker' and not v.original_mod then
SMODS.Joker:take_ownership(v.key, {
in_pool = function() return false end,
no_collection = true
}, true)
end
end
i figured kinda figured it out lol, it casts it as a number at some point (dunno where) and this part becomes nan when it does log10 of a negative
the math.abs was added by me oops
but that fixes it
might pr this
FINALLY TYSM
yk I gave up when I got to looking into the G.HUD definition cus I didn't want to deal with that, glad to see I wasn't far off, assuming this function is called there
hello there, I have a question about change the Planet and Spectral card skin. I modified the Tarots.png and use the lua code like :"local sprite_tarots = SMODS.Sprite:new("Tarot", deck_mod.path, "Tarots.png", 71, 95, "asset_atli")",but it stll no changes happen, is there something wrong?
Yes, SMODS.Sprite doesn't exist.
wait,I have modified the deckskin and tarots card skin, it is shown the new skin?
Last time I worked on my mod was with smods 0827c, anything I need to do or note moving to the newest version?
------------MOD CODE -------------------------
function SMODS.INIT.DecColors()
local deck_mod = SMODS.findModByID("deckPack")
local sprite_deck1 = SMODS.Sprite:new("cards_1", deck_mod.path, "decklc.png", 71, 95, "asset_atli")
local sprite_deck2 = SMODS.Sprite:new("cards_2", deck_mod.path, "deckhc.png", 71, 95, "asset_atli")
local sprite_jkr = SMODS.Sprite:new("Joker", deck_mod.path, "Jokers.png", 71, 95, "asset_atli")
local sprite_tarots = SMODS.Sprite:new("Tarot", deck_mod.path, "Tarots.png", 71, 95, "asset_atli")
sprite_deck1:register()
sprite_deck2:register()
sprite_jkr:register()
sprite_tarots:register()
end
------------MOD CODE END----------------------
No.
No, SMODS.DeckSkin
holy shit this code is ancient
pardon my language
or at least i think it is, i dont actually know old smods code
Sorry, I'm not good at code. just like to change skin, I downloaded the mods from nexus and copy that.
Yes, it's a year old.
oh my god it's ancient
I'd advise reading through code from mods posted in #⚙・modding-general instead; more up to date
i have a small question is there a way to start a game with the joker you created to test it out?
in this case... what should I do? how to use my picture?
Yes, DebugPlus
tyty
How would I go about making a joker that shows/names the next three blinds? I'm guessing that's not something predetermined, so I could maybe decide the blinds beforehand, and then force the next blinds to be those? idk where to start with this.
what are THESE colors referred to (The upcoming/skipblind color and tooltip header color)
solved,thx
Pseudorandom outcomes are inherently predetermined, so you could copy or patch the pseudorandom logic to give you the expected results of the next three blind calls.
Source(s): I've done this
return {
sound = "GI_TacoBell",
mult = card.ability.extra.mult,
card = card
}
end
if context.after and not context.blueprint then
return {
message = 'random message,
colour = G.C.MULT,
sound = "GI_TacoBell"
}
end```
I'm trying to have this joker play a special sound effect instead of the regular mult sound, but when I just define the sound in my mult return nothing happens.
I know it's not an issue with the sound itself too because it works fine in the second example where it's a custom message I'm returning.
Am I missing something stupid? I didn't see anything special I needed to do in the smods documentation, and using replace = in the sound effect doesn't work because I only want it to affect this one joker.
I also tried just using play_sound() in the function but then it plays as soon as the calculation starts which isn't ideal.
chat the second if statement wont work
I don't understand why it make me crash I just want to have a pool for my rare consumable
I think you need to do the mult message manually for it to play the sound
so something like mult_message = { message = localize{ type = "variable", key = "a_mult", vars = { card.ability.extra.mult } }, sound = "GI_TacoBell" }
you can also put play_sound in an event
the second statement wont work if the first one hits the probability
cons seems to be nil
anyway why all of this and not an ObjectType
um idk since they are already in the food set they can't be in a second one ig
yes they can
oh so its easier thx
so how do i make it so the second and first can BOTH work
Put the second if before the first if
how would i check what the upcoming boss blind is
Yes.
like if the current blind is "The Plant", a variable is set to true
if G.GAME.round_resets.blind_choices.Boss == 'bl_plant'
try adding return nil, true at the end
it seems to be running the original code
Which end?
at the end of calculate
how do i make legendary jokers free in the shop using card.ability.couponed = true card:set_cost()? (where do i write it)
SMODS.Joker{
key = "joker",
atlas = "jimbussy",
pos = { x = 0, y = 0 },
soul_pos = { x = 0, y = 2, new = { x = 0, y = 1 } },
pools = { ["Grandiose"] = true, ["bustjokers"] = true },
rarity = "busterb_Grandiose",
cost = 500,
blueprint_compat = true,
eternal_compat = true,
unlocked = true,
discovered = true,
config = {
extra = {
valuemodification = 4
},
immutable = { valuecap = 1e100 }
},
loc_txt = {
name = "{V:1,s:2}JIMBO{}",
text = {
"{C:legendary}Legendary Jokers{} can spawn in the shop and are free {C:inactive}(not yet free){},",
"all jokers gain {B:2,V:1,s:2}X#1#{} joker values at the end of the round."
}
},
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.valuemodification, " ", colours = {SMODS.Gradients["busterb_balatro"], SMODS.Gradients["busterb_epileptic"]}} }
end,
calculate = function(self, card, context)
if context.ante_change then
for i, joker in ipairs(G.jokers.cards) do
if joker.config.center.key ~= "j_busterb_joker" then
Cryptid.manipulate(joker, { value = card.ability.extra.valuemodification })
end
end
end
end
}
-- gray image of thinking baby meme
local oldgetcurrentpool = get_current_pool
function get_current_pool(_type, _rarity, _legendary, _append)
if next(SMODS.find_card('j_busterb_joker')) then
if _type == 'Joker' and _append == 'sho' then
local poll = pseudorandom('rarity'..G.GAME.round_resets.ante.._append)
if poll < (1/20) then
_legendary = true
end
end
end
return oldgetcurrentpool(_type, _rarity, _legendary, _append)
end```
hook the set cost function and make it not assign a price if it's relevant
in local oldgetcurrentpool or SMODS.Joker?
i'm sure there are potential scenarios in which you'd prefer to wrap a hook into a joker definition
but that's not what I'm suggesting
literally just hook it. if it's legendary and in the shop and that joker exists, make it free
if joker is legendary? i've never seen the format for that context
actually i've rarely ever used rarity checking
or i've never used it at all
so i'm not familiar
I don't know the syntax by heart, my guy, I don't see why I'd be the one checking it when you can just check baseball card and see how something like that works
this is what i didlua if context.other_joker and (context.other_joker.config.center.rarity == 4 or context.other_joker.config.center.rarity == "Legendary") then if G.shop_jokers then for _, card in pairs(G.shop_jokers.cards) do card.ability.couponed = true card:set_cost() end end end
frankensteined asf
Is couponed a pre existing thing that makes cards free?
Also very much recommend to not use function parameters as variable names for loops. Makes code way less readable and way more likely for something to slip by you
a lot of tags use it actually
Ah
Okay, so, I really recommend you just mess around with contexts work because you seem to consistently use them entirely arbitrarily
Or I might be out of my depth and context.other_joker also triggers when the shop is rerolled
do i just add G.shop_jokers in the giant context pillar?
Giant context pillar?
if context.other_joker and (context.other_joker.config.center.rarity == 4 or context.other_joker.config.center.rarity == "Legendary") and G.shop_jokers then
as opposed to
if context.other_joker and (context.other_joker.config.center.rarity == 4 or context.other_joker.config.center.rarity == "Legendary") then
if G.shop_jokers then
how do you set the price to 0
This is the exact same code, and unless I'm misunderstanding how that context works, it wouldn't work
Yeah, no, I checked just to be sure, but other_joker, like context.individual, is just a context that triggers during the main evaluation
gee golly, what am i doing wrong
I just said what you're doing wrong
But I recommend just rubber duckying, making some dummy code and trying stuff with print statement debugging to figure out how the code handles itself, because I'm not sure I'm the right person to help you. You seem to rarely really pay attention to what I try to explain to you.
Ah
i don't actually know a lot of lua, people just tell me what shit is and i just roll with it, hoping it works.
Anyway, I really really recommend rereading the smods wiki page on the calculate functions, so you can refamiliarize yourself with contexts. Also, remember that tools like VanillaRemade exist. Barely anyone here actually knows a lot of these things by heart, so very often if you ask someone how to do something that happens in vanilla, you're just having someone else check their dump, or the source code, or vanillaremade, etc.
i'm trying to make legendaries in the shop free yes
through a joker
except your code suggests that if you own a legendary, all cards in shop (not boosters or vouchers) are free
or through a get_current_pool
Maybe try to actually learn lua a bit if you're working with it for a project, though. Otherwise you're just hoping other people will respond to your questions often enough so that they write your code for you. And you won't be able to debug it yourself either
1.5 years of Lua affected my perspective on other languages
If you're unsure of how to make an effect work, do it piece by piece. Just one if statement at the time, without stacking them, and see if it's still going well.
i'm not cut out for this shit, i'm considering getting rid of everything for a while now.
cause people will think i'm a poser for making a mod.
1.5 years of other languages affected my perspective on lua
It doesn't help to tell yourself you don't know a language and just accept that as fact. Its your own responsibility to learn and it's not gonna happen if you just decide you don't know something.
Allow yourself to learn the modding framework a bit, because it's a lot more fun to make mods if you can be just the slighest bit confident in what you're typing. I barely know Lua either, as literally all my knowledge of it is through balatro mods
do i wanna read everything word by word, verse by verse, until i can no longer remember how to do my other hobbies?
i fear i would lose one in trade for another
I give up, man
figure it out or don't
my apologies for probably reacting a bit stronger than necessary btw
familiarize yourself by looking at other mods (this is usually easier for perculiar effects not available in smods)
slowly expand your knowledge about how balatro works as you progress
i should've just asked somebody else to do the mod for me.
i started off just as confused as you, what you could do to practice is checking out the steamodded wiki or seeing how vanilla balatro or other mods do it
you will get familiar with it over time
how many jokers have you made
you could check how the D6 tag does it
if you already have legendaries that spawn in the shop
but while im not the perfect guy to ask, maybe ask the others with more experience, they may be willing to help you out with the task
you could look at the astronomer joker code (in vanilla remade) which makes planet cards free
i think i wanna do it the way astronomer does it```lua
SMODS.Joker {
key = "astronomer",
unlocked = false,
blueprint_compat = false,
rarity = 2,
cost = 8,
pos = { x = 2, y = 7 },
add_to_deck = function(self, card, from_debuff)
G.E_MANAGER:add_event(Event({
func = function()
for k, v in pairs(G.I.CARD) do
if v.set_cost then v:set_cost() end
end
return true
end
}))
end,
remove_from_deck = function(self, card, from_debuff)
G.E_MANAGER:add_event(Event({
func = function()
for k, v in pairs(G.I.CARD) do
if v.set_cost then v:set_cost() end
end
return true
end
}))
end,
check_for_unlock = function(self, args) -- equivalent to unlock_condition = { type = 'discover_amount', planet_count = 12 }
return args.type == 'discover_amount' and #G.P_CENTER_POOLS.Planet <= args.planet_count
end
}
local card_set_cost_ref = Card.set_cost
function Card:set_cost()
card_set_cost_ref(self)
if next(SMODS.find_card("j_vremade_astronomer")) then
if (self.ability.set == 'Planet' or (self.ability.set == 'Booster' and self.config.center.kind == 'Celestial')) then self.cost = 0 end -- I just wanna know how i should change this one
self.sell_cost = math.max(1, math.floor(self.cost / 2)) + (self.ability.extra_value or 0)
self.sell_cost_label = self.facing == 'back' and '?' or self.sell_cost
end
end```
jokers have a rarity attached to them, maybe you can see where the rarity is located?
somehow I saw a different way without hooking
all i'm really doing is frankensteining from multiple mods
if legendaries do spawn in the shop in your mod here, you can use baseball card's code and check whether the shop item is a Joker and it is a rarity of 4 (i think thats legendary)
local oldcardsetcost = Card.set_cost
function Card:set_cost()
local g = oldcardsetcost(self)
if self:is_rarity('Legendary') then self.cost = 0 end
return g
end
I'm gonna make a bunch of stats for every country, however, I do not know why I'm making this.. Maybe show it beside a Joker? like with a tag like badge or something.. Do you all have any ideas?
-# I dont even know how to do that ;-;
ok this is much easier to understand
Maybe not at all 🤷♂️
oh wait, do i still need to add the SMODS.find_card to make it only work if it's meant to be a joker's ability?
Yes.
why is everything free
i wish i was kidding
how exactly would you play a george washington
👍
set a local variable to true, loop over all played cards, and if any of them has a .base.id that isn't 14, set the local variable to false and break out of the loop
oh i thought of that, idrk if it would work
is this right?
loc_txt = {
name = 'flag',
text = {
"Played {C:attention}Aces{} with",
"give {C:red}+#1#{} Mult",
"If hand is {C:attention}more than 1 card{}",
"and {C:attention}all Aces{}",
"{X:mult,C:white}X#2#{} Mult"
}
}
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and context.other_card.base.id == 14 then
local all_aces = true
if #context.full_hand > 1 then
for _, v in ipairs(context.full_hand) do
if v.base.id ~= 14 then
all_aces = false
break
end
end
end
if not (#context.full_hand > 1 and not all_aces) then
return {
mult = card.ability.extra.add_mult
}
end
end
if context.after then
local all_aces = true
if #context.full_hand > 1 then
for _, v in ipairs(context.full_hand) do
if v.base.id ~= 14 then
all_aces = false
break
end
end
end
if #context.full_hand > 1 and not all_aces then
return {
xmult = card.ability.extra.x_mult
}
end
end
end
i'm confused about what you're trying to do in context.individual, but the context.after part looks mostly fine. you should switch it to joker_main (or final_scoring_step if you absolutely want to give the xmult at the very end of scoring), and currently it gives xmult if you played at least 2 cards and at least one of them is not an ace
Scholar
scholar checks if a single card is an Ace, not if the whole hand is Aces
Why aren't you using Card:get_id()?
also why are you trying to give XMult in context.after, rather than context.joker_main?
update i need a little help getting the planet card into the planet pool
here is my code:
key = "franklinplanet",
loc_txt = {
name = 'Franklin',
text = { '({V:1}lvl.#1#{}) Level up',
'{C:attention}The Franklin',
'{C:mult}+16{} Mult and',
'{C:chips}+200{} chips'}
},
set = { "planet", softlock = true },
cost = 3,
pos = { x = 8, y = 3 },
config = { hand_type = 'The Franklin' },
loc_vars = function(self, info_queue, card)
return {
vars = {
G.GAME.hands[card.ability.hand_type].level,
localize(card.ability.hand_type, 'poker_hands'),
G.GAME.hands[card.ability.hand_type].l_mult,
G.GAME.hands[card.ability.hand_type].l_chips,
colours = { (G.GAME.hands[card.ability.hand_type].level == 1 and G.C.UI.TEXT_DARK or G.C.HAND_LEVELS[math.min(7, G.GAME.hands[card.ability.hand_type].level)]) }
}
}
end,
set_card_type_badge = function(self, card, badges)
badges[#badges + 1] = create_badge(localize('Man'),
get_type_colour(card.config.center or card.config, card), SMODS.ConsumableTypes.vremade_Planet.text_colour,
1.2)
end
}```
its saying i am attempting to add it into an empty pool, but the wiki says to set that its the 'planet' set
No, it's set = 'Planet'
the game crashes whenever i get the suit value from this
function SMODS.current_mod.reset_game_globals(run_start)
G.GAME.current_round.spinner_card = { suit = 'Spades' }
local valid_spinner_cards = {}
for _, v in ipairs(G.playing_cards) do
if not SMODS.has_no_suit(v) then
valid_spinner_cards[#valid_spinner_cards + 1] = v
end
end
if valid_spinner_cards[1] then
local spinner_card = pseudorandom_element(valid_spinner_cards, pseudoseed('spinner' .. G.GAME.round_resets.ante))
G.GAME.current_round.spinner_card.suit = spinner_card.base.suit
end
end
Log?
(G.GAME.current_round.spinner_card or {}).suit
No, you need to replace every G.GAME.current_round.spinner_card.suit with (G.GAME.current_round.spinner_card or {}).suit
Code?
Which line is line 318?
(G.GAME.current_round.spinner_card or {}).suit = spinner_card.base.suit
oh
my god
No, don't change the ones in SMODS.current_mod.reset_game_globals
fixed that, still crashes
i figured it out
turns out i had to replace (G.GAME.current_round.spinner_card or {}).suit with (G.GAME.current_round.spinner_card or {suit = 'Spades'}).suit
No, it's (G.GAME.current_round.spinner_card or {}).suit or 'Spades'
works either way ¯_(ツ)_/¯
how do i change the description of a card based on a value?
i dont mean like #1# i mean like a new line being added when a condition is met
how easy is it to tell what caused a card to be destroyed?
want to make a joker that scales when a food joker destroys itself, but i have no clue where to start with the “if it destroys itself” condition
dont want it triggering from something like sac dagger or ankh
hey guys how would I apply a custom sticker to a card via consumable
not sure that's possible unfortunately
take_ownership time 
SMODS.Stickers.modprefix_stickerkey:apply(card, true)
where modprefix_stickerkey is your mod prefix and the key of the custom sticker, and card is the card object you're applying the sticker to
ok thanks
trigger = 'after',
delay = 0.1,
func = function()
SMODS.Stickers.modprefix_stickerkey:apply(card, true)
return true
end
}))``` so then this is good
no you need to replace modprefix_stickerkey with your actual mod's prefix and the actual key of the sticker
ok but other than that its fine, right
otherwise yea that should be good
if card.skip_destroy_animation
ok
wait is that actually just exclusively used for self-destruction? or are there some edge cases where its not used in self-destruction, or is used in a place that isnt self destruction, that i have to account for
in vanilla yes, other mods might use it differently
local conv_card = G.hand.highlighted[1]
G.E_MANAGER:add_event(Event({
func = function()
play_sound('jabong_damn')
card:juice_up(0.3, 0.5)
return true
end
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
SMODS.Stickers.jabong_operad:apply(card, true)
return true
end
}))
delay(0.5)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
G.hand:unhighlight_all()
return true
end
}))
end,```
its applying to the consumable, please help ke
dont use card then
good enough™
from looking at code for various mods doing food joker stuff there seems to be a sorta… joker tag system going on with that?
what are the specifics on that and does it come with the food jokers already tagged or would i need to add the vanilla ones
use conv_card
No, it's conv_card:add_sticker('modprefix_key', true)
right my bad
cardis the card object you're applying the sticker to
as N said, use the conv_card you already specified earlier
it's an ObjectType, most mods copy the cryptid one
i think vanillaremade wiki has the code
it comes with the vanilla ones and other people can tag their jokers as Food
i assume the consumable adding the sticker wants to bypass checks if the card is compatible with the sticker, but yea that's also correct
what's up with the G table?
oh nvm, it was because I opened a directory below the smods folder
what's up with this code? Anything stand out as clearly wrong?
Yes, it's card:juice_up not card.juice_up
game still crashed 😔
You're missing y = before the 0
wait
ah yep, I just noticed this too haha
how do you get the chips that are about to be scored when in contextjoker_main?
I want to set a var to a percentage of the about-to-be scored chips
ah nvm, I found G.GAME.chips. Is that it?
SMODS.calculate_round_score()
ah, ok
@bold sleet getting relatively close in my PR, main issue is there's some weird indexing issues I have to figure out with selecting/deselecting packs, and then adding some UI juce like dissolve effects and what
Oh right and I'll add a button for selecting so you can easily drag within the priority list, since right now it selects/deselects on click
ok how would i make my own currency
there's no easy API for that but i do know a mod with a million new currencies
(hotpot)
there's also paya's terrible additions
yeah i wanna reporuduce what hotpot did with its currencies
any tips?
good luck
how do you change the text (from a localization file) for a joker?
the code is in a bunch of places
im cooked arent i
like rewriting a vanilla joker?
no, I want a modded joker to change its loc_text after a condition is reached
oh check the vanillaremade wiki
I'm making a tree joker that grows over time
there's a section for that
which joker's loc changes in vanilla? 😳
ah, ok
I assume this is it; do I put this return statement inside the joker that I'm changing?
thank ya kindly
so from the perspective of the localization file, it's two separate jokers?
yeah
interesting
something's wrong with my loc_txt D:
nvm. selling it and giving me a new copy of it fixed the loc_txt
anybody know what values to check for in a check_for_unlock that checks if the player loses to a finisher blind?
now it's complaining about this if statement
if cardExtra.growth >= cardExtra.maxGrowth and cardExtra.stage < 3 then
cardExtra.stage = cardExtra.stage + 1
cardExtra.growth = 0
cardExtra.maxGrowth = cardExtra.maxGrowth * 1.5
card.children.center:set_sprite_pos({ x = cardExtra.stage, y = 0 })
end
specifically, the first line of the if statement
how are cardExtra.[properties] declared here?
use card.ability.extra.[property]
I have this
is that necessary? try debugging with the standard
unsure if lua uses cardExtra as a pointer reference here
it's not necessary, but I hate having to rewrite the whole thing everytime 😔
Ctrl+F
replace cardExtra with card.ability.extra
i dont recognise this error
oh!
I will probably change some stuff after your PR and what not.
im guessing my mod doesnt fw editions
Feel free, not my mod
check in game over context?
i decided to change the prefix for my mod and its causing all sorts of funny errors so far
unsure where in this line it also checks if the player loses the run
additionally, I'm trying to make a blueprint-like joker that activates the joker to its left and the joker to its right
You mean it copies?
yeah
probably just add extra stuff in the return though
just unsure if i can rename the other_joker variable here
probably can
local effects = {}
for k, v in pairs(G.jokers.cards) do
if v == card then
if G.jokers.cards[k-1] then local effect = SMODS.blueprint_effect(card, G.jokers.cards[k-1], context); if effect then table.insert(effects, effect) end end
if G.jokers.cards[k+1] then local effect = SMODS.blueprint_effect(card, G.jokers.cards[k+1], context); if effect then table.insert(effects, effect) end end
end
end
return SMODS.merge_effects(effects)
ok i got rid of the edition and now im trying to make a sound effect thing
got this error
why is jokerforge like this
this is the sounds.lua file
this is the consumable that creates the sound
the crash message is saying I am comparing a table to a value at line 20, despite both being integers. What's wrong?
okay woah balatro REALLY doesn't like my joker
crashed as soon as i summoned it
no error message just straight up closed the game
lua moment
its that youre running probability checks without a context check
ope noticed something else too
bump
how do you play a sound effect inside of a return
how can i make a second "compatible/incompatible" text appear here
if to_big(card.ability.extra.growth) >= to_big(card.ability.extra.maxGrowth)
pleae omeone i need this
you'll want to put it in an event (picture from vanillaRemade)
sound = 'modprefix_key'
whats the sound for balancing
sound = 'gong'
do i see the goat of goats
what are all the args.type variants i can use for check_for_unlock
I'm getting an error on cardExtra.center:set_sprite_pos({ x = math.floor(cardExtra.stage / 3), y = 0 }). Do I have to put it in a to_big() again?
hi dilly!!!
nvm I figured it out
is there such thing as a args.type == 'round_lose'
hi bestie :D
i hope youve been well
what would the correct implementation of this be
check_for_unlock = function(self, args)
if G.GAME.blind.boss and G.GAME.blind.boss.showdown and args.type == 'round_lose' then
return true
end
end
No.
No, it's G.GAME.blind.config.blind.boss and G.GAME.blind.config.blind.boss.showdown
I'm getting an error at line 73. Anyone know why?
No, use SMODS.add_card
is this correct?
Yes.
can a local variable specified in loc_vars be modified in calculate and then referenced in check_for_unlock?
No, because it's local, it doesn't exist outside of where it is defined.
how might i check for game over in check_for_unlock then
also having some issues getting multiple compatible infomarkers to display
Guys what code would I need to change the texture of a specific joker and not all the jokers?
Where exactly would I find this, if I may have a look at it?
This is a hook to the pseudoseed() function that, if another flag is set, advances a given seed in a temporary table until the flag is reset
I use this to predict booster pack contents:
Very cool, I'll see if I can figure that out.
ok so, im trying to make the game play a sound effect
problem is, jokerforge's sound thing is a bit busted
so now im trying to figure out how to fix it
this is sounds.lua
key="mega",
path="hatch_mega.ogg",
pitch=0.7,
volume=0.6,
}```
in hatchet\assets\sounds you will find this file:
but it doesnt work
the game cant find it
in the play_sound call (or wherever you're putting the sound's key), you need to add your mod's prefix to the sound key. i.e. if your prefix is "hatchet", it'd be play_sound("hatchet_mega"), not just play_sound("mega")
ok so i found out it is indeed a recent jokerforge bug
but yeah i did it and it doesnt work
changed it to
key="mega",
path="mega.ogg",
pitch=0.7,
volume=0.6,
}```
this is still true
oh wait
the sounds folder needs to be inside your mod's assets folder
@viscid talon
i looked in the github for your mod
your mod prefix is "hatchet", not "hatch"
it needs to be play_sound("hatchet_mega")
thats an older version
the prefix has been changed to "hatch"
hold on, ill release a beta version rn
ya i've gotta run to class but hopefully someone else can help you
Why can't you push all the changes in a single commit?
fr 😭
idk how to do that
im not smart
There is no sounds folder in assets
oh i didnt push that
hold on
wait how
i swear i did
ok hold on
ok done
Are you loading sounds.lua?
oh shoot, thats missing from main.lua
HOW
the big issue with jokerforge is that its a bit too simple for what it is i wish to create, hence why i have a "backup" folder i always have to use to overwrite jokerforge's exports
ok uh, it works now
thankes
theres some small bugs but i can fix them
ok now its not working agian
booted up an older mod, and the same error comes up
this is definitely an error on jokerforge's side
probably report it in the jokerforge thread in #1209506514763522108 then
already reported it to their discord
this has been affecting other mods too it seems
heres the mod zip
im gonna hop to bed
how do i copy a card and add it to the deck... without adding it to the hand or otherwise having it just kinda awkwardly... stick around and not do anything
it just goes straight to the deck
i made a joker that spawn a random joker in my hand is there a way to make it so the joker i spawn get a random edition?
local new_card = create_card('Joker', G.jokers, nil, nil, nil, nil, random_key, nil)
new_card:add_to_deck()
G.jokers:emplace(new_card)
hi guys i need a little help D:
im trying to make a variant of the idol, heres my code (it's mostly from VanillaRemake):
key = "luigi",
loc_txt = {
name = 'Find Luigi',
text = {
'One random card in',
'your deck will give',
'{X:mult,C:white} X3 {} Mult when scored',
'{s:0.8}Card changes every round'
},
},
pos = { x = 1, y = 4 },
atlas = 'luigi',
rarity = 3,
blueprint_compat = true,
cost = 5,
config = { extra = { xmult = 3 } },
loc_vars = function(self, info_queue, card)
local luigi_card = G.GAME.current_round.clo_luigi_card or { rank = 'Ace', suit = 'Spades' }
return { vars = { card.ability.extra.xmult, localize(luigi_card.rank, 'ranks'), localize(luigi_card.suit, 'suits_plural'), colours = { G.C.SUITS[luigi_card.suit] } } }
end,
calculate = function(self, card, context)
local luigi = G.GAME.current_round.clo_luigi_card
if not luigi then return end -- prevent nil indexing
if context.individual and context.cardarea == G.play and
context.other_card:get_id() == G.GAME.current_round.clo_luigi_card.id and
context.other_card:is_suit(G.GAME.current_round.clo_luigi_card.suit) then
return {
xmult = card.ability.extra.xmult
}
end
end
}```
its been really difficult to check but from what i saw the joker never triggered
can someone help me out here?
https://github.com/nh6574/VanillaRemade/wiki#edition
also i recommend using SMODS.add_card
just emplace it into the deck
how so?
oo tyty
G.deck:emplace(card)
does clo_luigi_card exist
to my very little knowledge it should
do i do that instead of card:add_to_deck(), or in addition to it?
in addition, add_to_deck just calls whatever stuff it needs when the card is given to the player
uh i think i missed a step
clicking on the deck to show every card doesnt show the extra cards either
oh i see they're ghost cards
definitely means i fucked up somewhere though
can i see the code
G.deck:emplace(card_copied)
card_copied:add_to_deck()
SMODS.calculate_effect({message = localize('k_copied_ex'),colour = G.C.CHIPS }, context.scoring_hand[i])
G.E_MANAGER:add_event(Event({
func = function()
SMODS.calculate_context({ playing_card_added = true, cards = { card_copied } })
return true
end
}))```
relevant code
try adding
table.insert(G.playing_cards, card_copied)
besides that idk it looks fine
maybe add_card should have the possibility of just passing a card object instead of always creating one
since it already does all of that
smods pr 
i think there should be a copy_card wrapper
in what spot?
this is what add_card does, maybe the order matters
copy_card should already do the G.playing_card stuff
it might not, since vanilla effects that copy playing cards do it too
AH
g.deck.config.card_limit
how do you update the text when outside the blind after hooking the starting ante
change G.GAME.round_resets.blind_ante too
tnx!!
how do i make realtime-based mechanics? i've seen dt but i'm not sure how exactly that works
DeltaTime. This video is all about that mysterious variable that oh so many game developers seem to struggle with. How to use DeltaTime correclty? I got the answers and hope this video will help to deepen your understanding about how to make frame rate independent video games.
0:00 - Intro
0:34 - Creating The Illusion of Motion
1:11 - Simple Li...
it works for every other pack why doesn't this one want to function?
the loc_txt that is
Remove the :sub(1, -3)
aight
check the new comment
https://github.com/nh6574/VanillaRemade/blob/0d158691dc9aac5664bca0e09e531d93519fba04/src/boosters.lua#L15
SMODS.Seal {
key = "brunatre",
loc_txt = {
name = "Brunâtre Seal",
label = "Brunâtre Seal",
text = {
"{C:attention}Enhance{} this card when",
"it is {C:attention}retriggered{}",
}
},
pools = {["jabmfeature"] = true},
pos = {x = 1, y = 1},
atlas = "Enhancements",
badge_colour = HEX("B96762"),
unlocked = true,
discovered = true,
config = {
extra = {
triggered = 0
}
},
calculate = function(self, card, context)
card.ability.extra.triggered = card.ability.extra.triggered or 0
if context.main_scoring and context.cardarea == G.play then
card.ability.extra.triggered = card.ability.extra.triggered + 1
if card.ability.extra.triggered > 1 then
G.E_MANAGER:add_event(Event({
trigger = 'after', delay = 0.5,
func = function()
local enhancement = SMODS.poll_enhancement({ guaranteed = true })
card:flip()
play_sound("tarot1")
card:set_ability(G.P_CENTERS[enhancement])
card:flip()
return true
end
}))
end
end
if context.after then
card.ability.extra.triggered = 0
end
end
}
Why isn't this working on Glass cards?
I got it to work but thx
wdym exactly
hold on lemme show you what i mean
okay so now it just shows this whenever i apply the seal to any card
but like it used to mess up for only glass cards
i've hooked Card:start_dissolve to save the info of the last destroyed playing card to various game run variables, and i want this joker to return a message containing the destroyed card's value and suit as a message when it's destroyed, which it does but a step short. basically what it does is it returns the previous destroyed card's info, not the most recent destroyed card's info. how would i rewrite this to make it update with the most recent card's info?
if context.remove_playing_cards and not context.blueprint then
if G.GAME.last_destroyed_card_value ~= nil and G.GAME.last_destroyed_card_suit ~= nil then
return {
message = G.GAME.last_destroyed_card_value .. ' of ' .. G.GAME.last_destroyed_card_suit,
colour = G.C.FILTER
}
end
end
seals don't save to card.ability like cards do afaik
ohhhh
try saving stuff directly to card.ability instead of .extra
and use the mod prefix to not overlap with other mods
it's card.ability.seal.extra.etc
^ seals save their ability table to card.ability.seal
oh that's nice to know
got it thanks everyone
why do you need to use the global there if the context has the cards
so it can use the last destroyed card even if you don't have the joker
it's the run's last destroyed card
ok but why there
for simplicity's sake so i can just use the same vars everywhere, but i spose i could just use the context's values
No, hook Card:remove
i was already hooking dissolve for jokers so i just use the same hook
And save self:save() to one global variable instead of a lot of global variables.
Also put your mod prefix on the variable.
alright
And you just do message = G.GAME.modprefix_last_destroyed_card.base.name
Hello, I have a joker that upgrades when a card is scored, I currently have a message for when the joker upgrades and im trying to play a sound along with the message however I want this sounds' pitch to be unaffected by the amount of time elapsed during scoring and to change the volume. trying to return a function or adding an event in the return function plays the sound only once when scoring starts and returning an event with a function within it results in the sound timing being offset by other jokers that affect playing cards
SMODS.calculate_event doesn't exist.
Put the event in a func
sorry, meant add_event()
so return func that contains an added event?
Yes.
its an improvement but this method delays the sound until the next joker card scores
Code?
if context.individual and context.cardarea == G.play and not context.end_of_round and not context.blueprint then
card.ability.extra.totalxmult = card.ability.extra.totalxmult + card.ability.extra.addmult
card.ability.extra.chain = card.ability.extra.chain + 1
local current_chain = card.ability.extra.chain
return {
card = card,
message = card.ability.extra.chain .. "-Chain!",
func = function()
G.E_MANAGER:add_event(Event({
func = function()
if current_chain < 7 then
play_sound("tlj_ppc" .. current_chain, 1, .1)
else
play_sound("tlj_ppc7", 1, .1)
end
if current_chain > 5 then
play_sound("tlj_ppcspell", 1, .05)
end
return true
end,
}))
end
}
end```
what's this about?
How do you completely remove a poker hand type until a certain condition
Is this for a new hand or a hand in the base game?
In the base game
If that's the case, first thing would probably be taking ownership then updating the evaluate function
check context.evaluate_poker_hand
https://github.com/Steamodded/smods/releases/tag/1.0.0-beta-0711a
also SMODS.is_poker_hand_visible if you also want to hide it from the menu
Tnxx
Trying to works with quantum enhancements with the idea of the enhancement changing every round (like Ancient Joker with suits). I have that part down, with my only issue now being actually applying the enhancement. G.GAME.current_round.gowild_wild_joker.enhancement stores the enhancement's key. (I'll get to apply locations later, I want to focus on getting the enhancement to apply first). I'm not sure what should be in the return, if there is a solution at all
calculate = function(self, card, context)
if context.check_enhancement and context.other_card:has_enhancement("m_wild") and context.cardarea == G.play then
local enhancement = (G.GAME.current_round.gowild_wild_joker or {}).enhancement or 'm_mult'
return {
G.P_CENTERS[enhancement] = true,
}
end
end,
local r = {}
r[enhancement] = true
return r
working as intended ty!
i feel like it's the same.
Hello, i'm trying to make my own mod and i'have an issue with my joker, can i post the crashlog here? for having help
i don't understand why it crashed
you have a syntax error near line 6 of your TheShow.lua file
Right now I'm trying to make a custom splash screen and well..
I'm having issues onn how time was set up
SMODS.Joker{
key = "The Show",
config = { extra = { x_mult = 2 } },
pos = { x = 0, y = 0 },
soul_pos =nil
rarity = 1,
cost = 20,
blueprint_compat = true,
eternal_compat = true,
unlocked = true,
discovered = true,
effect = nil,
atlas = 'theshow',
calculate = function(self, card, context)
-- Lorsqu’un joker est vendu
if context.selling_card and context.other_joker then
-- Vérifie si le joker vendu est un Showman
if context.other_joker.ability.name == "showman" then
-- On augmente le multiplicateur stocké
card.ability.extra.x_mult = (card.ability.extra.x_mult or 1) + 1
-- Pour tous les autres Showman encore en jeu
for _, j in ipairs(G.jokers.cards) do
if j ~= context.other_joker and j.ability.name == "showman" then
shakecard(j)
end
end
return {
message = "x" .. tostring(card.ability.extra.x_mult),
colour = G.C.RED,
x_mult = card.ability.extra.x_mult
}
end
end
end,
loc_vars = function(self, info_queue, card)
return {
vars = { card.ability.extra.x_mult },
key = self.key
}
end
}
SMODS.atlas{
key = 'theshow',
path = SMODS.current_mod.path .. 'assets/jokers/TheShowMustContinue.png',
frame_w = 71,
frame_h = 95,
}
i don't understand what is my error, it all seams good for me
you can remove the soul_pos =nil line (it's missing a comma after nil which is why it's crashing, but it's nil by default so it's unnecessary to put it)
this is what I have made but due to the time never being synced into skipping, I have it like this.
( trust me for the past 2 days I tried to work on triyng to modify the splash screen in some way)
unless there is a way for it to like maybe have the screen to be managed into like skippable.
im still struggling with this code D:
im just trying to get the idol but i cant figure out how to get it to actually trigger
key = "luigi",
loc_txt = {
name = 'Find Luigi',
text = {
'One random card in',
'your deck will give',
'{X:mult,C:white} X3 {} Mult when scored',
'{s:0.8}Card changes every round'
},
},
pos = { x = 1, y = 4 },
atlas = 'luigi',
rarity = 3,
blueprint_compat = true,
cost = 5,
config = { extra = { xmult = 3 } },
loc_vars = function(self, info_queue, card)
local idol_card = G.GAME.current_round.clo_idol_card or { rank = 'Ace', suit = 'Spades' }
return { vars = { card.ability.extra.xmult, localize(idol_card.rank, 'ranks'), localize(idol_card.suit, 'suits_plural'), colours = { G.C.SUITS[idol_card.suit] } } }
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and
context.other_card:get_id() == G.GAME.current_round.clo_idol_card.id and
context.other_card:is_suit(G.GAME.current_round.clo_idol_card.suit) then
return {
xmult = card.ability.extra.xmult
}
end
end
}
local function reset_clo_idol_card()
G.GAME.current_round.clo_idol_card = { rank = 'Ace', suit = 'Spades' }
local valid_idol_cards = {}
for _, playing_card in ipairs(G.playing_cards) do
if not SMODS.has_no_suit(playing_card) and not SMODS.has_no_rank(playing_card) then
valid_idol_cards[#valid_idol_cards + 1] = playing_card
end
end
local idol_card = pseudorandom_element(valid_idol_cards, 'clo_idol' .. G.GAME.round_resets.ante)
if idol_card then
G.GAME.current_round.clo_idol_card.rank = idol_card.base.value
G.GAME.current_round.clo_idol_card.suit = idol_card.base.suit
G.GAME.current_round.clo_idol_card.id = idol_card.base.id
end
end```
i have tried every combination of adding my prefix (clo), changing the idol key to something else, keeping either
nothing seems to work :(
I think it's kinda perfect now.
that splash screen is 
G.GAME.current_round.clo_idol_carddoesn't seem to exist beforehand, or if it even does, there's noidfield for comparison tocontext.other_card:get_id()- did you put
reset_clo_idol_cardinSMODS.current_mod.reset_game_globals?
that first thing is what im trying to figure out
how do i define G.GAME.current_round.clo_idol_card
and for 2 no not yet i wanted to make sure the card actually works before getting to resetting every round
but i understand if thats the problem
omg yeah it was the second thing LMAO
ok find luigi now functions
ill need to buff it though because finding him is very difficult
I should have seen this kind of thing coming given how heavily Balatro uses shaders, but this still awes me
how do you check in a file if its being loaded from SMODS.include_file?
trying to apply the pixel reaolution to the shader but it ends up like this.
Yeah, and these shaders I'm making was for the mod.
though kinda wished maybe you can like have custom splash screens and backgrounds
unlocked = false,
locked_loc_vars = function(self, info_queue, card)
return { vars = { 18 } }
end,
check_for_unlock = function(self, args)
return args.type == 'discover_amount' and #G.P_CENTER_POOLS.Spectral <= args.spectral_count
end
would this be safe to check if the player has discovered all spectral cards, or should i just directly compare against 18 within the unlock function
Shadertoy 101
This is a planned feature of smods at some point being able to customise the main menu cleanly
absolutely confused by the relationship between #G.P_CENTER_POOLS.[Subollection] and args.[Subcollection]_count since it seems like
the amount of discovered cards in a collection is less than or equal to the number of cards in that collection would always return true
yay!
finally got the pixel shader thing to work
idk if that's possible
adym
