#💻・modding-dev
1 messages · Page 674 of 1
oh then its b_embr_effectgive_cards = "Effects",
you put a k where a b shouldve been
its fine i know u read my screenshot
No, it would be b_effectgive_cards
doesnt consumabletype embed the mod name to the key
if not then listen to somethingcom because they know this more than i do 😭
i tried both of your syntax and niethe rworked 😭
No, SMODS.ObjectTypes and SMODS.ConsumableTypes don't have mod prefixes.
What does your localization file look like?
did u include the localization file in ur main
no i mean
wait
i'm dumb
localisation file shoud be in your mod folder / localization / en-us.lua
im tweaked out
what letter do i put here for my card key
[X]_embr_PLACEHOLDER = {
i have no idea
c
why c?
Spam?

c for consumable i think
i mean it worked but for what purpose
oh that makes so much sense
okay tyty
@noble ore please stop talking 😭
-# just ignore that c_base exists in vanilla
Do we ping mods
<@&1133519078540185692>
Spam
Also fyi the steamodded wiki page has the class prefixes for each smods object on its page
https://github.com/Steamodded/smods/wiki
Which one? Boss, small or big?
i am the serpent
Noted
genuinely i think im slow
embr_effectGive = "Potion",
why is the label not showing 😭
dictionary = {
b_effectgive_cards = "Effects",
},
labels = {
embr_effectgive = "Potion",
},
},```
embr_effectGive vs embr_effectgive, it probably matters if the G is capital or not. You should make it fully consistent.
Remove embr_
nope
It should be k_key in dictionary
wait i just realized your pfp
you play poly bridge too?
peak
oh urray!! thank you
i was follwing what vanilla reamde was doing
@daring fern I have been trying to figure out how you place seal and enhancement on Jokers, like a DaVinci Code. My God I am terrible at codding but I work with four other people who can code not even they know how you did this madness, dude you got share your secrets
Seals can already be placed on jokers, so I just hooked Card:calculate_seal. For enhancements, I just set a value on the card and calculate the enhancements on certain contexts.
Your going to have to set me a code break down because both my modders friends told that was impossible
I tried but can't find anything that outright said localization: Enchantment on Jokers or seal on Jokers hook
Or least my very not skilled eyes didn't catch it
Yes, I don't comment my code.
I apologize, obviously didn't even get close yourstuff very complicated. It was example of how I don't know how to read code
Could be better if I send message, so it not here in public?
ok so this one is tricky, i am trying to make a joker that creates clones of used planet cards, and they all have a 1 in 4 chance of becoming negative.
i wann ask how to create clones of used planet cards
You can refer to VanillaRemade for all the parts of what you want to do. Constellation for the context of using a planet card, Perkeo for the effect of duplicating consumeables.
https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua
i mean, i'd still have to keep track of the card being used.
Is it possible to replace the small and big blinds with a random boss blind each?
That one's just on the smods wiki, it's context.consumeable available with context.using_consumeable
hmm... local card_to_copy, _ = context.consumeable
local function better_copy_card(card, new_card, area)
if not card then return nil end
local area = area or (new_card and new_card.area) or card.area or G.jokers
local cardwasindeck = new_card and new_card.added_to_deck or nil
local copy = copy_card(card, new_card)
if new_card and cardwasindeck then copy:remove_from_deck() end
if card.playing_card then
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
copy.playing_card = G.playing_card
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, copy)
end
if (new_card and cardwasindeck) or not new_card then copy:add_to_deck() end
if not new_card then area:emplace(copy) end
return copy
end
if context.using_consumeable then
local copy = better_copy_card(context.consumeable)
if SMODS.pseudorandom_probability(card, self.key, 1, 4) then
copy:set_edition('e_negative')
end
end
@daring fern What the hook use for enchantment on Joker?
Hi guys. Do you know how I could make SMODS.add_card add a card from the most played rank?
Been trying to figure it out, but no luck.
nothing in the game tracks most played card rank to my knowledge, so you'd need to make a whole custom stat for it
Yeah, I was starting to realize that just a bit ago.
for k, v in pairs(G.playing_cards) do
ranks[v:get_id()] = (ranks[v:get_id()] or 0) + v.base.times_played
end
table.sort(ranks, function(a, b) return a > b end)
local mostplayed = ranks[1]```
You reckon this could work?
yeah, i think that'll do!
aight, thanks. 
really need to find a way to disable this omg
Long story short an ex flagged my account
an ex
oh
bruh
How could I make a dynamic UI
like say a piece that constantly moves across the screen
I ask the mod and discord server and none them give me a solution
this happens with discord itself, they actually can't help you
you'd have to take that up with discord themselves, and they probably don't care either
how do you make this button affect a specific joker's values?
function G.FUNCS.stealmoney()
ease_dollars(-5)
end
this is for ultra greed, when you press the button, it should spend 5 dollars and then give ultra greed x0.5 mult
You right because reached out to them, they really could careless
you could have a global counter that checks how many times you've stolen, or you could send a context to jokers that money have been stolen from the shop
Whar
how do you set up a global again
if you would go with context approach you could do something like { shop_steal = true } and check on that condition in your joker's calculate
Note: it's good practice to add your mod prefix to custom contexts your mod adds
But actually modding questions, it possible to have a consumable permanently grants Jokers additional mult and chips, in similar way Hikers adds to cards.
But instead affect Jokers
global would be just any parameter inside G.GAME, so if you added G.GAME.shop_steals = 0 at the beginning of the run, you could modify that / check that inside of your joker
BB = {}
BB.money_counter = { }```
you'd be able to just mess with ability.mult and ability.chips, but it won't show in the UI. the cleaner way is probably to do it with a sticker (i.e., add the sticker if it isn't already added, else change a values associated with the sticker)
i think i'm supposed to make BB.money_counter an int value and not a table
the issue with this is that it doesn't survive reloading the run. anything that needs to persist through a run you need to put in G.GAME (or in case of a card, in a card area)
So essentially creative positive stickers. Instead their usually detrimental status?
Because looking to use consumable cards to power up them up, my other options was going through similar method that Seal on Everything did with granting seals to Jokers, but not being able to understand it
yeah there's no need to have it be seals. stickers at core are just modifiers that can go on any type of card
of course you'd have them be unable to spawn on shop cards
it's not finished since i'm still trying to figure out how to get the button to activate this joker's scaling mechanism
Xnil
Maybe what can do, is have this rare consumables place stickers that like said beneficial to only Jokers. Ok thanks for the idea!!
look at what the sell button does
main balatro or smods?
main balatro
ok so i found thislocal card = e.config.ref_table
ok idk what to understand from this
how could i check if a specific consumeable is unlocked/discovered?
trying to make a sort of artificial upgrade system where if you unlock the upgraded version of the consumeable, the original doesnt appear again
G.P_CENTERS[key].discovered or G.P_CENTERS[key].unlocked
ty
well good to know this game was never made with the idea that consumeables could be locked lol
bump
does anyone know why this function never seems to be called?
i did a simple override but it doesnt print at all
and i get this error evaluating it with and without override
scale being nil is also kinda weird
actually G.GAME.modifiers seem to be empty ???
mind the part where it says "higher stages of ante scaling"
the base function is get_blind_amount, this function is for what vanilla doesn't already handle
the docs should probably clarify that
what are the higher stages of ante scaling?
any stage beyond what vanilla has

event = 'released' i think
Can you change sell conditions? I have a joker that gives extra joker slots, but want to prevent the joker tray overflowing
wait no nvm, im dumb
what would be the easiest way to make a deck retrigger all current jokers? ie say, "you have 3 joker slots, but all jokers retrigger once"
Deck effects look similar to joker effects in terms of code
More precisely, eternal but without a visual sticker
And conditionned
And stackable with normal eternal
my current attempt is uh, very finnicky...
-- 3 joker slots, all jokers retrigger once each hand
return function(REW1RED)
SMODS.Back({
key = "resonance",
loc_txt = {
name = "Resonance",
text = {
"{C:attention}3{} Joker slots",
"All Jokers {C:green}retrigger once{}"
}
},
pos = { x = 5, y = 0 },
atlas = "decks",
config = {},
apply = function(self)
-- G.jokers does not exist yet when apply runs; limit is applied in hooks after start_run
G.GAME.modifiers.rew_joker_slot_limit = 3
G.GAME.modifiers.rew_all_jokers_retrigger_once = true
end
})
end
i have no idea wht i was on for this stuff at all
there has to be a more consistent way to make this
You can modify G.GAME.starting_params.joker_slots to change the joker limit within the apply.
As for the Retriggers, you should be able to give your deck a calculate function with the retrigger_joker_check context.
yeah I ask this some days ago but how do I make this work the problem is that I am changing a seal in the context.before and I need it to work in the context.main_scoring. like now its working with the code but the animation is wacky like first the seal is disappearing and I dont want that. So Somethingcom said that I need to hook the drawstep but yeah it doent work.
can you dynamically enable and disable the soul layer for joker?
or is that a static setting
i guess rearrange the order of operations?
make the cards flip over first and then apply the change while it's flipped
yeah idk I guess Im gonna do that
Yeah So I Know its not a good practice but by doing that it is working so yeah
is their a way to know if the card is already flip
card.facing == 'back' ?
resisting the urge to just make my own keybind system, ,,
how would I change the sprite of a deck (smods.back) mid run?
update for anyone who was curious: really not made for it
how do i add screenshake?
you could change the sprite to an empty one
you can put a draw function on soul_pos, that should do
make a second released keybind and set some flag in the held one to check for in the released one, which is then reset. if you think you have a better way to do that, do feel free to send a PR

If I want to insert my own function into game instances, would I have to do it via patching, since G seems to be created when reading my mod files
or is there another way to do it
oop my minigame state doesn't exist
any idea why my function isn't being called when I press the bottom button
local blind_tag_ref = create_UIBox_blind_tag
function create_UIBox_blind_tag(blind_choice, run_info)
local ret = blind_tag_ref(blind_choice, run_info)
if not ret then return ret end
local _tag = Tag("tag_uncommon", nil, blind_choice)
local _tag_ui, _tag_sprite = _tag:generate_UI()
_tag_sprite.states.collide.can = not not run_info
ret.nodes[#ret.nodes+1] = {
n=G.UIT.R, config={id = 'minigame_'..blind_choice, align = "cm", r = 0.1, padding = 0.1, minw = 1, can_collide = true, ref_table = _tag_sprite}, nodes={
{n=G.UIT.C, config={id = 'minigame_desc', align = "cm", minh = 1}, nodes={
_tag_ui
}},
not run_info and {n=G.UIT.C, config={id="minigame_container",align = "cm", colour = G.C.UI.BACKGROUND_INACTIVE, minh = 0.6, minw = 2, maxw = 2, padding = 0.07, r = 0.1, shadow = true, hover = true, one_press = true, button = 'foobar_select_minigame', func = 'hover_tag_proxy', ref_table = _tag}, nodes={
{n=G.UIT.T, config={text = "Play Minigame", scale = 0.4, colour = G.C.UI.TEXT_INACTIVE}}
}} or {n=G.UIT.C, config={align = "cm", padding = 0.1, emboss = 0.05, colour = mix_colours(G.C.BLUE, G.C.BLACK, 0.4), r = 0.1, maxw = 2}, nodes={
{n=G.UIT.T, config={text = "Play Minigame", scale = 0.35, colour = G.C.WHITE}},
}},
}
}
return ret
end
its calling the regular skip blind function
nvm found it
one of my patches was overriding the callback
any chance i could steal your code at some point in the future?
i have an idea that i could repurpose it into a mini shop :3
yippee :D
...wait i can just
what i'm doing is already far outside the realm of balatro anyways
I think I'm going insane
I'm dealing with an "attempt to perform arithmetic on field 'extra'" error but every call to card.ability.extra has some subvalue, either .extra.bankrupt_at or .extra.spritenum
alright it's happening even when there's absolutely no calls to card.ability
OOOOO
also do you have to play every fucking part simultaneously
wdym simultaneously
like i saw inputs for all three of them going off
i'm assuming you're still only controlling kris
pressing, holding, and releasing
look at this beauty,,
mind if I uhhh yoink that
go ahead
yea
here's the full file
is there a way to get if any key is pressed
you'll have to hook love.keypressed 
Me when I have fully custom controller for most kind of keybinds 
sick
assuming theres one for keyreleased too?
i assume so
i'm also maing a bunch of minigames lol
game already have tracker of pressed, held and released keys in each frame
-# me eating the entire ui
😋
oh where?
yea where
G.CONTROLLER.held_key_times
thx
man why does balatro have to be a well coded game
I have to actually spend time making good systems that work and are readable
That's the funny part, it's not. A lot of Vanilla code is an incredibly, overwhelmingly long if-elseif chain, and it has plenty more strange choices. In large part, it's SMODS that introduced good coding practices.
tbf thats fine
this makes me feel better about how i handled tenna's animations in the vid i sent
easy to plug into a program and parse
gamemaker has native json support
and yet the only time deltarune uses it is for the japanese localization
this 100% could've been a json file
also all songs are stored in the same functions
how do i get the position in the bg music?
how to destroy diamonds after scoring?
context.after
iterate through the cardarea you wanna destroy cards from and if they're diamonds destroy them
Played Diamonds give ^1.15 Mult, but have a 1 in 4 chance of being destroyed after scoring
blue joker and erosion should have what u need
^1.15? Isnt it just absolutely busted?
I dunno the exact code, but erosion knows the full deck size, and blue knows the current deck size
subtract then and you get that
full deck minus deck
taps the sign
G.GAME.starting_deck_size erosion uses
#G.deck.cards should be total cards in deck
and #G.playing_cards total playing cards
???```lua
if context.individual and context.cardarea == G.play and
context.other_card:is_suit(card.ability.extra.suit) then
SMODS.calculate_effect ({
emult = card.ability.extra.emult,
colour = SMODS.Gradients["busterb_eemultgradient"],
card = card
})
if SMODS.pseudorandom_probability(card, self.key, 1, card.ability.extra.destroyodds) then
if context.destroy_card then
remove = true
end
end
end
end
context.destroy_card is separate from context.individual. That part of your calculate should just be separate from your context.individual. context.destroy_card goes afterwards anyways.
if context.individual and context.cardarea == G.play and
context.other_card:is_suit(card.ability.extra.suit) then
SMODS.calculate_effect ({
emult = card.ability.extra.emult,
colour = SMODS.Gradients["busterb_eemultgradient"],
card = card
})
end
if SMODS.pseudorandom_probability(card, self.key, 1, card.ability.extra.destroyodds) then
if context.destroy_card then
remove = true
end
end```
https://github.com/nh6574/VanillaRemade save this link for quick access if you haven't yet bro.
wait
if context.individual and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.suit) then
return {
emult = card.ability.extra.emult,
colour = SMODS.Gradients["busterb_eemultgradient"],
card = card
}
elseif context.destroy_card and context.cardarea == G.play and context.destroy_card:is_suit(card.ability.extra.suit) and SMODS.pseudorandom_probability(card, self.key, 1, card.ability.extra.destroyodds) then
return {remove = true}
end
This is how it should look instead.
g i forgor to put remove = true to the return table ong
And yet it somehow works
Really well
Power of sheer dedication I guess
Can you help me put it together
local scale_val = #G.playing.cards - #G.deck.cards
that tells you the number of cards not in the dexk
Ok
how do you make a card that destroys a joker but also bypasses eternal
SMODS.destroy_cards(card, true)
Is the "improve your run!" text in the shop a sprite or editable text
I wanna make it say impair instead of improve on bzr stakes
It's text, you would have to hook localize to make it work on specific conditions.
Alright
Do you know if this table still works. I tried to use it, but it crashes.
keyed? i thought that was an indexed table
highlight limit in card area is not respected
what did i do wrong
also i can't seem to click the combine button as it does nothing
uum, maybe? I understand what the table does, but don't quite get how to arrange it.
Need to get into lua 😭
try this instead, maybe?
local ranks = {}
for i, v in ipairs(G.playing_cards) do
ranks[v.base.value] = (ranks[v.base.value] or 0) + v.base.times_played
end
local mostplayed
local played = 0
for k, v in pairs(ranks) do
if v >= played then
mostplayed = k
played = v
end
end
No, I edited my code to work.
uuu, thanks to the both of you. Will try it.
how do i change the soul_pos
during runtime?
yeah
i have a function in a custom joker that goes
change_soul_pos = function(card, newSoulPos)
card.config.center.soul_pos = newSoulPos
card:set_sprites(card.config.center)
end
and this still works for me
newSoulPos expects a table of { x = [number], y = [number] }
honestly, i should probably PR this as a base API addition for jokers, lot of people seem to want to change their joker's soul sprites during runtime
oh ok i just refresh the sprites then
yes
the sprite changes dont persist on reload
oh, right. i ran into that problem myself before and IIRC what i was told to do was to hook set_sprites and have it set the sprites to what i want them to be according to my conditions
but i was running into crashes when i tried and i wasn't getting any help with those crashes, so i instead just wrote another function on the joker that i standardise across all jokers that i need to do that with, which sees what sprite it needs to be based on the conditions i set, then sets it - and in my start_run hook, i add an event that iterates through all jokers in G.jokers, looks for that function and calls it.
it's a hacky solution, but it works. if you figure out the way to actually properly do this, please let me know
is there a function i can call when the card has loaded with all its ability
what's the goal
just apply the new sprite_pos and soul_pos on run reload
use an event in the set_sprites function
the event will delay it enough that the card ability is set up by the time the code runs
ok now how do i move the soul pos above the card
what?
i want to move the soul pos in the y axis
the actual sprite itself? you might want to look into drawstep stuff for that
yea you'll need a custom drawstep to change the physical position of where the sprite is drawn
you can probably copy/paste the soul sprite drawstep from smods and edit from there
How do I draw sprite from love.graphics.newImage (or from balatro Sprite class)?
what are you trying to do?
I'm trying to create an object that will be moving on screen and calling a function when hovered over
how do i force spawn a joker with eternal
SMODS.add_card({set = 'Joker', key = 'j_egg', force_stickers = {"eternal"}, no_edition = true}) didnt wrok im stupid
stickers = {'eternal'}, force_stickers = true
Is egg a placeholder or do you need to spawn an eternal egg
Because in case with the egg you don't need to force it
Egg is already eternal compatible
Definitely credit card
it's a flat $20 that you don't gain interest on, whereas you get temperance value out of an eternal egg
Eternal credit card won't help my swashbuckler
Yes, but SMODS.add_card uses SMODS.create_card which uses Card:add_sticker which checks sticker.should_apply, and that doesn't exist for vanilla stickers.
Oh
how can i check if a highlighted card in hand is a face card?
trying to make a blind that only lets you play face cards of the same suit
if card:is_face(true)
cant put card in a blind .w.
Yes, card would be the card that you want to check.
i get that, but i cannot put card in the calculate of a blind
i tested the code and it instantly crashes when i select a card
unless there's something i dont know about
Show the full code that crashes?
Yes, card is a placeholder for the card that you want to check for being a face card.
What exactly are you trying to do? I'm pretty sure context.debuff_hand isn't even used to debuff cards
And well. There is no card
im trying to make a blind that only lets you play face cards of the same suit
yes, and as far as i know based on the wiki, i cant just put that into the function
figured it out, the mark uses context.other_card:is_face(true)
local faces = {}
for k, v in pairs(context.full_hand) do
if v:is_face(true) then
table.insert(faces, v)
end
end
local passed = false
for k, v in pairs(faces) do
if not v:is_suit(faces[1].base.suit, true) then
passed = true
end
end
if passed then
blind.triggered = true
return {debuff = true}
end
You can do anything to any cards wherever (<almost wherever) as long as they exist and holy shit somethingcom is fast
oh, that's what you meant, sorry .w.
Wait like. You can only play faces or you can play anything but faces need to be of the same suit? This is a confusing effect lol
you can play anything but faces need to be the same suit
playing only faces would be diabolical tho lol
Oh my god somethingcom even edited the code after that specification 😭
bro's a legend 😭 🙏
Hey again guys. Would you know why this code sometimes works and others it doesn't?
I don't get it. I'm trying to make 2 copies of the most played rank.
That's hard to read
That's how... prototypes look like.
welp good news I don't have to deal with balatro UI jank
bad news I have 0 helper tools from balatro
i'm hoping love.graphics works similar to p5, since I have a lot of experience with it
how does it not work
Actually looking at the code now, the way you check for most played rank is a dubious idea, since it only accounts for cards in your deck. I would recommend to count that somewhere outside of the tag
oh, so sometimes it seems to register the most played rank and sometimes it just gives me random cards.
what cards did it work for
Any card I played the most. I test it by playing a 5 of a kind in the first blind.
I would get some video, but I think discord has a cap of like 10 mb.
no like did it work for 2s but not for 5s
I tested it with a lot of cards and worked on most of them.
I don't think I could say for certain it doesn't work for a specific rank.
yeah
get_id() gets ranks of face cards as numbers i'm 90% sure
its probably something with what evgast said
it does yeah
i just know I had a problem with one of my cards that wouldn't generate face cards cuase I was getting them wrong
wait clover
when it genreates the wrong card is it a 10 of spades or something else
or just a 10 of any suit
I think so too. I've seen examples of this being done as a global. But I had already tried that and it didn't quite work either. But this kind of worked, though.
I'll keep on trying
Yes, but since this server is at boost Level 3, you can upload up to 100MB
SMODS.current_mod.reset_game_globals = function(run_start)
if run_start then
G.GAME.rank_played = {}
end
end
SMODS.current_mod.calculate = function(self, context)
if context.before then
for k, v in pairs(context.full_hand) do
G.GAME.rank_played[v:get_id()] = (G.GAME.rank_played[v:get_id()] or 0) + 1
end
end
end```
I think that should work? Question mark
oh, no. it generates random cards. I think it's doing the base generation.
Oh oops
Hold on, I might get some video. brb.
can you try this
play a 3 of a kind of one card, then 5oak of another
aight
and go until it gives the wrong card
my suspicion is that it not finding the 5oak card
so it should return the 3oak card
okay, brb
if that doesn't work add 3 million print statements
frick
why is it skipping one ;-;
I got curious enough to actually try that. Yeah it does work
woah what debug menu is that
It makes the 2 copies of the 10th rank but not of the king
I would recommend going with globals whether you figure out what's wrong ot not, simply because that's more accurate 🤷♂️
yeah i have 0 clue why its making eights now
go my 500 print statements
The problem is because the rank you are inputting into SMODS.add_card is the id, not the key
Oh😭 😭
hold on, what. Isn't that the same.
why is it generating an 8 instead of a 10 then?
Yeah, I think that will be my next step. thanks.
No, the problem is every rank that is not a number between 2-10 uses it's name instead of it's id as it's key.
But the shit happens with numbers too?
Not only (f)aces
local mostplayedkey
for k, v in pairs(SMODS.Ranks) do
if v.id == mostplayed then
mostplayedkey = v.key
end
end
No, it made an 10 and a 8 instead of a King
oooh, that's pretty cool. Will try it, thanks.
I swear you gained an 8 of clubs
yeah it made an 8.
Also, for the record. I've been able to make face cards with the code in the video.
Hold on!!!!
It seems to be working quite well now. Will keep on testing it.
Thanks everyone who spent time with the problem. 
been trying to bug fix on my on for a bit but uhh-
I assume that's because face table is empty, just check if #faces > 0 before looping through it or smth
Swap the passed = true and passed = false
perfect, tyy :3
Is there a function that runs when all mods are loaded or smth like that
Game:main_menu
yippee
actually I was gonna do osu next lmao
please, im already ashamed enough that i cant play osu for shit, spare meee ;w;
funny how 2 people here are doing rhythm game stuff in balatro
(my mod's gonna have both lightners live and fnf)
There's no API to add badges to cards in a pool right?
Making sure that I didn't just make the stupidest hook ever
just do it manually idk
Yeah
@willow plinth
is the dt in all the update functions in ms, seconds, or something else
is this where I can ask for help regarding making my first mod?
in seconds, sometimes in seconds * G.SPEEDFACTOR
use G.real_dt instead
thx
how do you dynamically change the buy and sell cost of a card
but like not in an Egg way where it's only an additive bonus to the sell cost
only if you want to ignore gamespeed*
I mean, i wouldnt want the speed of a song in a rhythm game being based on gamespeed lol
yeah for sure, you'd want real_dt for that
yeah thats what im using
hallo!!
im crashing upon shop enter and im not sure why. i think its an issue with my custom rarity but im a little lost on why
key = "effect",
default_weight = 0,
badge_colour = G.C.RED,
get_weight = function(self, weight, object_type)
return weight
end,
}```
how do you check if you're selling a food joker
have you set up a custom pool or no
nope
if not then you gotta hardcode the vanilla ones
oh its a cryptic ad on?
oh okay
joker.config.center.pools.Food
typically its along those lines
ok so apparently context.card:is_food() works
i imagine spectrallib added that yes
where do i find the sources for mod audio? SOURCES only contains vanilla audio
oh nvmd
SMODS_Sounds
nvmd x2
it just returns nil
nvmd x3 sometimes it does???
wait that's SMODS.Sounds
not SMODS_Sounds
i'm still stumped
Depends on the thread. SMODS_Sounds does exist only in the sound thread
been seeing a concerning influx of bot activity as of late tbh
not even just here, but on a couple other servers im in too
question again
can you change what rarity badge a joker would display without actually affecting its true rarity value
i mean you can do anything technically
i think you'd have to hook something but yeah
you could add code to your hook for that
like
likeeeeee maybe hook into whatever displays that specific badge and add a check for if its that joker, adn then check against a certain value on that joker instead of its actual rarity
i'm not explaining this well bu tyeah
i have my own question actually- why isn't debugplus showing logs, i have to tab into the terminal that appears
its only showing its own logs and none others
uhh check settings maybe
like the settings has a thing that determines what level gets logged
yeah it's set to info and my logs are info
theres this
but ingame theres nothing
futhermore
oh good, so it's not just been me having problems with it!!
i actually haven't updated debugplus in ages
let me try that before i complain
yeah ok same problem
remove all the badges and generate a fake one
oh jeez uhhh
how???
like is there a config to prevent a joker form showing badge and then generate a fake one
or do i have to hook into the function that generate badges
"only show commands"
oh LMFAO
How would I check if a consumable is hidden (like the soul or black hole) so it can be avoided from checks?
question
if that's been toggled off for the last month and it still doesnt show print lines, what then?

show logs is checked and the log level is high enough, right?
idk what log level print is
is there a hook for when you load a save
because for some reason the Cat pool doesnt want to exist on gameload when Yahimod is installed even when i populate it in my own pools.lua and its not applying my sigils on those cards
(and right now to remedy my issue i just do a pool merge on new game load)
Hey folks, does anyone know the code section responsible for the area with and under the shop/blind signs? I've been looking around and the closest I've found is the UI for score, hands, discards, so on
the hidden value in the consumable's center will be true
yeah, i figured it out. had the wrong order for some variables and it was messing me up
does anyone have a solve for negative cards not showing in the deck view?
https://discord.com/channels/1116389027176787968/1483563299781214260 try my API mod when 
how do i show "no space" on the card area when it can't buy the totem
Hook G.FUNCS.check_for_buy_space and use alert_no_space
thank you
heyyy so i'm trying to add something that might be too ambitious and I really don't know what I'm doing
are there either like specific tutorials or examples i can pull from to make this
i've got like a husk of what i need but it doesn't actually do anything
-# ideally someone could do it for me with credit (at least enough for me to implement the rest, like the base types and necessary ui and stuff) but I get if you would rather just tell me how i could go about it
basically I have a set of consumables that when used, set a variable in G.GAME (you are choosing a class)
and when you have a class, a button will appear that will allow you to use an ability once per round (based on what class you're using) (except for one that costs money instead of once per round)
it will also ideally display in text what class you have, or maybe it can just do that on the button (with popup explaining it)
i can zip up and send my current codebase if necessary
https://github.com/Steamodded/smods/wiki/UI-Guide this is like pretty much all there is in terms of custom ui documentation
yeah i looked at that it went very much over my head
well like the only other option then is to just look at other mods i think
thats what im trying to do but the only one that i have in mind (my mod is an extension of it) 's codebase is so fucking ass
ui node types are also like the one thing thunk actually comments in the code saying what they are
what mod might that be...
ah
amazing stuff
anyway theres two links at the bottom of the ui guide that lead to some custom ui code
also i lost the screenshot but
local peepee
local poopoo
just wonderful stuff
better than cryptid variable names
Honestly I MIIIGHT be able to figure out the UI myself
it's like everything else as well
all i have is the consumables and the variable setting
and like a husk of the Object for the class
yeah, bleh
i could probably figure it out but it's extremely overwhelming
could anyone else help in theory?
what do you need help with
I got UI fresh on my mind rn lol
Hey, are you familiar with offsetting in UI? I'm trying to fine tune the y coord of my node but it doesn't seem to be affecting anything
config = {align = "cl", maxw = 3, padding = 0.1, r = 0.08, minw = 2, hinh = 0, hover = true, shadow = true, colour = G.C.CLEAR, juice = true, offset = {x = 0, y = 3},
try making it bigger
like really big
see what happens
Bet, 1 sec
Nothing it seems
hmmm
idk then I never messed with offset
you could put an empty box before it for a margin
Well, on the UI side of things, I really just need to create text that says what class you have and I need the button to use the ability
Do you maybe want to take a look at my shell of a codebase
sure
That's what I've been doing, in that case I'm out of ideas
Odd
It's not covered in the UI guide either
I guess I'll try to set the offsets to be global variables so I can mess about in-game
What in Jimbo's name am I looking at
"insert epic pjsk gameplay"
Is this like Guitar Hero
yeah
I see
WHY are you making project sekai in balatro
:3
Its rlly well done but damn
no its not but thank you 😭
this thing is held together with hopes and dreams
sliders won't even render properly and they eat your fps
sorry there's like. part of an attempt to get something but I really don't know what I'm doing
UI is nowhere near my strong suit
go go gadget zip bomb
I've never done it
is context.consumeable card or center? like do i get the key by going context.consumeable.config.center.key or by context.consumeable.key?
i swear its not 💔
I believe you need config.center.key
I mean
No harm in trying one and then the other if it doesn't work
okay I can't run your mod rn, but does the button show up in the UI
if not thats the first thign you should do
before making it a button
@median veldt
No, I really fully seriously have NO idea how to do any of that 😭
hooks and patches
If you can't run it because of the dependency, you can remove the dependency, as it currently doesn't use anything from it
i mean. Yeah
no I just have a editor running and I forgot to make an option to export my work
<@&1133519078540185692>
yk at least it wasn't a blatant porn server
yeah true
thx
lemme send some of my stuff for an example
only issue with ui stuff is it's really confusing to me
all i have right now is just the play hand button copied and pasted with like one thing changed
very good start
Would it help if I showed you like exactly where I want the button and what I want it to look like
thats how I got this working at the start
yeah
kk
local blind_tag_ref = create_UIBox_blind_tag
function create_UIBox_blind_tag(blind_choice, run_info)
local ret = blind_tag_ref(blind_choice, run_info)
if not ret then return ret end
local _tag = FooBar.Minigame:init((G.GAME.round_resets.foobar_minigames or {})[blind_choice])
local _tag_ui, _tag_sprite = _tag:generate_UI()
_tag_sprite.states.collide.can = not not run_info
ret.nodes[#ret.nodes+1] = {
n=G.UIT.R, config={id = 'minigame_'..blind_choice, align = "cm", r = 0.1, padding = 0.1, minw = 1, can_collide = true, ref_table = _tag_sprite}, nodes={
{n=G.UIT.C, config={id = 'minigame_desc', align = "cm", minh = 1}, nodes={
_tag_ui
}},
not run_info and {n=G.UIT.C, config={id="minigame_container",align = "cm", colour = G.C.UI.BACKGROUND_INACTIVE, minh = 0.6, minw = 2, maxw = 2, padding = 0.07, r = 0.1, shadow = true, hover = true, one_press = true, button = 'foobar_select_minigame', func = 'hover_minigame_proxy', ref_table = _tag}, nodes={
{n=G.UIT.T, config={text = "Play Minigame", scale = 0.4, colour = G.C.UI.TEXT_INACTIVE}}
}} or {n=G.UIT.C, config={align = "cm", padding = 0.1, emboss = 0.05, colour = mix_colours(G.C.BLUE, G.C.BLACK, 0.4), r = 0.1, maxw = 2}, nodes={
{n=G.UIT.T, config={text = "Play Minigame", scale = 0.35, colour = G.C.WHITE}},
}},
}
}
return ret
end
this uhh does something i forgor what
oh this actually inserts the ui
either one of the two spots really
oh over there
okay thats much easier
I thought u wanted it on the left
which meant you would've had to update and redraw the ui
nah it works better since it semi-ties to that thing that's next to it
function G.UIDEF.foobar_minigame()
local nodes = G.FOOBAR_MINIGAMES[G.GAME.foobar_current_minigame]:generate_gameplay_ui()
local t = {n=G.UIT.ROOT, config = {align = 'tm', r = 0.15, padding = 0.15}, nodes={
{n=G.UIT.R, config={align = "cl", colour = G.C.CLEAR,r=0.15, padding = 0.1, minh = 2, shadow = true}, nodes={
{n=G.UIT.R, config={align = "cm"}, nodes={
{n=G.UIT.C, config={align = "cm", padding = 0.1}, nodes={
{n=G.UIT.C, config={align = "cm", r=0.2, shadow = true}, nodes=nodes}
}}
}}
}}
}}
return t
end
function G:update_foobar_minigame(dt)
if not G.STATE_COMPLETE then
stop_use()
ease_background_colour_blind(G.STATES.SHOP)
G.FOOBAR_MINIGAMES[G.GAME.foobar_current_minigame]:set_ability()
local minigames_exist = not not G.foobar_minigame
G.foobar_minigame = UIBox{
definition = G.UIDEF.foobar_minigame(),
config = {align='tmi', offset = {x=0,y=0}, bond = 'Weak'}
}
table.insert(G.I.NODE, G.foobar_minigame) -- manually insert cuase it doesn't show up for some reason
G.GAME.FOOBAR_MINIGAME = true
G.STATE_COMPLETE = true
end
end
sorry i'm just posting code so I can talk about it without confusing you with stuff I did'nt post
mm ok
what you need specificly is this
table.insert(G.I.NODE, G.foobar_minigame) -- manually insert cuase it doesn't show up for some reason
this'll make the game draw your ui
ok what would happen if i basically copied and pasted your code into my thing
would it work or do i sitll need some patches
mmmminus some things that are obvious
acutally It would do nothing cuase I had to patch a custom game state in
but you shouldn't need to do that
yeah i only need it to show up during play
though i guess i'd actually want it to show up during always
do you want the UI to always appear, or only if you have selected a class
okay thats more annoying but still possible
so in whatever function that selects the class
your going to need this
it puts a string into G.GAME.BALATROSTUCK2_current_class for the reccord
function G.UIDEF.BALATROSTUCK2_class_ui()
return {ui table}
end
-- code that selects class
if G.BALATROSTUCK2_class_ui then
for i,value in ipairs(G.I.NODE) do
if value == G.BALATROSTUCK2_class_ui then
table.remove(G.I.NODE, i)
break
end
end
G.BALATROSTUCK2_class_ui:remove()
end
G.BALATROSTUCK2_class_ui = {
definition = G.UIDEF.BALATROSTUCK2_class_ui(),
config = {align="up to u", offset={also up to you},bond="Weak"}
}
table.insert(G.I.NODE, G.BALATROSTUCK2_class_ui)
then to make sure you get rid of it when they leave the run add
local create_run_ref = G.start_run
function G:start_run (args)
local ret = create_run_ref(self, args)
if G.GAME.BALATROSTUCK2_current_class then
G.BALATROSTUCK2_class_ui = {
definition = G.UIDEF.BALATROSTUCK2_class_ui(),
config = {align="up to u", offset={also up to you},bond="Weak"}
}
table.insert(G.I.NODE, G.BALATROSTUCK2_class_ui)
end
return ret
end
local go_to_menu_ref = G.FUNCS.go_to_menu
function G.FUNCS.go_to_menu (e)
for i=#G.I.NODE,1,-1 do
if G.I.NODE[i] == G.BALATROSTUCK2_class_ui then
G.I.NODE[i]:remove()
table.remove(G.I.NODE, i)
end
end
return go_to_menu_ref(e)
end
@median veldt
mmokay hold on
alright, i'm not quite sure what to put for the things you left up to me
for offset I kept mine at {x=0,y=0}
and my align is 'tmi'
what about the align and more importantly the ui table at all
isnt there docs for the align
and that generated the "insert epic pjsk gamplay" box
the UI table would contain your buttons
yes
mhm yeah
I just. Do Not understand it nor how to put it together
yeah
lemme find a ss of one of my decks i'll draw some boxes
a visual editor for ui and it gives you the ui table and the align stuff
that'd be nice
ngl i've been considering making tools like this
but i'm busy with my current mod rn lol
once you get the chance that would be so helpful
--- Generate Bonus tab UI
function G.UIDEF.foobar_view_bonuses ()
local ret = {n = G.UIT.ROOT, config = {align = "cm", minw = 3, padding = 0.1, r = 0.1, colour = G.C.CLEAR}, nodes = {
{n = G.UIT.C, nodes = {}}
}}
local pushcol = function (r)
r.nodes[1].nodes[#r.nodes[1].nodes + 1] = {n = G.UIT.C, config = {align = "tm"}, nodes = {}}
return r
end
pushcol(ret)
local row_limit = 5
for _, set in pairs(G.GAME.foobar_adaptive.clearedBlinds) do
for key, _ in pairs(set) do
if #ret.nodes[1].nodes[#ret.nodes[1].nodes].nodes >= row_limit then ret = pushcol(ret) end
local N = {}
localize{type = "other", key = "ba_" .. key, nodes = N}
local B = G.P_BLINDS[key]
local out = {n = G.UIT.C, config = {colour = G.C.WHITE, maxw = 4, padding = 0.1, r = 0.1}, nodes = {
{n = G.UIT.R, config = {colour = mix_colours(get_blind_main_colour(key), G.C.BLACK, 0.7), r = 0.1, padding = 0.1, align="cm"}, nodes = {
{n = G.UIT.O, config = {object = SMODS.create_sprite(0, 0, 0.5, 0.5, SMODS.get_atlas(B.atlas) or 'blind_chips', B.pos)}},
{n = G.UIT.T, config = {text = SMODS.Blind:get_obj(key).name or "ERROR", scale = 0.5, colour = G.C.WHITE}}
}}
}}
for _, line in ipairs(N) do
out.nodes[#out.nodes + 1] = {n = G.UIT.R, nodes = line, config = {align = "cm"}}
end
-- Please don't do this
-- this is not a good idea
-- store references somewhere instead
ret.nodes[1].nodes[#ret.nodes[1].nodes].nodes[#ret.nodes[1].nodes[#ret.nodes[1].nodes].nodes + 1] = {n = G.UIT.R, nodes = {out}, config={align="tm", r=0.2, padding=0.1}}
end
end
return ret
end
okay heres the code for the ss that I'm going to find
aight
Oh could I in theory take a ui table from like
the play button or something that looks similar
and modify it
okay here we go
i seeeee
heres what that generates
now lemme draw in the tables
@median veldt here's what the boxes look like
i see
idk why the wheel is blue
Guys I don't think Sushi is either green or blue
do you gain 1 Mult when a hand is played and lose 1 Mult when a discard is used
ok
Yes!! 💚
green 💚
where did I even go wrong
i just copied and pasted the play hand button and changed like one thing
whats the func, ref_table, and button
i did again just copy it idrk what those variables except func mean
func is the name of a function in G.FUNCS that gets called whener the item is drawn
id remove it
mm
anything else? cuz that didn't fix it
i hate errors that aren't direct lol
change button to temp_func and add
function G.FUNCS.temp_func(e)
print("hi")
end
did u remove both funcs or just one
ohwoops
is it rendering now?
nope :/ did I do it wrong
same error?
yeah
well first off nodes isn't a array-like table
it happens when I use the card for the record
?
mmmi'm a little confused
add those
after that i'm not sure whats wrong
its probably someting simple but I think i'm too tired to figure it out
mmmmSame error yeah :/
maybe try align="tmi"
function G.UIDEF.BALATROSTUCK2_class_ui()
return {n = G.UIT.ROOT, config = {r = 0.1, minw = 8, minh = 6, align = "tmi", padding = 0.2, colour = G.C.BLACK}, nodes = {{
n=G.UIT.C,
config = {
id = 'bs2_class_button',
align = "tmi",
minw = 2.5,
padding = 0.3,
r = 0.1,
hover = true,
colour = G.C.BLUE,
button = "temp_func",
one_press = true,
shadow = true,
-- func = 'can_play'
},
nodes={
{n=G.UIT.R, config={align = "bcm", padding = 0}, nodes={
{n=G.UIT.T, config={text = localize('b_play_hand'), scale = text_scale, colour = G.C.UI.TEXT_LIGHT, focus_args = {button = 'x', orientation = 'bm'}}}
}},
}}
}}
end
heres like a codeblock instead of a screenshot just to be safe
oh
keep the nodes the way they wer
i have that set to tr
yep
asfoilkjnd fuisdnfauhsljdnfasipje;f ds
same
okay gn
i'll wait and see if anyone else here has any ideas
Hey guys. It works perfect (needs testing for niche scenarios).
But I was wondering. How do I reset the text of the rank variable when the player finishes a run.
Or, how do I make the text of the rank in the collection be constant? So, it always says 'random'.
i am trying to get a sound to play, but i cannot for the life of me get it working. the game doesnt crash or anything, it just doesnt work. any ideas/tips?
It should be:
func = function()
G.E_MANAGER:add_event(Event({
func = function()
play_sound('modprefix_key')
return true
end
}))
end
no, you can return sounds in calculate functions. seems like it requires a custom message alongside it tho
https://github.com/Steamodded/smods/wiki/SMODS.Sound
ty
Yes, but they're not using a custom message, that's why I didn't use that.
since there are a couple others in chat now i'd like to bump this
heres like The original request
and the error i was getting
sorry about not specifying, but i ideally wanted the sound to play as the jumpscare does, ie not where return was
it did work there tho
Hey guys. Do you know why this tag gives 4 enhancements to the deck the first time and then 3 on subsequent? Don't get it.
play_sound("Krypton_EvilScream", 1, 0.9)
1 is the pitch percent, 0.9 is the volume
i figured it out alr, sorry shouldve deleted
it was a file organising issue, it was in a folder named sound not sounds
if G.deck.cards[i].enhancement == nil then
wtf is this 😭
lmao, I might have done some borrowing.
that's not how you check if a playing card has an enhancement
it works because it selects the entire G.deck.cards
use next(SMODS.get_enhancements(card)) to check instead
the reason it gives 3 enhancements is because the selection does not really exclude enhanced cards
causing a previously enhanced card to be selected again
Yeah, I had seen that one before. Kind of been scraping by. I try to cut corners to get to design.
But, yeah that makes sense. Thanks.
Hey, do you know where I could learn more about this? It crashes because of (card)

lmao
what's the key to replace the main menu card with an ace of hearts again?
yeah, that
but i dont know the exact wording for the set or key
...do you wish to have an another card with the original or outright remove it?
i want to remove the original and replace it with an ace of hearts instead
i already have the block of code correct, i just need to figure out the key
how do I make it play at normal speed?
it sounds sick but its not what
its also playing everywhere for some reason
select_music_track = function(self)
return G and G.GAME and G.FOOBAR_MINIGAMES and G.GAME.foobar_current_minigame and G.GAME.foobar_current_minigame.key == "fbminigame_foobar_projectsekai" and G.FOOBAR_MINIGAMES[G.GAME.foobar_current_minigame] and G.FOOBAR_MINIGAMES[G.GAME.foobar_current_minigame].current_song == ret.key and 10000000 or 0
end
return {
{ set = 'Base', rank = 'Ace', suit = 'Hearts' },
remove_original = true
}
ah, thank you
pitch = 1 in definition?
thx
any idea why this doesn't work though?
...why the or 0?
This function is called each frame to decide what music to play. Return values that are not nil, false or a number are converted to zero. The music track that returned the highest value is to be played.
now that I thinka bout it I could just not have that though
Just don't return anything if conditions don't pass.
yay it wotks
well it doesn't play in main menu at least
guh okay now it doesn't work in the song
go my 500 print statements
Opandora's box has a lot of stuff with music. Maybe you can reference that.
In fact let me pull it out
it's at the bottom
Don't know if it helps though.
oh I'm stupid
I tried to get the key attribute of a string
now just to figure out how I can delay the start
Pretty awesome.
could it possibly be as simple as just delay()?
add another state to sound and set it to true with a delayed event manager
i'm gonnna tie it into the current charts delay, since all of them have a set value before they start playing
makes sense
didn't realize the screenrecorder gave audio delay ;-;
that or i'm just washed
how the hell do i do a 7x11 pixel art A
don't use a triangle frame, use a pentagon one instead
Hi, do UI elements get updated automatically? For example, if I made a config for a mod, and I were to change a value in a UIBox, like the colour to red with a command, would it change immediately?
no, you'd have to restart the game with Alt + F5 before you can see the change
My bad, I meant with like DebugPlus for example
is this better?
you'd still need to restart the game
Ah
i mean, you can use Ctrl + M in debugplus to reload atlases but that's it
Is there a way to add it to the update loop of the game?
much better
i'd recommend only leaving a one pixel gap between the feet though, but that's just me
yes it'll be updated
if you use commands to change a UI box it'll be reflected in game
huh, didnt know that
Oooooh I see what the issue is
that still doesnt change the code directly tho tbh, so it's better to just restart the game with trial and error imo
you could use it to make changes, and then save the changes you made in your code
At the very least for the config menu, it is updating, but you have to re-open the config menu for it to take place, so I guess I need to like copy it and delete it each time it detects a change
prevents reloading the game 5 million times
if only I could do the same for my ui testing ):
Have you tried the DebugPlus watch command? I've never gotten it to work
idk man, i never saw it as that much of a bother ¯_(ツ)_/¯
nope
Less of a bother than wasted time really
^
I'd give it a shot, apparently it can watch a lua file and update it in-game any time you make a change to it
But I think it wants an ID and the times I've used it on a non-shader it's given errors about functions that are only called at the start of the game
fair but would it really save that much time in the long run trying to figure out how to patch it into the game's update loop? lol
yes
yes it would
fair enough .w.
the loading screen is quite long
that much i can agree with
i just dont have the skill to patch it myself and im too focused on the main point of my mods to bother anyway
Any of you guys worked with UIBoxes? The nodes in my UIBox seem to be missing/invisible
Sending snippet in a sec
is the UI box being rendered
meter = 0,
meter_active = true,
pink = HEX("FFFDD492"),
meter_func,
meter_UIBox,
}
METER.meter_func = function()
return {
n = G.UIT.ROOT, config = {align = "cm", nodes = {
create_progress_bar({
colour = METER.pink,
bg_colour = G.C.PURPLE,
label_position = "Right",
bar_rotation = "Horizontal",
min = 0,
max = 5,
w = 4.3,
h = 0.6,
tooltip = {
text = {"Meter flavour text here" },
},
ref_table = METER,
ref_value = "meter",
}),
}},
}
end
METER.meter_UIBox= UIBox{
definition=METER.meter_func(),
config = {offset = {x=0, y=1}}
}```
nope its not
In the patch file there's
{n=G.UIT.O, config = {object=METER.meter_UIBox}}```
id recommend inserting it into one of the G.I tables
.
.
this is what I did for my balatro ui based minigame stuff
Is there somewhere I can read up on this or is it one of those things you learn? I don't believe the UI structure guide on the wiki mentions this, or recalculating for that matter
Will give that a read, thank you
I figured it out via trial and error and reading the source code
Yeah that unfortunately seems to be the method
I had the same problem with my UI not being rendered lol
I'm gonna go eat first in hindsight, my brain's blanking on every word in there
Hi Friend
Its ui time 😁
If you want
Hey, is there a specific place these go to? I've currently got them in their own file that's loaded in with SMODS
can you send full error traceback
yeah you Will have to give me a bit
no
cant confirm without the stack trace, but im pretty sure your storing nil in G.I.NODES
OMG
I was right it was a stupid issue
you didn't make a UI box lmao
its just a regular table
METER = {
meter = 0,
meter_active = true,
pink = HEX("FFFDD492"),
meter_func,
meter_UIBox,
}
METER.meter_func = function()
return {
n = G.UIT.C, config = {align = "cm", nodes = {
create_progress_bar({
print("Implementing contents.meter"),
colour = METER.pink,
bg_colour = G.C.PURPLE,
label_position = "Right",
bar_rotation = "Horizontal",
min = 0,
max = 5,
w = 4.3,
h = 0.6,
tooltip = {
text = {"Meter Flavour Text" },
},
ref_table = METER,
ref_value = "meter",
}),
}},
}
end
if G.METER then
for i,value in ipairs(G.I.NODE) do
if value == G.METER then
table.remove(G.I.NODE, i)
break
end
end
G.METER:remove()
end
METER.meter_UIBox= UIBox{
definition=METER.meter_func(),
config = {offset = {x=0, y=1}, align = "cm", bond = "Weak"}
}
G.UIDEF.METER = METER.meter_func()
G.METER = METER.meter_UIBox
table.insert(G.I.NODE, G.METER)
local create_run_ref = G.start_run
function G:start_run (args)
local ret = create_run_ref(self, args)
if G.GAME.METER then
G.METER = METER.meter_UIBox
table.insert(G.I.NODE, G.METER)
end
return ret
end
local go_to_menu_ref = G.FUNCS.go_to_menu
function G.FUNCS.go_to_menu (e)
for i=#G.I.NODE,1,-1 do
if G.I.NODE[i] == G.METER then
G.I.NODE[i]:remove()
table.remove(G.I.NODE, i)
end
end
return go_to_menu_ref(e)
end```
There it is
no need for that assert
the file should already be loaded
Oh bet
oh Lmao how do I do that
NameOfYourUIBox = UIBox{
definition = {Function that has the layout of your script, imagine the config tab function for example
You could also just define your nodes here},
config = {align="cm", offset={x=0,y=0}}
}
Align and offset are optional values, they can be whatever
That's technically a UIBox already, do you have an Object node to put it into?
What do you mea
holy shiiitttt
{n=G.UIT.O, config ={object=YourObject, align="cm", etc}}
i dont have that actually but it works
i just need to position it better and i'm Not quite sure how to do that
yeah right there after class_ui =
so now the button is rendering, but I need to like. position it better
i dont Quite know how the positioning works and how to get it perfect
mess with the offset values
id look at the card areas to see what they use
alr
Where do you have it right now?
Similar issue rn
This rekoj is supposed to scale for every card that isn't in the deck, however it isn't scaling at all even after a supposed fix
Oh wait nevermind they set it to a max of 52 specifically
yeah i cannot find those
ok hold on i uh think im in the wrong file
i was looking in UI_definitions but theres nothing with G.I.
id do a blanket search of lovely/dumps
@median veldt While I have you can you check this please? Might help me
I know but you're the only one who I can talk to who's had the same issue 😭
I'm trying to do it without an object like you to see if it works
a whole lot of things in G and G.GAME are defined by calling a method, so search for just .CARDAREA
you want the insert one
look at the method it's in
alr
I seem to have done something right, but now I'm getting "bad argument #1 to 'draw' (Drawable expected, got no value)
your also not using a UIBox, just a table
wait nvm im stupid
ignore that
You're good lol
does it work the first time, but if you exit to menu and return it breaks?
Testing
oh also your storing than print statement in the table
it might be affecting something
It crashes when I try to start a new run, will try without the print
you need to recreate the UI after deleting it with :remove()
if G.METER then for i,value in ipairs(G.I.NODE) do if value == G.METER then table.remove(G.I.NODE, i) break end end G.METER:remove() end
Could you explain why we delete it before creating it if it exists? Is that how it's updated?
you get a leftover UI if you dont delete it
Oh right
and I mean when you leave the run and go to the menh
you delete the HI
UI
then when you go back into the run you need to recreate it
otherwise there's no UI to draw
Sorry for any silly questions, but if I have it saved to a table for example, and I have the call that inserts it, what would be the issue?
that would duplicate the entry
As in if it's deleted to clear the duplicate, what would stop it from copying METER.meter_UIBox to G.METER?
Wait
I might've found the issue
Nvm I've not
I did change if G.GAME.METER to if METER.meter_UIBox though because I never actually assign G.GAME.METER, unless that's intentional
So is this not sufficient then? It only assigns it when we're creating a run, which is only where I want it to be
if METER.meter_UIBox then G.METER = METER.meter_UIBox table.insert(G.I.NODE, G.METER) end
that should work
It appears to, still not sure on the Drawable issue though
It is from the graphics.draw at the start, but I don't know where it wants an argument
Okay wait I had my config unclosed 😭
Okay that wasn't the issue but somehow it wasn't giving an error either
The only Drawable I see is text_drawable so I'll try that
Setting text_drawable to true on them didn't seem to help
Ah, Drawable is a love property understandably
What's the purpose of using graphics.draw here if I've already set up a UIBox? Surely the Balatro UI should handle it
UI shenanigans here 
Yes indeed
My "UIBoxes aren't rendered", and as you do with Balatro, I'm peeking and poking til I find something
70% code here basically nonsense btw
You dont need do anything related with manipulating of existence of element inside G.I.NODE or G.I.UIBOX or G.I.CARDAREA or anything else
Unless you need render in very specific layer in specific conditions
Which in 99% cases you dont need
Game deleted all nodes in almost everywhere between stage transitions, you dont need to do it manually
Also, you need to create UIBox when needed, not during game loading, UI is not supposed to exist or be manipulated that early
I see, could you point me in the right direction then? I've cleared space above the dollars_chips area, and below the blind/shop corner - I've got that UIBox and its function but it doesn't seem to render, it exists though cause you can change the offset and such
Noted, I had it as such before but I was following someone more experienced than myself
depends on what you want to achieve


