#💻・modding-dev
1 messages · Page 65 of 1
Huh
hi, i need a bit of help
i'm making a tag that's gonna give you a pack of a new consumable type i'm making and i don't know how to do that and vanilla game code confuses me
thanks for your help
local console = {
object_type = "Tag",
atlas = "tag_cry",
pos = {x=3, y=2},
config = {type = 'new_blind_choice'},
key = "console",
min_ante = 2,
loc_txt = {
name = "Console Tag",
text = {
"Gives a free",
"{C:cry_code}Program Pack"
}
},
loc_vars = function(self, info_queue)
info_queue[#info_queue+1] = {set = "Other", key = "p_cry_code_normal_1", specific_vars = {1,2}}
return {vars = {}}
end,
apply = function(tag, context)
if context.type == 'new_blind_choice' then
tag:yep('+', G.C.SECONDARY_SET.Code,function()
local key = 'p_cry_code_normal_'..math.random(1,2)
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
card.cost = 0
card.from_tag = true
G.FUNCS.use_card({config = {ref_table = card}})
card:start_materialize()
return true
end)
tag.triggered = true
return true
end
end,
}
If this helps, here's how Cryptid does it for Code cards
it forces the info box to contain those specific values
update on magic trick: got the main cardarea api code required for the project working and had a first test on the joker retrigger api branch
retrigger api greatly simplifies what I have to do to get all the contexts working on the new system, although unfortunately it comes at the cost of making it so I have to override smods' override file which is pretty icky
not having to implement red seal does wonders though
it's a shame lovely development has been this slow
it really should be possible at this point to patch steamodded files
the only solution is to code it yourself 
I do wonder how would you patch a steamodded file specifically
cuz those are loaded with NFS not lovely
my idea was to hook into lua_load and specify the chunk name

realistically
can't you just use my solution
would have the same effect
a bit more annoying to add replacements
do packs not automatically emplace to the correct area or am i doing something wrong?
local tarot_booster_one = Ceres.CONFIG.jokers.enabled and Ceres.CONFIG.jokers.tarot.enabled and SMODS.Booster{
key = "tarot_normal_1",
kind = "Joker",
atlas = "booster_atlas",
pos = {
x = 0,
y = 1
},
config = {
extra = 3,
choose = 1
},
cost = 6,
weight = 0.2,
discovered = false or Ceres.CONFIG.misc.discover_all,
create_card = function(self, card)
local key = get_tarot_joker()
local _card = create_card(nil, G.pack_cards, nil, nil, true, nil, key)
return card
end,
ease_background_colour = function(self)
ease_colour(G.C.DYN_UI.MAIN, G.C.GREEN)
ease_background_colour{new_colour = G.C.GREEN, special_colour = G.C.BLACK, contrast = 2}
end,
loc_vars = function(self, info_queue, card)
return { vars = {card.config.center.config.choose, card.ability.extra} }
end,
group_key = "k_tarot_joker_pack"
}```
im assuming the latter
but idk what
fixed it
SMODS.Booster rework is about to be merged and makes this not your problem anymore (note: still working on some edits)
rn you would have to emplace the card yourself
at least I think that's what that is
You need to return the created card, which isn't happening here
_card is created card but returns card
Booster pack rework has you return a table instead and SMODS.create_card does it for you.
(Also makes taking ownership of packs for card effects doable!)
does it fix particles?
(I'm assuming particles are broken and I'm not doing it wrong because the colours seems to not make a difference)
It's generated in a separate function instead of hard-coded
I grabbed my example from the PR, I guess that version isn't in main branch?
yippee
oops
i'm going to send that back in 2min
loc_vars = function(self, info_queue)
info_queue[#info_queue + 1] = {key = 'p_kais_evo_pack_mega', set = 'Evolution', vars = {G.P_CENTERS.p_kais_evo_pack_mega.config.extra}}
return {}
end,
apply = function(tag, context)
if context.type == 'new_blind_choice' then
tag:yep('+', G.C.SECONDARY_SET.Spectral, function()
local key = 'p_kais_evo_pack_mega'
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
card.cost = 0
card.from_tag = true
G.FUNCS.use_card({config = {ref_table = card}})
card:start_materialize()
G.CONTROLLER.locks[tag.ID] = nil
return true
end)
tag.triggered = true
return true
end
end
i'm making a tab to create a pack for a new comsumable type i'm making, i actually have this code but it doesn't work* can someone help me please ?
*the tag is created but never activates
(sorry for the failed message just before)
why do i need to remove the context check ?
'cause it works with it
I don't think it's necessary, iirc the apply function is only called under the context you define in the config
I could be wrong though, I haven;t done a huge amount of tag work yet
yup it works without it
So if I use message = localize {} do I always need to put that type = 'variable', key = 'something' in there? And are there specific keys I'm supposed to use?
I also see some things using card_eval_status_text and I don't know the difference
Yeah, I think I just don't understand the key part of localize
thats the localization func
if you can understand it that hats off to you lol
ive got no idea what any of it means
my suggestion would be look at examples in the code
ik theres ones for chips mult dollars etc
I have!
what are you trying to localize?
i think when you return a message it just calls card_eval_status_text with that message
might be wrong
I just want one variable popping up that says the mult its giving you, and a different variable when it gains mult
So I need, assumbly, two different keys? a_mult and something else?
yeah
you can call card_eval_status_text with message upgrade
if you want a custom message you can throw it in the misc dictionary of the localization table
and then just use localize(key)
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex'), colour = G.C.RED})
you can put in your own message and colour
message can just be
message = 'string haha'
is there a function for debuffing cards other than the blind one?
or do i just set debuff to true
oh set_debuff
Yeah, I won't do this because that can't take a variable saying how much mult it gains
Oh?
Oh that's way easier
.. is a life saver
.. just adds vars and strings together?
.. combines the left and right side together as string yeah
only works on integers and strings though
out of interest, do you have much experience in any other languages?
I have some experience in C# from doing Unity projects
to be fair, changing types like that is kind of a weird thing for an operator to do
unless your name is javascript
in which case, type conversion goes weeeeee
fair enough
i mean my only experience before lua was python 💀
in python you also have to do str(...) + str(...) unless you're using f strings or something
man I miss += in lua
+= is very nice
it pains me every time i have to do x = x + 1
quick question everyone, is there no way to use another mod's atlas? 🤔
After 4 years of JS i missing a lot of stuff in lua tbh 
i wouldnt know
Just for one card?
I miss += so much
I guess yeah?
the atlas exists in SMODS.Atlas.obj_table but I can't seem to actually use it
prefix_config = {key = false} I believe
and then put the full atlas key for the atlas
wait
not key
prefix_config = {atlas= false}
I can't tell when G.GAME.current_round.hands_played is updated, I have a guy that gives +10 Mult for each hand you've played this round, and I was just updating it each time you played a hand, but I realized if you get it off judgement or it's debuffed then it won't increment like its supposed to
Trying to use the hands_played thing but it updates at a weird time?
there is (just realised I'm late)
just taking a guess here but does it not just update after the joker are triggered?
It always seems 1 off, and then when something is added mid-round, it doesn't seem to update it correctly
I have a +1 thrown on as a slapdash solution, but I don't like it
1-off makes sense if it's updated after the jokers are triggered (DNA for example checks if current_round.hands_played == 0)
Huh. Weird
it increments after the cards are discarded from the play area
when something is added mid-round, it doesn't seem to update it correctly
what do you mean by this?
I have a line where if you add it to deck it sets the value, but the Mult seems to stay at 0 until you play another hand
Which is not intended
If you get it with 1 hand left, it should be giving you +30 mult or whatever
Weird. Are you sure that that line runs?
Fair question, let me check
can you share the code?
You're so right, the add to deck was in my calculate
That is not where that goes
Ok! It works perfectly now
The only weird thing is it "upgrades" right before the round ends and it resets at end of round, but maybe I can check rounds_remaining to stop that, if that exists
when does it reset?
if context.end_of_round and not context.individual and not context.repetition and not context.blueprint then
if G.GAME.blind:get_type() == 'Boss' then
card.ability.drawn = {0,0}
return {
message = localize('k_reset'),
colour = G.C.RED
}
elseif G.GAME.blind:get_type() == 'Small' then
card.ability.drawn[1] = drawn
else
card.ability.drawn[2] = drawn
end
end```
might be useful
It resets around there, but it upgrades after jokers calc, so it upgrades and then resets, which is functional but looks silly
ah
what context do you upgrade in?
if context.after and not context.game_over and not context.blueprint then card.ability.extra.mult = (G.GAME.current_round.hands_played + 1) * card.ability.extra.addmult return { message = '+' .. card.ability.extra.addmult .. ' Mult', card = card } end if context.end_of_round and not context.repetition and not context.game_over and not context.individual and not context.blueprint then card.ability.extra.mult = 0 return{ message = "Reset", card = card } end
The two lines, top for upgrading, bottom for reseting
you could check in context.after if its the last played hand i guess
and not upgrade if it is
so I am curious if anyone has information on being able to change more than the face cards with the new customize deck option. Is it possible to add code to make it possible to both view and change the numbered cards using the customize deck? (sorry for repost I posted this question in the modding chat which I think is the wrong channel?)
Yeah, I was thinking that
local tat_spades = Ceres.CONFIG.run_modifiers.decks.enabled and SMODS.Back{
key = 'tattered_spades',
unlocked = false or Ceres.CONFIG.misc.unlock_all.enabled,
discovered = false or Ceres.CONFIG.misc.discover_all.enabled,
atlas = 'backs',
pos = {
x = 0,
y = 1,
},
config = {
vouchers = Ceres.CONFIG.consumables.vouchers.enabled and {
'v_cere_overflow_norm',
} or nil,
discards = -100000
},
loc_txt = {
name = "Tattered Deck of Spades",
text = (Ceres.CONFIG.consumables.vouchers.enabled and Ceres.CONFIG.perks.enabled) and {
"Start run with:",
'Deck of {E:1,C:spades}Spades{},',
'{E:1,C:attention,T:v_cere_overflow_norm}Overflow{} voucher,',
'{C:attention}3{} {E:1,C:green,T:cere_advantage}Advantage{},',
'{C:attention}0 {E:1,C:red}Discards',
} or (Ceres.CONFIG.consumables.vouchers.enabled and not Ceres.CONFIG.perks.enabled) and {
"Start run with:",
'Deck of {E:1,C:spades}Spades{},',
'{E:1,C:attention,T:v_cere_overflow_norm}Overflow{} voucher,',
'{C:attention}0 {E:1,C:red}Discards',
} or (not Ceres.CONFIG.consumables.vouchers.enabled and Ceres.CONFIG.perks.enabled) and {
"Start run with:",
'Deck of {E:1,C:spades}Spades{},',
'{C:attention}3{} {E:1,C:green,T:cere_advantage}Advantage{},',
'{C:attention}0 {E:1,C:red}Discards',
} or (not Ceres.CONFIG.consumables.vouchers.enabled and not Ceres.CONFIG.perks.enabled) and {
"Start run with:",
'Deck of {E:1,C:spades}Spades{},',
'{C:attention}0 {E:1,C:red}Discards',
}
},
apply = function(self)
G.E_MANAGER:add_event(Event({
func = (function()
for k, v in pairs(G.playing_cards) do
if not v:is_suit('Spades') then
v:start_dissolve(nil, true, 0.00000001)
end
end
if Ceres.CONFIG.perks.enabled then ease_advantage(3) end
return true
end)
}))
end,
}```
the apply func
its not the cleanest thing because if youre destroying cards you can see them dissappear
but ive heard that its gonna be neatened up soon to apply those before anything is visible
the code above is fully functional tho
I am almost entirely new to this lua coding, this is code for creating a deck itself?
ah, I was refering to the recently added crossover stuff
all good man
yeah that im not sure about sorry
darn, I'm sure it'll be figured out soon. I was able to add more custom textures to face cards, just wish I could do the same with the numbered cards (and especially the ace)
you could also do the upgrade in context.before depending on how you word your joker
im sure its possible and there are examples on here
if you word it as mult for played hands then i think it deincrements the hand count before any calc
yeah you can probably find a mod that does it and just take the code and do your own textures
Yeah but that's a different design
"+10 Mult per hand played this round (Currently +0)"
i think that makes sense upgrading before tbh
it takes away the hand as soon as you press play
I want it to be after, for balance
no worries then
I don't want to compromise balance bc of programming mostly
I think the best fix I can think of is getting the chips you score, and comparing those to the required chip amount of the blind to see if you won
And then not running the upgrade during that
thats a pretty good idea
is there any easy way to affect the rates of my jokers spawning?
i wonder how to let them become circles
where is stored the chip score I made at the end of the blind?
(reading back through what I've missed) health issues, my fault for not communicating it. we're moving ahead now that things have stabilized a little bit
feels good to be back though, I missed ya'll's insanity
card_eval_status_text keeps saying "ERROR" when it's supposed to be displaying a message here, am I missing something obvious?
You got it, boss
Yup, that did it
Thanks!
Ok, that's a lot of bugs ironed out =w=
so for magic trick what I'm thinking: since I'm already overriding smods systems for the basic functionality, it would make sense for me to standardize the way playing cards are calculated to use the same systems as joker retriggering (and in turn, update joker retrigger api to be more consistent with how playing cards do retriggering) and after that I'll just need to go through the contexts and make them use the magictrick cardarea api
DebugPlus doesn't matter but I just export all my files as lovely modules so I can just require them which is a bit messy. Iirc Saturn just looks for its mod name in a folswr but technically this could lead to it finding the wrong foldee (I haven't looked at how it's implemented). Really what we need is a way for lovley to tell us what direcoty we have
I ended up going with a ceres-like approach where I just try looking for a bunch of possible names
Flower Pot just does what Cryptid/Talisman does but I don’t really even need to know the name or position of the mod folder.
It’s just there in case I need it
Which mod adds 999 game speed?
Nopeus iirc
Nopues but 999 speed was split into a different setting
Welcome back, hope you're doing alright
Is there a way to just add Blueprint's compatibility UI to a joker via code? I was peeking at it the code earlier
you can put a main_end UI object in your loc_vars or use generate_ui function for more granular control
main_end should be good enough for compat display
are there any know issues with alerts being displayed for the blinds button in the collection menu even tho theres no alerts on any individual blinds?
id be kinda surprised if i managed to mess with it
i think I've seen that be reported
thanks, doing way better :-)
guys can I get a return from an event?
Where would it return to?
I've got this basic function to create a Joker
function UTIL.createJoker(key,edition,forced)
if POKE.Debug then
print("POKE: Creating Joker: " .. key)
end
G.E_MANAGER:add_event(Event({
func = function()
if forced or (edition and edition.negative) or (#G.jokers.cards < G.jokers.config.card_limit) then
local _card = create_card('Joker',G.jokers, nil, nil, nil, edition, key)
_card:start_materialize()
_card:add_to_deck()
if edition then
_card:set_edition(edition)
end
G.jokers:emplace(_card)
else
if POKE.Debug then
print("POKE: Cannot create Joker: "..key.." because there is no room")
end
end
return true
end
}))
end
but it uses add_event
i would love to make it so that the function returns the _card
then the function would be blocking
what's that?
the function wouldn't be able to return until the card is created
which is... the opposite of what add_event is created for?
the main goal is to have a function like this:
function evolvePoke(OLD)
destroyJoker(OLD)
createJoker(NEW)
displayMessage{card = NEW, message = 'Evolved!'}
end
i have already done the first two, I need to do the last
put the local var declaration outside of the event?
i can try
inside the event there is a check for if there is space available
if there is not I have to destroy the card?
Can’t the message be inside the first event?
How do I check if the card in the collection is drawn? (I'm assuming the transparency of the card also uses the thing I want)
oh, sorry, I meant what activates the shader
deck view menu?
greyed?
transparent ones yup
thanks!
but also check if this is the same in steamodded
cuz steamodded overrides this menu
ah, basically same
not ((SUITS[suit_map[j]][i].area and SUITS[suit_map[j]][i].area == G.deck) or SUITS[suit_map[j]][i].ability.wheel_flipped)
I'll simply check for card.greyed
but its def limiting it to 4 chars
That makes the thing
Isn't it always limits it to 4 chars???
thats what i thought
I was assuming that's what it does
also fine, but keep in mind it will only be a thing for deck view menu
because it creates copies of cards
Yeah, I need it for the deck view menu specifically
you want PREFIX: loyalty instead of MOD_PREFIX: loyalty
thank you
no prob, i ran into the same problem lol
it was driving me mad lol
it's definitely a little odd that it's the only field that doesn't have MOD_ in front
its just matching balatros inconsistency i guess lol
i mean mod headers are probably being replaced anyways lmao
not sure of the exact format yet, but backwards compatibility to classic mod headers will be kept
with what?
cool
although i doubt itd be very hard to update the format of my mods
I think one of the bigger concerns is still working on older builds when the new format comes around
I'm gonna come up with some specification of json files that will be identical between mod loading and the mod index
Huge
as for older builds, I was thinking of dropping a beta release alongside it
also maybe auto-update for steamodded itself
can the config file please specify which file to load so that we don't need headers and also make it optional so lovely mods can have the config just for metadata
also question could we add some common code config stuff to the file
like where the mod icon atlas is
also disable default conifg loader so it doesn't try loading my config.lua
yeah, surely that would be needed either way to avoid redundancy
yeah
sure (or move default config into the json file /j)
tbh default config should be a .jkr file so its miuch more obvious what's the default
if you are down to break every mod again
not sure about that since there's more information than just where the file is, i.e. the sprite's pixel size
it would be nice for the atlas to work if the mod can't load too
I would be fine specifying the options in the json
actually why not
good point
it can default to 34x34 (the usual tag dimensions)
some other config fields that would be handy, even if not used right away: source/repo/etc. for the plaace to get it. possible a second value for a download option zip
homepage (really any url the user can find about the mod at)
issues (url to post issues to)
repo I would definitely include in the format for integration with the index
speaking of, I noticed my auto-merge workflow doesn't work right because it can't run on forks with the permissions it needs
i need to rework it to actually use the automerge feature github has nowadays
Also if you want to go overwritng the versioning stuff,
Provides: id and version of something it provided. Other mods can require this. Useful for if I wanted to do something like provide a DebugPlusApi v1 and mods can depend on it, or if a mod is a drop in replacement for another.
that doesn't sound half bad
yeah I didn't invent the concept
drop-in replacements are worth considering especially in the context of an index where IDs are globally unique instead of wrt a user's mod list
I might also add some sort of check for the index where the filename has to match the ID specified in the file exactly
yeah
resolving deps might get a bit harder
probably could just be like x depends on y. These packages provide y, choose one
assuming you don't have a sutible one already
not looking forward to making all the UI around this ngl
yeah
I think I would just start with dep managment
then updates
then installing
dpe management would be user installs cryptid, and you can automatically grab talisman
updating would be what it says
then later worry about browsing mods
How can I make a card that appears in the pool that it isn't a part of? (like black hole appears in the celestial packs)
hidden = true and soul_rate = some_number
Also tbh I wouldn't have browsing right away if you can just install mods from a git url or zip url
and how to specify where it will appear?
black holes do not appear in tarot packs, aren't they?
it will always appear when generating a card for its own set, plus you currently can specify one soul_set (defaults to Spectral) that it will also appear as
it's not a great system because has no flexibility, gonna come up with something else soon
So if I understand correctly if I have a spectral card, I can put soul_set = 'Tarot' for it to also appear in tarot packs?
(and the hidden/soul_rate args too)
I tried it, it seems to work! Thanks!
It sounds like something ObjectType can handle (although there's so much other spaghetti nonsense I need to deal with before I can move back to that).
And here I thought adding rarity API was easy
oh yeah btw @frosty dock if you do end up just downloading zip files you can read them using this built in love method. https://love2d.org/wiki/love.filesystem.mount You could actually use this in place to load zips in the mods dir but lovely wouldn't be able to load them
imo lovely is too essential for that
I'd rather just depend on git but tbf it inflates file size
i mean you can clone without history :eh:
git should be tiny in most cases
I think the biggest issue is mods only in like discord or some other platform and users without git installed
i don't mean git itself
my .git folder for steamodded is 20x the size of the rest of the files combined
I mean the .Git folder
Actually I forgot mods have images and images and git dont play that well
yeah git is terrible with history of binary files
my mods folder is casually 300 megs 💀
You could still download zips and then just remove the old mod directory and unzip and move the unzip dir with Lovey's built in tool
lovey
To be fair I think my celedte mod directory is a couple gigs and it doesn't even use git
fair
Cursed mixed method where you unzip only the lovely files and then just stick the zip for the rest
This would require steamodded understanding how lovely works
Also if we support zips natively we can eliminate double directories by just not unzipping them that way
isn't there a way to ship/download a portable version of git?
Probably but I think on Windows its messy and you would need a seperate thing for macos
ew i can't test that
Oh idea for the config file folder name prop that can be a string as the expected folder name (so lovelt mods don't implode) and then it could also be an object with a name prop for the string and a required bool so that way mods could be disbked if they require that folder name but can't get it for some reason
alternatively lovely just lets mods know what dir they're in because they don't bother to find their own folders
Well yeah but lovekt is being super slow moving
is there a way to see if a card is a consumable?
(self.ability.set == "Tarot" or self.ability.set == "Planet" or self.ability.set == "Spectral") isn't very mod friendly
hold on a sec
self.ability.consumable or something like that
ah yeah, perfect, thanks guys
So I am reworking a Joker called PJA 10 on my mod. What i've changed it to do is give a "1 in 2 chance to create either a Wheel of Fortune or Aura card when any Booster Pack is opened." Now, my issue here is with the way I should go about writing the Joker's description text. The way the Joker will function is that when you open a Booster Pack, there is a 1 in 2 chance you will receive a card or not, then, if you do receive a card, it will be either a WoF or Aura . I want to write this in a way that is simple yet understandable for the player to read.
what's wrong with the description you have right there?
I think the player might expect to ALWAYS receive either a WoF or Aura card based on how it reads
"either" doesn't seem necessary, change "any" to "a"
Also check jokers that have booster pack in their descs for references
I used Hallucination as my reference and believe it or not, this is how it is worded
keep the "any" then I suppose
I still think it's clear enough btw
Yea other than that it's fine
Ok, i'll leave it alone then, thanks y'all
in theory I can make archive loading a thing
at face value it doesn't seem that complex
is there a way to affect the is_suit function kinda like smeared joker does
i cant seem to find any info on custom enhancements, is there any guides/documentation?
currently trying to use cryptids echo cards as a basis
I had asked about them
See @hushed cradle and @wintry solar
Although I don’t remember if Eremel’s was in a public repo
Read from here up to the PR talk at least
Im very new here so apologies for the potentially dumb question. I copied the riff raff code but cant seem to reduce the number of jokers generated, it always makes 2 common jokers. What am I doing wrong here?
calculate = function(self,context)
if context.buying_card then
self:start_dissolve()
G.E_MANAGER:add_event(Event({
func = function()
local card = create_card('Joker', G.jokers, nil, 0, nil, nil, nil)
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
return true
end}))
end
end
why is calculate(self, context) its suppsed to be (self, card, context)
nice thank you
I can help out, what do you need?
can i make the left look like the right?
got it
why is the white on both of these off-color
I get that they're based on dg&d, but the off-white on cards in there is just the artstyle of the game
ill change it to balatro colours
somebody should make a mod that lets enhancements have multiple possible appearances bcos having cards with various different imperfections is cool
oh that's a very cool idea
it can work with editions too
with shader vars it could be possible to make every card have different "seed" generated when it's applied, to affect the visuals
function process_perk_loc_text(ref_table, ref_value, loc_txt)
if not loc_txt then return end
if loc_txt.play then
ref_table[ref_value..'_play'] = loc_txt.play
end
if loc_txt.discard then
ref_table[ref_value..'_discard'] = loc_txt.discard
end
end```
uh
so im not sure how ref_table is nil
process_loc_text = function(self)
G.localization.descriptions[self.set] = G.localization.descriptions[self.set] or {}
process_perk_loc_text(G.localization.Other, self.key, self.loc_txt)
end,```
am i being dumb?
is it not G.loc.Other?
oh is it lowercase
that still crashes
once my recent PR is merged 🙏

yeah no crash this time
function loyalty_on_play_from_rows(card)
local key = card.config.center.key .. '_play'
local vars = card.config.center.vars or nil
local desc_nodes = {}
local t = {}
if G.localization.descriptions.Other[key] then
print('ben')
localize{type = 'other', key = key, nodes = desc_nodes, vars = vars}
for k, v in ipairs(desc_nodes) do
print(tostring('v'))
t[#t+1] = {n=G.UIT.R, config={align = "cm", maxw = maxw}, nodes=v}
end
return {n=G.UIT.R, config={align = "cm", colour = empty and G.C.CLEAR or G.C.UI.BACKGROUND_WHITE, r = 0.1, padding = 0.04, minw = 2, minh = 0.8, emboss = not empty and 0.05 or nil, filler = true}, nodes={
{n=G.UIT.R, config={align = "cm", padding = 0.03}, nodes=t}
}}
end
return nil
end```
would anyone know why this isnt working?
its giving me this
but its printing ben
but its not printing v
which ive just realised is a string 💀
so desc_nodes is empty?
but the loc entry def exists
what are you trying to do
think ive figured it out dw
just need to remove the bottom box
ive got this
but idk why its still making the box
oh
right yeh
im acc stupid
is there a way i can do this without overwriting anything
Put the bottom one as your standard description perhaps?
great idea
On discard: burn seems like it can fit into 1 line just fine
very true
so the desc_from_rows func isnt working apparently
function process_perk_loc_text(ref_value, loc_txt)
if not loc_txt then return end
local ref_table1 = G.localization.descriptions.Other
local ref_table2 = G.localization.descriptions.Perk
ref_table2[ref_value] = {}
ref_table2[ref_value].name = loc_txt.name
if loc_txt.play and not loc_txt.discard then
print('1')
ref_table2[ref_value].text = loc_txt.play
elseif loc_txt.discard and not loc_txt.play then
print('2')
ref_table2[ref_value].text = loc_txt.discard
elseif not (loc_txt.discard or loc_txt.play) then
print('3')
return
else
print('4')
ref_table2[ref_value].text = loc_txt.play
ref_table1[ref_value..'_discard'] = {}
ref_table1[ref_value..'_discard'].text = loc_txt.discard
end
end```
this code is a bit messy ik
its printing 4
so its the else that runs
one is written in one way, latrer new param is needed, written in other way
generate_ui = function(self, info_queue, card, desc_nodes, specific_vars, full_UI_table)
if card.ability.shred then
info_queue[#info_queue+1] = {set = 'Other', key = 'loyalty_shred'}
elseif card.ability.burn then
info_queue[#info_queue+1] = {set = 'Other', key = 'loyalty_burn'}
end
if not full_UI_table.name then
full_UI_table.name = localize { type = 'name', set = self.set, key = self.key, nodes = full_UI_table.name }
end
localize{type = 'other', key = self.key..'_play', nodes = full_UI_table.desc_nodes, vars = self.loc_vars and self:loc_vars(card) or {}}
if specific_vars and specific_vars.debuffed and not res.replace_debuff then
target = { type = 'other', key = 'debuffed_' ..
(specific_vars.playing_card and 'playing_card' or 'default'), nodes = desc_nodes }
end
end,```
can anyone tell me why its not putting my thing in the desc nodes
mb lol
yeah, that;s my guess too
ah
generate_ui = function(self, info_queue, card, desc_nodes, specific_vars, full_UI_table)
if card.ability.shred then
info_queue[#info_queue+1] = {set = 'Other', key = 'loyalty_shred'}
elseif card.ability.burn then
info_queue[#info_queue+1] = {set = 'Other', key = 'loyalty_burn'}
end
if not full_UI_table.name then
full_UI_table.name = localize { type = 'name', set = self.set, key = self.key, nodes = full_UI_table.name }
end
full_UI_table.main = localize{type = 'other', key = self.key..'_play', nodes = full_UI_table.main, vars = self.loc_vars and self:loc_vars(card) or {}}
if specific_vars and specific_vars.debuffed and not res.replace_debuff then
target = { type = 'other', key = 'debuffed_' ..
(specific_vars.playing_card and 'playing_card' or 'default'), nodes = desc_nodes }
end
end,
if G.localization.descriptions.Other[self.key..'_play'] then
full_UI_table.main = localize{type = 'other', key = self.key..'_play', nodes = full_UI_table.main, vars = res.vars or {}}
end```
is there something wrong with this?
it looks like im just overwriting main with nothing
doesn't localize return nil if you also pass a nodes?
and insert the localized stuff into nodes instead?
in the generate ui function for steamodded centers it does fulltable.name = localize(stuff, nodes = fulltabe.name
so idk why that would work but this wouldnt
oh, you're right... weird
not really possible to spawn the exact tutorial jimbo, but it's possible to use the same functions the card_character uses
awesome
nice >_>
i want a talking joker 💀
this gif is like 3 months old already probably
but I promise he will come back
xd
It is possible
I mean it won't be a Joker that way
card_character doesn't have the same functions as a joker card
@tepid eagle I referenced Bunco's code which is basically the same as the game's actual code, but I added some extra functionality to change colors and stuff
Although IIRC I didn't use them
The quoted message is an example
Can I add debuff to a card which can be purged by any tarot suit-changer or enhancer?
oh, sorry I didn't realise you wanted it as a playable card.
It's not me who asked lol but yeah
Oh
Yes it is
I don't think there's an easy way to do both
You could edit how suit changers and enhancers work by explicitly granting them those capabilities, but it likely wouldn't support modded consumeables
{C:green}
thanks
also how do i make the description affectable by any luck changing cards?
i tried G.GAME.probabilities.normal*1 then #1# but that doesn't seem to work
You want G.GAME.probabilities.normal to multiply the denominator
Although in the tooltip you would have the "1" from "1 in x" be G.GAME.probabilities.normal
That's how the game reads
what? nvm
before we continue
"1 in x" becomes "2 in x"
you mean the numerator right
you mean numerator.
the first one is #1#, the second one will be #2#, etc
don't have multiple #1#s
You could have the base value be something like "2 in 5", which you'd write as "2*p in 5", but then you can simplify to 5/(2\*p) in order to write math.random() < 5/(2\*p) or whatever, where p is G.GAME.probabilities.normal
Hence I think of it in terms of denominator
Because the LHS contains the random variable and the RHS contains all the constants
well, all the deterministic quantities
or you could just multiply the right side by p
Naturally you could swap it around, but this is how Balatro is written, so I think it'll be easier to interpret thunk's code if I explain it like this
which is what you are doing
Left
The p would be multiplying the random variable
wait let me show more of my code
Right I see what you meant
Actually if the random variable is a standard uniform distribution as it should then the RHS should be the inverse of what I wrote so you're actually making a check that matters
So it was in fact the numerator
An example from my code:
do i have to make more G.GAME.probabilities.normal*1's?
This is how I allocate the values
....
G.GAME and G.GAME.probabilities.normal or 1 is because you can look at the tooltip in the Collection
What part are you confused about?
the way you do it
why can't i just assign more G.GAME.probabilities.normal*1 as #1#, #2#, #3# etc.
I mean, I do assign G.GAME.probabilities.normal as #1# and #4#
As I said, G.GAME and G.GAME.probabilities.normal or 1 is there because if you try to look at a tooltip outside of a run (such as in the Collection), then G.GAME doesn't exist, which means G.GAME.probabilities.normal doesn't exist
how
I mean, in the same way you assign other values to #1#, etc.
why do you have a duplicate variable? 1 and 4
Because I didn't create a variable to store then reuse it
I don't think thunk does for Lucky Cards
Oh I see what you mean
Yeah thunk does do that
Although I do like how reusing the variable makes it easier to read
so i could do that the whole time
I'm pretty sure the probabilities table also exists in the collection
ok
also how do i loop for balatro
(im reworking voucher vodka)
got it working now
(1 in 8 is supposed to stay like that)
what does it mean?
what are the base game checks ignored?
Context: steamodded wiki / SMODS.Center
I think only if you access the collection during a run
nah it definitely works
check out get_current_pool to see what it skips
they all exist before starting any run
Outdated DebugPlus mentioned
Pretty sure they’re no longer ignored.
what changes?
None of that seems to use G.GAME.probabilities.normal
This page just wasn’t updated
I mean depends how old your version is and what branxh but the update broke the display on the top left and DebugPlus had a fix for that
main branch, commit from Aug 12 20:59:08
Hmmm, testing it it does seem to work, but I do remember wondering why did thunk do it and finding out when exactly it’s not defined
But I don’t remember at what point that is
Basiclly just fix the HUD, remove DT messages and performance HUD
i tried to read that and I got a stroke
please answer this question and i'll understand how this works
if I take ownership of Cavendish and do
in_pool = function(self)
return true
end,
it will spawn if I didn't get Gros Michel extinct?
thanks I understand now
How do i loop
what is the reason for two colours for consumable types?
when you use the secondary_colour?
lua 5.4 manual mentioned
With absolutely no knowledge of coding, modding especially, was there anywhere I could look for modding commissions?
Not that I’m aware of but out of curiosity what do you have in mind?
Is it currently possible to have multiple lovely files per mod?
Yes
Sweet! How can I do that? I'm assuming they're just need to be .toml files?
They need to be in a folder named "lovely" iirc
lovely.toml and lovely/<name>.toml
awesome, thanks!
anyone got a link to SDM_0's post about the colab? i cannot seem to be able to find it?
uuh yea thanks so much!
how to make a consumable only appear if satisfying a condition using smod.consumable api🤔
PSA: I'm going to be on vacation starting tomorrow until Wednesday, September 18th. Expect no contributions from me, to Steamodded or otherwise, during this time frame. I may respond to requests or merge/review PRs I deem important enough at will, please ping or DM me on Discord if you think this is needed. I'll be sure to respond but it might take a while.
have a good vacation!
ty
retrigger api is out and I'm still working on balatroAP so can't go full force on magictrick
enjoy your vacation :)
ty
🤔
is there a way to change the whole description of a card? like replace the whole loc_txt variable of a card on the fly
card.config.center is reloaded when continuing a run and different cards with same key share a same config.center so you can't store new description in center. my implementation is to store it in card.ability and inject into generate_card_ui to display from card.ability
okay now my problem is figuring out how the hell this function operates lmao
im tryna make tarot cards change description
okay wait
the fool is confusing me here
im seeing how it handles it's badge of last used tarot
but like
nvm
i found full_UI_table.info
okay nvm im still confused.
oops
im trying to figure out how this thing works
okay i found
text
time to see the parent path
oh
my.
god.
Role.Draw_Major.Role.Draw_Major
Some are definitely more unique and challenging to make than others
https://app.milanote.com/1SLi0Q1kdLoQ3B?p=hFVo8hVGc0J
some of those seem rather simple to set up, and then you have the ZAP!
Why the line 1917 might crash? Crashlog tells that the value inside pairs() is nil: #1220084296346501201 message
I don’t think it should ever be nil but I’ll do some investigating
For now it happened only to one person afaik
initially Master Hu was gonna say "Selling this during a blind plays the highest scoring hand possible using cards from your deck" but like yeaaaah how would that happen lol
This happened to me too
I think it either doesn't like having multiple paths of stakes, or it doesn't like your stakes
But that's just a guess
Actually mine has get_deck_win_stake in the description
can someone help?
add to deck doesnt have those parameters
does context.ending_shop work?
what do you mean, does it work
mb
i was going to ask if it usually works
because im trying to use it for a joker that creates planet cards at the end of shop
and it doesn't do that
how does your code look?
wait i just noticed something off about it
brb
im trying to make it imitate blue seal
your function isnt being assigned to anything
is it be cause of the positioning?
instead of doing x = 1 you just did 1
oh
assign your function to something
wait wheres this one
calculate = function(self, card, context)
I'm not actually sure if this is a post for here or #⚙・modding-general , but is there anyone who could give me some pointers on how on Earth I'm meant to debug a card being created with a nil centers
since i don't know where it's coming from
have you got the error?
uhhhh let me play a run until it crashes rq
it says it's in betmma but that's only because it has set_abilityref hooked
dang that's a lot of hooks
i have a lot of mods
the issue is without the center i can't even tell what it's trying to spawn
my guess is jen's almanac as the culprit
...
(20) Lua global 'create_card' at file 'Jen.lua:10207' (from mod with id jen)
Local variables:
_type = string: "Joker"
area = table: 0x2a649a90 {click_offset:table: 0x2a649578, static_rotation:false, shuffle_amt:0, parent:table: 0x251e7518 (more...)}
legendary = nil
_rarity = nil
skip_materialize = nil
soulable = nil
forced_key = nil
key_append = string: "sho"
(21) Lua global 'create_card_for_shop' at file 'functions/UI_definitions.lua:866'
Local variables:
area = table: 0x2a649a90 {click_offset:table: 0x2a649578, static_rotation:false, shuffle_amt:0, parent:table: 0x251e7518 (more...)}
forced_tag = nil
total_rate = number: 37
polled_rate = number: 8.95806
check_rate = number: 0
rates = table: 0x276e0448 {1:table: 0x2a61e0b0, 2:table: 0x2a61e110, 3:table: 0x2a61e170, 4:table: 0x2a61e1d0 (more...)}
(for generator) = C function: builtin#6
(for state) = table: 0x276e0448 {1:table: 0x2a61e0b0, 2:table: 0x2a61e110, 3:table: 0x2a61e170, 4:table: 0x2a61e1d0 (more...)}
(for control) = number: 1
_ = number: 1
v = table: 0x2a61e0b0 {type:Joker, val:20}
...
either that, or possibly some lovely hook at functions/UI_definitions.lua:866
the nil center only appears in the cryptid hook though
hmm, could possibly also be aurinko or cryptid since they seem to... hook?
I've seen this trace before
this is a different version of cryptid to the one I ahve though
true, but Jens/Aurinko could've possibly given the wrong arguments to cryptid's create_card
the annoying thing about debugging this is that it isn't a consistent crash
ugh that sucks
like i can't get it to happen 100% of the time, it just happens at random in shops
does continuing the run not throw you the same error?
it does, but it's getting to where the error shows up
(also the game usually just closes itself within like 4 seconds after it crashes)
oh? that's weird lol
i know half the time the actual on-screen log is cut off like two lines in so i need to go grab it out of lovely/log
create_card doesn't require a center though
can you checkk line 1557 of cryptid.lua?
it's stable when it isn't doing this
trying to debug that is a nightmare
90 if you add the steamodded and the lovely ones 🤣
(i updated cryptid and now it's crashing on boot on its own so uhhhhhh)
this one is a separate problem
I mean with the cryptid
It's likely get_current_pool is failing.
Oh no
Or maybe it's this?
center would be a table at this point not a key
didn't firch also have this issue that randomly got fixed...
If I had to wager it'd be this line, judging by the following parts of the stacktrace
local card = Card(area and (area.T.x + area.T.w/2) or 0, area and (area.T.y) or 0, G.CARD_W*(center and center.set == 'Booster' and 1.27 or 1), G.CARD_H*(center and center.set == 'Booster' and 1.27 or 1), front, center,
{bypass_discovery_center = area==G.shop_jokers or area == G.pack_cards or area == G.shop_vouchers or (G.shop_demo and area==G.shop_demo) or area==G.jokers or area==G.consumeables,
bypass_discovery_ui = area==G.shop_jokers or area == G.pack_cards or area==G.shop_vouchers or (G.shop_demo and area==G.shop_demo),
discover = area==G.jokers or area==G.consumeables,
bypass_back = G.GAME.selected_back.pos})
sorry, that one
I mean, it's the exact same code as what Thunk uses so I doubt it?
are u sure? or isn't it just taking a key, and writing the table back to the same variable?
I imagine it would be a key before it's reasigned to a table
i would poke more at this but the latest build of cryptid just crashes on boot if you don't have an existing savefile so i can't even keep testing it
to me it looks like either the joker pool (for a randomly selected rarity) is empty somehow or the chosen joker's key (?) isn't present in G.P_CENTERS for some reason
actually, shouldn't pseudorandom_element crash if given an empty pool?
I mean my cryptid file doesnt have anything remotely relevant at that line, so without that it's kind of just throwing ideas at the wall
line 1557 of my cryptid is also useless, but all the following traces have card_initref etc so I'm guessing it's a Card(...) call, and the only one I could find was the one I pasted above
yeah, center is nil there, but it shouldn't be is the problem, so it'll be somewhere before that I think
I might know the issue
There's a section that tries to change the center from UNAVAILABLE to a valid key
Except it doesn't loop
So there's a chance that after trying to randomly pick from the pool it could land on UNAVAILABLE again
I see the section you're talking about, but that's a while loop for me?
I can't read
you could say you got... thrown for a loop
yes, but I was meaning the problem is letting center be nil by the time it hits that function
idk then just throw in a print in the file for center or something
If this is reoccurring.
Oh, yes, of course
Clearly center is not inside G.P_CENTERS[center] so center has to be invalid.
^ Agreed, I'd try to print center before it gets replaced/used as index in G.P_CENTERS
see what the key is
how do i set a type of consumable to be able to appear when same card exists (like showman joker)🤔
yeah
doesn't Center.in_pool have a duplicate section?
i don't know about it
in_pool(self) -> bool, { allow_duplicates = bool }
- Define custom logic for when a card is allowed to spawn. A card can spawn if
in_poolreturns true and all other checks are met.- (Subject to change)
in_poolignores base game checks, except disallowing duplicates.allow_duplicatesallows this card to spawn when one already exists, even without Showman.
Does anyone have an easy way to replace in game textures? I made some stupid sprites that I want to add into the game
the wiki on this is out of date, it respects base game checks now unless you specifically ignore them
I think I'm going insane but I want to add IVs to the Pokémon Info box
right below the Level, a little hexagon without all the text, just the picture
Is it safe to make mod about Pokemons? 
I have no idea how to draw that inside a text box
The dice joker mod died something similar doendt it?
i'll look into that
ok the mod uses pre-made assets and I wouldn't want to make a .png with all the 32^6=1,073,741,824 possible IV combinations
hey guys
is there a joker or something that creates a planet card of the highest level hand?
ill take that as a no
Telescope
thanks
if a wildfrost pokemon exists i don't see why not
The triangle is drawn, but the game doesn't continue
add_to_deck = function(self,card,from_debuff)
function love.draw()
love.graphics.setColor (1,0,0)
love.graphics.polygon("fill", 100,100, 500,100, 250,500)
end
end,
why are you redefining the draw function
Yeah overwriting love.draw means the game can't draw
If probably just add an event that doesn't end to draw each frame
At least for testing
if i don't it won't draw nothing
For the final thing I'd modify the draw function of the tooltip
It probably does but only for a single frame
oh
the things I have to do are:
- make it so the canvas in which the shape is drawn is inside the ui box
- make it last until the ui box is not shown anymore
and my knowledge of LOVE ends here
trigger = 'immediate',
func = function()
-- love.Grapgics code here
return false
end
}))```
Try that
Mobile written code so its probably wrong
why are you overriding love.draw
.
Does this work?
how could i like change small blind into a boss blind? 🤔
Yes and thats run every frame
but it draws nothing and the game doesn't continue when I press other buttons like Select blind
loc_vars = function(self, info_queue, card)
G.E_MANAGER:add_event(Event({
trigger = 'immediate',
func = function()
love.graphics.setColor (1,0,0)
love.graphics.polygon("fill", 100,100, 500,100, 250,500)
return false
end
}))
end,
I did some digging and it seems like you can hook your cards draw method to draw
Oh steamodded has a generate ui method I'd take a look at that too
guys all my stuff have sprites so why am i getting these errors
do you know how hooks work
yeah
you can hook draw function
love.draw
instead of overriding it
but it has to be outside event
cuz then it's just going to stack hooks
simplest way would be to have list with objects to draw in your hook
then with event you add object to that list
and later remove
when you no longer need to draw it
thats basically how most(all?) of the things render in the game. lol
You should be able to hook your cards draw function
You'll be able to access the card and tooltips position from there as well
dont know what the use case is, just explaining the idea
if they need to draw smth on the card, that makes sense
This is the idea #💻・modding-dev message
is there a way to change small blinds into big blinds? or vice verca
or change the ante's a final boss appears?
yeah
dont know details, but cryptid does change blinds
there's stake that allows showdown blinds appear at any blind
and any blind can be a boss blind
Stakes
finally did some work on magic trick tonight
got the joker_main step of eval to retrigger all of its events instead of just the joker effect (to stay consistent with how playing cards retrigger)
although through that i've found out that my cardarea api is extremely busted and i should like completely rewrite it
hmmm, something has broken enhancements that have always_scores
if something broke its probably retrigger api
I dunno, does retrigger api touch playing cards?
found it! ruby stake :D
I also added some edition API
hi, i have a small issue lately
i updated steamodded yesterday and since then i have this crash when i try to launch the game
when i look at the dumps it seems to be related in someway to my mod but i can't see what's wrong, can someone help me please ?
Update steamodded again
okay
still there
the error is here (you can see a red { ) but i think it's vanilla code so i don't understand
one thing i'm 100% sure is that it's not my code
@languid mirage is this the lovely clobber issue you were dealing with?
i'm going afk for 5min i'll tell you when i'm back, are you okay with ping ?
hold on this is the same issue I was having I think
okay i'm back
oh mine is a different line nvm
damn
pretty much yeah
can you show lovely logs
mods/lovely/logs
also what exact version of steamodded do you have? You can find in mods/steamodded/core/core.lua at the very top
has to be a mod not being up to date with latest steamodded
this patch is failing, which I didn't change
something else replaces this part
or does that happen with no other mods installed?
well i update steamodded and bunco at the same so first i thought it was bunco but nope it seems that it's my mod which isn't released yet
do you have any lovely patches?
what are those again ? (sorry it's been a bit since i haven't done stuff with lovely)
.toml files
only if you have any in state_events.lua
like this one
(target field)
in this specific case I think the only reasonable fix is to change this one to be a regex patch
and change priority to higher than 0
like 99 or whatever
oh no not regex
me and firch spent idk around a week just to make one regex work
but also
[ \t]* add this in front of the pattern
this will match the indent
in front of which pattern ? in the code or on the site ?
actually it doesn't matter in this case
but usually in front of the result you copy from the site
like that ?
yep
i have to change something else or it's good ?
hm
regex patches uses line_prepend instead of match_indent
so it should be line_preprend = true ?
line_prepend = ''
yeah
what does the target area look like?
in the dump ?
yeah
like that (injection starts at line 1660)
whats off the screen at 1653?
for i=1, #G.jokers.cards do
--calculate the joker after hand played effects
local effects = eval_card(G.jokers.cards[i], {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, after = true, callback = function(card, ret) effects = {jokers = ret}
if effects.jokers then
card_eval_status_text(card, 'jokers', nil, percent, nil, effects.jokers)
percent = percent + percent_delta
end
end
this is the whole stuff because it's big
how would i get a hand's total score from a joker?
and that is weird because i'm sure that i haven't touched that code
did you change the priority of your own patch?
yes
what did you set it to?
99 because i was told to
try 1
i was thinking about reinstalling the game but why not
add lua if G.GAME.modifiers.debuff_played_cards then end
to the top of your payload
still that f- error
wait a sec i'm gonna remove all my mods then readd them one by one to see which one is making this
okay so it's clearly my mod which creates that error
lemme see if I can juggle the smods patch to not require the block you're changing
hum what ?
change it back to pattern patch
cuz indent is probably scuffed
you have to re-add match_indent=true
actually nvm
I don't think indent matters
space is missing after then 😭
I love regex patches
but also do that ^ you don't need to keep it as regex
so i put in patch and keep the pattern like that ?
I've also fixed the smods patch
@stupid we can replace the patch at line 107 of joker_retrigger.toml with this if it helps solve future problems
[[patches]]
[patches.regex]
target = "functions/state_events.lua"
pattern = '''(?<indent>[\t ])*if effects.jokers then\n[\t ]*[A-z(,' .)]*\n[\t ]*[A-z =+]*_delta\n[\t ]*end\n[\t ]*end\n\n'''
position = "after"
line_prepend = "$indent"
payload = ''' }) end
'''
It gets around doing this jank ass solution for kaishi too
oof
can't you replace all that a-z regex with [^\n]*
or is delta somehow necessary
doesn't seem to work for me
.
oh I replaced wrong thing
cuz patch at 107 is different for me
works fine, thanks
will add it into my PR with other patch fixes
what does ^ do in regex?
not
oh
nah the A-z stuff is just to avoid having the entire line in there
I can actually reduce it further, hold on
as long as the _delta is there it'll be fine
and the double end
and the double new line
those parts make it unique in the file
the two A-z groups can be joined in that case
this also works
does that not clobber anything else?
nah, but is there a chance it might?
it could do with other patches I guess
I guess if we just want _delta and \n\n, can do this
does anyone have code that crashes the game
I have a mod that binds crashing the game to [
not what im looking for but funny concept
what's wrong with lua's error?