#💻・modding-dev
1 messages · Page 649 of 1
i would expect that to always be 1
i assume 2 is the first entry in slots_to_retrigger
use SMODS.calculate_effect instead
repetitions are already checked once per card
^
So I am looking the Vanilla Remade and ripping the codes and mixing them up but I feel like I am missing something
SMODS.calculate_effect can't do retriggers.
:0
this doesnt work for anything that requires actually passing out the information to elsewhere, which is like anything other than scoring and money effects
do i do it in an individual hand context then
context.repetition
which runs once per card to retrigger
okay
is there a way to get an individual card's hand index from its other_card object
what for
checking if it should be retriggered against the slots_to_retrigger table
don't try to get the index
just loop over slots_to_retrigger, and check if G.hand.cards[slot] == context.other_card
if that's true for any of the slots, then retrigger
alright
My joker is trying to look for any played enchantment and store it when it finds it so it can put it on a different card (in the same hand). Would it be able to put it on a previous card?
yes but whether the enhancement counts to scoring or not depends on the contexts you use
i would recommend using context.before then looking through the hand with
for index, value in ipairs(G.play.cards) do
value is the current card being checked and index is the position of the card, so index = 1 is the leftmost, then it goes to the right
gotcha, it should do a midas type of check, thats the template im using. So yes, it would enchant pre-scoring
if you want it on the previous card you'd first check if G.play.cards[index - 1] exists, then apply the enhancement to it if it does exist
its just gonna pick a random card index other than the found enchant to use
its called stray magics for that reason
oh well then you would first save the index of the found card then use pseudorandom to pick another
Will do!
What is unique source string?
pseudorandom("seed", min,max) seed is a string that can be anything
the min should be 1 the max should be #G.play.cards
local randi = pseudorandom("modprefix_another_seed", 1, context.scoring_hand:size())
^ this is what i got
it's so you can only eliminate the debuff with the same string
like a password
scoring_hand only hits cards which score, not every card in the hand, do you want it to work on unscored cards or not
that is a good question honestly, I figured it would only be scoring but it could work on unscored, could work with everything held and still be in theme? That may make it less viable tho
Where within Vanilla Remade are Joker codes. Not their text description
midas got nerfed to not hit unscored a while back because of the insane vampire synergy
so its up to you how you treat it but
I was unaware, that makes so much sense
what is the joker pasrt
if you want it to be only scored cards, replace G.play.cards with context.scoring_hand and itll be the same
I wouldnt be too concerned bc it can only enchant one card every played hand so it wouldn't be terribly op
gotcha
I have
for i,v in ipairs(G.hand.cards) do
if v == card then pos = i break end
end
from the template
g.hand.cards is held cards in your hand
kk ill switch it out
g.play.cards is the full hand you played
g.deck.cards is the remaining cards in your deck
ima start a google doc with all the tips tbh
g.playing_cards is every card in your full deck, even those played or discarded or stuff
vanillaremade already has this kinda stuff in it im not sure if youd need to
tis true, I stole the midas reference from therer
it solves almost every problem
Ill keep referencing it, thanks for the help!
How can I check if a consumable is from a booster pack and not from your consumable slots?
in what scenario
im guessing they mean if you used a tarot from a pack or from your joker slots
used or just it existing?
used
in which case just check if it's in the booster pack card area when it is used
i do not remember the name of it but there is an area for it somewhere
check context.area
I tried if card.area == G.pack_cards then in the use function but it's not making a difference
card.area will always be G.play since its moved there for the use animation
use doesn't have context though
oh is this for the consumable itself
yeah
then just check area == G.pack_cards
whats the contexts for when a joker is destroyed
well then i can check if set is joker so
yeah
thatll work
context.card i think?
how do repetitions work?
in my case im trying to make a "reversed" brainstorm
kinda
Confused
if you're trying to make a joker that copies other jokers, like blueprint/brainstorm, that's a distinct feature from joker retriggers, which is a distinct feature from playing card retriggers
Revolutionizing
so which one are you trying to do lol
brainstorm but instead copies the ability of the rightmost joker
local ret = SMODS.blueprint_effect(card, G.jokers.cards[#G.jokers.cards], context)
if ret then
ret.colour = G.C.RED
end
return ret
takes a black and white picture of you and puts it in a file so wide you could use it as a stool
the file is labelled "people who changed left to right on blueprint/brainstorm"
thanks
you're pretty funny you know that
It should be k_modprefix_key in labels.
still prints as ERROR + the badge color doesn't change
am i supposed to change rarity to k_prefix_key?
No.
not how it's done on vremade
nvm it works
i have it without the k prefix in labels yet it works for me
what symbol?
Your calculate and first if is missing an end
can you show us the lines
you're estill not closing all the ifs in your calculate, you need one more end
there are a lot of other issues here too tho
like context.played isn't a thing
ok
how do you say when a hand is played
I need to setup a dictionary for the custom jokers
We made a joker called copycat that lets chat vote on what it should turn into
But the custom jokers end up being the j_prefix_name lol
In the list
is there anyway to change the config settings of another mod with my steammoddded mod?
SMODS.Mods["mod id"].config
awesome thanks
Anyone know how to change the textures of small blind and big blind in my mod?
redeeming a voucher during setting_blind makes it hang (no play or discard button)
are you doing it in an event
yes
what if you put that in another event
i tried putting the entire function code in an event
that caused the game to crash
or it mightve been betmma vouchers or something, honestly I dont know what happened
i will try double wrapping the function call in events i spose
is context.money_altered broken? Whenever I check for it, the game hard crashes
sounds like your smods is outdated
ah
double wrapping the function call in an event changed nothing
oh dang
hm
unless there was a specific issue associated with context.money_altered, i'd assume outdated smods would just not do anything with that calculation because context.money_altered would always be nil whenever it calculates
well then idk cause money_altered works fine for me
no idea then, the code might not be prepared for that state exactly
make sure youre returning true in the events
what is the crash
i am returning true
literally nothing
like, hard crashes
oh, what's your code?
i think whats happening is the game sends it back to setting_blind after the first hand got drawn, which makes the first hand not get drawn which breaks everything
removing the prev_state code didn't change this result though
you could change it to first_hand_drawn :3
i could wait until context.first_hand_drawn to redeem the voucher but id like to not have to do that
mostly because this effect triggers whenever food jokers get destroyed
seems like it's 0?
which ceremonial dagger does on setting blind
hmm
the lua code
wdym it's 0, what code are you trying to run lol
oh as in
haha
thought you meant exit code
:P
calculate = function(self, card, context)
if context.money_altered then
return {
dollars = card.ability.extra.dollars
}
end
end```
lol
this will infinitely loop
infinite loop crash
as
lol
ahhh
ah that would do it lmao
right, this makes sense
you should hook ease_dollars for an effect like this
Why is it not scoring
you're returning x_mult = card.ability.xmult when that doesnt exist
it should be card.ability,extra.xmult
everything else seems fine
thanks
apart from you are comparing every joker to a prototype object so this will debuff itself
yes
how to not debuff self
change if G.jokers.cards[i] ~= self then to if G.jokers.cards[i] ~= card then
you can also remove the first return that you have
and you have a check for a global joker_to_debuff value before you actually create that
thats intentional
ok
i delayed it to first_hand_drawn and it still didn't bring the play/discard buttons up
im wondering if its a good idea to manually set the state to the next one
what does your code look like?
it works fine for me on setting blind
there's just some jank with the hand area being visible
we fixed that by replacing the redeem line for use_card stuff
there is probably some stuff in here that is unnecessary with use card I would guess
yeah im very confused
I'm not doing anything with states though which I imagine is what causes your issues?
you have some extra stuff that doesnt seem super impactful (like voucher card add to deck) and the code for it being specific vouchers(?), where this one does random voucher, but outside that and the part with prev_state from before (which is now commented out and didnt solve it) i guess the events are different?
_delay is an argument my function puts in ive only ever used 0.8 for it though
i would think putting the whole function in an event is the same as calling the function in an event but i could be wrong on that
and your juice_card_until stuff, and whatever juice_hooligan does
oh yeah our events are totally different
your entire thing is an external function in an event?
it is an external function, but the function is called exclusively in events
can you show that?
its probably blockable and blocking i will try it without those
oh thats leftover code its not supposed to have setting_blind in there
i was trying to delay vouchers called during setting_blind to first_hand_drawn to fix it
there used to be more code with that its just leftover
in this hook, how could I cause the jokers to message that they added a money?
local ease_dollars_ref = ease_dollars
function ease_dollars(mod, instant)
if mod > 0 and next(SMODS.find_card("j_paperback_coin_collection")) then
for _, c in ipairs(SMODS.find_card("j_paperback_coin_collection")) do
mod = mod + c.ability.extra.dollars
end
end
return ease_dollars_ref(mod, instant)
end```
SMODS.calculate_effect({message = 'lol money'}, c)
Ah, that makes sense
danke
it doesnt do that anymore, but the same issue still happens
i hope its not a handy speedup thing
SMODS.Joker {
key = "jphone",
atlas = "My_Way_and_The_Highway",
blueprint_compat = true,
rarity = 1,
cost = 6,
pos = { x = 0, y = 1 },
config = { extra = { creates = 1 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.creates } }
end,
calculate = function(self, card, context)
if context.setting_big_blind then
local jokers_to_create = math.min(card.ability.extra.creates,
G.jokers.config.card_limit - (#G.jokers.cards + G.GAME.joker_buffer))
G.GAME.joker_buffer = G.GAME.joker_buffer + jokers_to_create
G.E_MANAGER:add_event(Event({
func = function()
for _ = 1, jokers_to_create do
SMODS.add_card {
set = 'Joker',
rarity = 'Uncommon',
key_append = 'vremade_riff_raff'
}
G.GAME.joker_buffer = 0
end
return true
end
}))
return {
message = localize('k_plus_joker'),
colour = G.C.BLUE,
}
end
end,
}```
(The overall plan for this joker is to buy an uncommon card virtually in a blind, but this code should just make an uncommon card for a big blind
and it doesn't)
I would definitely check this
how would i make a joker destroy the last played hand of a round?
its not handy speed, i disabled it same issue shows up
if context.after and G.GAME.chips >= G.GAME.blind_chips then
smods.destroy_cards(G.play.cards, nil, true)
end
something like this, but i dont remember the exact terms for these things or if it needs to be in an event or not
G.GAME.chips isn't updated by the time of context.after iirc
but i think ...and (G.GAME.chips + SMODS.calculate_round_score()) >= G.GAME.blind_chips should account for that
(help pls?)
context.setting_big_blind isn't a thing
just use context.setting_blind, and then you can check context.blind to see if it's a big blind (i dunno how off the top of my head, but i'm sure you can figure it out :3)
context.blind:get_type() == "Big"
is your mod prefix 276327632763 ?
SMODS.Joker {
key = "szymii",
atlas = "My_Way_and_The_Highway",
blueprint_compat = false,
rarity = 1,
cost = 4,
pos = { x = 1, y = 1 },
config = {extra = {target_suit = nil}},
calculate = function(self, card, context)
if context.before and not context.blueprint then
local suits, suits2 = {}, {}
for k, v in pairs(G.playing_cards) do
suits[v.base.suit] = (suits[v.base.suit] or 0) + 1
end
for k, v in pairs(suits) do
table.insert(suits2, {suit = k, count = v})
end
table.sort(suits2, function(a,b) return a.count < b.count end)
card.ability.extra.target_suit = suits2[#suits2-1]
end -- if there is exactly 1 suit with second-most frequency then we have a target
end
if card.ability.extra.target_suit ~= nil and context.repetition and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.target_suit) then
return {
repetitions = 1
}
end
if context.end_of_round and not context.game_over and context.main_eval and not context.blueprint then
card.ability.extra.target_suit = nil
end
end
}```
(coded this card wrong)
thats a hilarious mod prefix to have
no, it's xiferp
see above
isn't the phrase my way or the highway
i do believe your mod prefix is 276327632763
mywayANDthehighway
also yeah it is my way or the highway
I swore it was xiferp
{
"id": "276327632763",
"name": "Balatro_My_Way",
"author": [
"Jimbo Joshua Jokkeman"
],
"description": "The kind of Balatro I wanted to make for... a couple of months but never did",
"prefix": "xiferp",
"main_file": "Balatro_My_Way.lua",
"priority": 0,
"badge_colour": "666666",
"badge_text_colour": "FFFFFF",
"display_name": "Balatro_My_Way",
"version": "1.0.0",
"dependencies": [
"Steamodded (>=1.0.0~BETA-0827c)"
]
}
Yeah, it's xiferp
oh thats the id- why is that the ID
cuz yes
Amazing mod id
dude
im so regretting making curator use mod IDs now
mfs gotta remember a 14 digit code to get your stuff
also your display name can have spaces
you should use display name probably
Well, that's not the point
display name could have overlaps though
i used IDs cause they are unique but
i wasnt really considering the guy who made the mod ID 240 billion
this is
or actually this
can you not debug your own code ?
im guessing it might just be because you used pairs with g.playing_cards which is an indexed list so it should use ipairs?
if you use the wrong one the loop just doesnt run
but also yeah you should debug your own stuff
That is not how it works
Oh, wait, had an extra end
ok but it is, ive had this issue so many times
Pairs is just not ordered but goes over all indexes that exist
ipairs doesnt work if its not an integer indexed table but pairs always works
Ipairs only goes over integer indexes starting at 1 and ending at the first nil
it makes sense but grumble
i wish it would say something instead of just not running
it's because tables can have both
you could have a table like this
{ 1 = "x", 2 = "y", func = "placeholder" }
and you could run ipairs on it to just iterate over the first two entries or pairs to iterate over all of them
you should still use ipairs when possible because pairs doesn't guarantee that integer-indexed tables will be iterated over in order
this feels like forbidden knowledge that i can use for some fucked up shit somehow
but i cant come up with any fucked up shit to do with it
Okay, now it isn't crashing the game, but nothing
no impact
SMODS.Joker {
key = "szymii",
atlas = "My_Way_and_The_Highway",
blueprint_compat = false,
rarity = 1,
cost = 4,
pos = { x = 1, y = 1 },
config = {extra = {target_suit = nil}},
calculate = function(self, card, context)
if context.before and not context.blueprint then
local suits, suits2 = {}, {}
for k, v in pairs(G.playing_cards) do
suits[v.base.suit] = (suits[v.base.suit] or 0) + 1
end
for k, v in pairs(suits) do
table.insert(suits2, {suit = k, count = v})
end
table.sort(suits2, function(a,b) return a.count < b.count end)
card.ability.extra.target_suit = suits2[#suits2-1]
end -- if there is exactly 1 suit with second-most frequency then we have a target
if card.ability.extra.target_suit ~= nil and context.repetition and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.target_suit) then
return {
repetitions = 1
}
end
if context.end_of_round and not context.game_over and context.main_eval and not context.blueprint then
card.ability.extra.target_suit = nil
end
end
}```
no luck, no repetitions
KNow the issue: it isn't tablizing the suits
print("testing_table")
table.insert(suits2, {suit = k, count = v})
end```
Somewhere in this chunk of code is the main issue
in this code snippet, you switched it to ipairs, but the suits table isn't integer-indexed so it just skips the for loop entirely
this is not a very feasible task, you should have all the sprites for the joker on the same atlas and just change the position in-game
You would change card.children.center.atlas to G.ASSET_ATLAS['atlas_key']
Sorry Meta lol
oh does that immediately update the sprite?
lemme check that
I'm not sure but would not be surprised if it does since the game draws every update
thank you
i don't think it would, because the sprite object for the card already initialized with the atlas that the card originally set
lemme go test tho
Also if you need to change the sprite's position you would do card.children.center:set_sprite_pos({x = number, y = number})
card.children.center:reset() should
Hm. Okay, that part seems to work, but still no dice
oh huh it did switch immediately
i have been reinformed :)
Thank you ArtBox development for making me learn a lot about how this game does sprite drawing lmfao
i placed the destroy_cards in an event because it wasnt displaying correctly without it, but this seems to have created ghost cards
return {
repetitions = 1
}
end```
This isn't activating
help?
ok im confused why tf does this make ghost cards
Think I'm figuring it out: print(card.ability.extra.target_suit) is printing a suit and a value
I just wanted the suit
this might be after the cards are discarded in timing
That and it's not sorting the list by value
try context.destroy_cards
I think it's the event that's messing things up tbh
is context.destroy_cards late enough for me to be able to grab the score
without the event it visually destroys them before theyre scored
they still score but it looks jank
Ah nvm then
SMODS.Joker {
key = "szymii",
atlas = "My_Way_and_The_Highway",
blueprint_compat = false,
rarity = 1,
cost = 4,
pos = { x = 1, y = 1 },
config = {extra = {target_suit = nil}},
calculate = function(self, card, context)
if context.before and not context.blueprint then
local suits, suits2 = {}, {}
for k, v in ipairs(G.playing_cards) do
suits[v.base.suit] = (suits[v.base.suit] or 0) + 1
end
for k, v in pairs(suits) do
table.insert(suits2, {suit = k, count = v})
end
table.sort(suits2, function(a,b) return a.count < b.count end)
card.ability.extra.target_suit = suits2[#suits2-1]
end
if card.ability.extra.target_suit ~= nil and context.repetition and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.target_suit) then
return {
repetitions = 1
}
end
if context.end_of_round and not context.game_over and context.main_eval and not context.blueprint then
card.ability.extra.target_suit = nil
end
end
}```
sets card.ability.extra.target_suit to a table of two values, messing up the last part
it's literally the table.insert line you have
like that is actively intentionally what you are doing
you are inserting a table into the table
if i want to only destroy scoring cards i can just do remove = (context.destroy_card == context.destroying_card) right
I don;t wanna insert a table into a suit check
so access the suit in the inner table when you're setting target_suit
card.ability.extra.target_suit = suits2[#suits2 - 1].suit
or just use context.destroying_card and return true
activating on hearts now, not spades
now i gotta go make forever weed brownie incompatible with perishable lmao
(have spades as the lower suit to test)
Wait, it seems to work, hold on
Okay, it does work as expected barring ties
Now every card in my mod so far is successfully coded!
the first... dozen...
Least I know I don't have to worry about them as much code-wise
Honestly, love a funky interaction I coded in to one of the cards
Trust me, you find it, you'll love it
How would one make cards act as if they are a different rank?
why is it that everything I want to do is complicated or impossible
Another quantum ranks question to add to the pile
You mean only that rank or that along with it's original rank?
which one is easier
completely replacing the rank, not counting as both
like without replacing the card or changing the card
Yes, you would hook Card:get_id
wdym
the function Card:get_id is how everything in the game checks for rank
if you hook that, you can add logic that says "if the card is normally rank X but you have this joker, return rank Y instead"
can you return 2 ranks that are both different from the original?
no, as i just said, making a card count as more than one rank at once is the trickier option
ok
quantum ranks 😃
is there any ways to remove the rarity badges?
In function G.UIDEF.card_h_popup(card), if AUT.card_type == 'Joker' or (AUT.badges and AUT.badges.force_rarity) then card_type = SMODS.Rarity:get_rarity_badge(card.config.center.rarity) end line is most likely you need to influence, maybe?
Or just do the replacement with set_card_type_badge function in definition of the Joker?
@willow flower
I think vremade doesn't have atlases so check in the smods example mods I guess
https://github.com/Steamodded/examples/tree/master/Mods
it does have an example in the faq
Ouh
i'm trying to make an edition that allows playing cards to create a tarot card at the end of round whilst held in hand, but for some reason this happens twice (the joker part is fine though). how should i fix this? (on smods 1.0.0-beta-1016c)
calculate = function(self, card, context)
if ((context.playing_card_end_of_round and context.cardarea == G.hand)
or (context.end_of_round and context.game_over == false and not context.blueprint))
and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.0,
func = function()
SMODS.add_card {
set = 'Tarot',
key_append = 'bisexual'
}
G.GAME.consumeable_buffer = 0
return true
end
}))
return { message = localize('k_plus_tarot'), colour = G.C.PURPLE }
end
end,
i think you need to add context.main_eval to the part of the condition for the edition being on a joker
context.playing_card_end_of_round is just a secondary flag that's part of context.end_of_round so the joker condition is actually catching the edition on playing cards as well
ah alright, ty! (eta: to confirm, this fixed the issue!)
context.ending_shop doesn't happen at the same time as context.buying_card or context.open_booster
ah shit, what do i do then
If "skipping a shop" means ending the shop without purchasing anything you would have to set a flag on context.buying_card then check that the flag isn't set.
thanks
does adding Joker to your slot using DPlus trigger the add to deck?
any reason why alt+f5 suddenly stopped working? @_@
i think F5 only works
no such luck sadly, i have to alt f4 and boot up bala again when i make changes
you're on laptop?
correct
Fn + F5
that's bound to brightness down, i don't have an fn lock or anything enabled since pressing f5 by itself doesn't turn the brightness down
Try eval SMODS.restart_game() in the DebugPlus console.
that worked. is there a reason why alt+f5 isn't running this?
Trying to make this code work:
if context.remove_playing_cards then
local cards_to_destroy = {}
local count = math.min(#context.removed, #G.playing_cards)
for i = 1, count, 1 do
cards_to_destroy[i] = pseudorandom_element(G.playing_cards, "jester")
end
SMODS.destroy_cards(cards_to_destroy)
return {
message = "killed :)"
}
end```
At present, obviously its making an infinite loop
but what should I hook to not do this? `Card:remove()` is I think too late in the loop to do it
assuming that jester is a joker you need your prefix and a joker prefix on your 5th line, j_[prefix]_jester
You should set a flag in G for the joker before running SMODS.destroy_cards, and the remove it immediately after. Then just check if that flag isnt set before triggering the joker
hm, yeah that may work, i'll see if i can give it a shot
works, thanks!
hey guys i was wondering how i could create ui in balatro, what i want at the moment is a button that can be spawned in that runs a function when pressed, the ui page in steamodded is a little convoluted so i am asking for help
can you link me to vanilla remade
if you want to create a normal Tarot it should be set = "Tarot"
vremade uses a custom type as an example
what if you want to create a spectral
nvm
I misunderstood
do you need an atlas for tarot cards because the vannila remade doesn't show one
modded consumable cards without an atlas default to "Tarots"
yes
all textures require an atlas
blind textures require an animation atlas
thats what I thought
How do I set current chips and mult like plasma effect does?
I tried to copy the flint effect but chips seem to not work
(I set hand_chips and mult)
This is a problem with loc_txt or localization file
And with atlas if you added one
can i see the code
calculate = function(self, card, context) if context.main_scoring then return { func = function() hand_chips, mult = math.ceil(math.sqrt(hand_chips * mult)), math.floor(math.sqrt(hand_chips * mult)) update_hand_text({sound = 'gong', modded = true}, {chips = chips, mult = mult}) return true end, } end end
Its supposed to balance chips and mult but keep the score (for example 100 x 1 to 10 x 10)
try hand_chips, mult = mod_chips(math.ceil(math.sqrt(hand_chips * mult))), mod_mult(math.floor(math.sqrt(hand_chips * mult)))
SMODS' Scoring Calculation API takes over hand_chips and mult as scoring parameters, so modifying those globals directly no longer has an effect
the modification process is patched into mod_chips and mod_mult, so use those on the globals
Yeah it works, thanks
Is there a way to add like a round counter to the description of a joker
Or is that only for mults and chips
You mean like Loyalty Card?
Yeah
I probably just make a copy of it in joker forge see how it's done
looks like it uses remaning
I can probably make it work
if context.cardarea == G.jokers and context.joker_main then
if to_big((card.ability.extra.Remaining or 0)) <= to_big(0) then
card.ability.extra.Remaining = 5
play_sound("ttv_bomb_explosion", 1.0, 0.7)
G.E_MANAGER:add_event(Event({
trigger = 'after',
func = function()
if G.STAGE == G.STAGES.RUN then
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
end
end
}))
else
if context.end_of_round and context.game_over == false and context.main_eval then
card.ability.extra.Remaining = math.max(0, (card.ability.extra.Remaining) - 1)
end
end
end
end
}```
simple but effective
well guess I spot too soon doesn't work
I got this crash loc_vars = function(self,info_queue,center) local mult = 1 if G.GAME and G.GAME.dollars and G.GAME.dollars:to_number() < 0 then --This is line 1202 mult = 1 + math.abs(G.GAME.dollars:to_number()) * center.ability.extra.mult end return{vars = {center.ability.extra.mult, mult}} end, its weird
to_big(G.GAME.dollars) < to_big(0)
thx
How would I go about making standard packs include negative playing cards? Do I need to patch some code where the playing cards in packs decide their editions?
i would patch or hook poll_edition yeah, it's in smods/src/game_object.lua
but negative cards are very very powerful so consider carefully if that's what you want
i mean stuff like hone doesn't affect negative odds right?
so if they're always even rarer than polychrome i think that's fine
patch the function itself? i was thinking just patching some code where the standard pack calls it to have it include negatives in the poll
sorry i meant i would patch that line or hook poll_edition
i'm not sure how hooking would help. poll_edition isn't aware of what calls it, right?
it is because of the seed
unless you mean like make it include negative in the poll always, which sounds like a bad idea
ohh
hmm
hooking is better so you dont have any conflicts but patching is easier
so i'd need to hook it before it runs and do something like "if seed is whatever the standard pack is then no_neg = false"?
yes
How can I make something held in hand give x chips? Tried to return h_x_chips but it isn’t triggering
as an enhancement of sorts or as a hiker effect
Enhancement, like steel
return xchips in context.main_scoring
for some reason my game just randomly hard crashes after shop cards are created? i have genuinely no idea what could cause this since nothing ive done recently that could cause it as far as i know
I thought that would trigger it on scoring
there's two of them now, what's the difference?
idk what game dump is
i guess it's new with 0.9.0
no im not
context.main_scoring and context.cardarea == G.hand
Interesting okay
also h_x_chips should work from what im seeing
maybe h_xchips?
you should either return x_chips or have h_x_chips in the config
h_x_chips isnt a valid return value
I thought it was
thats not what that means
yeah thats for the config
read the text above
Is there a spot to see valid returns
- some calculations below have their own returns specified in the corresponding docs
SMODS.scoring_parameter_keys = {
'chips', 'h_chips', 'chip_mod',
'mult', 'h_mult', 'mult_mod',
'x_chips', 'xchips', 'Xchip_mod',
'x_mult', 'Xmult', 'xmult', 'x_mult_mod', 'Xmult_mod',
}
SMODS.other_calculation_keys = {
'p_dollars', 'dollars', 'h_dollars',
'swap', 'balance',
'saved', 'effect', 'remove',
'debuff', 'prevent_debuff', 'debuff_text',
'add_to_hand', 'remove_from_hand',
'stay_flipped', 'prevent_stay_flipped',
'cards_to_draw',
'message',
'level_up', 'func',
'numerator', 'denominator',
'modify',
'no_destroy', 'prevent_trigger',
'replace_scoring_name', 'replace_display_name', 'replace_poker_hands',
'shop_create_flags',
'extra',
}
if you want specificity.
Gotcha thanks
Cool that all worked
Slowly but surely I'm just collecting bookmarks on many resources so I can eventually have all of the information in the world about balatro modding and then I can just read things to fix things
oh god this is gonna get confusing, copper is already an enhancement in bunco
consider the following: 🤷
This should be on the wiki somewhere
anyone know how to make tags cause a retrigger? tried looking at the vanillaremade wiki but all of the examples use card.abillity.extra.repititions
key = "activetag",
pos = {
x = 0,
y = 0
},
config = {
extra = {
repetitions = 1
}
},
apply = function(self, tag, context)
if context.repetition and context.cardarea == G.play then
tag:yep('+', G.C.GREEN, function()
return true
end)
tag.triggered = true
return {
repetitions = tag.ability.extra.repetitions
}
end
end
}
current version never expends the tag
rip
i dont think this is something you can do with tags without hooking or patching some other stuff yeah
tag calculate when
you could also use mod calculate probably
:)
I could also instantiate a joker that blows itself up after use
that might be better than patching imo
i would use mod calculate in that case
SMODS.current_mod.calculate = function(self, context)
that's smart
update, it appears to just happen whenever a card in the shop finishes materializing, which is strange because i do literally nothing with that
does it crash without a log
hmm
like make the tag itself do nothing but calculate detects the tag and expends it?
and even commenting out my most recent addition doesnt fix it
yes
and i have no clue what could be causing this
how do I change the sprite of an individual card to a different position on the sprite sheet
i only remember how to do it globally for every version of the card which is not what i want right now
Playing card or Joker/Consumeable/etc?
does SMODS.find_card work for tags?
also don't know what function to run to force the tag to trigger from calculate
joker
iterate over G.GAME.tags and retrigger once for each copy of the tag you find
card.children.center:set_sprite_pos({x = ?, y = ?})
Changing soul_pos is card.children.floating_sprite:set_sprite_pos({x = ?, y = ?}) instead.
can't seem to call SMODS.Add_Card in any tag contexts
code?
never mind messed up the item name
bump
Code?
i dont even know what specific code could be causing this, but this is all the hooks i have relating to card creation. the crash just happens when any card finishes materializing in the shop, even without anything existing beyond the base game state
set_edition function also calls set_cost. Perhaps you got an infinite loop.
How do I replace font of joker descriptions? I tried to hook generate_card_ui but i don't know how to convert SMODS.Font into valid replacement for ui_return.main[1][1].config.font
should be ui_return.main[1][1].config.font = "[modprefix]_fontkey" iirc
assuming thats the correct node of course
Making my first mod, not finding much documentation on how to do anything. I have made a functional joker that works after leaving the shop but I want it to stop functioning if it is the only joker I have. The line I have for that is.
if context.ending_shop and next(g.jokers.cards ~= context.minus) then
How far off am I? Also the card's key is "minus" for context.
ui_return.main[1][1].config.font is a table, replacing it with text crashes the game because it can't index font.FONT
#G.jokers.cards is amound of jokers you have
oh, so if I just have it check if I have more than 1 joker, that'll sovle this
try ui_return.main[1][1].config.font = SMODS.Fonts.modprefix_fontkey i think
Thanks!
And the G being capital matters too. I am so confused why it uses the big G here and not elsewhere. It doesnt quite solve my issue in the rare case I have two of this same joker, but it's 95% more stable now. Thank you!
G is a global.
to check if all your jokers are that specific joker, check if #G.jokers.cards == #SMODS.find_card("j_modprefix_jokerkey")
SMODS.find_card returns a table containing all the copies of the joker (or any other card) you're looking for
Well damn that's perfect! Also looks like I was on the right track, but that code is a lot longer than I expected. Thank you very much! I am now crash-free!
where do I put the code that detects it?
I mean, if I put it inside of an SMODS.Joker object, it will only trigger when you have the joker.
<@&1133519078540185692>
its my money and i need cash now
theyre getting lazy now only one channel
I put a rental sticker on the bots
its costing them money, they dont have the budget to do more channels
use the global mod calculate
SMODS.current_mod.calculate = function(self, context)
well it's not a card is a mod
i am attempting to alter a mod for personal use and i want to make a joker compatible with blueprint and brainstorm. i changed this blueprint_compat = true, from false to true and in game it says compatible in the tooltip but it doesnt actually copy the effect is there anything im missing?
that's just a value for the ui yes
the actual effect should have a not context.blueprint somewhere you need to get rid of
(or it has an effect bp cant copy)
smods recently updated so that setting blueprint incompatibility will actually stop copying
that said most jokers were programmed before this change so most likely yes you will still need to fix their calculate function to work with blueprint
i am trying to modify this joker to work with brainstorm so your amount of brainstorms double every round but it just creates 4 brainstorms always does anybody know why this is? ```lua
SMODS.Joker({
key = "rustyprinter",
atlas = "Jokers",
rarity = "crv_p",
cost = 10,
unlocked = true,
discovered = false,
blueprint_compat = true,
pos = {
x = 1,
y = 0,
},
config = {
extra = {},
},
loc_vars = function(self, info_queue, center)
info_queue[#info_queue + 1] = G.P_CENTERS.j_brainstorm
end,
calculate = function(self, card, context)
if context.setting_blind then
if #G.jokers.cards < G.jokers.config.card_limit or self.area == G.jokers then
local new_card = create_card("Brainstorm", G.jokers, nil, nil, nil, nil, "j_brainstorm")
new_card:add_to_deck()
new_card:set_edition({ negative = true }, true)
G.jokers:emplace(new_card)
end
end
end,
in_pool = function(self, wawa, wawa2)
return true
end,
})```
how do you make an joker invisible
i dont know much but maybe referencing an empty PNG
card.states.visible = false
thanks
SMODS.Joker{
key = "nightvision",
config = { extra = { xmult = 1, xmult_mod = 0.2 } },
loc_txt = {
['name'] = 'Night Vision',
['text'] = {
[1] = 'Gain {X:red,C:white}X0.2{} Mult for',
[2] = 'every {C:attention}successful probability{}',
[3] = '{C:inactive}(Currently {C:white,X:mult}X#1#{C:inactive} Mult)'
},
['unlock'] = {
[1] = 'Unlocked by default.'
}
},
pos = {
x = 9,
y = 2
},
display_size = {
w = 71 * 1,
h = 95 * 1
},
cost = 4,
rarity = 3,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
unlocked = true,
discovered = false,
atlas = 'CustomJokers',
pools = { ["hatch_hatchet_jokers"] = true },
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.xmult, card.ability.extra.xmult_mod}}
end,
calculate = function(self, card, context)
if context.pseudorandom_result then
if context.result then
card.ability.extra.xmult = card.ability.extra.xmult + card.ability.extra.xmult_mod
return {
message = localize('k_upgrade_ex'),
colour = G.C.MULT,
message_card = card
}
end
if context.joker_main then
return {
xmult = card.ability.extra.xmult
}
end
end
end
}```
It gains Mult and indicates mult gain, but it doesnt apply said xmult at the end of the round
y 😭
you're not closing the if context.pseudorandom_result early enough, so the joker_main part is inside the pseudorandom_result part. and those two contexts never run at the same time
how do i stop SMODS.add_card from creating cards incompatible with the sticker its applying? i tried removing force_stickers = true but it just doesn't seem to apply the sticker to any card anymore
this is for a tag that spawns a perishable legendary
i dont think thats a feature
well that seems like an oversight
is there a way to add a blacklist to the add_card so i can just stop it from spawning the non-compatible ones myself
you can hook it
local ref = SMODS.add_card
function SMODS.add_card(...)
ref(...)
something like that
How can I get if a card is a playing card? Do I need to check that set is "Default", "Base", or "Enhanced", or is there a cleaner way?
check if card.playing_card exists
it's a number, i think it corresponds to the order all the cards appear in the full deck view
but it only exists on playing cards
interesting
are the values held in the G.hand table pointers to cards?
trying to do this but it doesnt seem to be returning a valid index
G.hand.cards
ah
i knew something looked off
thats why the other check earlier worked
how would I store a table between different contexts of a calculate function?
or i guess
ah wait i could set it when playing a hand
you can store it in config extra
Where can I find loc_vars for vanilla cards?
merci
How about consumables?
I'm trying to add the "Removes Negative from copy" to some cards and I can't find where Ankh does it
I did find DNA
am I stupit
does #G.GAME.hand_usage not count unique hands?
Yes, because items in that table are indexed with strings.
i mean shouldn't # just give the number of elements in a table?
Or am I misunderstanding lua?
Is the prefix t right afor tarots?
Oh, i see
# only counts a sequence, everything else is undefined
Is this right in general
no the prefix for any consumable is c
doesnt matter if its tarots or planets or spectrals or anything else
what is the code for your card?
you need
atlas = "deity"
ok
how do i get what area a card is in
card.area
ty
how can i check if a card is discovered?
wait nvm
ive literally checked this before
how do i check if a card is unscoring? vanillaremade wiki says i just card.area == "unscored" but it isn't working
what do I check if its the end o9f the round
context.end_of_round
that only works for context.cardarea == "unscored", card.area will always be a CardArea object
in what context is this
context.before
and is this on an enhancement or something else
blind
then do not SMODS.in_scoring(card, context.scoring_hand) to check for unscoring
ty
i tried adding if not SMODS.in_scoring(v, context.scoring_hand) then and now all the cards are scoring
so that's definitely wrong
what are you trying to do
check if a card is unscoring
to do something to unscoring cards during context.before
then that code whould work yes
well thats not what the function does so thats weird, thats why i asked for details
for a bit more context, i'm making a blindside joker thingy (which is essentially just a blind)
but that shouldn't affect anything
since i'm pretty sure blindside handles playing blinds as just playing cards
calculate = function(self, blind, context)
if context.before and not blind.disabled then
local triggered = false
for i,v in ipairs(context.full_hand) do
if not SMODS.in_scoring(v, context.scoring_hand) then
-- even without anything inside the if statement, its presence makes all played cards score
--[[v:set_ability(G.P_CENTERS.m_bld_queen, nil, true)
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end
}))
triggered = true --]]
end
end
if triggered then
return {
message = localize("elle_suggestion"),
colour = G.ARGS.LOC_COLOURS.elle
}
end
end
end```
i checked by commenting the if out, and it's definitely what's causing cards to get scored
it doesnt do that for me
make sure there isnt another mod changing it
or you can just copy the function code its just a loop
only mods enabled are my mod and blindside
and since i'm doing crossmod for blindside i can't just disable blindside
it creates a lot of negative tags
if context.end_of_round and context.main_eval
thanks
okay i checked and blindside doesn't seem to mess with the function
i'll just do this i think
okay why is this not working
for i,v in ipairs(context.full_hand) do
-- unscoring check, bc SMODS.in_scoring isn't acting right
local unscoring = true
for _, _card in pairs(context.scoring_hand) do
if card == v then unscoring = false break end
end
if unscoring then```
is it not setting unscoring correctly?
ah you wrote card instead of _card
key = "gloom",
path = "gloom.png",
px = 71,
py = 95
})
SMODS.Enhancement {
key = 'gloom',
atlas = 'gloom',
replace_base_card = true,
no_rank = true,
no_suit = true,
}
SMODS.Blind {
key = 'veguar',
atlas = 'clackerblindplaceholder',
unlocked = true,
discovered = true,
pos = {x = 0, y = 11},
dollars = 5,
mult = 2,
boss = {min = 2},
boss_colour = HEX("73a359"),
calculate = function(self, blind, context)
if not blind.disabled then
if context.before and not context.blueprint then
local faces = 0
for _, scored_card in ipairs(context.scoring_hand) do
if scored_card:is_face() then
faces = faces + 1
scored_card:set_ability('m_grasslanders_gloom', nil, true)
G.E_MANAGER:add_event(Event({
func = function()
scored_card:juice_up()
return true
end
}))
end
end
if faces > 0 then
return {
shakeBlind()
}
end
end
end
end,
}
When I play the hand, the face card becomes a blank white because the game hides that before actually appling the enhancement fsr. Anyone know how to fix this?
how come SMODS.find_card("Showman") isn't accurately returning when i have showman
find_joker("Showman") works fine so i can just use that ig, does SMODS.find_card just not like the vanilla jokers
because find_joker works based on card.ability.name, while SMODS.find_card checks card.config.center.key
so it should be SMODS.find_card("j_ring_master")
Is there a list of valid context.types for tags?
I see
its called ring_master internally? you learn something new dumb about this games code every day ig
selzer ❤️
ok this isnt working theres gotta be a better way of doing this
what is the goal here
spawn a random legendary that can be perishable with perishable
i have a legendary that completely breaks with perishable but add_card doesnt seem to have an easy way to exclud that
local pool = get_current_pool("Joker", nil, true) --i think?
for k, v in ipairs(pool) do
if v ~= "UNAVAILABLE" and G.P_CENTERS[v] and G.P_CENTERS[v].perishable_compat == false then
pool[k] = "UNAVAILABLE"
end
end
local selected_joker = pseudorandom_element(pool, seed)
should work
and what would the easiest way be here to make it only legendaries
No, because it could choose UNAVAILABLE
also that yeah
right
it should already do that
since legendary is put as true here
oh ok
so could i just replace the G.P_JOKER_RARITY_POOLS[4] in my original code with get_current_pool("Joker",nil,true) and that would work
i think so
ok neat
just change the way that the random key is chosen
whats wrong with pseudorandom_element
it would still be able to choose UNAVAILABLE
so you check if there are any available options first and use j_joker if there arent any
and if there are then
do a while loop after the first pseudorandom element until the key isnt UNAVAILABLE
How do you make the next joker in the shop negative
ok this doesnt work i gave myself 15 copies of the tag and managed to get 3 whole copies of Cheese Sandwich
my mod adds 15 legends
I did not really understand it and it felt like it was dependent on being a tag
hey, im trying to make a joker that debuffs all of the joker to its left
someone knows how to do that perchance ?
ok so i think whats happening is that the pool doesn't update by the time the next tag has been redeemed. uhhhhhhh i have literally no clue how to fix this
How do you check if you are at a store
oh im being stupid
if G.STATE == G.STATES.SHOP
i just need to put it inside the tag:yep event lmao
how do you get the properties of a joker from its key again? i forgor
What do I do to make this work
what are you trying to do
i assune they want the first card of every shop to he negative
theres a new context for it
i feel like im stupid for forgetting this but i genuinely just cant rember how to do this lol
yes
thats it thx
context.starting_shop and make G.shop_jokers[1] negative
this could also make consumables negative though so if thats not intended the solutions a bit more complex
thats fine
hey! could someone check over my code to see if "jingled_belled" applies only when the card is force selected and isn't accidently saved between rounds:
calculate = function(self, card, context)
if context.hand_drawn then
local any_forced = nil
for _, playing_card in ipairs(G.hand.cards) do
if playing_card.ability.forced_selection then
playing_card.ability.joker_belled = true
any_forced = true
end
end
if not any_forced then
G.hand:unhighlight_all()
local forced_card = pseudorandom_element(G.hand.cards, 'lemon_jinglebell')
forced_card.ability.forced_selection = true
forced_card.ability.joker_belled = true
G.hand:add_to_highlighted(forced_card)
save_run()
end
end
if context.individual and context.cardarea == G.play and context.other_card.ability.joker_belled then
context.other_card.ability.joker_belled = false
if context.other_card.debuff then
return {
message = localize('k_debuffed'),
colour = G.C.RED
}
else
return {
xmult = card.ability.extra.xmult
}
end
end
if context.discard and context.other_card.ability.joker_belled then
context.other_card.ability.joker_belled = false
end
return nil
end
I'm worried about end of round especially but i dont know if context.discard covers that
(Discord is glitching when I try to jump to the message)
for some reason, its not sending a message "TEST" when it should, is G.play non existent for context,post_joker or is there a different issue
ipairs(G.play.cards)
G.play is a bunch of stuff, none of which is integer indexed
so it just skips the loop lol
im so dumb, thank you 😭
oh
but
it shouldnt interfer with the final return no?
not sure about that tbh
yeah after trying that it still didnt send a message
it also didnt return with context.after so im unsure whats the issue
context.post_joker and context.cardarea == G.play don't happen at the same time.
well thats very annoying
maybe im going about this wrong
how would you guys go about implementing a joker which force selects a card and makes the selected card give x3 mult when played
when i would save the card itself in a variable it would be lost when reloading, checking .forced_selection doesn't work because its removed once played, and making a temporary variable seems to create alot of edge cases
thinking about it, id imagine another card destroying this joker using the last method could be problematic
i have a problem , i create a sticker named Song sticker , but it display ERROR , how can i fix that
Add label to your sticker
Im pretty sure the parameter IS label
Or it isn't wait
Pretty sure you gotta put something under Dictionary in localization or something like that
Okaaay I checked, I think you need to put the name of your sticker in misc = { labels = { sticker_key = "sticker_name" } }
Actually check the smods wiki to see how the localization files are organized and shit
Also what the fuck is ^1000 bruh 😭
idk :))) , this is m friend mod , he want me to fix it
WE HITTING 10{1000} WITH THIS ONE 🔥 🔥 🔥
i request some feedback on my in development mod can anyone help?
I can give feedback. Got a GitHub link ready?
yah here you go : https://github.com/eliyoakum-sudo/Unfair-Foodz-balatro-mod-expanded
it looks finished but is not done at all
How would I change blind mid-blind?
Sorry it took a whole hour, but I have a .txt file with some feedback ready.
okkay send it
Sent
thx also i did kinda figure itd be buggy from the fact it was made in jokerforge
<@&1133519078540185692>
I want to make a joker win xmult every time a joker retriggers but this doens't work, why?
i get this crash, when is it safe to access game
tbh nvm
ill make it a lovely patch
post_trigger probably doesn't get retriggers
doesnt activate when this does
either when scaling or scoring
I also tested with the base joker
ok why do my lovely patches not work
this seems simple enough but it isnt workin
Check the lovely dump, maybe?
To see if your patch is in there, and if's not, probably patch the line you see.
do you have post_trigger enabled?
interesting
it is in there
but it doesnt seem effective
how do you enable it?
Then there is little I can help you with.
I lack any context to help you any further.
indeed
ofc, here the point is simply to prevent blue stake from taking a discard
but it seems to be doing it regardless of the patch
Can't you SMODS.take_ownership or something like that?
:3
now to see why the other 2 patches arent
thanks!
ok for the latter two im fairly certain im not targeting them right in some way
how could I make animations play at the same time instead of just after?
i think im not targeting this file right
looks correct to me
ah fack
why is this not workign 😭
yea i cant figure out why it wont work for this patch
i lied it wasnt lmao
i opened a run on white stake
so all the patches in my lovely.toml dont work
this is the folder structure
have you checked the lovely dump
yes
wait
hold on i need to like reopen everything
i think maybe it was showing me an old dump
yea it was
man its confusing
it doesnt seem to work
im gonna take a crack at this tomorrow
the dump shows a change but it doesnt actually work
waitttt
im an idiot
wow this game is fucking confusing
ok im switching my strategy
is it possible to just change variables after the game starts
i tried this earlier and i just crash
because GAME doesnt exist yet
do you want to do it just for blue stake or for every game
these are for every game
the blue stake change is whatever the main change was the hands and discards
<@&1133519078540185692>
<@&1133519078540185692>
try SMODS.current_mod.reset_game_globals
did it like this
but either ive misunderstood how these variables work or this approach itself isnt working right
you need to check for run_start
i see
but yeah if it doesnt work then its something else
liek so i suppose
hook Back:apply_to_run
yep that worked
and as a bonus it also makes blue stake non effective
because i added a line at the top that sets discards = 4, and this function runs after stake effects are applied
(ofc i put the line before code for the deck specific effects)
ty so much N' you are a life saver
how do i check if the previously played poker hand is better than the currently played hand?
like, ranks higher on the Run Info page
or even, how do i get where a hand is on the Run Info page?
thanks ^U^
how do i make a card unplayable?
Hook G.FUNCS.can_play and check if G.hand.highlighted contains the unplayable card then do e.config.colour = G.C.UI.BACKGROUND_INACTIVE; e.config.button = nil
thank you
you're a life saver
how do i prevent cards from spawning and is there a pool with every joker in it
Hook create_card and G.P_CENTER_POOLS.Joker
was there not a ban cards thing in smods or smthn
Do you want to stop all cards or specific cards from spawning?
i want a specific collection of cards to be the only cards that can spawn by natural means
for k, v in pairs(G.P_CENTERS) do
if not table.contains(collectionofcards, v.key) then
G.GAME.banned_keys[v.key] = true
end
end
search for generate_starting_seed()
what for
To create consumable that changes seed
G.GAME.pseudorandom.seed = 'seed'
G.GAME.pseudorandom.hashed_seed = pseudohash(G.GAME.pseudorandom.seed)
If I'm gonna make a basic "Food" pool, do I need to check if one already exists or is it fine?
Like in case of another mod including a pool of the same name
i mean
you could just check for G.P_CENTER_POOLS.Food
and make one if it doesnt exist
for a pool?
That's for centers, which are like Jokers, decks, enhancements etc etc
oh ok
if not in specific challenge check
if not G.GAME.challenge == "c_modprefix_challengekey" then
-- code here
end
if multiple objecttypes exist with the same key the contents will just get merged
so depends on what you want
So it kinda doesn't matter at all then? Cause I assume if you're adding a Food pool you'll probably will put vanilla stuff in it, and then modded jokers are added in their definition
Or am I being a dumbass
it shouldnt matter if one already exists yeah
but you should always define it if you use it in your own mod
how would i prevent other mods from making title screen cards? there is like 8 of them in the modpack im making this mod for so you cant even see the logo
all the cards are still there
oh cant see the logo in that way
yeah
like with unjankify i can squish them closer but that doesnt really solve the problem of every dang mod makign a card for the main menu
idk probably just destroy all but the first title screen card when the title screen loads ig?
though idk if that would work unless you always load last
yeah. i dont exactly know how to destroy them because every mod seems to add them in a slightly diffrent way. thats pretty much exactly what ive been trying
for k, v in pairs(G.title_top.cards) do
if v ~= G.title_top.cards[1] then
v:remove()
end
end
thanks!
i implemented it like this and its not doing anything?
function Game:main_menu(change_context, ...)
mm(self, change_context, ...)
if self.title_top and self.title_top.cards then
for k, v in pairs(self.title_top.cards) do
if v ~= self.title_top.cards[1] then
v:remove()
end
end
end
end```
Trying to learn to modify the main menu how did you change the background and add the cards
Been digging through the smod and vanilla wiki like crazy for this
i didnt. but id look at like idk yahimod or something to see how they do it. if u cant find it there look in someone elses mod
but you usually hook the main menu function like im doing there and then do pretty much what the source code does but tweaked for your mod
how would i prevent the destruction of a joker once using a sticker?
whether its by dagger or anything that would delete the card
hook card:start_dissolve() and if the card has the sticker just, prevent the destruction (don't finish the hook, cancelling the function call) then remove the sticker
also when you do this remember to turn card.getting_sliced to false on the card, or else it wont be able to be destroyed by dagger if it procs again since dagger ignores jokers with card.getting_sliced which is applied when it goes to destroy things
bumping this from a while ago, still haven't found a way to hook it or manually change the handsize in the way that i want
theres a joker from yahimod that does that lemme see if i can find it
card.ability.card_limit = card.ability.card_limit + 1
darn beat me too it
got it to work
is it possible at all to use pseudorandom (or any of the SMODS pseudorandom functions) in a way that doesn't advance the given seed?
thank u
i don't know off the top of my head how it works, but i definitely know there are some modded jokers that predict the contents of booster packs, so it should be possible
what script is the get_flush() function in? i need to hook it
Yes, you would use a function that predicts the pseudoseed of a seed.
functions/misc_functions.lua
cheers ^^
how can i get a random suit upon joker creation? i don't know why this isn't working
why does adding the third hook here cause the game to crash, when starting a run?
log mentions card.ability being nil here in utils:
function SMODS.get_enhancements(card, extra_only)
if not SMODS.optional_features.quantum_enhancements or not G.hand then
return not extra_only and card.ability.set == 'Enhanced' and { [card.config.center.key] = true } or {} <----```
If I wanna change some lines in vanilla items, is it better to use take_ownership, copypaste vremade code and edit it, or do lovely patches?
Cuz with take_ownership most of the code is the same but I have to repeat all of it anyway
But I heard patches should be avoided
So
why not just return message and colour as normal?
returning message as normal doesnt remove the default mult message
but also i realized that i made a mistake
You would always have to lovely patch because the original code will still run unless you return.
looked at the code and fixed it but also it still doesnt change anything
No, mult_message should be a table.
I mean with take_ownership you have to replace the functions you want in their entirety, so they do return, so it's working fine for me rn. I'm just wondering if patches would be a better way
vanilla things dont have any functions though
they are just baked into existing functions
which will sitll run if the custom one doesnt return anything
Yes, mult_message is not used for editions.
You would have to use remove_default_message
And then return a message normally.
not passing the card into is_suit_ref if you havent fixed yet
Where can I find loc_vars for consumables i.e. Ankh? Doesn't seem to be in card.lua
I wanna find where it appends "Removes Negative from copy" to the description
merci
why cant i drag around the card on the main menu?
local mm = Game.main_menu
local recentered = false
function Game:main_menu(change_context, ...)
mm(self, change_context, ...)
if self.title_top then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
if self.title_top.cards and #self.title_top.cards > 0 then
for i = #self.title_top.cards, 2, -1 do
self.title_top.cards[i]:remove()
end
local remaining = self.title_top.cards[1]
if remaining and not recentered then
remaining:set_alignment({
major = self.title_top,
type = 'cm',
offset = {x = 1.5, y = 0}
})
recentered = true
end
end
return true
end
}))
end
end
why cant i drag around the card on the main menu?
local recentered = false
function Game:main_menu(change_context, ...)
mm(self, change_context, ...)
if self.title_top then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
if self.title_top.cards and #self.title_top.cards > 0 then
for i = #self.title_top.cards, 2, -1 do
self.title_top.cards[i]:remove()
end
local remaining = self.title_top.cards[1]
if remaining and not recentered then
remaining:set_alignment({
major = self.title_top,
type = 'cm',
offset = {x = 1.5, y = 0}
})
recentered = true
end
end
return true
end
}))
end
end```
to do a hook, you need to save your call to mm in a local variable, and at the end of the hook return that variable, i'm pretty sure
the hook works like the card gets offset and the extra cards get removed i just cant move the remaining card
also im fairly sure im doing both those things
try self.title_top.cards[1].states.drag.can to true at the end
nope
local recentered = false
function Game:main_menu(change_context, ...)
mm(self, change_context, ...)
if self.title_top then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
if self.title_top.cards and #self.title_top.cards > 0 then
for i = #self.title_top.cards, 2, -1 do
self.title_top.cards[i]:remove()
end
local remaining = self.title_top.cards[1]
if remaining and not recentered then
remaining:set_alignment({
major = self.title_top,
type = 'cm',
offset = {x = 1.5, y = 0}
})
recentered = true
self.title_top.cards[1].states.drag.can = true
end
end
return true
end
}))
end
end```
i mightve put it in the wrong place?
try all the way at the end of the hook
and also try adding self.title_top.cards[1].states.hover.can = true maybe
nope
ok
didnt work
i can hover over it and click it it just wont move
ive got unjankify on and it just wont move even if i change how far apart cards on the logo are
lowke forgot i was in a discord call lmao
hey yall
how do i make stuff like custom jokers
is there a good video or smth
Follow the guides at https://github.com/Steamodded/smods/wiki/Your-First-Mod and https://github.com/nh6574/VanillaRemade/wiki to set up your mod, then look at https://github.com/Steamodded/examples/tree/master/Mods for example mods and https://github.com/nh6574/VanillaRemade/tree/main/src for recreations of everything in the vanilla game. Be prepared for lots of reading and come here when you have questions!
ok thanks!
Fyi the example mods are very outdated
k
is this not how youre supposed to do this
Check vanilla remade 
erm
Localization
