#💻・modding-dev
1 messages · Page 690 of 1
I might be stupid lol
do I set it in the calculate function?
I guess thats really my question is where do I set it
I mean I guess I wouldnt have to worry about you gaining the joker as its debuffed
anywhere
I just threw it in calculate it was spitting me errors if I tried setting it in SMODS.Joker as I was intending
what errors
can you send the code
unless im not reading you right
It's fine if its in calculate I think
just gotta make sure in_pool also returns true if its nil
o
yeah thats several syntax erros lmao
your putting it in a table
put it in a function
its not in the calculate function
you want it to happen during the calculate funciton right
Probably better to yeah
put it in there
you put it in the joker definition table
thats invalid lua
nor would G.GAME exist if it was
I presumed that much but definition of anywhere is a bit uh..broad
😛
in laymans terms anyway
I assumed you knew lua syntax ;-;
surely thats not an unreasonable assumption
I never said I knew the ins and outs of this programming language and from the sounds of i asked a pretty introductory question 😭
Sorry for being stupid 😛
anyway throwing it in loc_vars worked, thanks
time to see if the effect works as intended
and to see if it shows up in the shop
cool does show up 🔥
not changing hand size tho..
😠
incorrect context I think but idk why card_added should trigger when you gain the joker, no?
maybe because I bought the card..
that might be why
you probably want to be using add_to_deck instead of calculate
if im correctly assuming what the intended effect is
yes, the add_to_deck function for jokers will trigger whenever it is acquired (bought from shop, or created from judgment/riff raff/the debugplus keybinds/etc)
and then use remove_from_deck to revert it
Harmony gives 1 hand size 1/6 chance of destruction
greg only appears when harmony was destroyed, and gives 2 hand size
alright
I already was handling remove from deck to cover debuff clauses
vanillaremade win
yea vanillaremade is a great place to look
Yeah i've been using vanillaremade but, sometimes its needle meeting haystacks y'know
it recreates basically all vanilla content as if it was modded, and it's a great place for common questions about how to recreate behavior that vanilla has (e.g. "how do i add hand size" can be found by checking how juggler behaves)
and I dont necessarily just wanna full copy the first time around, wanna actually try to learn y'know.
but yeah I think I get enough of the internal gist at this point
not to sure where to get started with this, but does anyone know where any templates for modding are to get started?
VanillaRemade as i just mentioned is a great resource
the repo also has a fantastic Wiki tab that should help you get off the ground
https://github.com/nh6574/VanillaRemade/wiki#balatro-mod-development-faq
https://github.com/Steamodded/smods/wiki/Your-First-Mod
these are the two sources ive been using
ya that's perfect
vanilla remades link is more of a q/a, the "your first mod" is more of the template
do you know where i can find the download for it?
have you considered clicking those two links
in particular, the Your First Mod page links to an installation guide
So your first mod page will get u installing steammodded if u havent already installed that
in the vanilla remade link under "general development" it goes through a step by step process on how to make your mod
oh sorry on my computer the messages didnt load
had to check on my phone to actually see them
Anyway greg and harmony seem to be working as intended 🔥
Actually, oops all sixes compatibility.
if you're using the SMODS.get_probability_vars and SMODS.pseudorandom_probability functions, it's already compatible with oa6
gotchya, should be good then
Hey all, what would be the easiest way to get the directory/name of the current log file from lovely?
Is it possible to have something appear for a specific duration? Say, have text pop up on screen for x seconds?
SMODS.calculate_effect({message = 'message', delay = number}, card)
^
Sick! Thank you!
Itll just be at the bottom
Since files are sorted in alphabetical order the latest date will be at the bottom
From within a mod I mean @slim ferry
I don't mean in the file itself lol that is obvious
what's the goal exactly
I am trying to read the entire contents of the current log file
and what is the purpose of doing that
I will be creating a checksum of the log
This is for the multiplayer mod
Trying to have easier tampering detection
I don't think that's a good idea, that'll instantly make every other mod installed trigger the tamper detection (even if it's a harmless qol mod)
False
You do not know what I am trying to do
Either answer the question or don't please lol
then please elaborate, because I don't see how you can create a checksum while easily accounting for a wide variety of harmless differences and that sounds like really cool tech I'd genuinely like to know about
anyway yes look into the NFS thing eris mentioned. I'm not too familiar with it but you should be able to pair it with SMODS.current_mod.path, which is the path of the mod folder as the mod is loading
I am trying to detect LOG TAMPERING not mod tampering.
Ironically creating a hash for mod tampering is easier. I did this for the bean tournament.
I see, gotcha
I think I previously did it by traversing to the folder, sorting the logs, and taking the last entry, but surely if the game can just write to the log file then it is stored in memory somewhere.
I have a joker that adds a playing card to your deck, but its not triggering hologram.
if context.setting_blind then
if card.ability.extra.amount > card.ability.immutable.cacap then card.ability.extra.amount = card.ability
.immutable.cacap end
for i = 1, card.ability.extra.amount, 1 do -- loop card generation
if card.ability.extra.kai_gift == true then
SMODS.add_card { set = "Playing Card", key_append = "goob_append", edition = 'e_negative', area = G.deck }
card.ability.extra.kai_gift = false
card:juice_up()
else
local random_edition = SMODS.poll_edition { key = "goob_seed", guaranteed = true, no_negative = true }
SMODS.add_card { set = "Playing Card", key_append = "goob_append", edition = random_edition, area = G.deck }
card:juice_up()
end
end
Any reason why its not triggering holo?
How do you put a shader on your mod badge?
fuck
Can we see your code?
which
the one that has set_ability
oh main.lua?
card.lua?
think im gonna try reworking this and do SMODS.create_card then do :add_to_deck() and see if that fixes it
this one?
I think its scored_card:set_ability("m_wheeloff_fondue")
is that line 279 in card.lua?
where do i find the card.lua
er..nevermind
Im also relatively new, I just ran into that error before with set_ability
that did not fix it
😭
fixed it, needed playing_card_joker_effects({ _card })
(and made the funcion a _card variable)
Surprised add_card doesn't already do that
but eh, maybe u dont always want it to trigger jokers
The good news is now I can actually show on the clown desc the specific card added (or last one, if ur a cryptid head)
what is the best/ easiest way to change the values of a joker, i.e something like fruit smoothie from cryptid
oh as per vanillaremade certificate, you're actually supposed to call this line
this should be cleaner i think
use the value manipulation functions provided in either Spectrallib or Blockbuster Value Manipulation
ok, cool, I really should see how vanillaremade does things if its something like this or harmony
nice qol added 🔥
How would I go about adding this value (G.mannpower_strange_counter_total) to this achievement's description? I tried putting it in the loc_vars, but it doesn't seem to be working properly.
I should make achievements/unlocks for my jokers at some point. Jobingles = have huge deck. Jobangles = run out of cards.
Dont know about the rest tho
Deathkill win a run with 0 or less gold lol
Mine are just the TF2 strange ranks, but I'm making the ones after 100 become just career triggers rather than triggers in a single run
The 135 is a loc var?
The local variable is the progress.
The 135 is just normal text
Hmm idk
How can I send another texture into a shader?
I need to mask my mod badge using it
is there a way to make a consumable instantly draw cards to hand?
one of the cryptid consumables kinda does that
which one?
alright, thank you!
np, good luck
specific cards or just the top cards
SMODS.draw_cards(num)
oh thank you!
achievements might not accept formatting from what i see
i can probably work on that for smods later this week
So I've been trying to make it so you get Xmult, discards, and hand size. But only the Xmult and Discards are working
if you add more than one of the same key to a table only the last one will be added
that is to say, you have 2 add_to_deck and remove_from_deck, combine them
Thank you
How would I add extra hands in a joker?
Like, drunkard but hands instead of discards
have you checked the code for grabber
Not yet, does that show how to do it?
yes
Thank you.
So I did that, but when i sell my joker it didn't get rid of the discards
I mean hands
reverse the operation in remove_from_deck
like here
thanks
How would I change the score requirement of an upcoming boss blind?
You could edit the ante scaling parameter directly
Though that also affects the small and big blinds. Bodged solution ik but just throwing that out there
You would have to patch create_UIBox_blind_choice
Okay, I'll look into that.
For making a custom deck, would I start by making a folder in my src folder like with jokers, or what?
yes
as long as you load it in main.lua
why doesn't this work?
SMODS.current_mod.menu_cards = function()
return {
key = "v_crp_cryptposting_directors_cut",
edition = "e_crp_overloaded",
}
end
which smods version are you on
these are the definitions btw
SMODS.Edition {
key = "overloaded",
...
SMODS.Voucher {
key = "cryptposting_directors_cut",
atlas = "directors_cut",
}
and it previously worked when using the old cryptid method
@gilded blaze any idea or am i cooked 😭
your mod's prefix is crp right
How do you juice up the x in the scoring table
G.HUD:get_UIE_by_ID('hand_operator_container'):juice_up()?
I'm trying to rework the blue seal by adding a 1 in 2 chance, but somehow the seal adds 1-2 planet cards instead of 0-1 planet cards, like it adds one guarenteed then retriggers with the 1 in 2 chance. I have no clue what is wrong in my code to cause that extra planet card to appear
You would have to patchCard:get_end_of_round_effect if you want to change Blue seal's effect.
is there a way to make SMODS.calculate_effect create a message that appears above a deck? i tried passing both self and back in a deck's to that function but it doesnt appear above the deck
I can't use return because it's an event
you could probably try SMODS.calculate_effect({ message = localize("k_upgrade_ex") }, G.deck)
Works well enough, thank you!
only downside is that it doesnt juice the topmost card but that's whatever
It should be G.deck.cards[1] or G.deck
bro I don't get it all I want to do is make hex set the jokers sell value to 0 and none of this works wtf how do you do this
literally trying everything that exists and it doesnt work lol
you need to hook the calculate_cost or whatever its called
i did it for one of my cards lemme find it again
eligible_card.ability.extra_value = -eligible_card.sell_cost
ohhh I misunderstood how that works
That doesn't juice it either but i am queueing it right before a draw event which might be related
Actually yeah that makes sense
Thank you
nvm ignore what I said and use somethings answer
ye it worked first try lol
you only need hooks if you want changes across cards
ty regardless
how do i make these reflect when i modify all booster sizes?
you shouldnt manually set booster_choice_mod and booster_size_mod to the packs
that gets handled automatically and you dont need to do anything
is the boolean param of SMODS.find_card() a thing to determine if it should count Debuffed cards?
yes
alr
hi dev chat :3 :3
i know red card checks for packs being skipped and theres a global for it
but how would i check for the type of packs that's skipped
like specifically triggering on skipping an Arcana pack but not Celestial pack
booster.config.center.kind
i don't remember where the booster is stored in that context
context.skipping_booster + context.booster
so context.booster.config.center.kind == 'Type' ?
yeah
aw heck
-- Track boosters packs skipped
if context.skipping_booster then
G.GAME.boosters_packs_skipped = G.GAME.boosters_packs_skipped or {}
G.GAME.boosters_packs_skipped[context.booster.config.center.kind] = G.GAME.boosters_packs_skipped[context.booster.config.center.kind] or 0
G.GAME.boosters_packs_skipped[context.booster.config.center.kind] = G.GAME.boosters_packs_skipped[context.booster.config.center.kind] + 1
G.GAME.boosters_packs_skipped_this_run = G.GAME.boosters_packs_skipped_this_run or 0
G.GAME.boosters_packs_skipped_this_run = G.GAME.boosters_packs_skipped_this_run + 1
print("[HangedMan_CalcEvent] A " .. tostring(context.booster.config.center.kind) .. " Pack was skipped")
print("[HangedMan_CalcEvent] There has been a total of " .. tostring(G.GAME.boosters_packs_skipped_this_run) .. " Booster Pack(s) skipped this run" )
end
what is incorrect about this code
can you print context.booster.config at the start of the check
ok gimme a sec
How do I check, if a specific Boss Blind got selected?
ok this has been resolved
context.booster was already the centre, so context.booster.kind is enough
thankies :3
if context.setting_blind and context.blind.key == "bl_modprefix_key" then
for vanilla blinds, use context.blind.name == "The Hook" instead
Forgot to mention that I need it for a lovely patch, my bad
Okay, other question: I'm trying to make a custom boss blind, that changes stuff. You don't play hands anymore but have to answer stuff. Why is it crashing with so much errors? Like, it says that CONTROLLER is undefined and the same for SETTINGS for example. What may cause that issue? Because that would resolve the need for this key
there's not much I can help since the mechanic is alien
unless you show me your snippet
This is the blind. get_random_riddle("the_riddler") is just a function that picks a random riddle from a file and returns that
If you still need something, let me know :3
create_UIBox_buttons is a general constructor for UI buttons
why are you hooking it for this Boss Blind's effect
function G.FUNCS.destroy_a_card(e)
local index = math.random(1, #G.hand.cards)
SMODS.destroy_cards(G.hand.cards[index])
end
using math.random here will not respect the run's seed
I did this like 6 months ago, so I don't know why anymore... How do I use it normally?
I know that but I probably should make it respect the seed
you did it 6 months ago...
I recommend starting from scratch, it's no use trying to salvage this abomination
Can you help me on how to start then? Like what I should use as a reference or what I definetly shouldn't do this time?
first, start with familiarizing yourself with contexts https://github.com/Steamodded/smods/wiki/Calculate-Functions
you can then decide when the riddle shows up
your old SMODS.Blind code didn't use any of the contexts, which made the function fire a bajillion times
also start with something simple, study the game code and SMODS APIs more
based on your code 6 months ago I believe you did not study contexts at all before jumping into making a complicated and unconventional blind
Sounds like me. Can I ask you whenever I need help with something? Like through dms or by using @
I'm going to bed soon
No, I don't mean today. I mean in general when I'm struggling with it
ah, sure then
just talk and ping me here
Got it, thank you :3
mind you that I may talk here on my phone, it's a lot more limited there as I don't have easy access to my mod's code, the game's code and SMODS APIs
All good
can someone explain how to make the values change when pack contents increase
are there any guidelines for what forcetrigger should do?
i think it usually just gives the bonuses without any conditions.
theres no official guidelines so you could just make forcetriggering give drawbacks
if youre increasing cards and choices in packs in the proper way then you dont need to do anything
that is modifying the two associated values in G.GAME.modifiers
this is how im doing it, the packs get the effects but the description wont change
secondly how would one get this to spawn naturaly on consumables?
yeah pack descriptions in general dont change for that
there isnt a way to change that without heavy patching as far as i know
OH WAIT HUH
oh oops
well idk then actually
oh wait its just the default loc_vars for packs that does that and SMODS takes ownership of the vanilla packs
so if you leave loc_vars out entirely i think it just works
there should probably be a util function for that actually
you can just SMODS.Booster.loc_vars probably
I see
if you dont return anything else in loc_vars just leave it out, else you can do the vars like this
and if youre returning other vars then just manually append to v.vars
yo im kinda new to modding and just doing it for fun and also im JUST starting in lua
just wanted to know what is important about loc_vars and what uses could i give it
i know it sveery important 😭
thhats about it tho
Hey, try giving this a read
feel free to drop in here with any questions
loc_vars is used to provide data for your jokers description
check out the page aure sent, but the most important thing is that you use it to fill in stuff like +#1# mult and make it display +4 mult
is this lua in general or smods
also ty
smods
how much lua do you know
and do you have any other coding experience
just python so honestly nothing 😭
how much python
im like mid level in python
you should be fine
Agreed
ik my way around most functions i draw the line at threading tho
Isn't Python also 1 index?
you should like never have to touch that unless your doing some shenangains
no its a reasonable language and is 0 indexed
doing shenanigans is the funniest part tho
me when I call an integer and it deletes my system
yeah but like really advanced shenangains
see you get it
im just doi ng this because i actually wanna put my time into a dumb project like a mod for my friend group or something related to coding
been learning just python for like 2 or 3 months but is jus tthe stupid python excersises
so im just tryna analyze the way balatro works now since is a game i always looked up to when talking about design
Balatro Modding is a good starter project, it's pretty easy to pick up and Lua is pretty forgiving as well. There's also generally a ton of resources and support for newbies like yourself to use
yeah ivbeen reading so much github has so much info regarding smoded
have you taken time to learn lua
like jsut basic lua syntax
not that much honestly
seems similar enough to python
once you figure out the syntax thats basically all you need
I also have a few video tutorials out there if that interests you. Currently goes over setting up your project file, how to make a joker, and what patching/hooking is
like the logic is very similar but the syntax is like the interesting part
and yeah its simple enough that you should be able to figure it out just by looking at it
since you have previous experience
Maybe give some parts of this a read if you want to get a bit more of a feel for what the differences are
but you should be fine either way
ive made a joker, but im using example jokers, so i wanna understand how it actually works yk
of course
so far I think the most unintuitive thing for me is that you can call functions like func{table params}
like why
i feel like in like hypothetical scenarios im uncapable of learning
I'll link the vids then because I think you'll gain some desired knowledge from them
https://discord.com/channels/1116389027176787968/1486847115127947374
yes yes this is all so helpfull
i have the same issue with js doing
func`string`
frankly this is even worse
i keep forgetting what tables even are 😭
i know it was something related to lists but thats about it
python dictionary/classes
they're basically dicts
oh i see
and also lists yeah
okay that explains a lot
i mean dicts are basically just list inside of lists so yeah that makes more sense
basically they can be indexed with anything
number indices make list entries of sorts
{1, 2, 3} is a list-like table with key:values 1:1, 2:2, 3:3
-# except nil
is first value the key and second the actual value ?
{a = 2, b = 3} is a normal table with key:values a:2, b:3
yeah
so like a is 2 and b is 3
right
yaeh i kinda get that
{1, 2, 3, a = 2, b = 3} is a combination of both of them, with key:values 1:1, 2:2, 3:3, a:2, b:3
yep
oh you can just use any key ever okay
so literally dict
pretty much
no nil is nil
nil is null
nil is literally nothing
akin to None or null
right
there's also metatables which let tables cosplay as functions among other things
so like basically to empty a variable
so they're technically more than just dicts
i don't think thats useful rn lmao
it isn't
just saying that they're not literally dicts
fair
-# iirc this is what makes smods fundamentally work for the most part but obviously you'd know better than me lol
they might in some weird obscure case
okay I won't explain much but these are basicly dunder methods
no they are really useful
but not when your starting modding
metatables are how lua's class system works
i mean im not thinking of really becoming a modder, i mean maybe the goal is just to learn, also have fun
fair
that was my start too lmao
some of this is very simple and start and some of it is confusing
that goes for anything tbh
yeah because it's generally how you make something that resembles classes
anyways
ty all for help ill try to like
check everything out and see how much i can just note
is it okay if i ping you or are u just active like that
people check this channel pretty often
i'm open to ping though
I hope you'll find the community eager to assist
Does anyone know how to make a new hand show up in the run info menu? heres my code, I did just copy one of the hands from the example but i plan on replacing it.
my current idea for hands are pair hands but its with cards of the same suit and rank
does the consumable appear
oh wait
my main mod file is a json where in the mod info data says its a .lua file
Its still not showing up for some weird reason
the planet doesnt show up either?
havent tried it yet
well if it doesnt then the file is not loading
but it doesnt show in collection
then the file is not loading lol
idk whats happening this is my main file
whats the structure of your folder
wait, does something need to be the same as the foldername?
no
No.
patching/hooking time yay
working on trying to make a new hand for the idea i had, but idk how i would code the detection plz help
if i make a card a legendary card can it still show up in shop
BUT CAN I PLEASE MAKE THAT A THING
local ret = {}
for k, v in pairs(parts._2) do
local suits = {}
for kk, vv in pairs(SMODS.Suits) do
if v[1]:is_suit(vv.key) then
suits[vv.key] = true
end
end
for kk, vv in pairs(suits) do
if v[2]:is_suit(kk) then
table.insert(ret, v)
break
end
end
end
return ret
oh cool thanks
Take ownership of the legendary rarity and change its weight
i made them a little too op how can i nerf them.. i want more like ideas
Mario 64 DS: find luigi.
yea its luigi
so anywas i need ideas onb how to nerf kindness luigi harder than spectre nerfs two time
w idea
reset at end of round, and also make it only count played and scored hearts
i dont really want it to reset tho but i can see what i can do with the other idea
it seems to crash when i hover over the planet card
It should be modprefix_key not modprefix_key_name
since card is always the joker itself in calculate functions, and not blueprint when its context.blueprint, is there a way to get a ref to the blueprint card in that case
context.blueprint_card
how do you make a Joker eternal properly
card:add_sticker("eternal", true) visually adds the sticker, but it can just still be sold for some reason
Does the joker your putting it on have eternal_compat?
ah
is there a way to have it not able to naturally be eternal, but let it still gain eternal later?
You would have to patch SMODS.is_eternal
yea i cant be bothered to do that tbh
would this method do nothing to an already eternal joker?
Yes.
How do I determine if a playing card is flipped
I have a joker that when you are playing cards, flips them, sets a random enhancement, and then unflips. But if the scored card is already flipped, it shouldnt flip them face up
card.facing == 'back'
thanks
how can i disable a joker from triggering a message when it provides mult?
remove_default_message = true
ok so i have a joker with 2 + 2/3 ^mult. however, whenever it triggers, it shows 2.66666666666666666667 ^mult. this isnt that bad of an issue, but i would like to round it to two decimal places. how can i do this?
im using a message = ('^' .. card.ability.extra.emult)
to do it
number_format(card.ability.extra.emult) maybe
i know there's a way to round to two places but i dont remember if i made a function for it in jokerdisplay or if it was that one
if you're using the exponential mult provided by talisman/amulet, i don't think you need a message at all. and the automatic message that would be generated should just round it automatically
its spectrallib repurposed
that should have the message then
does your mod depend on slib or did you copy the code into your own mod
the problem is i couldnt get the imbuilt ones to display properly, so i used manual messages
my friends are tech illiterate so its easier for them to just download a mod with it inside of it
yes i copied
if they can install 1 mod they can install 2 mods
i don't see any reason not to just make your mod depend on spectrallib
i do it for them when i see them, its just easier i prefer it that way
you can also zip them in a release like cryptid does
true
how can i make the description like that card's having a enhancement?
is there a way to get three random elements from a table and make sure they're all unique
use psuedorandom_element and remove the selected item frmo the table
alr thank you
is there a way to make an enhancement effect in context.before that doesnt run once per card
i want to do the effect only once per played hand
What is the goal?
how would i get a hand to level up with a vanilla hand?
like i have a joker that lets you select more cards so i added three pair and 6 of kind but i cannot figure out how to sync the levels
Hook SMODS.upgrade_poker_hands
interesting ok thanks
how would i get this to naturally spawn on random consumables?
run an effect before a hand is scored
the issue is that just using the calculate function in the enhancement causes it to run the code once for every card with the enhancement
I want it to run once per hand instead
local oldcreatecard = create_card
function create_card(_type, area, legendary, _rarity, skip_materialize, soulable, forced_key, key_append)
local card = oldcreatecard(_type, area, legendary, _rarity, skip_materialize, soulable, forced_key, key_append)
if SMODS.ConsumableTypes[_type] and not card.playing_card and not card.edition then
local edition = SMODS.poll_edition({key = 'edi'..(key_append or '')..G.GAME.round_resets.ante})
if edition == 'e_modprefix_key' then
card:set_edition(edition)
end
end
return card
end
where would this go?
You would put in your file but outside of any object definitions.
you can just set a global and clear it in context.after
or use mod calculate and check for the enhancement there
can i erase the vanilla enhancement?
what do you mean
i mean i want to delete all of this or just disable all of it
you can probably take_ownership of them and set in_pool and no_collection
ok thanks:))
is this right?
how would I do a mod calculate?
cause that seems like a better solution in this case
is there a way to not have the pop in effect on card titles while having a custom font
not what i said but if it works then it's probably fine
SMODS.current_mod.calculate = function(self, context)
maybe you can with dynatexteffect but i dont think there's a specific in-API way to remove it other than that or hooking localize
because i do remember E: and f: being exclusive
I thought that was E and X
yeah f is compatible with all others
yeah my bad its just that i use X too in that title
lool
ah
but it doesn't work...
also how would i change the weight of it spwaning on consumables?
does that work for pokerhand?
it does but poker hands dont have in_pool
Hi! I'm trying to write some UI for the first time and I can't figure out what's wrong with the following code. It works except for the recalculate call in the cycle_options callback, which fails because toggles_container.UIBox is apparently nil. But I can't figure out what I need to do for it to... not be that. Any ideas?
SMODS.current_mod.config_tab = function()
local toggles_container = {n=G.UIT.O, config={
id = 'toggle_container',
object = UIBox {
definition = mod_stake_toggles(mod_names[1]),
config = {align = "cm", minw = 1, minh = 3, outline = "1", outline_colour = G.C.BLUE}
}
}}
local config_ui = {n = G.UIT.ROOT, config = {r = 0.1, minw = 8, minh = 6, align = "cm", padding = 0.2, colour = G.C.BLACK}, nodes = {
{n = G.UIT.C, config = {minw = 1, minh = 4, colour = G.C.CLEAR, padding = 0.15}, nodes = {
{n = G.UIT.R, config = {minw = 1, minh = 3, align = "cm", outline = "1", outline_colour = G.C.PINK}, nodes = {toggles_container}},
{n = G.UIT.R, config = {minw = 1, minh = 1}, nodes = {
create_option_cycle {
options = mod_names,
opt_callback = 'hs_switch_mod',
ref_table = cycle_ref
}
}}
}}
}}
G.FUNCS.hs_switch_mod = function(args)
toggles_container.config.object:remove()
toggles_container.config.object = UIBox {
definition = mod_stake_toggles(args.to_val),
config = {align = "cm", minw = 1, minh = 3, parent = toggle_container}
}
toggles_container.UIBox:recalculate()
end
return config_ui
end
function mod_stake_toggles(mod_name)
local toggles = {}
for _, stake in ipairs(G.higher_stakes.modded_stakes[mod_name]) do
print(stake.name)
toggles[#toggles+1] = create_toggle({row = true, label = localize { type = 'name_text', key = stake.key, set = stake.set }})
end
return {n = G.UIT.ROOT, config = {align = "cm", colour = G.C.BLACK, outline = "1", outline_colour = G.C.CYAN, minw = 1, minh = 3}, nodes = {
{n = G.UIT.C, config = {align = "cm", minw = 1, minh = 3}, nodes = toggles}
}}
end
it seems like you're trying to define G.FUNCS.hs_switch_mod inside of config_tab
Moving it out hasn't made a difference, sadly, when coupled with another way to grab toggles_container like shoving it in the cycle_options' ref_table
Lemme stuck the whole thing on GitHub real quick
you gave the node an ID, why not grab it by calling G.OVERLAY_MENU:get_UIE_by_ID('toggle_container')?
you're getting a UIElement this way, unlike before where you just grab a prototype table
Oh! I didn't know that was something I could call that on - I gave it the ID so I could try doing config_ui.UIBox:get_UIE_by_ID but that also returned nil. Let me see if that works instead
In the meantime here's the full context:
https://github.com/atlanticaccent/higher-steaks
That and fixing a typo fixed it, thank you!
its not
How would I make legendaries appear in the shop? 🤔 thinking about making a joker that has them show up
local oldgetcurrentpool = get_current_pool
function get_current_pool(_type, _rarity, _legendary, _append)
if next(SMODS.find_card('j_modprefix_key')) and _type == 'Joker' and _append == 'sho' then
local poll = pseudorandom('rarity'..G.GAME.round_resets.ante.._append)
if poll < (1/odds) then
_legendary = true
end
end
return oldgetcurrentpool(_type, _rarity, _legendary, _append)
end
what would be the context that something like bonus card would trigger on
(it doesnt use a calculate function, but if you were to recreate bonus card and have it use a calculate function instead of the built in system)
You can't recreate Bonus Card with a calculate function, because it adds it's chips to the cards base chips.
quick question, is it possible to have multiple consumables reference the same localisation description?
e.g. if i had multiple Apple Cards that share the same description "This is an Apple Card"
yes, key in loc_vars
the different booster packs do this because each different art is a different object
:o yay
how do I get the deck back of a card?
like, the sprite object?
deck key preferably, though sprite pos could probably work
well usually cards have the same back as the current deck except for that one copy glitch that is fixed in smods
its for a drawstep that needs to work during deck selection too
me when i get xy problem'd..
here's how cryptid does it https://github.com/SpectralPack/Cryptid/blob/6daf1302f37751a888eeee74b9964d88c6c92938/lib/ui.lua#L12
it seems to account for galdur too
ah this looks like a very good example of what I'm trying to do, thanks
do :juice_up() calls need to be done in an event?
i feel like i keep seeing them exclusively called in events
They don't need to be in an event, in that you won't crash the game or something. But events help a lot with timing.
hey im looking at astra's video where is this code located in vanillaremade
the wiki (scroll down, it's part of a rather long section)
https://github.com/nh6574/VanillaRemade/wiki#how-do-i-organize-my-files

is it possible the sacle down the contents of a UIBox embedded in an object node
like to 0.9
local function is_mouse_near_card(card, mx, my, padding)
local x = card.VT.x * G.TILESIZE * G.TILESCALE
local y = card.VT.y * G.TILESIZE * G.TILESCALE
local w = card.VT.w * G.TILESIZE * G.TILESCALE
local h = card.VT.h * G.TILESIZE * G.TILESCALE
local sw, sh = love.graphics.getDimensions()
padding = padding or (0.1 * math.min(sw, sh))
return mx > x - padding and mx < x + w + padding and
my > y - padding and my < y + h + padding
end
local card_cap = 50
local rank_thereshold = 20
local draw_hook = Card.draw
function Card:draw(layer)
local function is_area_allowed(area)
if area == G.consumeables then return true end
if area == G.jokers then return true end
end
if self.area and is_area_allowed(self.area) and self.highlighted ~= true then
if #self.area.cards >=card_cap and self.rank and self.rank >=rank_thereshold then
local mx, my = G.CONTROLLER.cursor_position.x, G.CONTROLLER.cursor_position.y
if not is_mouse_near_card(self,mx,my) then
return
end
end
end
return draw_hook(self,layer)
end
local l_update = Card.update
function Card:update(dt)
if self.area and #self.area.cards >=card_cap and not self.bl_optimized_request_update then
return
end
if self.bl_optimized_request_update then
self.bl_optimized_request_update = false
end
return l_update(self,dt)
end
eval_hook = eval_card
eval_card = function (card,context)
if card.area and #card.area.cards >=card_cap then
card.bl_optimized_request_update = true
end
return eval_hook(card,context)
end
this reduces lag a bit but it doesn't make the game run clean with lot of cards like I want it to
what else I need to modify?
What is the goal?
I'm trying to optimize it to be able to run lot of jokers and consumables at once (jokers may be harder) but I noticed with consumeables If you have something like 200 consumeables and even If they aren't being rendered the game still lags for some reason even If they don't have any calculate functions
have you considered the amount of memory that is being juggled and cpu power it takes for that amount of cards
but the cards are not being rendered at all and they don't have calculate functions
the memory part though
does the memory cause significant lag even with small amounts like 200(because it has many variables or something) and should reducing that fix it?
I tested that by making the update function and draw function and calculate function do nothing
and lag was still there when getting to 3 digits
for consumables is because can_use is run a lot im assuming
Hey, is there a built-in way to offset the logo of the game?
G.SPLASH_LOGO.alignment.offset.x or .y
also G.title_top as well to move the cards
Thank you!
just downloaded the debug mod. i feel a bit silly asking this, but what's the command to spawn a joker?
i looked through the github and found a list of supposed hotkeys, but none of them seem to work :/
aha, i have figured it out
i had to hold tab, not just press it
yeah think u figured it out but collection and then find the joker u wanna spawn and press 3
same for anything else
To spawn things you go into the collection, hover your cursor over what you wish to spawn, and press 3
Pressing 1 unlocks it if locked and pressing 2 discovers it if undiscovered
Holding tab is for in game stuff, like giving money, rerolling bosses, etc.
It also tells you how to cycle through editions, enhancements, seals, etc. as well as how to duplicate and despawn things among other commands
alright, i've racked my brain enough to feel like i can once again ask for some assistance. this joker is supposed to give +1 hand size for every 4 wild cards in your full deck. i cannot get it to work unfortunately, and i think i did so much spaghetti code that my mind is a bit broken as well. if anybody's able and willing to help me troubleshoot, i'd be more than appreciative
add_to_deck = function(self, card, from_debuff)
card.ability.extra.hand_size = 0
local count = 0
for k, v in pairs(G.playing_cards) do
if SMODS.has_enhancement(v, 'm_wild') then
count = count+1
end
end
card.ability.extra.hand_size = math.floor(count/4)
G.hand:change_size(card.ability.extra.hand_size)
end,
update = function(self, card, dt)
if G.playing_cards then
local count = 0
for k, v in pairs(G.playing_cards) do
if SMODS.has_enhancement(v, 'm_wild') then
count = count+1
end
end
if card.added_to_deck then
G.hand:change_size(math.floor(count/4)-card.ability.extra.hand_size)
end
card.ability.extra.hand_size = math.floor(count/4)
end
end,
remove_from_deck = function(self, card, from_debuff)
G.hand:change_size(-card.ability.extra.hand_size)
end
wait, is this the whole thing?
wow that's condensed
is this all i need to have inside under my calculate = function(self, card, context)?
No, this replaces the calculate function.
alright, i replaced it and now the game crashed when i try and view it
i must've replaced it wrong
bump
how would i force trigger tag1 from tag2
-# provided tag1 is present (for example: rare tag)
i don't know if this is a cryptid thing or something but forcing a rare tag normally wouldn't be possible without manually recreating the effect, since it triggers in a specific shop context
well, i want to force remove a tag without activating its effect
you can just iterate through the tags and call tag:nope on it im pretty sure
no idea how id do it, i'm exploring uncharted territory
the tags are in G.GAME.tags
loc_vars = function(self, info_queue, card)
info_queue[#"Info"_queue + 1] = G.P_CENTERS["joker"]
local j = card.ability.extra.Joker or 'j_joker'
local n = card.ability.extra.Jokername or 'Joker'
return {vars = {j, n}}
end,
how do i make this actually provide the info queue
the hells tag:nope anyway
G.P_CENTERS.joker isnt a thing
im trying to figure out what to replace joker with
this is from SMODS
info_queue[#1116390750314307698_queue+1] = G.P_CENTERS.j_stone
i tried doing G.P_CENTERS.j but that didnt work
wait i got it
the key of the object you want the info queue from
thats also not a thing
iinfo_queue[#1116390750314307698_queue + 1] = G.P_CENTERS[j]
this is what i needed to get it working
provided j is a key, yeah that will work
ill bump this to see if anyone else can give a guide
Just does the visual "Nope!" and removes the tag.
alright, i have a joker idea that i want to try and code, and i want to get a rough idea of how i could approach it.
This Joker gains +2 chips per combination of 15 in scored cards.
(ex: the hand 5, 5, K, K would score 8 chips)
my thinking is that after we have all scored cards, i run through every single combination of card grouping, check if their total is 15 (doing some extra stuff to make Aces count as 1 and not 11), and increase a variable if so. anybody know of a better way of doing this?
bump
i literally gave you a guide 😭 you're just asking people to code it for you at that point
just ask the specifics of what you don't know
the idea is idk how id trigger tag:nope but ill look at how cryptid does it
N just told you how to do it? Iterate over G.GAME.tags, and for each tag check whether it's the tag you want to remove. If so, call :nope() on it
i was just about to say
run an if statement if a tag is present, if it is; remove it
would there be a problem with duplicates?
idk how id trigger tag:nope
It takes no arguments. You can checktag.lua:24, it definesTag:nope
.
problem solved
when you iterate you need to check that the tag is your heart tag and just :nope the first one you find if you only want to delete one
run an if statement if a tag is present
not really? you should, for each tag, check whether that tag is the one you want (something likeif mytag.key == "hearts" then ...)
if it is; remove it
yes (by calling:nope())
Depends, are you removing multiple tags at once? If only one every time, you're fine
one at a time
although should i do something in the event i have two
having three broken hearts causes an immediate game over and if you gain a heart you lose it and a broken heart is also lost
-# Was about ask a Question but N' has already answered it before, Thanks N'! 
local wiki = N
oh lars the bug i told you the other day wasn't fixed lol
uh
Should be fine. You can let one of the tags successfully activate, removing the other one
what does that mean 😭
the orphan text is still there, it turns out that specific version of smods we were testing at the time had another bug that prevented it
i can probably pr the fix this weekend
if you do, just ping/dm me on discord so I actually see it
is there a formula to simplify tetration??
like how theres a formula for factorials
so instead of calculating how much is !10000
you just use the factorial formula
what?
I inversed the place where ! is supposed to be
I put it at the beginning but It's at the end
no not that
I understand you didn't mean subfactorial
I mean what does this mean
Like there's Stirling's formula for factorial
instead of calculating 1000! you do it with a formula, which is just calculating 1000!
I meant so you don't have to do 1000x999x998...
1000 times
which is a lot slower
so you use stirling's formula
is there a equal for tetration?
theres no way float exponentiation is faster than integer multiplication
If you were to calculate factorial without using stirling's formula for factorial of 1000 you would need to do 1000 for loops
thats what I mean
float exponentiation is really fricking expensive
I think we're understanding different things
wait lemme create a function to explain
im thinking of sqrt(τn) * (n / e)ⁿ
which includes float roots, division, and exponentiation
all very expensive operations
compared to a for loop and integer multiplication
spectrallib has code for doing it
Nice
I'mma look into it
what I was trying to mean was
local function fact(n)
local result = n
for i = n-1,1,-1 do
result=result*i
end
return result
end
local function stirling_approximation(n)
local x=math.pi*2
local a = math.exp(1)
return math.sqrt(x * n) * (n / a) ^ n
end
local result = stirling_approximation(10000000)
how the stirling_approximation function will be much faster than doing 1 million for loops
but I suck at math
so I can't really explain it clearly
do you know the name of the function?
search tetra itll probably come up
okay so im stupid I though float exponentiation was like O(n)
its faster
function Spectrallib.tetrate(base, height)
-- just use Talisman/Amulet's tetration if possible
if Talisman then return to_big(base):tetrate(height) end
-- avoid easy cases; taken from omeganum tetrate
if height <= -2 then return NaN end
if base == 0 then return height == 0 and NaN or math.ceil(height) % 2 end
if base == 1 then return height == -1 and NaN or 1 end
if height == -1 then return 0 end
if height == 0 then return 1 end
if height == 1 then return base end
if base == 2 and height == 2 then return 4 end
-- the function itself
if height > 1e6 then
if base < math.exp(1/math.exp(1)) then
local negln = -math.log(base)
return Spectrallib.lambert_w(negln) / negln
end
return base == 1 and 1 or (base > 0 and base < 1 and 0) or (base < 0 and NaN) or math.huge
end
local frac = height - math.floor(height)
local tower = {}
for i = 2, math.floor(height) do
tower[#tower+1] = base
end
local tot = tower[#tower] ^ (base ^ frac)
for i = #tower, 1, -1 do
tot = tower[i] ^ tot
end
return tot
end
this is regular tetration but it doesn't approximate it
I'm pretty sure theres a way to approximate it though
I'm trying to come up with something but I suck at math and my mind is just overflowing
I realized that 2^(2^(2^2))
is 65536
however 2^(4^2)
is also 65536
and that reduces the work in half I think
If someone who's good at math could help me I'd appreciate
how can i create a joker when the run start and not when the run is continued?

and if yes do food jokers destroying itself counts?
holy shit teto
im pretty sure the wiki answers this
no
that's context.destroy_card
wait being destroyed
okay both are wrong
those 2 are for checking if a card should be destroyed
ok assume im talking about whichever one triggers when a card is destroyed
context.remove_playing_card (playing card destroyed) and context.joker_type_destroyed (anything else)
yes
What may be the reason, this shader does not apply to the floating sprites? The shader switches between visible and invisible and I have apply_to_float = true in the edition
it would help if we had code
What code? The shader code or the edition code?
The shader/edition is called forgotten
weird
Yeah, as far as I know, I did nothing wrong
@daring fern Sorry if I misunderstood your bio regarding pinging you but do you have a clue why this isn't working?
Also, how do I allow spaces in a text input?
wait no_styled_name is a thing?
Interesting
is there an option for like "only_description" or "only_text" or "only_info_queue" or smth?
is it actually like mytag.key or what do i plug there
/genq
This makes me crazy TwT
how do i use quantum enhancements
uh thats not good
iirc I had to do a hook for Card:should_hide_front for some of my antics.
I wanna change how my Enhancement draws the Base-Sprite....
Where would I start? What do I need to hook or even Lovely-Patch?
(The basic goal is to draw half the Sprite-Size)
Hey funny i'm literally looking at that rn 
probably a drawstep
if you named the iterator mytag then yes
i didnt?
(if you have no idea what I'm talking about, start googling "lua for loop")
-# Which one would you suggest looking at specifically for drawing the Base-Sprite (in SMODS->src/card_draw.lua)?
Actually; I'm gonna assume "key = 'front'" now that I'm looking at it owo'
yeah i didnt name any iterator such
then change it to [whatever-you-named-it].key
?
G.GAME.tags[i].key
ok so this is my code rn
calculate = function(self, card, context)
if context.check_enhancement == 'm_stone' then
return {
m_stone = true,
m_mult = true
}
end
end
}
it doesnt seem to work
i do have the optional features enabled in main.lua
over here
context.check_enhancement is true|false
oops
?
You might want to take a look at the documentation
ok now it just dies
just ignore that it references retriggers
oops i mustve looked at the wrong page
I'd keep the if G.GAME.tags[i] and G.GAME.tags[i] == ..., just as safety (it doesnt break anything, but it doesn't hurt to have it)
Secondly, if you want to only delete one tag, you'll need to stop the loop somehow after noping the first tag
the explanation didnt rly make much sense so im just taking some code from the extra credit mod instead
ok so it works but it makes major lag spikes
maybe its bc of the handy mod? tbf im not on the latest version of smods
lemme fix that
Is there a way I can make a specific joker store slot have a discount, and not the others. I'm thinking about making a joker that gives you a store slot w/a discount
Not sure what type of slot, im thinking random per shop visit
(tho voucher slots might not be fun so maybe 50-50 between joker and booster)
idk just making things seeing if this is implementable
I might just do u get gold back whenever u buy something
Former:
Have a hook on Card:set_cost_value.
In context.starting_shop, choose between G.shop_jokers and G.shop_booster, then randomly choose between the slots.
Then, in context.modify_shop_card, check if the card is in said slot and call :set_cost() on said card.
-# Or something of such.
🤔 thanks
Front might work, but I may also suggest fully making your own as well
I am so lost in the sauce rn 
We love being lost in sauce
I see that it calls suit:draw(self, layer), but I can't find a draw() function that takes 2 parameters..?
Edit: Is it using Nvm, still have no ideaSMODS.loading:draw()?
I don't really get how I would go about drawing the Base-Texture but at half Size with a custom Draw step :/
Guys, I'm making a mod in JokerForge and I'm getting this error when I create a consumable. Like, when I remove it, the game works again.
you should not have both talisman and amulet installed first of all
also probably ask in the joker forge discord
oooooooh, thxx!
yeah, but idk how 😭
such is the suffering of exploring new territory
The best advice I can give you is to just start researching it. If you google "lua stop loop", you'll get some great results that should point you in the right direction
have you ever heard of break
?
missed child continue:
how do i make a joker give xmult ONLY for 7s?
as in like
it wont give mult unless your hand has only 7s and nothing else
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xmult } }
end,
calculate = function(self, card, context)
if context.joker_main and context.full_hand[1]:get_id() == 7 then
return {
xmult = card.ability.extra.Xmult
}
end
end
}```
this code does nothing, which is NOT what i want ^^^^
you're only checking the 1st card of your hand
loop on all cards in context.full_hand
if context.joker_main then
local passed = true
for k, v in pairs(context.full_hand) do
if v:get_id() ~= 7 then
passed = false
end
end
if passed then
return {xmult = card.ability.extra.Xmult}
end
end
Well, getting somewhere
thank you something!
what does for k and v in pairs(context.full_hand) mean?
im guessing what its doing is looking at my full hand and saying "if every card ISNT a 7, you're not doing it right"
if only
for key, value in pairs(table) do loops over all of the keys in table and gives each corresponding value
if you swap pairs for ipairs it does the same but only for ascending integer keys
^ it runs the loop once per every element in table, and you can use key and value to access info about each element
every [anything] has a key assigned to it if it's in a table. it's decided by the table, not by the cards
so the loop here is sorta like a border guard checking to see if the key matches the 7
i think im just being stupid
oh right
anyway every time the loop runs in something's code, k is the index of the card in context.full_hand, and v is the card object itself. the loop checks each card's ID, and if even one of them isn't a 7, it sets passed to false and therefore it won't give the xmult
How do I stop the normal suit from rendering? o~o'
hook the front drawstep to skip it if it's your custom enhancement
-- Seven Sisters
SMODS.Joker {
key = "sevensisters",
pos = { x = 7, y = 0 },
config = { extra = { xmult = 3.5 } },
cost = 9,
rarity = 3,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
unlocked = true,
discovered = false,
atlas = 'HatchetJokers',
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xmult } }
end,
-- Code by Somethingcom515
calculate = function(self, card, context)
if context.joker_main then
local passed = true
for k, v in pairs(context.full_hand) do
if v:get_id() ~= 7 then -- if even one card is NOT 7, its false. ~= is the lua equivalent of !=
passed = false -- the local "passed" variable is set to false
end
end
if passed then
return { xmult = card.ability.extra.xmult }
end
end
end
}
--[[
k = *key*
v = value
the code above runs a loop for each corresponding key within the table.
everything within a table (whether its cards, blinds, etc) is assigned a key.
everytime the loop runs in the code, [k] is the index within the context (your full hand) while [v] is the card object
itself. think of [k] as a search string and [v] as the card object. your loop is checking each card's ID. if even one of them
ISNT a 7, the code will not run, hence why its set to false
--]]```
is this correct
Okay stupid question; How do I hook a drawstep? 
smods maintains a list of drawsteps like most of the other stuff it provides, SMODS.DrawSteps.front.func would be the function you need to hook
looks good yea
yippee
i like storing little notes in my code so i can look back and remember
thank you gozaimasu
SMODS.DrawSteps.front.func is function you're looking for
yeah im being stupid
421% of the time
how do you alter shop rates with a specific joker
im trying to make a joker that increases the likelihood of encountering negative jokers in store
sorta like what Hone does
peek yahimod yahi joker
-# YAHIMOD OF ALL MODS 😭
please do NOT look at yahimod code 😭
yeah i took a look and it looked like such a mess 😭
anyways time to bang my head on the keyboard 421 times because of my stupidity
ok so the wormhole deck (cryptid) has something like this G.GAME.modifiers.cry_negative_rate
im unsure what the "cry" means
ohh cryptid
LOL
cryptid prefix
im so dumb
yes
sobs
local oldenegativegetweight = G.P_CENTERS.e_negative.get_weight
SMODS.Edition:take_ownership('e_negative', {
get_weight = function(self)
local weight = oldenegativegetweight(self)
for k, v in pairs(SMODS.find_card('j_modprefix_key')) do
weight = weight * number
end
return weight
end
}, true)
ahhh so i have to take ownership then
ill make notes!
and im guessing number is substituted for 2
or i have to make number a local variable and define it as 2 ?
you should replace number with whatever the config value is for the joker
that controls the negative rate
o i see
so v.ability.extra.whatever
well its meant to make negative jokers 2X more likely
oo oke
hmm
-- Black Joker (Ownerships) / Code by Somethingcom515
local oldweight = G.P_CENTERS.e_negative.get_weight
SMODS.Edition:take_ownership('e_negative', {
get_weight = function(self)
local weight = oldweight(self)
for k, v in pairs(SMODS.find_card('j_hatch_blackjoker')) do
weight = weight * 2
end
return weight
end
}, true)
--[[
We are taking ownership of the game's negative rate!
The old weight is defined as a GAME variable. We are taking the base weight, then telling "Black Joker"
to apply its increased rate, which is 2.
--]]
-- Black Joker
SMODS.Joker {
key = "blackjoker",
config = { extra = { negative_rate = 2 } },
pos = { x = 9, y = 0 },
cost = 9,
rarity = 3,
blueprint_compat = false,
eternal_compat = true,
perishable_compat = true,
unlocked = true,
discovered = false,
atlas = 'HatchetJokers',
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
return { vars = { card.ability.extra.negative_rate } }
end,
}
this is what ive got rn
im unsure what to do next, or what to note
Looks Good :3
Until you start dragging it somewhere :(
is it a little laggy when you drag it?
No not at all, it sticks perfectly... it's just very offset x'3
Oh my gosh, Thank you!
I was just looking for that 
are my notes correct
also setting the weight to 2 does almost nothing
i keep rerolling and the odds i get a negative joker arent any more likely
you're changing a 0.3% chance to a 0.6% chance
how do base game jokers interact with pools
do you just have to manually create pools for them or do they already have some
gotcha gotcha, ill try and figure out the maths then
0.6% to 25% seems good for a joker of this rarity
whatever the pools thing in an SMODS.Joker is
idk if that's this
0.3 in 1 or 0.3 in 100
that's for this https://github.com/Steamodded/smods/wiki/SMODS.ObjectType#api-documentation-smodsobjecttype
but there are no base game pools and for the most part the utility has been replaced by attributes in the latest version
can you make modded attributes?
yes
alr
1 in 3 jokers being negative seems game breakingly strong
what is key_append in SMODS.add_card?
bump
how would you add a custom joker as an info_queue?
It's a string that gets passed into in_pool as args.source so cards know what their being created from.
table.insert(info_queue, G.P_CENTERS.j_modprefix_key)
also RNG seeding
would info_queue[#info_queue+1] = G.P_CENTERS.j_CGN_Yin work?
yes
would the load order of jokers affect this
no
whats causing this to crash then
what's the log
oh i just realized the issue
im having two jokers info_queue each other
so it just infinitely does more info_queues
you can check for card.fake_card
is there a way to fix this
so it doesnt add it when its in a tooltip
if not card.fake_card then
info_queue[#info_queue+1] = G.P_CENTERS.j_CGN_Yang
end
would this work then
yeah
alr thank you
still doin it
G.GAME.tags[i]:nope()
eremel i wanted to know if im doin it right 😭
you're not thats why I gave you some different code 😭
i have a .lua for making dynamic big poker hands but it seems to only apply visually and the actual returned value is unchanged
how do i fix that
Hey!
dont know what thatll do but when ill test
pretty weird for a oneliner
Well you’re trying to nope a value tag that you never set so it’ll just crash
@keen totem you forgot about me
you're not supposed to replace the entire thing if that's what you're thinking 😭
just the nope line
how do i replace the mult sound effect in scoring with another sound effect?
like in a simple base joker for example
if adding sound to the return doesn't work you can try mult_message = {message = localize{type='variable',key='a_mult',vars={number}}, colour = G.C.MULT, sound = key }
it just plays it as soon as i press the play button when just sound in the return, so yeah thats helpful thanks
if that happens then youre doing something wrong
i meant mult = number, sound = key
if context.joker_main then
return {
mult = card.ability.extra.mult,
sound = ("prefix_examplekey")
}
end
something like that?
yeah, if it doesnt work then it just wont play the sound
? mult still scores, just the sound plays as soon as the hand starts
theres def a simple fix tho
ill put something together
i have no idea why it would do that
what about this
so this gives me two different crashes. one happens when i try and view the joker in the collection. i believe what happens is that it tries to count the playing cards, but if you're in the menu, it doesn't have any cards to count so it crashes. then, if you try to view the joker in your collection during a game, you get an error saying that hand_size is a nil value (not sure why that is). any chance you can help me?
Yes, I updated the code, also change the variable in the config to hand_size instead of handsize
it no longer crashes, but now once you have a wild in your deck, your hand size decreases once per frame
do i need to change anything in the loc_vars?
No, I updated the code again.
just so i'm learning, what are you changing and why?
in my code, i'm trying to debuff a random joker from an array.
if #jokers > 0 then
local temp_card = pseudorandom_element(jokers, pseudoseed('bgn_aj_joker'))
G.jokers.cards[temp_card].debuff = true <-- this line is wrong
end
problem is that my temp_card variable is a joker and in order to debuff a card, i need to use an integer. if i have a joker, how do i find it's cooresponding integer value?
don't
temp_card and G.jokers.cards[joker's position] are literally the same table in this context
you also shouldn't set Card.debuff directly
use SMODS.debuff_card
how would i make an info_queue box for a tag
i can't find this on the documentation wiki, any chance you have the link to where i can read ab this?
info_queue[#info_queue + 1] = { key = "key", set = "Tag" }
yeah i am being stupid
What are you trying to do?
if you get a game over during a blind, prevent it (just like mr bones but in a tag)
secondly, if it finds a broken heart, destroy both tags (this and broken heart)
the broken heart will have a seperate implementation where if you get three of them, instant game over
And what’s currently working?
nothing :D
Tags don’t use the normal calculation cycle at the moment, they have a different workflow
So your context checks will never pass
well, what do tags use?
for i = 1, #G.GAME.tags do
G.GAME.tags[i]:apply_to_run({type = 'shop_start'})
end
this is the equivalent of SMODS.calculate_context({entering_shop = true}) but for tags
so if i put type = 'game_over' will it activate on a game over
yes
function SMODS.current_mod:calculate(context)
if context.end_of_round and context.game_over then
for i = 1, #G.GAME.tags do
local triggered = G.GAME.tags[i]:apply_to_run({type = 'game_over'})
if triggered then
return {
message = localize('k_saved_ex'),
saved = 'ph_mr_bones',
colour = G.C.RED,
}
end
end
end
end
well, for preventing game over you definitely need more work
i was thinking of taking mr bones code from vanillaremade to get the job done
check out the updated snippet
also got this snippet to check for any broken hearts
uh
put that global calculate in main.lua
also change your apply to this
apply = function(self, tag, context)
if context.type == 'game_over' then
local prevent_trigger = false
for i = 1, #G.GAME.tags do
if G.GAME.tags[i].key == 'tag_dw_brokenheart' then -- tags have prefixes btw
prevent_trigger = true
break
end
end
if prevent_trigger then
tag:nope()
else
local lock = tag.ID
G.CONTROLLER.locks[lock] = true
tag:yep('+', G.C.GREEN, function()
G.CONTROLLER.locks[lock] = nil
return true
end)
tag.triggered = true
return true
end
end
end,
test time
also
how are you going to deal with multiple instances of this tag
let SUAS happen? actually no, it just wastes all other tags
i don't know
at the same time, the broken heart is supposed to like get rid of the heart tag and itself
that's the problem
how are you going to deal with x instances of this tag and y instances of that tag
having 3 instances of brokenheart cause an instant game over
and if you get a brokenheart while having a heart they should both self-destruct, i'd use destroy_card but does it work on tags
no
both the vanillaremade wiki and smods wiki dont say a lot