#💻・modding-dev
1 messages · Page 59 of 1
uhhhhhh im getting a weird issue
so i have a joker that has a chance to destroy played cards
it works just fine but it draws the destroyed cards back to the deck after destroying them
this ends up making "phantom cards" which cannot be played but do count to hand size
and i uh dont even know where to start on fixing this
I have no idea why I'm getting this error message when I'm not using juice_up in this Joker
if context.other_card.debuff then
return {
message = localize('k_debuffed'),
colour = G.C.RED,
card = self,
}
else
local cen_pool = {}
for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do
if v.key ~= 'm_stone' then
cen_pool[#cen_pool+1] = v
end
end
context.other_card:set_ability(pseudorandom_element(cen_pool, pseudoseed('ench_forest')), nil, true)
return {
message = 'Enhanced!',
colour = G.C.MONEY,
card = self
}
end
end```
Never mind, I fixed it by changing card = self to card = card
can i use in_pool for enhancements to stop them spawning on cards in standard packs?
Use SMODS.eval_this inside a for loop
why does this happen and how do i avoid it from happening
The misalignment?
ye
the same layout w/o the input boxes looks normal
its two columns with each text as a row
ok i figured it out
i had to wrap the text inputs into rows too
Throw some padding in there though my dude
ye
i love ui code
swag
rn the last bit of ui code left for now (the new connection status/goal ui) and then i'll be able to go back to working on actual features like challanges
also i wonder if this can be fixed
this happens when u press enter in any of the fields
its been doing this since before me
it doesnt break anything other than looking like that until you refresh the page so its not top priority
it doesnt seem like context.destroying_card works with probability?
i think if i make the callback function reset the window it should look fine
this is how it currently looks, if i take the other if statement out of comment it just doesnt function at all and never activates
calculate = function(self, card, context)
-- if context.individual and pseudorandom('minihakkero') < G.GAME.probabilities.normal/self.config.extra.odds and context.cardarea == G.play then
if context.destroying_card and not context.blueprint then
card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
return true end
-- end
end
Maybe check how Trading Card does it
trading card doesnt use context.destroying_card
what's it supposed to do?
its the same one i was working with prior, its just that i found a bug in it where the cards werent actually destroyed
how are you destroying the cards?
well first it was through the event manager, which removes the cards from the deck but not from the hand, so you end up drawing cards that dont exist to the deck
then in the most recent example it was through context.destroying_card which doesnt seem compatable with probability
that's not how contexts work
context is just a table of information that the game sends to calculations to determine what to do
well, for sure i cant seem to make it have an only 1/8 chance to destroy a card using that
do you have the event manger version you had?
calculate = function(self, card, context)
if context.individual and pseudorandom('minihakkero') < G.GAME.probabilities.normal/self.config.extra.odds and context.cardarea == G.play and not context.blueprint and not context.repetition then
local destroyed_cards = {}
destroyed_cards[#destroyed_cards+1] = context.other_card
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
for i=#destroyed_cards, 1, -1 do
local card = destroyed_cards[i]
if card.ability.name == 'Glass Card' then
card:shatter()
else
card:start_dissolve(nil, i == #destroyed_cards)
end
end
return true end}))
card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
end
end,
also why is not context.repetition not working?
i just tested it again and it was working at one point but now its not
calculate = function(self, card, context)
if context.individual and pseudorandom('minihakkero') < G.GAME.probabilities.normal/self.config.extra.odds and context.cardarea == G.play and not context.blueprint and not context.repetition then
.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
if context.other_card.ability.name == 'Glass Card' then
context.other_card:shatter()
else
context.other_card:start_dissolve(nil, i == #destroyed_cards)
end
return true
end}))
card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
end
end,
try this
I assume to change it to G.E_MANAGER?
oh yes
doesnt work, still adds blank cards to the deck
well, actually originally it didnt work, because destroyed_cards was a nil value, so i put in local destroyed_cards = {}
did that, blank cards are added again
hmmm
context.destroying_card does work to not add blank cards
destroying cards during any scoring context will create blank cards
and context.destroying_card must be used
calculate = function(self, card, context)
if context.destroying_card and pseudorandom('minihakkero') < G.GAME.probabilities.normal/self.config.extra.odds then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
if context.other_card.ability.name == 'Glass Card' then
context.other_card:shatter()
else
context.other_card:start_dissolve(nil, i == #destroyed_cards)
end
return true
end}))
card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
end
end,
right?
no wiat
im pretty sure i tried that but ill do it again
but also with context.destroying_card the event manager is unnecessary
calculate = function(self, card, context)
if context.destroying_card and pseudorandom('minihakkero') < G.GAME.probabilities.normal/self.config.extra.odds then
card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
return true
end
end,
I think this should work
unless you're smart like me (I have blank card removed during drawing to deck)
oh it works!
now i need to make sure that retriggers dont cause it to upgrade more than once
yep, thank you!
turned out to be way simpler than i thought, no event nonsense or whatever
random thought I just had but unable to test rn
what happens is you spawn a locked card outside of collection
like iirc it is possible because I did accidentally break archipelago's item system once, but would those locked items behave normally outside of looking weird
for some reason, this doesnt do anything unless the joker is in G.jokers and not in the cardarea i made
You’ll need to create your own calculation calls
its being called, but G.GAME.blind.chips is 0
rest in peace reverie cine card slot
yeah theres literally no spot i can put it in
maybe if i set the cardarea width to 0.001..... i could put it in the left of the bar....
What’s the new area for?
curses that can be purified for buffs
I’m not sure if enhancement pools are properly sorted or not yet
ah nws
for my weird enhanced cards ii can probably right a thing to have booster packs with cards with only those enhancements tho right?
im not too worried if theyre available in regular standard packs or using the illusion voucher tbh
in_pool needs some more work anyways, rn it disrespects all base checks
on consumable types or what
uh consumable types yeah
if i wanted my consumable type to be available in tarot packs for example
that just gets called from the inject function of each SMODS.Consumable with a matching set
you could use that to add to tarot pools, but that means it can always show up in place of a tarot
else you'd have to do something like omen globe does
thats probably better for what i want actually
what would i put as the center tho?
the center_pool?
ill see if i can find an example of it being used, i can probably figure it out better from that
any ideas what I'm doing wrong here? first time making a joker like this and it keeps crashing lol (crashes says it has something to do with line 66?)
So the joker im working on now, I want to give this effect: 1 in 2 chance to give either a Wheel of Fortune or Aura card when you open any booster pack. I currently have it coded properly to give a Wheel of Fortune card , but how would i add the chance for it to select between wheel of fortune AND Aura randomly?
if you have a chance in the config
like 0.5
then do pseudorandom to get a random number from 0 to 1
if its below the chance give wheel of fortune
if its above give aura
elseif context.after and not context.blueprint and not context.control_devil then
if pseudorandom('pochita') < self.config.woof_chance then
return {
message = 'Woof!',
}
end
end```
like this
config = {
mult_min = 16,
mult_max = 36,
x_mult_min = 1.1,
x_mult_max = 1.4,
x_mult_chance = 0.2,
chips_min = 57,
chips_max = 73,
chips_chance = 0.6,
money_min = 1,
money_max = 3,
money_chance = 0.2,
woof_chance = 0.7,
},```
i should be careful with wording this joker, bc what im trying to achieve is a 1 in 2 chance to give a card or not, and then if it gives a card then its either a WoF or Aura. So essentially its like Hallucination but when it hits, it chooses between 2 consumables
have you got it to have a 1 in 2 chance for wheel so far?
or just always give wheel
It currently has a 1 in 2 chance for a WoF yes
cool
then just pop in smth like this
should work perfectly
Ok 🙂
might be complicated for a beginner, but how would I do something like gros michel/cavendish? I want a joker that only appears after another joker of mine is eliminated by a spectral card (ankh/cryptid's gateway)
use yes_pool_flag and no_pool_flag in your joker
Has anyone been able to successfully use love threads? I just want to load in code from a module but it doesn't seem to like that
try using Lovely to inject the module instead?
This has been incredibly helpful for me, Cavendish is actually an example used in here as well.
No matter how I load the code in, the channels don't appear to be doing anything
thank you! I think I've managed to get it the pool_flag part done
now I just need to figure out how to make the trigger
how would I make this check for itself? For itself is about to be destroyed?
I found a "selling self" but have yet to find a "destroying self"
wait what
how did I do this, this is not doing what I thought I would do, I was just gonna test to see if the message I linked to it would send
every played hand is automatically destroying itself, that's actually kind of a cool effect, but how did
only scoring cards too? hmmm, I assume it's somehow linking the context to the previous individual context? maybe? I guess?
here's how the whole effect looks btw
Destroying card is for whether you should destroy the playing card or not, so you’re returning a table which equates to true so it destroys them all
huh, intresting
lol, thought it was just a "pre" version of cards_destroyed or something
@hushed cradle here’s an example
have you got any of the code??
Yes
GitHub
See if Disenhancements is public
If not ask them because I’m not home right now
iirc Disenhancements is public
cool thanks
Which things require Talisman support? Obviously blind chips, but what about ante?
blind and hand chips, base chips of poker hands
that's it
@wintry solar i have not found a solution to this issue and you seem to be the UI legend. would you have any ideas?
oh it's a remnant of the smods config stuff, if you open the collection it'll be fixed
theres a fix in a PR somewhere thats waiting to be merged
so its not my fault? 😭
no
great thank you LOL
wait, is it this one? seems to have been merged already
i am getting the exact same bug though, opening the collection solves it LOL
does anything else mess with the active mod?
I have a button in my mod's config that refreshes the main menu by using the go_to_menu() function. is this the wrong way to do this?
that sounds like it could be it
is there a better way to accomplish the same thing?
why do you need a button in your config to go to the main menu?
I need the user to specify a particular setting before I allow them to click the play button. The play button is disabled until they set this, then they click the main menu button to refresh the page, which updates whether the play button is clickable
I see
you could throw a reset to the active mod value in your button press function
What's the function for that?
also what would the effect be? I kind of like how it takes you back to the main menu when you click the button
whereabouts does the replace base card, no rank, no suit, always score actually work for smods enhancements?
is it possible to add those options to my own smods thing
can i patch a patch?
does lovely have priorities?
I think G.ACTIVE_MOD_UI = nil would do the trick
yes and yes
oh nice
This fixed it!! Thanks so much dude
can anyone help me out a bit please
im trying to get this text to say smth different
local perk_atlas = SMODS.Atlas{
key = 'perk_atlas',
path = 'perks.png',
px = 71,
py = 95,
atlas_table = 'ASSET_ATLAS',
}
-- taken from Disenhancement mod
SMODS.Perks = {}
SMODS.Perk = SMODS.GameObject:extend {
obj_table = SMODS.Perks,
obj_buffer = {},
required_params = {
'key',
},
set = "Perk",
loc_txt = {},
config = {},
pos = { x = 0, y = 0 },
atlas = 'perk_atlas',
unlocked = true,
discovered = false,
colour = HEX("9151b5"),
reverse_lookup = {},
class_prefix = 'pk',
inject = function(self)
if not G["P_PERKS"] then G["P_PERKS"] = {} end
if not G.P_CENTER_POOLS["Perk"] then G.P_CENTER_POOLS['Perk'] = {} end
if not G["shared_perks"] then G["shared_perks"] = {} end
G.P_PERKS[self.key] = self
SMODS.insert_pool(G.P_CENTER_POOLS[self.set], self)
self.reverse_lookup[self.key] = self.key
G.shared_perks[self.key] = Sprite(0, 0, G.CARD_W, G.CARD_H, G.ASSET_ATLAS[self.atlas] or G.ASSET_ATLAS["stickers"], self.pos)
if self.soul_pos then G.shared_perks[self.key.."soul_pos"] = Sprite(0, 0, G.CARD_W, G.CARD_H, G.ASSET_ATLAS[self.atlas] or G.ASSET_ATLAS["stickers"], self.soul_pos) end
end,
process_loc_text = function(self)
-- Create "Perk" description group if it doesn't already exist
if not G.localization.descriptions["Perk"] then G.localization.descriptions["Perk"] = {} end
-- Follows the same localization that Seals do
SMODS.process_loc_text(G.localization.descriptions.Other, self.key, self.loc_txt, 'description')
SMODS.process_loc_text(G.localization.misc.labels, self.key, self.loc_txt, 'label')
end,
get_obj = function(self, key)
if not G["P_PERKS"] then G["P_PERKS"] = {} end
if not G.P_CENTER_POOLS["Perk"] then G.P_CENTER_POOLS['Perk'] = {} end
if not G["shared_perks"] then G["shared_perks"] = {} end
return G.P_PERKS[key]
end,
}
function Card:set_perk(perk, silent, immediate)
self.ability.perk = nil
if perk then
self.ability.perk = perk
if not silent then
G.CONTROLLER.locks.seal = true
if immediate then
self:juice_up(0.3, 0.3)
play_sound('gold_seal', 1.2, 0.4)
G.CONTROLLER.locks.seal = false
else
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.3,
func = function()
self:juice_up(0.3, 0.3)
play_sound('gold_seal', 1.2, 0.4)
return true
end
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.15,
func = function()
G.CONTROLLER.locks.seal = false
return true
end
}))
end
end
end
end
local prototype = SMODS.Perk{
key = "prototype",
loc_txt = {
description = {
name = 'Prototype',
text = {
'{C:blue}+11{} chips, on play create',
'a {C:spectral}temporary{} {C:attention}Blueprint{}',
'and {C:red}burn{} this card',
},
},
label = "Perk Card",
},
config = {
chips = 11
},
colour = G.C.GREEN,
pos = { x = 0, y = 0 },
atlas = 'perk_atlas',
}```
this is my code
gonna be honest i got no clue what im going on
but im confused as to why at least the ui is different
the badge was working at some point but its not anymore too im not sure why
i have the label working now somehow
don't disenhancements use lovely to patch the UI?
DVD logo jumpscare
yeah there is some lovely stuff, but i wanna edit the cards text like 6 of spades
I had a hook to do it for other reasons. Not sure if there's an intended way of doing it
Although for my reasons it made sense to add to the tooltip rather than partially overwriting it
Try seeing how Enhancements do it
exactly
i wanna overwrite the cards name tho
pretty sure it just appends to main end in the generate ui func
that's what I did for the other thing
so you can hook it to do that, or maybe now there's a better way to do it
you can define your own generate card ui function for steamodded objects i think
but im not sure how i do it correctly lol
I'd like to know too @frosty dock
Unrelated: I'd like to hear what you think. I made this hook because I implemented a Joker that changes card suits as they're being played, so this makes it so they're correctly debuffed by appropriate Blinds. However, as a secondary effect it seems to make the Pillar debuff each played hand. Should I just patch the Pillar too or do any of you have a different suggestion?
same happens when playing a face cards with midas mask, not sure why it is
id probably just patch pillar too
ik there was a bug in base game that enhancing a card would undebufff it against the pillar
so maybe someone tried to fix it but actually broke it in another way
There's possibly further side-effects with other mods which is why I'm asking
I could maybe replace the Blind.set_blind call with manually iterating over the played cards and debuffing them, maybe
im not too sure the best way to go about it tbh
For now I'll try patching the Pillar. I'm sure I can use lovely or a hook but I think I could take_ownership of it?
I haven't done that before though
Judging by Steamodded source code I could do something like
SMODS.Blind:take_ownership('pillar', {debuff_card = function(vars) … end})
anyone have a clue how to make it so that a UIT object (G.UIT.O) can be flagged as a controller selectable object, like, at all?
using one of the helper functions such as create_toggle makes a selectable toggle but i can't replicate the secret sauce
Out of curiosity, since i've never seen this, is there any easy way to have a joker appear above all the others in your hand? like when you highlight/pick it up, it renders above the other jokers
AFAIK love renders objects in order, so maybe rendering it last would be the simple way to do it
Only thought we have is to make it highlighted but, we dont know if that'd mess with buying and selling etc
How can I make a joke tell when a card is created
print(<joke>)
or you can hook it up to some ui stuff
💀
lmao
yeah man you can actually scale up your playing cards if you just play cards with higher value
I mean is the one mod where you can just keep adding seals making walky talky a scaling jokee
Or does it make the playing card a scaling card
they're talking about vanilla
Yeah but this is #💻・modding-dev
it was in #🕹・game-discussion
Yes but this isn't #🕹・game-discussion
I meant joker
Idk there's probably a thing emitted
Look at the one jokee that does the thinf
I forgot which one it is
Its a new legendary that ads x1 mult per card created this includes tarrots planets spectrals jokers and playing cards
you can hook to the create card function
Oh ant card created might be a bit harder
be careful
yeah, and for shop
Or opening the deck
I would hook it on add_to_deck
But then jokers and consumables
both are added to deck
If something add_to_deck then
when you purchase a card from the shop add_to_deck is called
I can't wait to make a mod that calls add to deck on on a bunch of random things and then immediately destroy them
What about jokers that make stuff like tarrots
Also wait I could have used that for DebugPlus
Do they count to
I might be stupid
ive used add_to_deck a lot
it's useful for adding aditional variables to cards for consumeable tracking etc
I manually have a lookup table to figure out what area yo go to based off type and then emplace them manually
Yes I am
I couldn't figure out a better way
To be fair I was referencing the spawn code which akos doesn't use that
Also for playing cards I probably don't want to use that as I want them in the hand
Although maybe there's a simple way for thst
i think u can just emplace() in card area hand
do I need to check separately for each type of card or could I check all cards easily
but u also need to add_to_deck iirc
oh this isnt that bad, i imagined u had some weird map or something.
probably want to add to deck if G.HAND isnt available tho
Yeah but I'm lazy
💀 respect
I have to reimplemt half of the reroll boss code cause thunk
Maybe I should just hook things more often
I could just hook the function for getting a boss blind
And then reroll
Or add a property
And use it
Oh actually look at how I change rnaks (up and down)
I actually just loop through G.P_CARDS to find the card with the right rank and suit
But I also have to loop through my ranks value to find the next one
So there's 2 loops per rnak change
And one has to go through all cards (more if modded ranks/suits)
after i understood hooks it made my life so much easier
Also then look at the suit changing
There's a function for it
But not rnaks
Technically I could do some string manipulation to skip the second loop in ranks but I didn't feel like it
Also with custom ranks/suits it gets potentially messier
this hover effect is so underrated
Having trouble figuring out eval_this, is there a place I should look to figure out how it works?
I guess I should post a specific issue: Here, I want wild card to give +3 mult, and I can't simply use returns here because eventually, I want it to be able to have multiple effects. If I'm understanding eval_this correctly, this should work, but it does not.
if context.individual and context.cardarea == G.play and context.other_card.config.center == G.P_CENTERS.c_wild then
SMODS.eval_this(context.other_card, {
mult_mod = 3,
message = localize({type = 'variable', key = 'a_mult', vars = {3}})
})
end
end,```
i think you want m_wild for the enhancement
might be misremembering tho
if you go to game.lua you can see the keys for all the game items
but enhancements have the prefix m_
--All enhanced card types here
m_bonus = {max = 500, order = 2, name = "Bonus", set = "Enhanced", pos = {x=1,y=1}, effect = "Bonus Card", label = "Bonus Card", config = {bonus=30}},
m_mult = {max = 500, order = 3, name = "Mult", set = "Enhanced", pos = {x=2,y=1}, effect = "Mult Card", label = "Mult Card", config = {mult = 4}},
m_wild = {max = 500, order = 4, name = "Wild Card", set = "Enhanced", pos = {x=3,y=1}, effect = "Wild Card", label = "Wild Card", config = {}},
m_glass = {max = 500, order = 5, name = "Glass Card", set = "Enhanced", pos = {x=5,y=1}, effect = "Glass Card", label = "Glass Card", config = {Xmult = 2, extra = 4}},
m_steel = {max = 500, order = 6, name = "Steel Card", set = "Enhanced", pos = {x=6,y=1}, effect = "Steel Card", label = "Steel Card", config = {h_x_mult = 1.5}},
m_stone = {max = 500, order = 7, name = "Stone Card", set = "Enhanced", pos = {x=5,y=0}, effect = "Stone Card", label = "Stone Card", config = {bonus = 50}},
m_gold = {max = 500, order = 8, name = "Gold Card", set = "Enhanced", pos = {x=6,y=0}, effect = "Gold Card", label = "Gold Card", config = {h_dollars = 3}},
m_lucky = {max = 500, order = 9, name = "Lucky Card", set = "Enhanced", pos = {x=4,y=1}, effect = "Lucky Card", label = "Lucky Card", config = {mult=20, p_dollars = 20}},```
yeah there you go
Yeah that fixed it
I've expanded the Joker quite a bit, and right now, it's supposed to amplify the effects of Suit Mult jokers on Wild Cards. For some reason, though, it's adding the Mult before the chips get added, which is very much weirding me out. Is there a way to get it to be... normal?
for k, v in pairs(G.jokers.cards) do
if not v.debuff then
if v.ability.effect == "Suit Mult" then
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end
}))
SMODS.eval_this(context.other_card, {
mult_mod = 3,
message = localize({type = 'variable', key = 'a_mult', vars = {3}})
})
end
end
end
end```
you can put the eval this inside an event maybe?
that way itll be delayed enough for the chips to count first
Now the Mult just doesn't happen at all, so that's probably not it.
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
SMODS.eval_this(context.other_card, {
mult_mod = 3,
message = localize({type = 'variable', key = 'a_mult', vars = {3}})
})
return true
end
}))
end```
Oh wait, it does happen, just after the hand is scored. Still not it
you might have to use patching or smth
i dont think the game is designed to have jokers do multiple things like this really
I guess I just deal with them applying in a weird order
maybe you could do your own eval this for the cards chips
then smth like
context.other_card.calc = true
and patch so when it tries to eval the chips from that card
is checks to see if calc is true
and if it is it doesnt display any chip message
bit convoluted but im not sure what else you could do
I think I just accept that it's kinda jank and move on
This Joker idea is really jank anyway
some things just have to be jank sadly
like ive got an enhancement that can retrigger cards
to do that i just calculate it as if its a red seal lol
if context.repetition_only then
local seals = card:calculate_seal(context) or {repetitions = 0}
if seals then
ret.seals = seals
end
if card.ability.set == 'Enhanced' and center.calculate and type(center.calculate) == 'function' then
center:calculate(context, ret)
enhancement_calculated = true
end
if ret.seals and ret.seals.repetitions > 0 and not ret.seals.card and not ret.seals.message then
ret.seals.message = localize('k_again_ex')
ret.seals.card = card
end
return ret
end
```
horrible code
I honestly should just scrap this Joker, trying to expand it just causes way too many problems for me.
Unless I find a better way to amplify Joker effects on certain cards, this one's going in the bin
fwiw I tried using eval_this before but ended up just doing a lovely patch too
then again i too have also scrapped jokers bc they were too much to engineer
are you able to define custom additions tab for smods
because the mod im working on is going to have not much actual additions, so it makes more sense to me to put all of the additions into a single screen instead of having a bunch of categories 1 item each
I was sad when I realised your decks didn’t have them when making sure they worked in galdur
oh its from hovering over the word
i thought it was a badly place info box lol
is that base game?
its cool asf
well i dont actually sorry
my mod folder is sad
uh is just a backup of ceres lol
well its not really a full backup
its part of the mod that isnt functional yet
but i dont wanna finish it yet
and dont want it in the first release i make
ah, makes sense
so ive just got it in there
this might be a really dumb qquestion but how do i use inject_card for consumable types
say i wanna have this consumable type appear anywhere tarots can
figured it out
inject_card = function(self, center)
SMODS.insert_pool(G.P_CENTER_POOLS['Tarot'], center)
end```
someone tell me if thats wrong tho please
seems to work tho
more polished version 
BBQ? more like JJQ 
fire mod is real???
what if spades and clubs use the blue fire
also just finished moving all of archipelago's connection status/goal ui into its own box instead of using love.print
swag
now the russian localization can properly display stuff
(me when i lie)
i think the worst part of this update is that i can now understand ui code
old version would've skipped the stake entirely
but modded suits exist
ooh did you just? https://discord.com/channels/1116389027176787968/1261009015585112145 >_>
cool, I was adding this for jen's almanac
but I thought it could be nice as separate mod too
its fine, i'll prob won't be working on it for a long time
tho i do like to eventually get to it once i actually know how to code :)
i'd love to see where you'd go with this :>
you'd need to learn at least basics of shaders for this btw
or you'll end up with something like this #💻・modding-dev message
How do I calculate cards played that do not score? So for a played hand of Q,Q,Q,9,7 and assuming i dont have Splash, how would i look for the cards besides the Q's
The effect im trying to apply is to strength cards played that dont score. Is this possible? I havent found any modded jokers that do anything to non scoring cards played
So for Q,Q,Q,9,7 the 9,7 permanently upgrade to 10,8
you check if the card is in full hand but not scoring cards
dont remember the exact variables you need to check but its definitely possible
i had a joker that only activated when you played a bunch of nonscoring cards, but then i reworked it so cant check the code
Ah I see, not sure where to go from here tbh 🤔
I'll try some experimenting with it
What do you think of the art for Solomon David?
Tbh, not that bad, i did get distracted by the dvd logo
I love the idea :)
I'll change the effect a bit still
So you fight an extra boss each boss (without refreshes)
Hmm
is it possible to pause a card effect/the event manager until a certain condition is reached
alright, pack it up, this one's cooked
aw man my cards caught fire
burn those who dare to care for me
I love how the ^Mult just isn’t doing anything
i love the colour change >_>
Is this a nil check for a boolean?
uh
it's always true
we love if true then
You could change the event itself, maybe
I'm looking at it and it seems non-trivial to play custom sounds without SMODS
wait nvm this mod depends on SMODS
I'm stupid
that usually means something used to be a check there but then got changed to always proc 
I do that sometimes too, and forget to remove if
i like keeping my stuff relatively clean so i always remove unnecessary code
do ... end but longer
me too
Solomon versus Solomon
Yep
uhh cause I was looking at the code and it doesn't seem to do it
unless I'm stupid
also how do I play a sound???
it's automatic for all GameObject subclasses that don't explicitly disallow it
sounds don't have a class prefix, so just <mod prefix>_<key>
you play sounds with play_sound like base game sounds
so I have to know my mod prefix
no
do vol and pitch args in play_sound work now
eg does it still use the values declared in the gameobject
then what do I pass to play_sound
you can just save the result of the call from SMODS.Sound and use the key field on that
actually <Sound>:play(per, vol) also exists for legacy reasons
but it just delegates to play_sound
oh wow it works
eval play_sound(SMODS.Mods.BlackHole.joker_sounds.default.key)
now time for lovely
didn't I only do that for modulate? 🤔
nvm i just dum
what I wanted to achieve is to have these values only apply to music
just coded the coolest item
What does that mean
archipelago shuffles items across multiple games
ap item locations are different from ante clear locations right
i made a card that brings the item you unlock directly into your hands
atm i have them reading from the same pool as shop vouchers, but by the time they're released they'll have their own configurable pool
also spectral is the only one with a cool effect, tarot and planet just unlock random items like the voucher
but what does "unlock an AP item" mean
it makes sense in context
^
Hi
and I'm asking for context
yes
Cool, Archipelago is a randomizer
items are locked until they're found by either you or one of your teammates
For Balatro?
Not quite, it's more of a framework
Let me get into simpler details
Now that I think about it, isn't the game already random?
Can't you do multiplayer in the same seed?
Archipelago is a framework that allows you to shuffle "Items" across "Checks"
is it wonder trade
An "Item" can be anything.
Imagine, for instance, Joker (the standard one)
Let's say that we make Joker into an "Item"
With some logic, we can create the following code for Archipelago:
"As long as I do not posses [Item: "Joker"], the Joker "Joker" is debuffed."
Now
(or removed)
We can hide these kinds of "Items" across "Checks"
A "Check" is any condition
For example,
"When I beat Ante 1, I will check [Location: Ante 1]."
sorry to intterupt your discussion but can I figure out how long a sound is/when it's done playing?
I know this doesn't sound like it's leading into anything, but these are the basic concepts
I think those are usually called flags
Right you are
but this is ye olde randomizer lingo
and since Archipelago is based on ye olde randomizers, the lingo stuck
Much to my chagrin
Anyway
But I still don't see what about this being a randomizer is relevant
since balatro is already random
Hold on, we're just explaining basic concepts
The multiplayer feature is the added extra no?
just two more things
two more things and it'll click
so bear with me for a bit longer
Each [Location] can hold exactly one [Item]
afaik no
I remember aure and MathIsFun talking about synchronized sounds
which I think is related
So, we have one [Location] and one [Item].
When randomizing, we'll assign each [Location] a unique [Item].
Therefore, we'll get, with our rudimentary logic
[Location: Ante 1] contains [Item: Joker]
Now, let's extend these, the [Location] list and [Item] list, into everything Balatro has to offer
For Locations, every Ante, every Shop, and every Stake
For Items, every Joker, every Consumable, every Deck
We have now created a [World: Balatro]
Archipelago relies on [Worlds] to create unique kinds of gameplay
If we submit this [World] on its own, we'll create a Balatro run that's part familiar, part new
Familiar in the fact that Balatro is a rougelike
so yes, stuff in shops, stuff in packs, etc. will be random across runs
but new in the fact that you'll need to "re-unlock" everything you've found
idk why you're talking like you're either talking down to me or trying to sell me something I can't quite tell ;P
I'm not doing either
I'm just re-explaining it in a way for us programmer brains to understand
😮
every Joker now has an unlock condition, and it won't be usable until you've "unlocked" an [Item] by visiting its [Location]
Think of that as meta-progression
as any [Items] you find will last between runs, as long as in you're in an Archipelago [World]
Now, what Archipelago uniquely facilitates
(and the whole point of this)
is mixing and matching [Locations] and [Items] between different [Worlds]
For example, let's throw in another familiar game into the mix
We'll add [World: Slay the Spire]
Through luck, we can get something like
[Location: Act 1 Boss Chest] contains [Item: Smeared Joker]
Suddenly, the unlock condition is completely impossible within Balatro
You'll have to play Slay the Spire in order to complete the unlock
that, in essence, is the kind of interactions Archipelago facilitates
I mean you could've started with that and it'd have saved us both 15 minutes of our time
That's fair
Is a world a single game or a set of games?
One game
So what's a set of worlds?
an archipelago
Why isn't it called an Island then?
VERY simple concepts
Is it Multiworld or Archipelago?
to a programmer friend for 45 minutes
it's a multiworld
It's specifically called a multiworld
That's why the literal name of the website is "Archipelago, a Multiworld randomizer"
Sorry for wasting your time, that's entirely on me
why is it called Archipelago if Worlds aren't named Islands?
That
I have no
ing clue
archipelago basically twists a game or a set of games into a makeshift metroidvania
And I honestly wish it was named an island
Then again I wish [Locations] were called [Flags] but [Events] are a thing
well it's either explaining all the basic stuff or actually play it yourself to know what archipelago is
which makes me suffer
i learned by the latter
Just for clarity
To be fair, it's probably simply because Archipelago sounds more interesting than being named MultiWorld or something.
also. 🍔👑
I mean they could've said you can lock items in one game behind a flag set by a different game
in a multiworld like
[World: Slay the Spire]
[World: Minecraft]
[World: Balatro]
We can have such fun conditions as
[Location: Visit a Nether Fortress] contains [Item: Rare Card Drop]
[Location: How did we get here?] contains [Item: Jolly Joker]
It's only the interaction between different games that's actually new
i'd say randomizing unlocks in the same game is already new
I'd argue it isn't
I was almost lost in the midst of explanations phew
speedrun randomizers have been a thing for generations
But it's doable by modding Balatro
like 90% of my contributions to balatro ap were inspired by how sonic adventure 2 ap handles stuff (mostly because thats the only ap game i play lol)
You don't need Archipelago for it
At least you, the reader at home, now know what an Archipelago is too
You can make a Balatro randomizer mod; Archipelago can allow Balatro to interact with other games
i think i was envisioning it like StS when i first had the idea
like the stakes update was literally just cus i found the random level order fun
I just watched some AP games to get the idea of it
Although
I will say
the most fun I had with Archipelago
is watching Brundi and co. panic as they saw the Three of a Kind annoucement anticipating a Balatro update that may break mods
And I get to respond with
:)
knowing full well it wasn't
-# For legal reasons, that's a joke, even we mods don't know what's under the other cards
I had never heard of Archipelago
Burndi and co.
I think I've only seen some SMO randomizers
basically the entirety of #⚙・modding-general during that time
Maybe SMW? Though I can't remember
I've watched people play vanilla and modded but I'm not sure about randomized
but as I said I did watch randomized SMO
How does that work?
Is it just every load transition moves you to a different Kingdom?
i'm still mad that balatro had to be contained inside the ad server
I mean I've seen that but I was thinking of the time they randomized the number of Moons
the what
Essentially
oh i thought you were talking about door randomizer
due to the fact it contains cards and poker
Balatro is treated as an "18+" game for Archipelago
Oh it turns out those were both the same video
You should watch me live on Twitch:
https://twitch.tv/Smallant
▶Discord: https://discord.gg/Smallant
▶Twitter: https://twitter.com/Smallant
▶Reddit: https://reddit.com/r/Smallant
▶TikTok: https://tiktok.com/@Smallant
▶Post Office Box (I'll open it on stream):
Tanner Ant
PO Box 283 Prince George A
Prince George, BC
V2L4S2
Edited by: Mike Remer...
if it werent for pegi, we'd be homing for the top of the main page
Oh hi SmallAnt
smant jumpscare
Oh you're the second developer (I just checked)
sorry for the unintentional disrespect lmao
I couldn't remember for the life of me
technically i'm a dev for balatro ap but i only fixed deathlink text initially
it's okay next time just be disrespectful intentionally 👍
orz
Flawless logic
If you're on the contributor page
then you're a dev
that's me!
My personal contribution toward Archipelago is I created a plugin for RPGMaker VX Ace games to connect to Archipelago
Was it easy?
No it took me like, an entire year
especially since the docs lie to you more than they actually explain anything
but that's something I wouldn't talk about on this server, due to us being severely off topic already
quick just talk about some RPGMaker game to mod into Balatro
Mod that turns the Quit button into an Off button
I keep thinking of Archipelago as a hub world and I'm wondering wth they're talking about 😅
Mod that turns Painted Deck into Ib Deck
Welcome, reader at home
Start from here
it's a nice hub world until someone (me) joins with Muse Dash all songs with DLC
Mod that makes the sleep mode in your PC the Yume Nikki mode
Oh wait is that program that, for example, if you get a boomerang from a Zelda game you unlock a power-up in a Mario game?
yea
Neat
Put Chess into the Balatro world
stupid idea, what if every combination of enhancements + suit/rank was a location
You need to reach GM status to unlock the play button in Balatro
i asked burndi to add item names to the voucher way back when bcos i saw sonic adventure 2 shop and seeing "Four Fingers" there was so peak i wanted it in balatro that moment
It's not that hard, to be fair
you just read the datapackage
okay we're really going off topic now
also those are now optional bcos i added a config for that
#🃏・off-topic is dead, if anyone wants to continue discussing AP, let's head there
Also Archipelago Chess
is a hilarious idea
I will create it when I get the time
its already a thing btw
we are now 46.53% the amount of lines that balatro localization has
@hushed cradle @wintry solar is your mod on GitHub? I wanted a reference on how to add Enhancements
The only mod that adds one I could find is Cryptid but it's hooking calculate_seal to make it work
I haven’t started doing this

D6 Jokers adds one and it's pretty simple implementation.
I was hoping to find something with a calculate function
yeah mine is
where
Thank you!
can we have tailsman skip animations?
No we have tailsman skip animations at home
tailsman skip animations at home:
Nopeus 2
I made it worse
Nopeus 3
[manifest]
version = "1.0.0"
dump_lua = true
priority = 0
[[patches]]
[patches.pattern]
target = "engine/event.lua"
pattern = "self.timer = config.timer or (self.created_on_pause and 'REAL') or 'TOTAL'"
position = "after"
payload = """self.blockable = false
self.delay = 0"""
match_indent = true
``` if anyone wants it
Now get a few canvases in there and see what happens
That is an unfathomably satisfying sound
Coincidentally that's the sound Waluigi makes when you put them in the dishwasher
The background is cool here
what's the mod that makes the deck menu look like that? looks really cool
the game might've freezed seeing that base event queue is stuck at 7 lmao
the game was indeed frozen
the queue is probably not going to get that large with this mod as theres no blocking
I think it might've recovered if left long enough but the amount of retriggers I had was in forever territory
is the console usable?
no there was no frame updates
the console won't open until the next frame
if it is open it might workk
not actually sure
I mean in general 😭
I tried using it today but it didn’t seem to work
oh
Unless I missed some instruction
are you on dev branch
probably not
I’m in f0d5970
Which is 2 commits behind master and a lot of commits behind dev
debug plus console is really useful
so true
you'll need to grab the PR for enhancement calc to make it work properly
- Isn’t it already in main? I was looking at it earlier and I thought it was already there;
- I still don’t have your mod tho.
no
the stuff in main doesn't work
it gets called by mistake in the joker calculation which means it's harder to actually do stuff
actually mb that PR should be good to merge
it also fixes the random stake crashes 🎉
Could retrigger API get merged relatively soon, if you don’t mind me asking?
One of the Code Card ideas pretty much requires it in order to be implemented
is the corresponding cryptid PR stable / how well tested is it?
ive been using it for some of my stuff
i havent encountered any issues so far
at least not with actual functionality
retriggering jokers that retrigger cards looks a bit funny
but it works
Moderately stable from the little testing I’ve done
Do you need help to merge the Retrigger API?
I'll do a bit of my own testing first then
no way this actually worked wth
mod idea bookmark thign that sticks up above the joker thing so you can find specifc jokers when you are spawning like 20 jokers a round
I'm trying to hook into a vanilla joker and add an info_queue, but, I'm apparently messing up the grammar somewhere, I've spent somewhere between 5-15 minutes looking at this block, and I'm not seeing where. Could someone point it out for me?
SMODS.Joker:take_ownership('ring_master', {
local old_loc_vars = loc_vars
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = {set = 'Other', key = 'Tests'}
return old_loc_vars(self, info_queue, card)
end
}, silent)
Man, why is it so hard to come up with a good idea for a 7s Joker!? No wonder thunk never made one.
you can't put a variable declaration inside a table constructor
you'd put that outside the take_ownership and would also need to check if it exists before calling it
as vanilla jokers don't use the steamodded system
Got it, appreciate the help.
loyalty card is already in balatlo
thanks i wasnt too sure
Ehh, simple question, I have a Joker I want to give a 1 in X chance to give TWO of the same consumables. How do i make it give 2 instead of only 1?
you can probably just copy the other consumable with copy_card
copy paste the same segment of code 💀
?
to get it to spawn 2 of the same card
new_card:add_to_deck()
G.consumables:emplace(new_card)```
probably as an event that fires off only when you have the space
card being the first card
local thing = {}
local cards = 93
for y = 3, #to_string(cards) + 2 do
thing[#thing+1] = 'yes'
end
for this, that in pairs(thing) do
if this and that then
new card = create_card(stuff blah blah)
new_card:add_to_dick()
G.place:put_card(old card)
ned
end```
^^ most effecient way
how tf do you spell effieenet
effcint
best way to do it^^
create_card spawns a random card out of a pool though?
you can give it a forced key
the effect they need is creating 2 of the same
unless the first card is also forced key, you cant reuse the code
lua local _card = create_card('Joker', G.jokers, nil, 0, nil, nil, 'j_blueprint', 'ben')
you could randomly pick a key for the forced key
then do it
💀
and how would you efficiently pick that
probably generate a random number between 1 and a million
see if G.P_CENTERS[num] exists
if it doesnt
????
?????
👍
or you could just
let the game generate a card the way it normally does and then copy it
local random_range = 10000000000000000000000000000000
local random_num = random_range
while not G.P_CENTERS[random_num] do
random_num = -- random number from 1 to random_range idk how to in lua
end
create_card(blah blah forced_key = G.P_CENTERS[random_num] blah blah)
but twice
also G.P_CENTER_POOLS[Set][Random out of #G.P_CENTER_POOLS].key would be much more efficient way of doing that
even if it is wrong
but you need to sure its random
so maybe e300 ish to be safe
also def use a while loop
are you trolling
yes
ive been trolling since i said copy paste the same segment of code lol
best way is to keep creating 2 random cards until they happen to be the same
💀
people are looking for help here
do not copy paste the same code 🙏
I'm actually only trying to give two random planets using this local card = create_card('Planet', G.consumeables, nil, nil, nil, nil, nil, '8ba') I should have specified that, sorry y'all
all good
you can just do
for i = 1, 2 do
local card = create_card('Planet', G.consumeables, nil, nil, nil, nil, nil, '8ba')
-- add to deck and emplace etc
end```
to do it twice
thats good because oyu can use a variable instead of 2
for easily changing it later down the line
also it would be good to do it through events
oh yeah
Ok, I think I want to make them negative planets as well. As of now the Joker functions and gives only 1 planet but whenever i tried to use c:set_edition({negative = true}, true) it would not work (crash), which just means im not understanding how to use that function.
c is supposed to be the card
try card:set_edition('e_negative', true)
That works
Ty, never realized how easy it is to break the game balance with negative planets til now. I wish negative planets didn't stop standard versions of themselves from appearing.
I believe it was Betmma Vouchers that had some sort of temporarily eternal mechanic that forced you not to stack a free, once per round tarot card that a voucher gives. Use it or lose it sort of thing. Real talented modder whoever made that voucher. Something like that would prevent this custom joker from being a planet spawn manipulator.
Suggesting the clean syntax and not thunk jank 👌
what did thunk mean by {negative = true}
me when the only reason i know the better way even exists because i saw aure talking about how painful it is to see the thunk jank
me when i scroll up in #1248865517112918016
is there a better joker example for steamodded than the default
i find that it really doesn't cut it most of the time
what is the "default"
I don't think he ever references them though
nvm, I saw a different message than the one you referenced
the color thingy is funny tho since iirc that caused/causes? a bug where switching to high contrast mid run keeps old colors of cards in standard packs
or nvm, the suits are textures, so that shouldn't be a problem
can anyone help i tried coding this joker and i think i royally fucked up the code
you see those red {?
yeah but i dont know why they're there
they look like they're closed
after the end
the first event isnt closed
ah so like this?
oh i removed that because i thought it would cause an error 😭
the function of the second event isnt ended
no those are still badly placed
put them where the squiqqle is after the }
vscode is pretty good at telling you how to fix your syntax errors, you should probably get used to that
i followed all of vscodes syntax error things and now the games bullshitting me about <eof> expected near else
it told me to remove the "end }" at the end of file, but its also telling me not to?
when i add an if to my else it says that thats not supposed to be there
but when i remove it it also says to add it
thats because you've closed all your events in the wrong places
just move the else to wherever the hell your if is
i dont know if that exactly works considering my full code
evil syntax
||```lua
calculate = function(self, card, context)
if pseudorandom(...) then
G.E_MANAGER:add_event({
...
})
else
return {...}
end
}
did you just spoiler a code block?
yes
I didn't know you could do that
||```
```||
so like this
all those squiggles are vscode telling you that it isn't going to work
look at them all
its screaming at you
no matter how many of the things i fix and unfix it keeps telling me this
if you don't understand how to format code I'm not sure how to help you 🤷♂️
thank you sm
tht got rid of all the errors
:D
atleast i think
i was also wondering if there were any errors with the code before the function part
as viewing the joker ingame crashes
there is no 4th argument to loc_vars that would be center
np
you should just be using card there
tried removing center and it still crashes
dw about apologising lol
you're still using it
oh so you mean change the center.ability to card.ability
k
and its fucked up oopsie
what does your code look like t
yeah so odds isn't inside extra
it's actually in config[1], which means it doesn't get transfered to ability at all
so like this
inside extra..
yeah it isnt
that will work if you do card.ability.odds
for the other one
return { vars = {card.ability.extra.mult, probablity, card.ability.odd}}
wait why not?
local reward_card = Ceres.SETTINGS.card_effects.perks.enabled and SMODS.Perk{
key = 'reward_card',
atlas = 'perks',
pos = {
x = 2,
y = 0,
},
config = {
cost = 6,
message = {
text = 'Tag!',
colour = G.C.GREEN,
},
},```
this works for me
only select values from config get copied into ability iirc
oh wait shit i forgot to make the code check if its the end of round before killing my thing
its suicided as soon as i select the blind
i mean i didnt write any of steamodded so youll kno wbetter than us
if it works, whatever
generally I'd put things inside extra because everything else can and will be inconsistent depending on what it's named
yeah the only issue with it is the fact thatd i dont know how to make the destroy code only run at the end of round
hey do you know what could be wrong here in the above message
the new if statement isn't wrapped
i recommend indenting if statements consistently so that it's easier to tell when that happens
if thing then
stuff here
if something_else then
more conditional stuff
end
end
if other_thing then
more stuff here
else
other code
end
im confused on HOW to wrap it
every if ... then needs an end somewhere
that's what indentation is for
?
oh my godi
i just checked the vanilla joekrs lua
and the full thing has a copy of gros michel
i wasted like an hour 😭
So the next Joker I'm working on I want to have check for the total number of spectral cards used. Ik you can check for tarot cards, but how do I check for Spectral cards?
the same as tarot but replace tarot with spectral
That easy huh
I tried just replacing tarot with spectral and it didnt work but i suspect my issue is with something else then ty
It only exists for Tarot iirc because of Fortune Teller no?
well idk what the code you have is
but isn't it just card.ability.set == "Spectral"?
No its a G.GAME thing
If hes trying to get all used spectral for a run
What i was fearing when I was looking at Fortune Teller, any options here?
I can rework the Joker to just do specific things on Spectral use instead
you might be able to use a lovely.toml patch file to inject tracking for spectral uses if you can find it in the code
Man i wish, I don't think im ready to try something like this yet bc i'm still very much a beginner. There's another Joker in my head that I know isn't quite possible without using that as well, maybe some day

moment
