#💻・modding-dev
1 messages · Page 98 of 1
yeah so adding a event in the extra queue does the job
is it possible to get how many times one card will be retriggered?
buuuut idk how to pass the card into it
'nother new wiki page
we are eating GOOD
You should include tprint here (its a balatro function but it'd handy) https://github.com/Steamopollys/Steamodded/wiki/Utility#debugging
Also thank you for including the assert in the load file example
sure lemme do that
Wow I didn't know about half these utilities
SMODS.stake_from_index feels like it should return nil if it doesn't exists
Fair
I've realized I did pull a dupe on some already documented util functions
@frosty dock u think function patching utils would be useful? It's not like it's hard to do in lua but it would just remove like a tiny bit of boilerplate.
Idk it would save like at most 2 lines, and possibly some overhead
would it even save lines?
Yeah like one, for the function back-reference
I don't think it makes sense
Also I don't think the function could even replace the original very well
It would need a jank pass the table and key
Yeah it would still require the direct setting of the original function namespace outside the func most likely
could have a ref_table-ref_value approach but that still looks bad
local oldfunc = G.FUNCS.reference
function G.FUNCS.reference(...)
local ret = oldfunc()
-- stuff
return something
end
-----------
patch(G.FUNCS, 'reference', 'after', function(result, ...)
-- stuff
return something
end)
would also likely need several different types of patching with different arguments to allow modifying return values and args and whatnot
not worth it
True, function patching just has too many dynamics to consider
just makes things more confusing because it's nonstandard
Maybe you should just make a wiki page on patching functions. So it's easier to understand for new modders. Low priority but I think it would be useful.
really util functions should mostly be things that are
- Really complex/need a lot of work to do
- Prone to causing issues that you can help avoid
- done frequently
Yeah I think it falls into the last one, but it's hard to capture all use cases
So yeah honestly not worth
yeah but something that is extremly common and done in 1 or 2 lines doesn't need a util function
ok so I want a consumable card to only be usable when in a blind, how would I do that?
create a custom can_use and check whether the player is in a blind
https://github.com/Steamopollys/Steamodded/wiki/SMODS.Language one more page done
(i actually couldn't bother explaining why a certain feature was missing here, so i just sneakily added it in)
i didnt think of this at the time but making huge joker slots like 10k or whatever would have made joker stencil too good, so this setup stops that from being possible
tru
good point actually
apparently lua5.1 doesn't have integer division yet?? (only introduced in 5.3)
im trying to make an enhancement that causes a card to be destroyed similarly to glass but idk where the glass enhancement's associated code for being destroyed is
i tried to look
actually im just not gonna worry about this
state_events.lua:962
ok so im making it where a consumable's affect expires after the blind ended but idk how im supposed to do so
like, I cant use context stuff
i'd put it in a logic loop with a boolean flag and set the flag to true when the consumable is used
and then set the flag to false in context.end_of_round so it stops there
theres probably a more elegant solution but i think that'll work
alright
"omg wild cards should be immune to debuffs!!"
I can do you one better.
Can I change the color of text on a badge
working on refreshments!
I wanna add some kind of detail on the bottom but I'm not sure what to do
Maybe a shadow for the wine glass?
oh true
does anyone know how smod bypasses localization for modded joker names?
which badge are you talking about
I'm doing a rarity badge for a consumable
oh then I'm not sure if I know anything about that sorry
But instead of changing the background color I want to change the text color
What badge do you know about
the badge for the main mod
I can prob use similar code
Ok il look In steamodded to see how that works
That didn't help but thanks for trying
slight update to wine but also the placeholder sprite because its funny
actual slop
What’s this for btw? Looks interesting
Refreshment consumable cards
they may typically be ones with temporary effects but im considering changing that
true
what would Wine be?
+4 discards
+1 wine (must have room)
its only for one round so its not THAT good
Hydra card that just adds 2 negative copies of itself. Doesnt do anything else
Would this be its own separate consumable type or what
but it can get you out of a tough spot
What other ones do you have?
milk - +3 hands
bread sticks - blind is reduced by 25%
those are the ones thats coded so far anyways
is there like a theme behind them or is it just bread sticks
Like I can see wine being discards in this case bc it’s red
Maybe wine can also be -1 hand size as a trade off? +4 hands seems OP
is there any theming like that for the other ones?
oh this is a similar thing to Statement cards god dammit
to put it into perspective
there are very similar alchemical cards that give +1 hand and +1 discard for round
+4 is insanely powerful
yeah it is I realize
well I do want these to be strong, they are temporary effects after all
but maybe I should dial it down a bit
You could do something like
Wine - Refreshment Card
- +2 Discards, -1 Handsize
Or - +2 Discards, -1 Hand, something like that
There should be a trade-off
Or +3 discards
this is theoretically infinite money
Sell value of $10, decreases sell value of all other Jokers by $1 when sold? Kinda came to mind from the idea of repeatedly cutting off heads and getting more exhausted over time.
I wanna make some custom joker art
I have a really cool idea
Can someone give me a png?
where do I found the source code for the legendary jokers
never mind in the code it's Caino instead of Canio
So when I use my Joker all the messages work but the Xmult doesn't actually apply to the score. what would be causing this to happend?
can we see the code? its usually forgetting the right _mod in the return AFIAK
Decided I'd start a new chapter in my modding journey
Crimson's Ultimate Card Collection became ShinkuLib, and now I'm using it along with your usual collection and make Shinku's Card Binder
Honestly, a cleaner name than well..
Y'know the acronym
Any Ideas I get are gonna be thrown against the wall here in the binder
Goofy stuffs
I'm using FearJoker's lovely patches (with permission) to be able to have consumables that stay for a while to have temporary effects
I have calculate code that perfectly destroys a card after the round is over, but this isnt retriggering any cards
any help?
what are these btw are they decks???
Enhancements
the -1 ante enchantment is insane
I'm not trying to go for balanced. I'm going for learning how to make stuff
ah yeah that makes sense
I need to try and make some enchantments myself eventually haha
So the card binder's gonna be full of wacky stuff. Think Cryptid and Almanac but me learning how to do stuff
I may change it to something like 1 in 2 chance to do +1 ante or -1 ante
im fucking stupid
it's just a burning memory
?
But yeah, while stuff like Tier 3 vouchers will be in ShinkuLib, things like my Extreme Decks and whatnot will be in this card binder mod
Had a cursed thought:
What if you tried to Ortalab the Ortalab cards without reference of Balatro?
It's like Google Translating over and over
I may be making stuff with stuff from ShinkuLib down the line so...
Idk if i'll make it a dependency or one of those "If Mod Loads" atm
But safe than sorry, Gonna be dependency
Can I dm anyone in regards to modding. Got some questions about injecting. That's all.
generally you can ask in this channel but a dm is fine
I'm generally against DM support. It requires one on one interaction which can get annoting as the person giving support if you don't know how to do something or have to leave or whatever and now they aren't getting support. Also since others can see the coversation it means that the knowledge isn't he shared so people reading the channel don't gain that knowledge, aren't able to correct mistakes and also can't take over support if the original helper can't follow up
Made a PR for this, someone lemme know if that was unnecessary
Does lovely 0.6 allow multi line targeting without using regex?
Yeah just use toml's multiline strings
Or do you mean patching mutliple lines with one pattern
Patterns only looked for single lines unless they were regex patterns
Yeah I'm not sure then
Yes
Neat
mayhaps?
I never got a response
That would be amazing if it does
Ah it's usually because its some basic questions and I dont wanna flood this channel with small basic questions.
No longer have to spend ages figuring out the exact regex string to match the specific area
where does the game determine the hand type of the hand played?
theres nothing wrong with usign this channel for that
Just dont have the best experience asking basic questions in some servers
we don't judge (except jokingly)
Or if you are a filthy pirate man
Fair enough
Also others might have the same questions and can find the answers too sometime later
heck it'll help me, since I anticipate I'm going to need to patch the hand type evaluation stuff
but I'm not quite there yet so I can just keep a reference to this convo
I tried to mod an unity game, that was a pain
Now gonna try this first
got the metadata working now gotta figure out how to make the mod itself
I assume you already found the docs then?
Yep!
great
I have an idea on how to implement it, but multiline patterns aren't a thing as of 0.6.0
Also I didn't realize that you were asking about that in particular
I swear it's not
try the patch

me defining a new variable in lua
I thought it worked tbh
real
last I checked the pattern patch is checked per line
local i, flag = 1 ❤️
What are you trying to do?
what's PR #68 got to say about that?
two currently drafted ideas
a card enhancement that makes a card act as the most advantageous rank
a joker that adds a wild 5 to all (or only some) hand evaluations
all I know is I need to look at how it works to even see how possible those ideas are
oh so since beta7
I've been keeping you guys in the dark because I like to see suffering
(I legitimately forgot)
iirc there's been some kinds of implementations of the former, but they didn't support custom ranks
@crisp coral you'll never guess what just happened
so there's no fully functional implementation of that yet afaik
I'm fine with it only counting the standard 13 ranks, since the theming is around there anyway
you may be able to get away with hyjacking the evaluate functions in SMODS.PokerHand's
not too familar with the hand evaluation system
I should try to make quantum ranks work again, haven't even tried in a while
oh yeah you could jsut hook get_id
I forgor it was a function
the wild 5 one could probably just add it to the played cards array and let the game caluclate it
not really, that doesn't let you support multiple ranks on one card
true
I could help after wrapping up quantum enhancements
but you coudl look at the played hand and figure out the most useful rank
Ideally we don't need to brute force it
I mean you could be smart with vanilla hands
tried to make quantum ranks before and got stuck on straight calculation
straights seem the hardest
it's hard to support modded hands without manually supporting them, having them support you or brute forcing
makes me wonder if brute force would be worth considering for that "ease" of compatibility then
since in theory the performance hit would only occur with quantum ranked cards, right?
depends
things start getting tricky with multipel quantum ranks, bigger hand sizes, etc.
3 quantum rank cards even at the standard 13 ranks would need 2197 full hand evaluations
hm... I see your point on the need for compatibility then
yeesh baboy!
but you could maybe make it so only evaluates hands between the best possible hand and the worst hand already known to be possible? that'd probably do something to reduce the search space
straights probably account for a lot of that time, but it's fairly fast to tell something isn't a straight
I wonder if there’s some leetcode problem for this that we can yoink the solution of
I mean you can always gurantee an x of a kind with x quantum cards
so you can start at that
card with any rank
like wild cards but for rank instead of suit
say a card can be a 3, 4, 5, and 8 simultaneously
that sounds impossible
how "global" would the choice of card be? if there's a combination that makes a straight and one that makes a 3oak, it shouldn't contain both I presume?
cause otherwise we'd have fake straight flushes and stuff
nothing is impossible
unless we somehow overwrite every vanilla joker that uses ids and force every mod to use some Card:is_id() function or whatever
that would almost certainly have to be the case yes
that would take quite a long time
is_id() my beloved 🙏
the conversion will be a joyous day
I’m already doing that with enhancements
regex my beloved
you probably would get very far with a simple regex yeah
we already do a bunch of crazy patches
Also probably it would be is_rank instead of is_id
it's not impossible
whar are regex patches.....
since rank IDs are just in order of registration and don't mean anything
judging by the Nope! im assuming that it is either something i should know or something really complicated
cursed
congrats, it's both!
hahaha both
patches that use regex
ew
A regular expression (abbreviated regexp or regex) is a way to describe sets of characters using syntactic rules. Many programming languages use or support regular expressions. A regular expression is then used by a special program or part of a programming language. This program will either generate a parser that can be used to match expressions...
silence, regex is godliness
incredible power if wielded properly
has to be mastered for millenia to achieve omnipotence of coding
who is this old man
real...
relevant https://regexlicensing.org/
yeah it's never caused performance issues
Stephen Cole Kleene, introduced the concept (of regular expressions) in 1951
annotations mine
ever
Luna implemented quantum ranks right?
can't have performance issues if it's written in rust
Wasn't it deemed to be too inefficient?
Rewrite all of balatro in bevy
can we burn his corpse
not in a cremation way
in an at the stake way
who wants to parse html with regex? i do i do!
I wrote a debian control file parser with regex
so I take it I should probably work on the other things I have drafted for my mod for the moment
We advance one more step on the clock https://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html
It's actually not that bad, just a very dense representation of logic. There are tons of resources online to help and it's genuinely an insanely useful tool to have.
oh no I meant in regards to the quantum rank enhancement I wanted to add earlier
Oh yeah that's probably not possible
Without being very slow
And/or buggy
the add a 5 to hand evaluation did sound possible though... I just didn't catch where I'd need to hijack/patch
without some patches we have in Steamodded that would actually fail horribly
vanilla hand evaluation rejects anything with 6 cards or more
lol
Also for hand eval you'd probably need for the wild 5 to actually exist and not just be some dummy table
I was mainly thinking of having it adjust what the hand would think it is
like how you can make a flush with wild cards, then lose the wildness due to Vampire, but it still evals as a flush
fun read
again though, I still don't know (even roughly) where I'd need to adjust the base game's code, assistance on that front would be appreciated
yeah
thought jimbo was male
Yeah where do you think the liquid came from
😨
How do you set the locked text of a joker?
What does unlocking the text do
Do you put the unlocked text in unlock then?
iirc it's like when a card shows up in shop and says "purchase this joker to see what it does" (which would be the unlock text)
it's not clear by the code though
How would I add an info box next to a jokers description that says like "art by _"
So if you don’t want the joker to reveal it’s ability you do text {} then unlock
if TagSelected (random double between 0 and 1) == (a string) then
that is never true
there should be a weird ass mod where all the unlocks are like riddles
So how do I get orbital tag to load a proper hand?
no like where all of the unlock texts are like
you make tagselected the actual tag you selected and not the random number
I may be mistaken, but is it the fact that for the orbital tag, you construct the tag but never actually add it?
instead adding a blank orbital tag later
Why aren’t you using pseudorandom_element?
wdym?
I want it to be just balatro tags, if i just use tags it'll grab other modded tags included my own
Instead of that god awful if tower
what's the signature for that? didn't know that existed myself
you can still just make a list of all the tags you want to include and pass that thru
I just looked at what was in Balatro and the one i found was Certificate's if statement
i can?
Does this look about right? Im trying to make it look like meat/bacon. Maybe its too pink?
It looks raw
what if it wasmore like this
bacon
sure, im open to suggestions
I made it more contrast?
How much hue did you shift it by?
Maybe you could make the darker colors in red and the lighter in yellow
Something like this
have you tried adding add_tag to line 119?
its a function that (pseudo)randomly picks an element from a table
instead of using a horrendous if statement, use that
its a bit funky lookin but heres Hekikomori
It works now
okay it seems i will be cooking today
is there by chance going to be a chain linking them
gee how did you know
you cocked though 🔥 , whats its effect
also you needd a background right
may i put forward an idea
How do you modify hand size?
what's the difference between h_mult and x_mult
oh so h_mult is for Jokers like The King
there is no joker named that
I found G.GAME.starting_params.hand_size, and tried increasing it, but it didnt seem to work in a deck?
apply = function ()
G.E_MANAGER:add_event(Event({
func = function ()
-- Increase hand size by 5
G.GAME.starting_params.hand_size = G.GAME.starting_params.hand_size + 5
return true
end
}))
end,
my bad I meant the Baron who has h_mult for every king in hand
that would be h_x_mult not h_mult
h_mult is for Shoot the Moon
h_x_mult is used by steel cards
ya
baron actually just uses an x_mult return val
wait what the fuck
h_mult is a thing???
i thought yall were talking about like
card ability's h_mult
you can return it??
i thought it was just like
you can just do h_mult by it's self?
i thought you just needed to return mult
whats the difference between returning h_mult and returning mult??
h_mult might just be a shortcut?
mult is literally shorter than h_mult
do you need to return h_mult?
idfk
it might be for cards that only stay in your hand, so they don't count if played wrong, Raised Fist also has it
I like the chains
q: i am NOT good at spriting, is this acceptable for legendary text or does anyone have any notes or something?
i was looking at how the legendary jokers names are written and trying to emulate it
Is G.playing_cards the played poker hand or the regular hand?
crying, i'll have to look for another name now lol 😔
ugh
SMODS.Tag:apply arg signature is inconsistent with other functions, it doesn't take self
Lots of tag stuff is inconsistent I’ve found
I also have no idea what the custom generate ui function was doing other than not handling loc vars properly so I just commented it out in case it was needed
it'll break some mods but it's best to have things consistent
any other specific inconsistencies that come to mind?
Sawry
I’m not a massive fan of the way they trigger by requiring the context in the config, I don’t remember if they have a set ability function or not either
Isn't there's one for orbital tag?
It is specifically for orbital tag, yeah
I don’t remember if it is called for every tag or not though
hm I haven't actually looked at that commit at all until now - your solution is less than ideal unfortunately, it completely tosses tooltips out the window?
Does it? It just uses the base game function to draw the tooltips
your loc_vars call just throws a tossaway empty table in as info_queue
I'd rather have some way to pass the Tag into generate_card_ui than taking loc_vars out, it won't work for custom generate_ui functions either
Yeah that makes sense
which we do have an argument for, I hope passing a Tag into doesn't doesn't break stuff too badly (it shouldn't)
well that makes a lot of sense, here I was thinking I'd just forgotten to add my info queue stuff to certain tags but I've actually just clobbered it away 😄
aight that's now working properly
while I break Tag:apply, does anything else need breaking 🤔
btw this is why I insist on having proper docs before we're stable
these things always happen
that restriction shall be lifted. I can add set_ability as well
Not really breaking but rather fixing the editions having a white text?
enhancements*
Right mb
yeah that should also be fixed. i meant tags specifically
when is the set_ability called? will it help with the orbital tag problems that crop up every now and then?
or does it already do that by default?
I don't remember
it's called right when calling the constructor
How do I get my Joker to say the actual value of the Joker? Right now, when I play a heart card, the adds X_mult goes up instead of the actual value of the Xmult. As shown in the video, it's going up by 1 when it should be going up by .25. It also says the value it goes up is increasing, and the base value (the value it should be adding to x_mult) is nil instead of the base mult. I have no how this happened and no idea how to fix it if someone may help me
said video
Show your whole joker code
alright it's live
PSA: As of Steamodded's latest commit 1216c, a breaking change has been made to tags (apply function signature changed from (tag, context) to (self, tag, context). Until the respective mod authors address this change, all mods that add tags to the game will not work with this version. If you are experiencing crashes due to this, please downgrade Steamodded temporarily.
1- Your Xmult gain is actually 1 instead of the .25, try swapping those two's values
2- Your loc_vars returns a value that doesn't exists in its config called Xmult_gain, which explains the nil
3- card.ability.extra.Xmult = card.ability.extra.Xmult + 1 should have the 1 replaced by card.ability.extra.Xmult_mod (or Xmult_gain whichever you end up using)
4- In the return of the calculate function, X_mult_mod should be Xmult_mod instead
ok give me a sec to try out these in, I'll be back
How do you destroy a card in the hand? I tried using SMODS.remove_from_deck, but it crashes with a nil value.
if context.joker_main then
-- Get random card from hand
local dCard = pseudorandom_element(G.hand.cards, pseudoseed('gluttony'))
sendTraceMessage(dCard.name, 'TRACE')
-- Destroy card
SMODS.remove_from_deck(dCard, false)
return {
message = 'Consumed Card',
colour = G.C.RED
}
end
what's the difference between X_mult_mod and X_mult_gain, and are they interchangeable?
No not really they're just variable names if used in extra
It's just that usually people use "Xmult" for the Xmult gained by the joker and "Xmult_mod" for the modification given to Xmult if it's a scaling joker
If the variable names don't match, the returned vars in loc_vars won't find said variable value
am I going crazy or does the boss.max on blinds not get used anywhere?
So Xmult for the base mult (Baron is 1.5 Xmult) and Xmult_mod is for scaling Jokers (Vampire is 1Xmult then every enhanced card is +.25 Xmult_mod)
It's just naming convention, call it the_xmult_i_give_to_the_og_xmult if you want lol
The normal Tag Cards will be for #1210976027036352582
oh K
oh true lol, so there aren't any hard coded names for stuff like that?
The random one is #1318248620125851749
indeed it is an unused field
Only inside the extra table yes
ive been thinking
remember ro-balatro
what if i made a remake?
just improved it and such
ro-balatro?
Sometimes jokers have a self.ability.x_mult defined or something like that, but it's annoying to work with
The roblox mod
oh
What if we just had one mod that recreates some of the big mods from 0.9X Steamodded that isn't updated
we need to check the context type too now right?
IT WORKS NOW THANK YOU
does anyone know where I can find all these properties?
Most of them (if not every of them) are in game.lua
Thank you
@frosty dock also should the set_ability be passing self through it too?
G.E_MANAGER:add_event(Event({
func = function()
if G.GAME.hands_left == 1 then
print("1 HAND LEFT!!!")
end
end
}))```
Anyone know why this isnt printing anything
Hello, I'm adding a simple Joker to test this out but it's just not working 😦 Anyone knows what I'm doing wrong? Thanks
MyJokers.lua
-- Import utility functions
local utils = require(SMODS.current_mod.path .. "/MyJokers-utils")
-- Create an atlas for cards to use
SMODS.Atlas {
key = "MyJokers_atlas",
path = "MyJokers.png",
px = 71,
py = 95
}
-- List all Joker files here
local joker_files = {
"enamored_joker",
}
-- Load and register Jokers using the utility function
for _, filename in ipairs(joker_files) do
local joker = utils.load_joker(filename) -- Load the Joker table
SMODS.Joker(joker) -- Register the Joker
end```
MyJokers-utils.lua
```local utils = {}
-- Helper function to load all Joker files
function utils.load_joker(filename)
return require(SMODS.current_mod.path .. "/jokers/" .. filename)
end
return utils```
enamored_joker.lua
```SMODS.Joker {
key = "enamored_joker",
loc_txt = {
name = "Enamored Joker",
text = {
"Played cards with",
"{C:hearts}#2#{} suit give",
"{C:mult}+#1#{} Mult when scored",
}
},
config = {
extra = {
s_mult = 5,
suit = 'Hearts'
}
},
rarity = 2,
pos = { x = 0, y = 0 },
atlas = "MyJokers_atlas",
cost = 7,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true,
soul_pos = nil,
loc_vars = function(self, info_queue, center)
return {
vars = {
center.ability.extra.s_mult,
center.ability.extra.suit,
}
}
end,
calculate = function (self, card, context)
if context.individual then
context.other_card:is_suit(self.ability.extra.suit) then
return {
mult = self.ability.extra.s_mult,
card = self
}
end
end
}
would you be able to share the rest of the code?
see if changing self.ability and center.ability to card.ability works
It gets loaded properly ingame aswel
yeah the problem is that the code is only that
Ah 😭
in a json file aswell
ah
If you're just running this at the top of your file, the event will be cleared when the run is started
it does, but I just noticed it doesn't actually pass through the tag... oops
yeah that's what I meant 😂
Ah, how would I resolve this exactly
run it at a later point
probably knowing what your goal is would help with where you want this to run
Just trying to print smth when I have 1 hand to figure out how stuff works
that's all
you can add the prop no_delete = true to your event to keep it around
telephone
I should maybe change the rings to a more pleasing color, I may just make it orange or blue
Thanks I tried that but the Joker does not appear at all in the Jokers collection and the mod isn't in the mod list
orange would look great
on this bg atleast
Do you have a header or metadata file? Need one of those to init the mod
not sure how to help from here sorry
also if you want you can use DebugPlus and then run eval <code> in it's console for messign arounf with stuff
cc @obsidian jungle
Thank you :)
np thanks for the help
the ModdedVanilla example in Steamodded doesnt have one and it works, I dont have them
It does actually
I'd recommend reading this https://github.com/Steamopollys/Steamodded/wiki/Mod-Metadata
Oh you meant that
Its there I had removed it due to message length
--- MOD_NAME: MyJokers
--- MOD_ID: MYJOKERS
--- MOD_AUTHOR: Me
--- MOD_DESCRIPTION: Adds leveled up Jokers of existing ones
--- DEPENDENCIES: [Steamodded>=1.0.0~ALPHA-0812d]
--- BADGE_COLOR: c7638f
-- Import utility functions
local utils = require(SMODS.current_mod.path .. "/MyJokers-utils")
-- Create an atlas for cards to use
SMODS.Atlas {
key = "MyJokers_atlas",
path = "MyJokers.png",
px = 71,
py = 95
}
-- List all Joker files here
local joker_files = {
"enamored_joker",
}
-- Load and register Jokers using the utility function
for _, filename in ipairs(joker_files) do
local joker = utils.load_joker(filename) -- Load the Joker table
SMODS.Joker(joker) -- Register the Joker
end
Oki
I was looking for a tutorial like that, thanks for sharing the link 😄
I'd also recommend checking the tutorial videos of this thread https://discord.com/channels/1116389027176787968/1307744498360520805
you were hella right
No way Ness' father
that pretty neat
Quick question, any way to wait in lua, I know that in roblox it's wait()
Balatro uses delay(x)
Ah, thank you
Thanks 👏🏽
I've heard very good things about that thread
ok but genuinely that vid helped me a lot
G.E_MANAGER:add_event(Event({
func = function()
while true do
if G.GAME.hands_left == 1 then
print("1 HAND LEFT!!!")
end
print("Code ran")
delay(10)
end
end
}))```
Tried to add a listener but my delay isnt delaying
i wonder if this opinion is unbiased
I pretty sure this never exits the while loop? also G.E_MANAGER stuff needs to have a return true at the end
Thats the intention. I want a listener that listens the entire game.
events are usually blocking and repeat by themselves
Pretty sure you'd need to inject in whatever lowers the hand left
yeee, lemmie test some stuff
ok now I have art for all my jokers except the food suit ones which I am totally not gonna procrastinate on
OK, till after playing around with it a little more, it turns out that the X_mult and X_mult_mod are switch and renaming design in the extra table, doesn’t fix it
I’ll watch them in the whole code tomorrow again thank you
Sorry it didn't fix it, hopefully you get it right next time 👍
I mean the mod still work’s indented but X_mult modifiers X_mult_mod instead of the other way around
Oh
Neat art! What are the effects?
Swap the values in loc_vars maybe
Wait is this the food joker one
I think I have a video that displayed all of them gimme a sec
I'd need to see the modified full code again
oh wait I didnt notice you asked for only one of em
x2 chips if hand does not contain face cards or 10s
x2… chips 🤨
why not just xmult it’s literally the same and maintains the integrity of the game 💔
the vid doesnt use the json but I made it work now (kinda, it crashes on startup lol)
I originally edited the source code directly but it was not optimal for updates. Im trying to adjust with steamodded now, thanks for the suggestions
I guess ill change it to xmult
new docs just dropped
actually nvm i need to remind myself to not listen to literally everyone
Aura on fire with the steamodded docs
also, wait
isn't Tag a Center?
no
it behaves like a center in certain ways
but it can't actually extend Center because well.. tags just aren't quite centers
ok so im tryna make smth that works like Splash and its saying that scoring hand is nil, is there anything I'm missing?
card_eval_status_text isn't working for whatever reason?
now what's left
- Stake
- Seal
- Challenge
- Sticker
- DollarRow
- DeckSkin
why do we need DollarRow again
not sure why it wouldn't work, it does everything the exact way it's programmed, including rolling all of the other cards except for itself, but for some reason, it's so fucked up with eval status 😭
i like barely care honestly it's more of an aesthetic thing at this point
even when it was working it was laggy for some reason which is also hella weird
maybe i should put all of the other logic in an event manager or something?
because that code is in G.FUNCS.evaluate_play, not in a Joker's calculate
ah
why can i never have anything even slightly basic work when im coding
i cant seem to load files
relatable
real
trying to get the left file to load the right one
why
it returns as function
that's how it works though 😭
also do assert(SMODS.load_file("path/to/file.lua"))()
that one
ok it sorta works
im starting to remember why i abandoned robalatro in the first place lol
What's the assert for?
try using SMODS.eval_this instead maybe? less chances to mess up, though I don't see any issues at a very quick glance
properly error when an issue occurs during loading instead of silently failing
(I'm still not sure why that isn't default behaviour)
ooo
i will!
is it literally the same function
Interesting
basically, but formatted better
is there anything else i have to change or do i just do the exact same thing
oh nvm i found it in the api
it shouldn't silently fail either way since you can't call a nil value, it's just for better debugging behavior if things do go wrong iirc
these are examples from my own code
elseif context.ending_shop and not context.repetition and not context.game_over and not context.blueprint and not context.individual then
-- cannot use return, possibly not supported from this context?
SMODS.eval_this(card, {message = "+2", colour = G.C.MULT})
elseif context.selling_card and context.card.area == G.jokers then
card.ability.extra.mult = 0
-- cannot use return, possibly not supported from this context?
SMODS.eval_this(card, {message = localize("k_reset"), colour = G.C.MULT})
oh cool thanks
I'd argue that returning nil is equivalent to silently failing
nyope still nothing???
not my point, it will still fail if you try to call it
assert ensures you get proper error messages instead of some 'attempt to call a nil value'
weeeeird
not my point either, why do I have to ask for the error message
feels like I'm back to coding in C
you might have some way of handling not having loaded the file correctly, in which case you can handle that
if I throw you a crash if things go wrong, it's on you to catch it first
dude this is so weird wtf
it prints fine to the console, but it will NOT fucking do the eval at all
but Lua has exception handling 😭
where are you calling this function?
it's common practice in lua to build these sorts of functions in a way where they can be thrown directly into assert
this is it grabbing the key of the card in the same logic by instancing itself
i'm just getting pissed off that it isn't doing anything
it potentially matters, yes
this is what load does, and SMODS.load_file is supposed to be a drop-in replacement for it
it'
it's not in the card logic, if that's what you're asking
this is separate logic since i'm using a custom function to add a custom button to my card which this is handling
said custom button
key = "enamored_joker",
loc_txt = {
name = "Enamored Joker",
text = {
"Played cards with",
"{C:hearts}#2#{} suit give",
"{C:mult}+#1#{} Mult when scored",
}
},
config = {
extra = {
s_mult = 5,
suit = 'Hearts'
}
},
rarity = 2,
pos = { x = 0, y = 0 },
atlas = "MyJokers_atlas",
cost = 7,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true,
soul_pos = nil,
order = 3.1,
loc_vars = function(self, info_queue, center)
return {
vars = {
self.ability.extra.s_mult,
self.ability.extra.suit,
}
}
end,
calculate = function (self, card, context)
if context.individual and context.other_card:is_suit(self.ability.extra.suit) then
return {
mult = self.ability.extra.s_mult,
card = self
}
end
end
}
I'm trying to understand but the key is very much there
literally ALL of the logic on this button works EXCEPT for the eval text and it's pissing me off
like there's no way i have this fucked up
SMODS.eval_this(card, {message = "Nothing to roll!", colour = G.C.RED})
is this not exactly how it's formatted???
is this the only joker you're defining?
it's almost 100% that your card value isn't actually a card
hence why I asked to see where you call the function
I was afraid that that'd be the reason
big sigh
local utils = dofile(SMODS.current_mod.path .. "/MyJokers-utils.lua")
-- Create an atlas for cards to use
SMODS.Atlas {
key = "MyJokers_atlas",
path = "MyJokers.png",
px = 71,
py = 95
}
-- List all Joker files here
local joker_files = {
"enamored_joker"
}
-- Load and register Jokers using the utility function
for _, filename in ipairs(joker_files) do
local joker = utils.load_joker(filename)
SMODS.Joker(joker)
end
Yes for now
i mean
yeah see
whatever man i'll just throw it in chat
you're not actually returning anything from the file
d4 = function (card)
if #G.jokers.cards-1 == 0 then
print("Nothing to roll!")
print(card.config.center.key)
SMODS.eval_this(card, {message = "Nothing to roll!", colour = G.C.RED})
return true
end
SMODS.eval_this(card, {message = "Roll!", colour = G.C.MULT})
local count = #G.jokers.cards
local counter = 1
for i=1, count do
if G.jokers.cards[i] ~= card then
local rarity = G.jokers.cards[i].config.center.rarity
rarity = (rarity == 4 and 4) or (rarity == 3 and 0.98) or (rarity == 2 and 0.75) or 0
local is_soul = false
if rarity == 4 then
is_soul = true
end
local c = create_card('Joker', G.jokers, is_soul, rarity, nil, nil, nil, "wbin")
c:add_to_deck()
local temp = G.jokers.cards[i]
G.jokers:emplace(c)
temp:remove()
G.jokers:remove_card(temp)
table.insert(G.jokers.cards, i, table.remove(G.jokers.cards,#G.jokers.cards))
end
counter = counter+1
if counter > count then break end
end
WrenBind.can_roll.d4 = false
return true
end
It was written before SMODS converted to lovely meaning there was some annoying boilerplate and overrides when adding a row on the dollar screen.
you're calling SMODS.Joker in the file then calling it again on the return value of the file
and yes i DO check that this is the card if you see the card.config.center.key
Lovely fixes this so just thanos snap it (EXCEPT keep the negaive dollar portion, that's actually good).
aight
`return {
key = "enamored",
loc_txt = {
name = "Enamored Joker",
text = {
"Played cards with",
"{C:hearts}#2#{} suit give",
"{C:mult}+#1#{} Mult when scored",
}
},
config = {
extra = {
s_mult = 5,
suit = 'Hearts'
}
},
rarity = 2,
pos = { x = 0, y = 0 },
atlas = "MyJokers_atlas",
cost = 7,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true,
soul_pos = nil,
order = 3.1,
loc_vars = function(self, info_queue, center)
return {
vars = {
self.ability.extra.s_mult,
self.ability.extra.suit,
}
}
end,
calculate = function (self, card, context)
if context.individual and context.other_card:is_suit(self.ability.extra.suit) then
return {
mult = self.ability.extra.s_mult,
card = self
}
end
end
}`
Thanks, did this instead
triple backtick for an actual full codeblock
local me = nil
for i=1, #G.jokers.cards do
if (card == G.jokers.cards[i]) then
me = G.jokers.cards[i]
break
end
end
print(me.config.center.key)
this also prints j_wrenbind_d4
```lua
you_can_make_real_code_blocks_like_this()
```
yes but I got tired of copying pasting that character xD
lowk so pissed off about this not evaluating correctly 😭
it is like. solely aesthetic at this point that has no reason to not be working
i even made it go through all of the jokers in the hand to find itself and then call itself and that did literally exactly the same thing
next to 1 I have \ and |
i'll just try SMODS.find_card
I dont even have the character to make "not equals" in lua 😮💨
oh that's fun
is there LITERALLY no way to make text appear outside of calculate?
istg tarot cards do this ALL the time
time to go look at the actual code ig
ok
i figured it out
not entirely sure what to snap, anything still in here that should go?
function alert_no_space(card, area)
G.CONTROLLER.locks.no_space = true
attention_text({
scale = 0.9, text = localize('k_no_space_ex'), hold = 0.9, align = 'cm',
cover = area, cover_padding = 0.1, cover_colour = adjust_alpha(G.C.BLACK, 0.7)
})
card:juice_up(0.3, 0.2)
for i = 1, #area.cards do
area.cards[i]:juice_up(0.15)
end
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.06*G.SETTINGS.GAMESPEED, blockable = false, blocking = false, func = function()
play_sound('tarot2', 0.76, 0.4);return true end}))
play_sound('tarot2', 1, 0.4)
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.5*G.SETTINGS.GAMESPEED, blockable = false, blocking = false,
func = function()
G.CONTROLLER.locks.no_space = nil
return true end}))
end
``` this is 100% what i need
that would make sense seeing that the ` and ~ are on the same key for me 🤣
gosh 🙄
technically the function i wanted is attention_text
let's see if it works
fucking hopefully man i want to move onto actually working on today's dice
not me with a custom keyboard putting these on the outer column of my right index finger
ooh, fancy!
You can set a scale in the function parameter
it's kind of not in my symbol layer though, i moved it to my diacritics layer because I ran out of space in the other one lmao
i mean ` is kind of a diacritic character right
The string.find lines w/ "payout_arg" and anything tied to above_dot_bar
Rest should be fine
Is it possible to decide the order of a new joker? or does it automatically put it after the last
I hope
i got it to work this just sucks
The default scale for card_eval_status_text is 0.7 btw
they're ordered by when they're loaded, this conveniently groups vanilla and each mod together in the collection
no it covered the entire thing
also i can't use card_eval_status_text
What
Yea
anyway i figured it out
there's no* way for you to change this
-# * except with lovely patches
makes sense
altho for my purpose having them next to each other woud've been better
is there some kind of lovely patch or smth I grab so my consumables can be kept when taken from a pack
most I can find is cryptid's code cards but idk if I should just take this whole thing
Yea they use a lovely patch to do that
There's also Pokermon that does it if you need another ref
Pretty sure they mean the "reserve" button?
oh
oh i misread
ah whoops
is there a way to make my sound have multiple different values it picks from randomly built-in or do i have to add that myself
so uhhhhh, why cant balatro find the atlas for my consumables?
i made a class that adds the atlas but it really doesn't like me
oh, interesting one
when extending the class, it doesn't add any mod prefix
so you'd need to add it manually in this case
just the mod prefix
pretty sure someone brought that up before 🤔
i don't see you using SMODS.ConsumableType here but I assume you also have that set up?
oh god i need ot redo the art lol
extending SMODS.Consumable is at most for convenience
yes
ok good
theres going to be some commmon behaviors between gears
mainly the multi-use system
lmao
multi-use is actually properly supported by smods now (this is what i was trying to say above when i misunderstood the question)
How do I delay the add_joker to when the return message shows up? Currently, it adds the joker right when a hand is played:
if context.joker_main then
-- Copy joker
add_joker('j_JG_hydra', 'negative', true, true)
return {
message = 'Hydra created',
colour = G.C.FILTER,
card = card,
chips_mod = card.ability.extra.addAmnt,
mult_mod = card.ability.extra.addAmnt,
}
end
oh btw, is there a way to put a calculate funciton into a class, and then add to that calculate function in objects created from it?
yes
how?
define a new calculate function on the object and call Class.calculate(self, card, context) inside
nevermind, that was stake prefixes not attempting to prefix the key #💻・modding-dev message
was that ever fixed? 🤔
i don't remember that, but the code (at least in game_object.lua) for stakes was last modified in september
unless I'm misunderstanding the issue though, it's not set to not do prefixes somewhere-?
I'll quickly try to create a small example
is there an easy way to access all of the registered global sounds for my mod?
actually nvm i like what i have
oh nvm i see what that is
the way above_stake tries to get the stake it needs is weird
your solution actually prevented the mod prefix from being applied because it already existed, so that part does nothing. only prefixing above_stake was ever needed
there's probably a better solution to that
I think I made it not prefix it so you can put it above other mod's stakes
but we can probably add an extra flag in there for that situaton right?
nothing prefix_config can't solve
should probably be done using prefix_config yeah
also gonna failsafe the crash by making sure the stake actually exists
understandable errors are always nice
yay i love bringing back all my balatro modding rage
testing your changes, only to realize you never hit save
real
also anytime you make changes having to fix 7 different syntax errors
also what's with applied_stakes while we're breaking stuff
it has the same behavior of just adding the class prefix
uhhh hold on
also throw prefix_config on it?
yeah
something something consistency
yep, it's another change of default behavior, but better to do it now than never
this is why we should have done more docs much sooner, this wouldn't go unnoticed as much
I realised this later too haha
I guess changing the above_stake to include the mod prefix would've also worked
#💻・modding-dev message
appreciate it 👍
Is there a way to retrigger each played card x amount of times? Basically blueprint, but greater than 1 time.
i think im doing it wrong
are you talking about playing cards and do you mean hanging chad,
or are you talking about blueprint and do you mean jokers
?
unless manipulating values that are direct entries in the joker table is somehow forbidden
because said values are not going down
at all
you probably shouldn't be doing both : and passing self
ok
yeah you don't want to pass SMODS.Gear as the first arg here
Yeah, like how Hanging Chad works, but with all cards in the played poker hand.
looks like its both the former and the latter
also this self is the prototype, not the card. even card.currentuses won't save properly, so you should have it on card.ability
you can have a config var in extra to be sure, or safeguard with or 0
try looking at the basegame code for hanging chad and e.g. seltzer, and https://github.com/Steamopollys/Steamodded/blob/main/example_mods/Mods/ExampleJokersMod/ModdedVanilla.lua
btw Aure you nuked a smidge too much, adding this patch back should fix negative dollars missing from the cashout
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "local r = {n=G.UIT.T, config={text = localize('$'), colour = G.C.MONEY, scale = ((num_dollars > 20 and 0.28) or (num_dollars > 9 and 0.43) or 0.58), shadow = true, hover = true, can_collide = false, juice = true}}"
position = "at"
payload = '''
local r
if i == 1 and num_dollars < 0 then
r = {n=G.UIT.T, config={text = '-', colour = G.C.RED, scale = ((num_dollars < -20 and 0.28) or (num_dollars < -9 and 0.43) or 0.58), shadow = true, hover = true, can_collide = false, juice = true}}
play_sound('coin3', 0.9+0.2*math.random(), 0.7 - (num_dollars < -20 and 0.2 or 0))
else
if num_dollars < 0 then r = {n=G.UIT.T, config={text = localize('$'), colour = G.C.RED, scale = ((num_dollars > 20 and 0.28) or (num_dollars > 9 and 0.43) or 0.58), shadow = true, hover = true, can_collide = false, juice = true}}
else r = {n=G.UIT.T, config={text = localize('$'), colour = G.C.MONEY, scale = ((num_dollars > 20 and 0.28) or (num_dollars > 9 and 0.43) or 0.58), shadow = true, hover = true, can_collide = false, juice = true}} end
end'''
match_indent = true
kk
and my config
is this the default use function and how are you calling it?
okay actually there's one more, i forgot about unlocked_stake
yeah, default
also omg galdur really should just be base steamodded
i cannot beleive i have lived without it for so long
decks and stakes are so effortless
uh now you removed both self and :
you need SMODS.Gear.use(self, card, area, copier)
oop
speaking of galdur, these stake changes might break it a little bit
sad
really?
I don't think they should do
there's some places where it uses applied_stakes being prefixed the way it currently is
lines 410, 663, 994 in galdur.lua, that looks to be all though
it might break the save stickers though
Can you have multiple returns for a Joker in different contexts?
anyways there's actually 3 different prefix_config options just for stakes now
should there be some umbrella option that covers as a default for all of them?
Like a return in context.repetition and one in context.joker_main?
yeah you can return in an if statment
is there a reason you would want to use one but not the others?
pretty sure that update was specifically for a compat change with cardsleeves so if you're not using that you don't need the update 😅
it justs needs the 'stake_' .. bit removing right?
it might be the memory leak fix too
you could need to refer to a vanilla stake in one place but not another, so there's reason for it to be separate
yep
you might have one of these
not sure how useful a unified default option gets in the general case tbh
how do i get my config to actually, like, save
😭
i have it working but i can't figure out how to make it save the values
it just reverts when i open it again
are you looking at the right location btw?
sobs
oh not that config
whar
don't mind me
oh nw
this ui shit is a HEADACHE
tbh this is at the bottom of my list of shit i'm focusing on rn with this mod
god speaking of which i should start an actual github repo
usually this works fine for saving once you exit the mods page, given you're writing to your mod's config table
I'll push it up without such a feature, if anything breaks it's because this is a breaking change, I'll be off to bed xd
i tried that
the first thing u said
anyway i'm fuggin hungry
not that like. anyone asked
how are you referencing your config file?
and are you using the custom tab or the config_tab? 🤔
um
i based it on cryptid tbh
Got Ortalab editions working with Aurinko
@mellow sable this might also break cryptid fyi
ok
i call Wrenbind_config = SMODS.current_mod.config at the top of the file
though not majorly i don't think. it shouldn't try to double prefix applied stakes
it doesn't seem to break galdur
not surprised if it only breaks pink stake
i'm not saying it's impossible i fucked it up i just dunno what i did wrong? i have ref table and ref value
and the rest of the stakes are fine once that's changed
let me try with cryptid stakes
is the config ref_table not just the config itself?
or should it be the key?
like this is my config file ```
return {
["IsaacSaveFileNum"] = 1,
["IsaacVersion"] = "Repentance+"
}
ref_table should be Wrenbind_config assuming you don't nest tables
it could be because you aren't using the config tab
is there a better way to identify a card's enhancement than ability.name?
card.config.center_key
card.config.center_key
nope nvm
and tthats just the m_key variety?
hey gamers, im very new to this so bear with me but is there a way to read the total chips and mult (before jokers) of the played hand inside the calculate function of a joker?
{
n=G.UIT.ROOT, config={align = "cm", padding = 0.05, colour = G.C.CLEAR},
nodes={
create_option_cycle({
label="Choose Your Isaac Save File",
min=1,
max=3,
ref_table=Wrenbind_config,
ref_value="IsaacSaveFileNum",
options={1,2,3}
}),
create_option_cycle({
label="Which Version Are You Playing?",
min=1,
max=3,
ref_table=Wrenbind_config,
ref_value="IsaacVersion",
options={
"Repentance+",
"Repentance",
"Afterbirth+",
"Afterbirth",
"Rebirth"
}
})
}
}
oh no it does break galdur
current state of the Balatro Mod Manager. Not many changes to see, but a lot of backend-work (stable functionality) was done.
nice
i think a good idea would be to let you save different mod lists that you can install and uninstall
i end up being turned away from stuff like dimserene's modpack because i dont know where i can put my current modlist
It will be supported on Linux / Windows / macOS
great
any guidance? 🥺
are you using SMODS.current_mod.config_tab or not
use the config_tab
(cryptid probably does it differently because they want a fancy name for their tab)
iirc thats hand_chips and mult?
is that inside context?
Does anyone here know how to make a paper texture :>
(This isn't just blueprint to the left if you're wondering)
i'm getting "attempt to index field color (a nil value)" for some reason
local wrenbindTabs = function() return {
{
label = "Isaac Settings",
chosen = true,
tab_definition_function = function()
return {
n=G.UIT.ROOT, config={align = "cm", padding = 0.05, colour = G.C.CLEAR},
nodes={
create_option_cycle({
label="Which Version Are You Playing?",
ref_table=Wrenbind_config,
ref_value="IsaacVersion",
options={
"Repentance+",
"Repentance",
"Afterbirth+",
"Afterbirth",
"Rebirth"
}
}),
create_option_cycle({
label="Choose Your Isaac Save File",
ref_table=Wrenbind_config,
ref_value="IsaacSaveFileNum",
options={1,2,3}
}),
}
}
end,
}
} end
SMODS.current_mod.config_tab = wrenbindTabs
is this not right?
they would just be globals
use the inner tab_definition_function instead
revamped all the card enhancing gears, and made slingshot one of them because oh my god slingshot was just annoying and uninspired and also really really bad
wdym
just use that u mean?
yeah
oh i see it
you might also want to use https://github.com/Steamopollys/Steamodded/wiki/SMODS.config_tab
hmm i've just completed my config implementation and it just ✨ worked ✨
granted mine were only bool values but should be the same concept
🤷♀️
is this not. exactly this?
SMODS.current_mod.config_tab = function()
return {
n=G.UIT.ROOT, config={align = "cm", padding = 0.05, colour = G.C.CLEAR},
nodes={
create_option_cycle({
label="Which Version Are You Playing?",
ref_table=Wrenbind_config,
ref_value="IsaacVersion",
options={
"Repentance+",
"Repentance",
"Afterbirth+",
"Afterbirth",
"Rebirth"
}
}),
create_option_cycle({
label="Choose Your Isaac Save File",
ref_table=Wrenbind_config,
ref_value="IsaacSaveFileNum",
options={1,2,3}
}),
}
}
end
did i fuck up somewhere or am i going insane
how are you checking if it saved
don't you need to save it in a different func
you don't need a different function
i am checking if it saved by going from config to additions and then back
epicbossmusic = SMODS.current_mod
epicbossmusic.config_tab = function()
return {n = G.UIT.ROOT, config = {r = 0.1, align = "cm", padding = 0.1, colour = G.C.BLACK, minw = 7, minh = 2}, nodes = {
{n = G.UIT.R, config = {align = "cl", padding = 0}, nodes = {
{n = G.UIT.C, config = { align = "cl", padding = 0.05 }, nodes = {
create_toggle{ col = true, label = "", scale = 0.85, w = 0, shadow = true, ref_table = epicbossmusic.config, ref_value = "boss_regular_enabled" },
}},
{n = G.UIT.C, config = { align = "c", padding = 0 }, nodes = {
{ n = G.UIT.T, config = { text = "Regular Boss Music", scale = 0.5, colour = G.C.UI.TEXT_LIGHT }},
}},
}},
}}
end
and it reverts back
mine's mostly UI guff
yeah iunno dude mine's a lot different though
you have to press the back button to save it
is your ref_table and ref_value is correct it should store it
yes
doesn't create_option_cycle need a callback to store it's result
oh yes that's probably it
finally, an answer that isn't "do you know how to program or are you making shit up"
speaking of, what would i even do for that
ig i could just reference the game code
G.FUNCS.cycle_update = function(args)
args = args or {}
if args.cycle_config and args.cycle_config.ref_table and args.cycle_config.ref_value then
args.cycle_config.ref_table[args.cycle_config.ref_value] = args.to_key
end
end
oh
eh, we (atleast, I) don't know you and you were doing things different from the wiki, our first questions will definitely be "are you sure you know what you're doing"
