meter = 0,
meter_active = true,
pink = HEX("FFFDD492"),
meter_func,
meter_UIBox,
}
METER.meter_func = function()
return {
n = G.UIT.C, config = {align = "cm", text_drawable = true}, 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" },
},
ref_table = METER,
ref_value = "meter",
}),
}
}
end
METER.meter_UIBox= UIBox{
definition=METER.meter_func(),
config = {offset = {x=0, y=1}, align = "cm", bond = "Weak", text_drawable = true}
}
``` Also would it just be this then?
#💻・modding-dev
1 messages · Page 675 of 1
Even this part have a lot of issues
I would love to learn
METER is global variable, not local which is not okay unless it's unique enough
It is a bit vague but it will be the only one, and I plan on renaming it to something less generic, I agree
then, meter_func and meter_UIBox specified inside METER in on top of file treated as elements of array aka [1] = meter_func, not meter_func = nil
A lot of text_drawable in ui, I personally not sure what it does but you definitely dont need it, it's internal variable
Could you elaborate on this?
Right yes, I meant to delete those, it was an attempt at a workaround to a deleted thing
Which programming language you actually know?
C, C#, Python
I would understand C++ concepts if need be
Is this about them having random unassigned memory at the moment?
in Lua, table is combination of dictionary and array, if you specify key = value, then it sets as key = value { a = "b", c = "d" }
But if you do like this { "a", "b" }, then they're inserted as elements of array and you'll get { [1] = "a", [2] = "b" }
{ meter_func, meter_UIBox } is same as { [1] = meter_func, [2] = meter_UIBox }
So if I tried to assign anything to them it'd be like assigning it to an array with no key?
Any idea why giving a UI box an offset is making it fly offscreen?
I have its major set to G.hand, and every time it renders it just flys off down-right
Im trying to make it appear in the same place the blind payout does
Guy invented Earth's gravity in Balatro
Not sure though
That might explain why 2 meter-like objects fall rapidly down the screen right before the starting Jimbo animation
I got it to stay put if I force its VT.y to a certain position, but that makes any items it rendered have their collisions work on what would be the next frame
which is why my button was offset
that would crash
Oh, is that not valid syntax in Lua
unfortunately not
Damn
Just to be sure, I'm not missing anything here am I?
`# Implement meter UI definition
[[patches]]
[patches.pattern]
target = 'functions/UI_definitions.lua' # The file you want to patch.
pattern = '''
contents.dollars_chips,
contents.hand,
''' # The line(s) you want to patch. In pattern patches it should be the whole line(s).
Make sure it's unique in that file. (Unless you want to patch multiple different lines, of course)
position = "after" # Where you want to patch it: 'before', 'after' or 'at' (this last one replaces the whole pattern)
payload = '''
{n=G.UIT.O, config = {object=METER.meter_UIBox}},
''' # What code you want to append/replace it with.
match_indent = true`
because you need specify not only major, but also parent, offset and alignment for predictable behaviour
what would the parent be for an element I'd prefer to be standalone
like the blind cash out screen
parent is parent it needs to be rendered inside of
it belongs for rendering mostly
For movement major is used
what would be the highest level parent then
I mean highlt depends on what you want to render and where
^
cash out consist of multiple parts
So for a near-guaranteed UIBox render, these are necessary?
so what's wrong here
this was an old pic using some hacky stuff
made all the mouse collison inaccurate
but this is what I want it to look like
rn its just flying off the screen
Just copy G.round_eval definition 
I did
Then you missed something while copying
it's pretty straightforward UIBox which positions itself in bottom center
where's major
oh wait I removed it
lemme add it back
wtf
this id exactly the same as I had before why is it working 😭
thx
spectator effect
it's just too under the screen
???
why does it detect my mouse where it is though?
If it detects but on click nothing happens then button function you specify just does nothing for some reason
no the buttons working
its just offset down right for collision
Probably fucked up UI structure
when you mixing up things you shouldn't game may not display/process UI properly
would drawing it at the end of the love.draw do this
Why you draw it manually
honesty i dont know
I have a draw loop for my minigsme and put it in there
didnt think to add it to G.I somewhere
Why you doing that in a first place
If you're messing around with G.I then you're 100% doign something very wrong and janky
how would you get standalone custom UI to render
Or it's somethign very complicated and specific
Just create UIBox, it handles rendering for you
thats what I did and nothing shows up
but what would it be attached to if it's stand..
ah thx
parent/major or both?
parent needs to be nil, because if parent is present, UIBox doesnt render by itself
major is for placing
Hey, does the role type go into the UIBox definition or the Object Node btw?
So like Major and such
okay now this happens
WHY IS IT MOVING
I never touched this wtf
@primal robin any idea?
again, where's major
okay its not moving now but it wont render (this is drawn seperately)
i did major = G.ROOM_ATTACH
So I made a stake above gold that basically applies 1 more green/violet stake... Is it normal that the scaling starting from ante 9 is that insane? Ante 9 is a bit harder than Ante 10 on gold, and Ante 10 is almost twice as big as ante 11 on gold, wtf
also ante 8 is a straight x2 which is quite big
You've messed something up I'd imagine
okay so now at least the UI box isn't lying anymore
now I need to figure out the actuall position
i would assume so too but i just copied vanilla remade's code for green stake
You say it applies it one more time right? Show me your multiplication/addition/additional application
VERY weird question:
How do I get the profile's name and be able to pass it into a localization file?
Teach me your way master
that's all
What's your scaling modifier
?
G.GAME.modifiers.scaling
that's all there is to the code
that's what the game uses for that effect
that's the code from vanilla remade
You have to look deeper into it then
It's not an immediately helpful answer but it is usually unlikely that you can find the issue if you're just looking at the above-the-hood code or not checking variables like modifiers.scaling
.
is there a smod method that turns the highlighted card into a certain rank
also what does assert() do
Thanks, I'll have a look
It tries to load the file and if it gets an error in the process it'll print it instead of crashing the game
oh
SMODS.change_base(the card, suit, rank)
ok
thanks
how do i get the highlighted cards rank?
and how do i turn it to a queen
You can try and dig through Death's code to see how to get the rank.
do i just put like "queen" or something
sorry i meant suit
Should be same case except looking for the suit.
G.hand.highlighted[1].base.suit (assuming you only have 1 card highlighted)
Doing that won't work because all the cards have a respective value in code.
Aces = 14
Kings = 13
Queens = 12
Jacks = 11
ok thanks
if you want the rank you do G.hand.highlighted[1]:get_id()
And Major in this case acts as parent? Cause it affects what's moving it anyways
how do i do a certain rank]
like queen
i jyust put 11?
assert(SMODS.change_base(G.hand.highlighted[1].base.suit, G.hand.highlighted[1].base.suit, 11))
12
this function takes the name of the rank, so here you'd do "Queen"
also if you don't want to change the suit, you can just put nil
SMODS.change_base(G.hand.highlighted[1], nil, "Queen")
And you've got this in an Object Node elsewhere?
Oops! The game crashed:
[SMODS P"code.lua"]:38: Tried to call SMODS.change_base with invalid arguments: suit="Diamonds", rank="12"
Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-0406a-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.8.0
Platform: Windows
Steamodded Mods:
1: TheP by GhostlessYT [ID: Perv, Version: 1.0]
2: DebugPlus by WilsontheWolf [ID: DebugPlus, Version: 1.4.2, Uses Lovely]
Lovely Mods:
Stack Traceback
(3) LÖVE function at file 'boot.lua:352' (best guess)
Local variables:
errhand = Lua function '(LÖVE Function)' (defined at line 575 of chunk [lovely debugplus.console "debugplus/console.lua"])
handler = Lua function '(LÖVE Function)' (defined at line 575 of chunk [lovely debugplus.console "debugplus/console.lua"])
(4) global C function 'assert'
(5) Lua field 'func' at file 'code.lua:38' (from mod with id Perv)
(6) Lua method 'handle' at file 'engine/event.lua:55'
Local variables:
self = table: 0x016d3310 {start_timer:true, timer:TOTAL, blockable:true, trigger:after, func:function: 0x01686fc0, delay:0.1, complete:false, time:48.048870866328, blocking:true (more...)}
_results = table: 0x00fc2c58 {blocking:true, pause_skip:false, time_done:true, completed:false}
(7) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
self = table: 0x00fcd3e0 {queue_last_processed:39.533333333332, queues:table: 0x00fcd408, queue_dt:0.016666666666667, queue_timer:39.536464271982}
dt = number: 0.00995168
forced = nil
\
what did i do wrong
its all in here
G.PROFILES[G.SETTINGS.profile].name
Thanks
At this point it seems Object Nodes are for everything BUT UIBoxes 😭
So I can just call the UIBox directly
any idea why this won't place the image properly?
draw_results = function(self)
if self.ability.results_ui then
local cover_UIE = self.ability.results_ui:get_UIE_by_ID("chart_cover")
if cover_UIE then
local SPRITE_DIM = 300
local transform = cover_UIE.VT
local w = transform.w / SPRITE_DIM
local h = transform.h / SPRITE_DIM
love.graphics.push()
love.graphics.scale(G.TILESCALE*G.TILESIZE)
love.graphics.translate(
cover_UIE.VT.x + ((cover_UIE.layered_parallax and cover_UIE.layered_parallax.x) or ((cover_UIE.parent and cover_UIE.parent.layered_parallax and cover_UIE.parent.layered_parallax.x)) or 0),
cover_UIE.VT.y + ((cover_UIE.layered_parallax and cover_UIE.layered_parallax.y) or ((cover_UIE.parent and cover_UIE.parent.layered_parallax and cover_UIE.parent.layered_parallax.y)) or 0))
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(self.ability.cover_image, 0, 0, 0, w, h)
love.graphics.pop()
end
end
end,
No idea
welp this works ig
Ok, I looked up how to try and concatenate the variable into the string, and we got that.
I found the problem, it's in SMODS' formula
whoever coded it added an extra multiplication on accident
i just opened an issue for that
oh whoops
Im surprised nobody noticed this issue, I assume it's been there since the function exists
Surely many mods have some additionnal green/purple stakes
I don't think it's been used that much
I know cryptid has these kinds of stakes, but I'm not sure if it doesn't provide its own scaling
not sure beyond that, but I do think it not being noticed correlates with it not being used much
then again there's been errors in widely used parts of smods code that went unnoticed none the less, so maybe no one else has cared yet
this is normal though, the scaling is intentionally nonlinear from ante 5 on
Yes ante 8 makes sense
I've tried like 3 different methods to get this to pull the name. Nothing's worked and the quip has been blank.
Help. pls.
that's what you use variables for
the data you want to access is unavailable at the time localization is loaded
Yeah that I noticed
Which makes sense, I just didnt expect it to be this rough
So I can't grab the profile name when the localization files are loaded.
bump
yeah, you have to use a variable. I think quips do support those?
has anyone tried giving a joker a frontsprite?
i don't mean a soul sprite, i mean an actual front sprite.
as in the layer the playing cards use
that works fine, you just assign a sprite to the card's children.front in set_sprites
that's just changing the card's sprite isnt it
not exactly, it's a separate layer
oh ok
-# you can also add your own layers with separate shaders using SMODS.DrawStep
im not well versed into how sprites work, i havent toyed too much with them
i use stickers
that's a perfectly well alternative
stickers have a shader applied to them by default tho right?
you can remove them anyway
right
Hey Quick Question
Is My button Supposed To Fly Off Screen When Summoned
rhetorical question ik its not
lemme get s video hold on
no need i know whats happening lmao
do this
and get rid of the thing that adds its to G.I.NODE or wherever you put it
i got the video anyway
i'm a little confused what you mean
in the code that creates teh UI box
ok so the first one
mmm then what
just add the variables that i didnt add?
in the config?
add this in the config
major = G.ROOM_ATTACH, type="room",instance_type="CARDAREA"
how can i make a sticker not add its localization text to a card's info_queue?
figured it out with a hacky solution: made a dummy entry in localiztion whose only purpose is to be removed via code patched into generate_card_ui that passes over the info_queue, looks for it and sets that info_queue index to nil if the key matches, then had the sticker's loc_vars return that key
get rid of the table.insert
and do this
ya
if u don't do that it won't render
figured
YAY BUTTON
of course i'll need to adjust some things and i have no idea where the text is but
its a button
also why does the temp_func only run once
from my understanding the text should be there, no?
the node exists
oh also the code for continuing a run doesn't work
do I need to hook into some savegame function to save G.GAME.BALATROSTUCK2_current_class? because the issue is that its not saving
no that should be saving
~~well its not
wait hold on
i might just be: stupid
yeah I am
it was saving
i just didnt trigger a save
lmao
so yeah only problem is the text really
bump
what's the best way to add editions (or seals/enhancements) to played cards before scoring? the first approaches i tried with the before context each have their own problems and i feel like there's something i'm missing.
calculate = function (self, card, context)
if context.before then
for _, playing_card in pairs(context.scoring_hand) do
if playing_card.edition == nil then
-- Card scores as holographic and juices up before scoring but is visually editioned as soon as play is pressed, which looks odd
playing_card:set_edition("e_holo")
-- Card juices up and visually turns holographic before scoring, but does not actually score as holo
-- Additionally the juice up is immediately before scoring with no delay, which also looks odd
G.E_MANAGER:add_event(Event({
func = function ()
playing_card:set_edition("e_holo", true)
return true
end
}))
end
end
end
end
use context.press_play?
you should do the former but instead make it playing_card:set_edition("e_holo", nil, true)
iirc
this delays the animation but still actually applies the edition while scoring is calculating
wait no
its "e_holo", nil, nil, true im pretty sure
huh, i didn't see the fourth argument in vanilla balatro's card.lua file, is that a steammodded addition?
yes
-# you should set up the balatro and steamodded lsp for that since smods has comments saying what functions get overridden since recently
i think i had it set up at some point but ever since setting up git source control it doesn't seem to work(?)
i have a .vscode folder in my mod directory with a classes and lib but it's in my gitignore (since the lsp def doesn't need to be tracked i don't think) and i don't know if that's causing it to not work
that shouldnt cause any issues
basically i have the mod folder open in VSC, in the mod folder is the usual .lua files and localization folder and all that, as well as the aforementioned classes and lib under <mod directory>\.vscode\ . unless it needs to be <mod directory>\.vscode\lsp_def\classes or smth
wait
no the lsp should be in a settings.json file
in the .vscode folder
pressing F1 and selecting Open workspace preferences (JSON) should take you to creating one
oh looks like there is one but it's just. my figura LSP library for some reason??? haven't even made a figura avatar in ages
lmfaoo
then how would i add the steammodded directory as an entry in settings.json if the mod folder looks like this, would i have to add the whole file path or is there "it's in the same folder as settings" shorthand or smth
relative path:
okay update, having lsp_def in the mod directory works but if i add lsp_def/ to .gitignore the autocomplete/function view/whatever it's called just stops working which is. kind of annoying, i'd rather not have the entire smods lsp_def in my repo, is there a workaround here
a vscode workspace with both your mod and smods should do
-# mine actually has the whole mod folder, which I don't claim is ideal
no such luck, .lua files seem to only autocomplete/have lsp def if they're parented to the smods folder
unless i gotta save the workspace first or smth >_>
Opening the Mods folder with VSCode works for me, odd
And as Cat said, having both SMods and your currently-working-on mod's folder in it
you mean like this, right? 'cause it's not working.
-# if it's not working because i'm using a symlink to have the mod folder in Documents\git\ then ourrruouorughughghhhh
A hwhat now
Yes that should be fine
symbolic link
ok, turns out the fix is
- have smods and my mod folder in the same workspace
- have
lsp_deffolder in both - add
lsp_defto.gitignore(git is only tracking my mod folder)
weird, that shouldn't be necessary
How do you make it so that a button returns a different thing based on what joker you’re holding? Cause I just found out that ultra greed and Neo metal simultaneously activate when I click one of their buttons.
what's your button code
i do actually need to look into this myself as i i plan on implementing some wacky button stuff
I’m pretty sure it works beyond “different jokers call for different buttons” and you can just assign a new return based on what joker it’s on
i see. and your button node?
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 i get contexts if I'm making a custom thing
like i don't have any code that actually calls use_ability yet i don't know what to put as the context
ooobuttons = Card.highlight
function Card:highlight(is_highlighted)
ooobuttons(self, is_highlighted)
asc = {
n = G.UIT.ROOT,
config = { padding = 0, colour = G.C.CLEAR },
nodes = {
{
n = G.UIT.C,
config = { minw = 1, minh = 1, padding = 0.1, align = 'cm', colour = G.C.CLEAR },
nodes = {
{
n = G.UIT.R,
config = { minw = 1, minh = 0.5, padding = 0.01, align = 'cl', colour = G.C.CLEAR, button = 'universaljokeruse', r = 0.1 },
nodes = {
UIBox_button { label = { "Use" }, scale = 0.4, minw = 1.3, minh = 0.7, colour = G.C.RED, r = 0.1, button = 'universaljokeruse' }
}
},
}
},
}
}
if self.highlighted and self.config.center.evilbutton == true and not self.ability.extra.to_copy then
self.children.love = UIBox({
definition = asc,
config = {
parent = self,
align = 'cm',
offset = { x = -1.5 , y = 0 },
colour = G.C.CLEAR
}
})
elseif self.children.love and not self.highlighted and self.config.center.evilbutton == true then
self.children.love:remove()
self.children.love = nil
end
end
-- WORK ULTRA GREED
function G.FUNCS.universaljokeruse()
SMODS.calculate_context({greedbutton = true})
end
you can really throw whatever in as the context and have the card do something depending on it.
oh.
what are you trying to do
despite the de-cardeization, it still works like that.
i'm writing the code that calls use_ability, and I don't know what to put in the function call
here i'll back up a bit
you choose a Class
and this class has an ability
there's a button ingame that when clicked, it will call the class' use_ability function
Class derives straight from Object, so I don't think context is actually something passed yet
just call something like
if obj.use_ability then
obj:use_ability(obj, {whatever flags you want here})
end```
you don't need a context for that
well
i do because different classes have different effects
actually i guess I still don't need contexts
yes but they will have their own functions
yeah
so you just call the class's function when you click the button
is it a manually activated ability
Yeah with the button
oh.
You can only use it once per round (except for one which you can pay to use
you only need contexts if its a passive
that's also not true
contexts only exist because calculation calls the same function over and over again, the contexts provide different flags for different timings along with other useful information for each timing
thats stilll a "passive" activation
this is a bit of a hacky solution, but in the uibutton table call where you specify button, add ref_table = self
for your universaljokeruse func, add an e argument
then change your context call to a more generic one that allows you to distinguish that specific context, while making sure to pass in e.config.ref_table in your context table. so something like
function G.FUNCS.universaljokeruse(e)
SMODS.calculate_context{ universal_joker_use = true, instigator = e.config.ref_table }
end
and then theoretically you should be able to distinguish between your different jokers in calculate by checking for card.config.center.key == context.instigator.config.center.key...? 
regardless, you should be able to work something out from there. your primary issue is that you're trying to make your button func distinguish between two different sources without a way to do so
although from there, you'll probably run into a problem where if you have duplicates, they'll both do something when you press the button on one
honestly, maybe instead of using a calculate context for this, you might be better off setting up a function in your joker, something like
function G.FUNCS.universaljokeruse(e)
local card = e.config.ref_table
if card.config.center.my_func and type(card.config.center.my_func) == 'function' then
card.config.center.my_func()
end
end
```? and then doing what you need the button to do in that function
as in it could happen without forced input
forced input could also use contexts though, it's about functions being used for multiple different things from different places, not whether it's passive or active
oh shit okay uh
so that Class object
i've created one and I:
a) don't know how to check if it exists
b) don't know how to actually spawn one into the game
Oh sorry it's a GameObject
Same issues thoug
alright time for my issue 😓
ive made a custom rarity. when entering the stop, my game just crashes immediately. this is the code for my custom rarity
key = "effect",
default_weight = 0,
badge_colour = G.C.RED,
get_weight = function(self, weight, object_type)
return weight
end,
}```
and here is the crash
…I think different buttons isn’t such a bad idea.
Documentation me thinkss
this isn't necessarily different buttons per se, just more actually trying to distinguish one button use from the other, since your issue was that your button use on one joker was triggering both what you wanted that button to do and your other joker's button functionality - you just weren't distinguishing between the two at all
How do I implement a Shoot the Moon effect in code? The example mod I'm going by doesn't have an example for this
im not trying to flood g.funcs though
Oh no what I meant was I think I should just make another button.
Trying to figure out how to make a button work is already stress for one day.
if your using buttons that going to happen
Trying to do it on multiple jokers will just make me suicidal.
oh perfect
thanks!
welp, ONWARDS TO HITTING THE FUNCTION LIMIT
(and a shit ton of knuths arrows worth of coding warcrimes
like actually, wheres the commit that lead to this, my head feels like it will split open
Saxton Hale - Spend $5 to increase operator, increases price by ^1.5 each use.
Actually make that $25
atp i think they killed a person to make that function possible
cause i cant even find a commit about it
i might tweak i would LOVE help with my crash 😭
LOVE? like LÖVE2D?
yes
i think ive asked four times now across two different days and ive been ignored each time
and i cannot figure it out myself
What’s ur crash
^^
i've looked at this crash several times and can't figure out why it's doing that, sorry 😭
how are you guys teaching yourselves how to make these mods? I need some advice
what
if im being honest i started vibe coding but that can only get me so far. and also i feel dirty doing it
steamodded wiki and vanillaremade are your friends
slamming my head against a wall aka digging into balatros code and other mods code
your mods are not of latest
I started doing that too
i wanted to die
oh yeah i havent updated in a while
whats your editor?
shoulkd i do that
vscode
lovely 0.9 now
do you have the LSP
1503? now
LSP?
and also repeatedly ramming my head into the wall, too
Lots and lots of practice and experience, and also lots of asking for help (from human programmers)
along with config set up for smods lsp
Yes, theres one for VSCode
version.dll in the balatro steam folder is for lovely right
these b*ts are getting crazy now theyre promoting lua???? /j mods do not ban pls
LMAO
is it possible to set up something similar to a workspace library in notepad++
hold up funny idea
FRIXK NO CHROMECRASHRS
I dont got wifi
oh nvm the stuff is still stored in cache sick
What’s this
DEVELOPERS HATE THIS ONE EASY TRICK!!
go to https://github.com/Steamodded/smods/wiki for free tips on how to mod!!!
adds smods and balatros lsp to the thing
right but where is this
.vscode/settings.json
However sometimes people don’t know where to use certain things
?????
thats smods
I tried to run smods beta or whatever from the github and it kept crashing
I think I installed this one from the balatro mod manager
well regardless I added those paths to the settings
question
is the extra calculate function at the bottom necessary for essentially what is a worse golden joker?
...there's a mod manager?
Yeah but apparently its extremely outdated
in this case, I think so, since it's setting dollars to a value, it needs to be able to access the context of when to do that <-- am still relatively new to all this, I very much could be wrong
Hmm
Is it possible to rename "chips", or is that hardcoded where it appears? If a poker hand name is changed (using take_ownership and a localize() call), it more or less auto-updates everywhere else, but I can't find a similar method for something as base as the term chips
hey i figured it out
what was it?
no fucking idea
but it snot crashing anymore 😭
i replaced my custom rarities file with the one here, and then i added my custom rarity to this file, ran it once, and then i removed the vanillaremate part
and its working
I think you could use SMODS.current_mod.process_loc_text and iterate over it recursively and use string.gsub
I'll have to look into it! That sounds sick
what are some mods with custom card areas i can look at for reference
i dont wanna pester yall wit questions and so i just want examples ^^
for setting up the cardarea, you could look into the helper function introduced with steamodded 1221a: https://github.com/Steamodded/smods/wiki/1221a#modobjectcustom_card_areas-helper-function
and here's a screenshot of how i do this in my mod where i implement a custom 1-joker-large cardarea for certain custom decks
iirc atm you will also need to write a patch to add the cardarea to evaluation - something like:
[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/utils.lua"]'
pattern = "-- TARGET: add your own CardAreas for joker evaluation"
position = 'before'
payload = '''
if [condition to check if your cardarea exists] then table.insert(t, [reference to your cardarea here]) end
'''
match_indent = true
overwrite = false
times = 1
see here how joyousspring does that
hope that helps
i'm new to custom cardarea stuff myself. so far what i know is that you can populate it using SMODS.create_card/SMODS.add_card by including area = [reference to your cardarea] in your arguments
in a .toml file in the /lovely/ subdirectory of your mod
mm ok ty
youll never believe it
im having more strange nil index crashes!
lemme keep tinkering but i may have questions
wait i know exatcly whats going on holdon
im trying to make a consumable spawn a specific joker in a specific card area
key = 'sparkling_water',
atlas = 'Potions',
set = 'effectGive',
pos = {x = 1, y = 1},
use = function(self, card, area, copier)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('tarot1')
SMODS.add_card({
key = 'j_embr_sparkling_water',
area = 'embr_potionArea',
})
return true
end
}))
delay(0.6)
end,
can_use = function(self, card)
return true
end
}```
...that's odd. my understanding of what T is in that context is to do with sprite rendering. it shouldn't be nil. do you still get this crash on the current release of steamodded?
wait a minute
does the area arg take a string?
it could be to do with that. try passing a direct reference to the cardarea instead
why the FUCK did potassium turn itself on after i updated smods LMFAO
that's interesting
how silly
but that fixed it
i need to play with the scalee but its there
oh wow you can just drag these freely😭
that means it's not being added to your cardarea correctly
could i see your cardarea definition
bump :3
oop. what was your code for this object?
sorry, ping because late reply
all good
hmm. are you running debugplus? if so that would be quickest to help determine if the class exists
yep! ^u^
in-game, try just simply doing eval BS2.Classes and eval BS2.Class in the console and seeing what that outputs. if you get anything other than nil, that means your things exist. but would also be useful to see if it's as you expect
as for spawning one, do you know where you want to spawn them? into the joker area? the consumables area? the hand area? your own custom cardarea?
you could also test spawning that with debugplus, too
looks right
they're not really cards at all
that makes sense
there's only ever one at a time
but given that you want to spawn it, you intend for there somewhere for it to be, no?
i'm actually not sure if i am getting the meaning of spawn right
i see
i just need there to be the presence of the object so that its ability can be triggered
i suppose i could put it somewhere with no sprite or anything
i hate to bother you over and over
however
what do i put in my utils.lua for it to properly patch? when using target = '=[SMODS _ "src/utils.lua]' it crashes complaning that utils.lua doesn exist which is correct.
i tried pointing it towards target = '=[SMODS _ "src/objects/cardarea.lua"]' and that loads the game but the new joker doesnt do anything
the attached crash is for the former case
in that case, you could make a variable in G.GAME to put it in
G.GAME.BALATROSTUCK2_class
...what? the first one should work. what is the patch?
version = "0.1.0"
dump_lua = true
priority = 0
[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/utils.lua"]'
pattern = "-- TARGET: add your own CardAreas for joker evaluation"
position = 'before'
payload = '''
if true then table.insert(t, embr.potionArea) end
'''
match_indent = true
overwrite = false
times = 1```
what exactly is embr?
my mod prefix
change your condition to if embr and embr.potionArea then
oh yeah true
anyway, yes.
omg that worked
um.
thank you i love you so much
what value
i've never really created a custom gameobject
the gameobject is bs2_class_bstuck2_[class name]
under what condition do you want the object to be
i guess, spawned, since there isn't really a good term for it
created?
"exist"
rather than "not exist" which is what it is currently i think
hold on let me check something
i lied
it booted but it still doesnt work if its in the custom area
i'm assuming this means that i am wrong in my judgment
sorry twin but i have no idea 😭
mine is a really janky way doing things
the stuff in my custom card area is just regular jokers disguised as something else
check lovely/dump/SMODS/_/src/utils.lua to see if the patch is being applied
hm. line 70 is the first in the screenshot.
oh
wiat
nope
i know the problem
this file is 3.5k lines long what am i looking for in here
check the part where you patched!
i actually don't know anything about creating gameobjects 🫠 much less instantiating one into a G.GAME variable. i'm sorry
ctrl + f for -- TARGET: add your own CardAreas for joker evaluation
one moment i might not need to instantiate it if this works.
i in fact do not!!!
oh right this specifically is a iteration issue
i was about to bring that up yeah
i may be stupid
its there!!
local t = {G.jokers, G.consumeables, G.vouchers}
if embr and ember.potionArea then table.insert(t, embr.potionArea) end
-- TARGET: add your own CardAreas for joker evaluation
return t
end```
isnt it embr.potionArea
that would do it
what is the correct way to refer to your cardarea
could i see your cardarea definition please
game.embr_potionArea = CardArea(
16, -- x coordinate
3, -- y coordinate
game.CARD_W * 2,
game.CARD_H * 0.5,
{
card_limit = 1,
type = 'joker',
highlight_limit = 1,
no_card_count = true,
align_buttons = true,
}
)
end```
pulled off of the smods wiki
in its own file
youre probably right
i gueeess that could work, but iirc what's recommended is to put it into your mod's global table and refer to it that way
it was not
do you have a global mod table that you put things into?
i see. you should just be able to put it into a global variable anyway so that SMODS can access it
so before your cardarea definition, put
[your global variable name here] = nil
``` then immediately following it but before the end of the function, put
```lua
[your global variable name here] = game.embr_potionArea
``` then in your patch, change the payload content to
```lua
if [your global variable name here] then table.insert(t, [your global variable name here]) end
the name can be anything you want, so long as it is exactly the same across all substitutions
np 👍
<@&1133519078540185692>
sigh
do you think the people who get hacked fall for the same scam that the accounts do or do they do multiple different kinds
cuz if so thats just sad
actually i'm pretty sure it is the same
like a virus
i once fell for that steam report scam and they had just done the same thing
lmao, that one was funny. To be fair, coding too much messes you up.
lmao??
I meant the way the spam was worded.
oh yeah lmao
what function can i hook into to set a variable at the start of every round?
elaborate on the start of every round? like when you start a blind? or when you start a new run/load it?
the former
hook new_round()
it's iin G.GAME so it'll save if you load it
kk
Lets hope I remember how to hook lets go its been a bit
G.FUNCS.new_round or just new_round
yes
for anyone reading back over this and wanting the latter, that'd be Game.start_run(self, args)
but for that one, if you want a point in runtime that's still in the main menu, G.FUNCS.start_run(e, args)
probably because of the _
cuz i have this one earlier
BRo
al i did was change the name
let me check what line that is
it needs to be local new_round_ref = new_round, without the parentheses
oh
i knew that
you should be copying the function itself, not the return value of the function
yea
Is there a way to check for a poker hand in G.hand instead of G.play?
pretty sure there's a function that evaluates poker hands for any given table of cards, but i don't know the name of it off the top of my head
oh it's literally evaluate_poker_hand()
pass it a table of cards (e.g. G.hand.cards) and it'll return a table with a bunch of other tables detailing all the contained poker hands
sweet, thanks!
No, it would be G.FUNCS.get_poker_hand_info
Ah; with that, how would I get a poker hand? i.e. checking for "Two Pair" in G.hand.cards
...where is G.FUNCS found in the code, anyway? I'm checking the lovely dump and I could also benefit from checking draw_from_hand_to_deck
G.FUNCS.get_poker_hand_info is in src/overrides.lua, G.FUNCS.draw_from_hand_to_deck is in functions/state_events.lua
next(select(3, G.FUNCS.get_poker_hand_info(G.hand.cards))['Two Pair'])
do you mind elaborating on the difference between the two?
-# why select(3, ...)
evaluate_poker_hand doesn't call context.evaluate_poker_hand
ah, fair enough
Because G.FUNCS.get_poker_hand_info returns 5 values, and the third one is the poker hands.
ahh, okay!
Thanks for the help!
is there a function i can call that would serve the same effect as return { message = whatever } in a joker
like making a message pop up under a card
SMODS.calculate_effect(effect, card)
So does a calculate function for SMODS.Challenge work as normal or is there some trickery I need to know going in?
It's the same as an SMODS.Back calculate function.
both ceremonial dagger and riff-raff trigger on context.setting_blind but ceremonial dagger triggers first. why does their order in the joker zone not affect the order of their resolution?
wait. i think i know what's wrong. my code
the event manager my nemesis
Is it possible to replace the Jimbo card that appears when you win/lose?
And possibly the default Jimbo joker that appears in games even if you disabled vanilla jokers
So this SHOULD spawn only 5 of the same Joker, but it's spawning infinite of random ones
You need a context check also you're returning true before it can create the other four jokers.
So what context check should I use for when I start the run?
I got it to spawn all 5 of the same Joker, so that's fixed
You shouldn't, you should use apply
for i = 1, 1, 5 do
that would be start = 1, end = 1, step = 5
use #G.jokers.cards ~= 5 instead of not (#G.jokers.cards == 5)
the error would be not (#G.jokers.cards = 5), you're trying to assign instead of comparing
And this would allow me to use the apply properly instead of relying on calculate, yes?
apply = function(self, back) rather than the calculate?
This keeps throwing [SMODS WildcardCollection "crossmod/music_music_rotation.lu:48: attempt to index field 'jokers' (a nil value).
And for the life of me, I don't get how.
that's because apply is called before areas are initialized
put that inside an event
5 Weezers
FINALLY it works
why is your game malignantly orange
Trance
Spooky theme

im curious, is there a way to get highlighted jokers/consumables the same way you can get highlighted cards in hand?
G.jokers.highlighted and G.consumeables.highlighted
oh, you can do that? thank you
note that the cards in that table will be in the order they were highlighted
not the order they’re placed in
unrelatedly, is it possible to get card retriggers from the use event of a consumeable?
use = function(self, card, area, copier)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('timpani')
card:juice_up(0.3, 0.5)
return true
end
}))
for _, playing_card in ipairs(G.hand.cards) do
if SMODS.has_enhancement(playing_card, 'm_bonus') then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
playing_card:juice_up(0.3, 0.5)
ease_dollars(math.max(0, card.ability.extra.bonus_dollars), true)
return true
end
}))
end
end
delay(0.6)
end,
Here's what I'm doing. It works, but obviously there's nothing that checks for retrigger effects like red seals or mimes. I'm like, fairly certain that it's just not possible to do this, which is probably fine, but it would be nice I guess
What is the goal?
well this already works
it just adds $4 for every bonus card in hand when the consumeable is used
the goal is ideally to make it so that if the card would be retriggered in hand, it would give $4 again
for k, v in pairs(G.hand.cards) do
if SMODS.has_enhancement(v, 'm_bonus') then
local reps = {1}
local j = 1
while j <= #reps do
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
v:juice_up(0.3, 0.5)
ease_dollars(math.max(0, card.ability.extra.bonus_dollars), true)
return true
end
}))
if reps[j] == 1 then
SMODS.calculate_repetitions(v, {repetition = true, cardarea = G.hand, card_effects = {{}, {jokers = {dollars = math.max(0, card.ability.extra.bonus_dollars)}}}}, reps)
end
j = j + 1
end
end
end
is there somewhere i can hook that will let me do stuff just after a run starts but after any consumeables from deck/challenge have been gained?
you might not need to hook it
have you tried reset_game_globals?
wasn't aware of it. where does that get called?
that works, thanks! I didn't know about calculate_repetitions
https://github.com/Steamodded/smods/wiki/The-Mod-Object#modreset_game_globalsrun_start
not sure of the exact timing off the top of my head
you can try searching the code, or you can just put your thing in there with a couple test prints to see
if it's too early you can probably just use an event to delay your thing
neat, ill give it a try
would there be a way for a blind to debuff all scored cards?
like, i want to make it so that the unscored cards are the only ones that count to score
making them count was easy, just copy Splash code, but making the scored card not count is where im struggling
Do you want to debuff it or make it unscoring?
is that... not the same thing?
Yes, there are jokers that trigger on unscored cards.
ah right
let's say debuff then
if context.debuff_card and next(G.play.cards) and SMODS.in_scoring(context.debuff_card, select(4, G.FUNCS.get_poker_hand_info(G.play.cards))) then
return {debuff = true}
end
```?
uuhhh nope, doesnt work .w.
maybe i wrote smth here wrong, idk
how can i allow the player to select 2 jokers at once while they have a card selected that wants to interact with 2 jokers? i know cryptid did it, but looking through the files i can't find where that code is :(
https://github.com/SpectralPack/Spectrallib/blob/7b92966e527b99a7afb0b70a7a08d4fd9295582c/other_utils.lua#L17-L23 this does it permanently like in cryptid, idk how to make it if you have a specific card selected without breaking other stuff that changes the limit
yeah basically you just manipulate G.jokers.config.highlighted_limit
you can use something like this for dynamic adjustments when you select ceertain cards
sorry if this is easy and im just missing it, but how do you check if the played hand has at least two scoring cards of the same rank and suit?
my bad
they run when they can, useful for making code that waits for and runs after some condition is met
additionally since it’s a queue you more easily control the order of things happening
because by default events block each other, and some animations are events it allows to do something on animation finish / chain animations
Jade Penguin moment.
I'm just gonna give this to you:
local function has_identical_cards(card_list)
local ranks = {}
for _,card in ipairs(card_list) do
local rank = card:get_id()
local suit = card.base.suit
ranks[rank] = ranks[rank] or {}
if ranks[rank][suit] == true then
return true -- The for-loop stops here
else
ranks[rank][suit] = true -- After, we go check the next card
end
end
-- All cards checked and nothing was found
return false
end
-- To use the function:
if has_identical_cards(G.play.cards) then
-- do something
end
idk, looks fine to me /j
thank you sm!!!
how would i check if a certain card is in a card area
and also, how would i change the functionality of an already existing enhancement
oh lovely
is it possible to like
card.use()
and it'll use it if card is a consumable
wdym?
like if I were to run a for loop through G.consumeables.cards and if they're a certain type of consumable, force it to be used
cuz i have a deck that i want to spawn two cards and use them immediately
Infinite Tower
Legendary Joker
If your hope is known to shatter and you doubt that we'll survive [...]
All tags become Lightbulb Tags. Use this card to consume one Lightbulb Tag and gain +2 xMult.
Lightbulb Tag
At the beginning of blind, turn all playing cards in hand into the Brights suit and give them the light enhancement.
Brights (from 0 Error)
Brights have the special property of counting as all 4 vanilla suits.
Light Card (from Cryptid)
When played with 5 other scoring cards, gain x0.2 Mult and increase requirements by 5.
I'm making an expansion mod that requires both 0 Error and Cryptid and this is the first legendary joker. Thoughts?
did i just make 4 halves of brights
ASaS has 4 special suits that acts as 2 of each vanilla suit
You made your own suits
You shouldn't compare your mods to other mods, because what you bring to the table is its own thing and you should keep it that way!
Besides Brights interact weirdly with flushes
i love oyu
uh
i may be stupid
but what if my description changes if a different card exists
can i put an if inside of my loc_vars?
oh dang, i didn't know VR had an faq. im gonna read the whole thing and learn so much shit lol
yes
how would i check a card's printed suit ignoring wild and smeared joker?
does card.base.suit do that?
yeah, checking card.base.suit will ignore wild & smeared
i am trying to make it so a joker destroys itself if it is not clicked for 15 seconds. how would i go about doing this?
Make an update(self, card, dt) function for the joker that counts up a timer by repeatedly adding dt to it. When that timer exceeds 15, destroy the joker.
Then, hook Card:click() and if self.center.config.key matches your joker's key, reset the timer to 0.
local click_ref = Card.click
SMODS.Joker{
-- stuffs
config = {
extra = {
timer = 15
},
immutable = {
timer = 0
}
},
click = function(self)
local ret = click_ref(self)
self.config.center.ability.immutable.timer = 0
end,
update = function(self, card dt)
card.ability.immutable.timer = card.ability.immutable.timer + dt
if card.ability.immutable.timer >= card.ability.extra.timer then
SMODS.destroy_cards(card)
end
end
}
I think that should work
oh update takes card that makes it easier
i dont believe SMODS.Joker.click exists
bump
this in fact does not work
just says use is a nil value
The function you're looking for is Card:use_consumeable(area, copier)
what do i set to copier?
You can just exclude it, I think it's for like, the Fool.
okay so i'm assuming i have to destroy the card manually 😭
because it used the card but the card sitll exist
yeah ok
i tried implementing this and it didnt work. any ideas why?
how did it not work
crash?
no reset?
I made this on my phone so i'm going off memory
nah its alg (your really good then wow)
okay click probably doens't override like I thought it would then
when you click on the card does its UI show up like normal
okay then yeah it doens't override what I thought
do this
im so sorry to bother you with more ui but i just have one small thing
how do i add l9ike a tooltip to my button
the tooltip is already in localization it's jsut c_bstuck2_[your class]
use the func thign in config
G.FUNCS.hover_minigame_proxy = function(e)
if not e.parent or not e.parent.states then return end
if (e.states.hover.is or e.parent.states.hover.is) and (e.created_on_pause == G.SETTINGS.paused) and
not e.parent.children.alert then
local _sprite = e.config.ref_table:get_uibox_table()
e.parent.children.alert = UIBox{
definition = G.UIDEF.card_h_popup(_sprite),
config = {align="tm", offset = {x = 0, y = -0.1},
major = e.parent,
instance_type = 'POPUP'},
}
_sprite:juice_up(0.05, 0.02)
play_sound('paper1', math.random()*0.1 + 0.55, 0.42)
play_sound('tarot2', math.random()*0.1 + 0.55, 0.09)
e.parent.children.alert.states.collide.can = false
elseif e.parent.children.alert and
((not e.states.collide.is and not e.parent.states.collide.is) or (e.created_on_pause ~= G.SETTINGS.paused)) then
e.parent.children.alert:remove()
e.parent.children.alert = nil
end
end
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
if not G.GAME.round_resets.foobar_minigames then
G.GAME.round_resets.foobar_minigames = {
Small = FooBar.get_next_minigame_key(),
Big = FooBar.get_next_minigame_key()
}
end
local _tag = FooBar.Minigame:init(G.GAME.round_resets.foobar_minigames[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
DAMN!!!!
heres what I did for my thing
the important part is the func = 'hover_minigame_proxy', ref_table = _tag
i'm a bit lost
that creates the function to be called one and provides data to it
wait not once sorry
called every frame
whenever its drawn
i have the func i'm just not sure what i'm supposed to put in it?
lemme add comments
G.FUNCS.hover_minigame_proxy = function(e)
if not e.parent or not e.parent.states then return end -- something broke, don't crash
if (e.states.hover.is or e.parent.states.hover.is) and (e.created_on_pause == G.SETTINGS.paused) and
not e.parent.children.alert then -- you are hovering, and you weren't hovering last frame
local _sprite = e.config.ref_table:get_uibox_table() -- generates the popup
e.parent.children.alert = UIBox{ -- display the popup
definition = G.UIDEF.card_h_popup(_sprite),
config = {align="tm", offset = {x = 0, y = -0.1},
major = e.parent,
instance_type = 'POPUP'},
}
_sprite:juice_up(0.05, 0.02) -- unneeded
play_sound('paper1', math.random()*0.1 + 0.55, 0.42) -- unneeded
play_sound('tarot2', math.random()*0.1 + 0.55, 0.09) -- unneeded
e.parent.children.alert.states.collide.can = false -- if the popup goes overtop of the button, this makes sure the button won't be pressed accidently
elseif e.parent.children.alert and -- you stopped hovering
((not e.states.collide.is and not e.parent.states.collide.is) or (e.created_on_pause ~= G.SETTINGS.paused)) then
e.parent.children.alert:remove() -- kill the hover
e.parent.children.alert = nil
end
end
hey chat is there a way to make my joker message display chinese characters?
wait chinese
yeah you'd just need to change the font
oh thank you!!!
okay this works for japanese
f:2 for simplified chinese and f:3 for traditional
just change the number till it works for chinese
f:5 for japanese
now i can have comedic chinese text 🔥
i wish there was a pixel font for the other fonts tbh
iirc you can make cusotm fonts
how to do the hook part, im relatively new to this and have no clue how from what i can see in other mods code
dont think ive hooked something before
i can explain hooks in a bit unless foo gets to it first
ye chat im not getting this to work 😭
couldnt find hooks in the smods docs
it just pops up as the {f:2}
local hook_ref = hook_func
function hook_func (args)
-- do something
local ret = hook_ref(args)
-- do something
return ret
end
theres stuff in vremade iirc
i forgot to save 😭
vremade?
vanilla remade
yeah hooking isn't an smods feature
recreates the balatro jokers and stuff as if there they were a mod
welp nvm it still didnt work 😭
i think sometimes it's a little overprogrammed but
ya
neat
namely the boosters i think its like a lot more than necessaryy
actually i think its like that on purpose
show code?
oh
no is simplified
i actually don't think text styling is supported in that
i thought you were talking about loc_txt
it might work if you use the localization function
alright, uuughm Now what
what exactly do i set for ref_table
you can
oh ye then ill prob do that!
whatever generates the tooltip
no like what has the code to generate the tooltip
oh
like returning the UI nodes
or like i meant pull from locvars
do i need to make it myself? if it's just from localization?
saddd ye
you can pull informatoin from that
but you'll have to format it
when pulling informatoin from there it will be formattingi n the right colors and stuff, but you gotta do the UI box
not too sure on what im doing wrong, but the game crashes with this text when booting it up but im sure its not to do with my lack of knowledge on hooks but it just being a local variable there.
can i just steal the code from like anywhere really
??
or
wait you sent me yours
i'd just have to replace the text in that with localize functions?
what
k back
your snippet is going over my head i'm so sorry i have no idea what to edit in this function
bro its a ss of the ss I sent into discord
okay so once you make the UI box
you want to call localize
with type = "whatever type your entries are located in"
key = "key to find your entry"
and nodes = some local variable you assigned to an empty set before hand
that will populate said local variable with nodes you can insert into our UI nodes
i'm so sorry you're going to hate me
i'm still so confused 😭 okay hold on let me think aloud cut me off if i'm not getting it
i need to make a ui box
the code i can borrow from either an existing function ingame or i guess i could also just use your snippet from earlier if i modify it
thennn i put it in a variable in config called ref_table? or
yeaaah i'm sorry your codeblocks are not helpful 😭 i can't make heads or tails of any of it
i got the hovering code down, that makes sense i just. don't have a ui box nor do i know how to create it, and i'm not sure what ref_table is supposed to be
ref_table provides information for the tooltip ui generation function
it can be whatever you want it to be
this means nothing to me 😭
is the tool tip ever going to change
not necessarily, considering that the button gets remade when you change your class
it just needs to display the name and description of the related consumable
is your localization file like this
Other = {
class_sushi_class1name = {...}
}
or something?
if so set ref_table class1name
okay set ref table to the class name
the actual Class object doesn't need localization
'c_bstuck2_' .. G.GAME.BALATROSTUCK2_current_class?
yep
alright that's there
okay
change local _sprite ... to local _sprite = BS2.get_class_uibox_table(e.config.ref_table)
and make BS2.get_class_uibox_table(key) return the popup ui nodes
and the ui nodes i can get from that one screenshot?
style the UI nodes however you want
to get the text you want to place inside from the localization fiels
i swear I was holding shift
well i just wanted it to be like
your friendly neighborhood tooltip
that all the cards use
so i'm assuming I wouldn't really need to change much from that
look into the UI_Definition file then
is this in other or Descriptions
local name = {}
localize{type="name", set="bstuck2_Class", key=e, nodes=name}
local desc= {}
localize{type="descriptions", set="bstuck2_Class", key=e, nodes=desc}
that'll give you text nodes you can insert for the name and description
title is already a text node
and text is a list of text nodes
just put them in the nodes key
like nodes={title}
back to the paperback error
no clue what thats about
just do nodes = text
there doesnt seem to be as much code as i thought there'd be
balatro's UI is pretty neat
also you don't need if title
it won't crash if its nil
so like this
this is the paperback code.. i'm. really not sure why this is triggering??
Ah.
wait no that still shouldn't error out??
i'm just going to turn off paperback for a sec i'll deal with that later
yeah thats a future issue
that's more like it
whats the stack trace
toki pona spotted
:3
ooooh
i've told you to do the same thing 3 times and you haven't done it omg
nodes=title
sorry!!
nodes=desc
Okay, Did I Do It Wrong
that should work
wtf
okay get rid of adding the nodes for now
made it nodes = {}
and see what happens
try making a root a r or c
pardon?
so like this
yeah
idk if this helps but here's that line in dumps
oh man, you're so out of luck, you're messing around with pretty complicated stuff right now
☹️
why is it this hard to add a damn tooltip 💔
this seems like there should just be a function for it
localize function does not returns array of element, it returns array of array of text lines which you need manually pack into rows and then into column
or smth like this in short it's really shit
ooooh thats what I got wrong
mb
there's a lot of conversation so maybe you have already tried this but have you tried to use the tooltip/detailed_tooltip field on the node?
detailed gets from a center like {T:} iirc
wait since when was that a thing
or do the smods patches/overrides not iplement into the skip tag area
this is a vanilla thing
why does the tag tooltip not do that 😭
dunno
Awh.
i had set it to this, dunno if i misinterpreted your statement
but the {title=... thing didn't work with detailed either so
i dont recall the syntax
remind me how i dump localization files again?
ok it read it, it has to be the center object
so G.P_CENTERS[key]
forgor lua was 1indexed omg
