#making-mods-general
1 messages · Page 98 of 1
that's not the vanilla void, it's the void from Visit Mount Vapius' museum patch
Is it your mod?
no
What kind of mod is it?
Are you trying to update it?
it changes the farmhttps://www.nexusmods.com/stardewvalley/mods/9347?tab=description
I guess so
If it's just mod u install downloading again properly fixes things, some mod managers like vortex eat files
I'm still putting the display name modders give directly into Data/Furniture (after replacing FF tokens), so there wouldn't be any FF tokens left for the game to try to tokenize, so my only worry is if it's possible for a tokenized string to get considered as a FF token by mistake
Looks like it has a manifest to me
Maybe try downloading it again and verifying you get all the files
In the future u can ask tech support questions in #1272025932932055121
This chat is for making your own mod
If you're using a mod manager, don't lmao
(it has two manifests, because it's two mods in one)
(this map looks like hell, it's so freakin' big)
I love it
Well if u use something entirely different then u can just dodge the issue prob 
After looking at the LocalizedText Strings in Data/Furniture, it looks like [[ModID]] (or its friends) would never show up by mistake, so I'll keep [[]]
what does a string using i18n looks like so I get an idea of that too?
lmao
You will never see it in content
It's tokens all the way down
Technically, you'll never see any of CP's tokens in data because they're resolved before they hit the pipeline
Yeah that too 
so if a modder wants to edit a string of FF data containing a i18n token with a CP pack, the CP mod would have to handle the translation of this token, right?
Yeah
I'm partial to the box-drawing characters, myself: ►►ModId◄◄
yeah, that I figured out
It's a bit of a pain point that u can't patch other people's i18n
hmmm
(where as u could patch LocalizedText since that read from an asset)
What about with Button's mod?
I can't remember lol
but FF still has to parse i18n tokens to support it right?
Naw
Ah yes, the search results of Button are Button's Books, BETAS and the 37 translation mods for the books mod
Well your FF content packs would because that's all you
Just what I was hoping for Nexus
CP would have resolved the i18n to the actual string
considering using éModIDè to give an advantage to french modders
Incidentally a way to expose ur tokens to cp would be registering it
If you do this then u could do like {{ff:modid}} in cp and let cp do the token stuff
FF data doesn't always go through CP
(CMCT does seem to only allow reading)
ok, I think I got every info to put i18n on the TODO list, and decide whatever I'm going to put around FF tokens later
Alright. My fork and therefore my PR are now up to date for 1.6.13. \o/
{[(ModID)]} just to be sure
(I think anyone with access to the decomp should automatically have access to my fork, also? So there's that.)
Embrace chaos make it “ModId” U+201C U+201D
Banned
I wish I knew how to do those codes T^T
Never too late to learn
Open wordpad, type in 201C and then push Alt + X
nah, I keep forgetting how to do it
I've learned like 3 times now
I don't know where else it works, but not Discord lmao, had to copy paste those bad boys
I like linux, I just have to do ctrl+shift+u, then type the code and it just works
“ModID” like this
when location data works 
O.O
You can use a fish mod to check for this stuff
Like a fishing sea (with fish predictions) or just visible fish
should be good
Some asked me to backport SpaceCore 1.26 to 1.6.8? 
(Not gonna do it, but just odd because backport requests are pretty rare for me)
I got a similar funny request for RadialMenu, except that there's literally nothing to backport since the code didn't change.

(users)
So basically they have no idea what they're asking for lmao
Well it was a "something broke" type of request except they were still on 1.6.8 and saying the new version didn't work. (when there was no need to update in the first place)
Like, they wanted to keep using game version 1.6.8, but decided to update to all the 1.6.9+ compatible mods anyway.
Would SMAPI even tell them there were updates?
1.26 is new to 1.6.9
So nobody makes the same mistake I did, when I worked on adjusting that NPC mod the other day, I used the 2.4.0 CP format since I'm on 1.6.9+, but 1.6.8 won't recognize that because you need CP 2.3.0 on 1.6.8
I mean, there is for sure new stuff in 1.26 but like, I don't know what they could possibly think they need from it in 1.6.8
I think S&S is the only mod requiring features from the new version
(And was why this person asked)
Might depend on SMAPI version? I did update the required version in the manifest, so if they were still on old SMAPI then I'd think it wouldn't show a notification for a mod require a newer SMAPI version. But, given the nature of the request, for all I know they also updated SMAPI without updating SDV.
So they also want S&S for 1.6.8
Though S&S won't work on 1.6.8 either due to the light changes and stuff, so...
Yeah, I mentioned that I don't tend to backport my mods, and that S&S requires 1.6.9 too so it wouldn't help in this case anyways
Hm, I didn't consider if you left the old version of SMAPI in the minimum required
I updated a couple of mods that also worked on 1.6.8 still and left the old Api version because of it, but I wonder if that's gonna cause issues now lol
I have no idea if SMAPI's update check actually works that way, just wanted to make sure they didn't try to install newer mod version on old SMAPI version.
But for all I know it still reports an available update.
So re: SMAPI updates, it's purely mod version number based. So you could have two SDV versions of the same mod, but they'd need the same mod version to not cause update checks for anyone
If you're on SDV 1.4 using an old spacecore, you'll still get update notifications for the 1.6.9 ones
Oof
(As far as I understand, I guess I've never tested it)
Makes sense, since SMAPI would have to actually download the update and look in its manifest to know that it's not compatible with the current SMAPI version.
I wonder if setting minimum game version changes that
Probably all it looks at is the file version in the Nexus API.
Does not
Yeah, that would make the most sense
trollishly sets min game version to 2.0
In fact, I think one mod author screwed up the Nexus versioning and caused SMAPI to report an incorrect update.
(one that I know of, I mean; probably hundreds have done that)
Incidentally, the S&S feature that uses SpaceCore 1.26.x isn't a "critical" one... but it's one that helps users a lot and will reduce questions by a large amount. (The guidebook stuff)
And maybe even help with the Mateo misgendering
(Since pronouns are listed on the about page for each NPC)
Backporting is also just annoying 
I think u can use UpdateFull for that
It wouldn't be too bad for -> 1.6.8, but still mildly obnoxious
But it also includes a long hash
It's nothing compared to 1.6 -> 1.5
You say that now, but wait until we're on the SMAPI 4.1.26 patch.
(Kidding, Pathos! But whoever voted for 4.1.5 in the other day's deadpool is officially out of the running.)
Ah, interesting. (Also noticing I said mod build config and not manifest builder, but clearly you knew what I meant)
It looks like I could even use just Update
I didn't know that was a field
i think its relatively new (docs says added in 2.0)
adds that and minimumgameversion to common.targets
Oh no I'm on 2.1, minimumgameversion isn't until 2.3
Guess I need to change that too and hope nothing breaks
it always gives me this long version though "MinimumApiVersion": "4.1.6+09dd92a74f13a3edeccb72242015876d7b5f6463",
We just have to get all the different mod sites to add a new thing to their Api that broadcasts what version of the game the mod is for
instead of stopping at 4.1.6
Even with Update? That's odd
with update it stops at 4.1 which is ok for 1.6.8 and 1.6.9 at least
i usualy state on each update what verson its tested on
Ah, but if people could read this problem wouldn't exist
Yeah, in all my file descriptions I mark what version the release works for
(Important because I don't maintain proper changelogs since I'm lazy)
Or more like if people didn't have selective reading
Yeah, putting info in the mod description vs. putting it in the manifest are really for two very different audiences.
hm how would i make a custom asset that cannot be invalidated 
Make it a content pack I guess
A custom asset type, or literally ac ustom asset?
Like, couldn't you just load it with mod helper?
i can load and cache it ofc, but idk when it'd be fully populated for the first time
if i do it in gamelaunched it's empty bc of content patcher order of ops
You could probably do what SMAPI/game itself does and just force reload it if it gets invalidated.
Yeah, I think that's part of what you're supposed to do
You could cache it a few ticks after the save is loaded (to give CP and other mods a chnace to edit based on save tokens)
well the purpose is actually to avoid doing harmony patch more than once 
Well, I think I just heard enough not to want to know more.
so that is why i am hoping to obtain complete set o data at <unknown ideal point in gameloop>
"Harmony patch" and "asset invalidation" don't belong in the same sentence.
Hmm, my manifest builder isn't updating to 2.3.1
I mean, wouldn't inserting your own method that checks your data with a transpiler kind of solve that?
yea im sorry for committing sins
Am I missing something <PackageReference Include="Leclair.Stardew.ModManifestBuilder" Version="2.3.1" />
i would rather not patch every call to Game1.playSound
It's not mine to forgive - that's between you and your loving bug report page.
Relevant meme (though change "twice" to "thrice" if chu is doing something new, since Button's mod and Theme Manager are what I'm thinking of with twice)
Re: the manifest builder version, there was something about that in here the other day.
Compromise
(I think that's button's mod)
Clearing the package cache should probably fix it.
Did you try closing and re-opening? My VS has been being really stupid about updating my nuget's lately
Do your own content packs but PR smapi to accept optional content packs
That fixed it! 
I'm glad, though wish it weren't necessary lol
And yeah I'm getting the weird minimumapiversion too
Please, for everyone's sanity, do not write code that changes its behavior based on the caller in the stack trace.
"bother Pathos" route
@rancid musk Any idea why Manifest Builder would be doing this with <MinimumApiVersion_Behavior>Update</MinimumApiVersion_Behavior>? (Specifically the hash)
...I may have done that in a mod before
And how much did you regret it?
I can't recall if there was a good reason or if I just didn't want to write a transpiler
Yes, that area! 🙂 Sorry, I fell asleep!
anyways maybe i just table this half baked idea and make ModThatChangesTheShippingBinSoundsToSomethingElse for tea
Yes, it's in SpaceCore. It's horrific
I made sure it was a method that wasn't called too often though
Not that it excuses it
So I'm not exactly sure why option 2 requires adding transpiler patches in response to assets. Couldn't you add one transpiler patch globally, and have that patch check the current state of the assets?
the desired ability is to change what sound cue is called in specific context
I get that, but just separate the state from the patch.
If the version has a prerelease set, it changes behavior to include the prerelease. I suppose it shouldn't include the build if nothing else.
I want to do an update soon to add support for content pack bundling version updates, so I'll see about changing the behavior then.
but wouldnt i need to know where the sound is being played from 
But it needs to include the prerelease if you're building against a prerelease, otherwise when you go to test it your stuff won't load because 4.1.0-beta is older than 4.1.0
simple usecase is changing StardewValley.Buildings.ShippingBin.openShippingBinLid's "doorCreak" to something else
Well, isn't the prerelease the dash part? I mean the +hash part
What does "where" mean? If "where" means "what method" then it just seems like a suboptimal and fragile way to solve the problem.
Yeah, +hash is build and it probably shouldn't ever include that. So my next update will remove it.
Thanks! (That was the specifically the part I was asking about, I totally understand and agree with the prerelease thing)
You could do something similar to what AFS does for random checks, and scan all methods (or a large list of methods) for every reference to playSound, just transpile them all to do your check.
it does mean what method yea, and unfortunately there's not really any further info about the desired sound cue
Maybe I will finally figure out how to get nuget to not try to use the wrong dll version with the next update too.
I might ask gpt in case it can pull weird msbuild internal knowledge out of somewhere
Or transpile them individually, don't try to do the thing where content patches trigger harmony patches because it's kind of gross.
@ivory plume In a manifest.json, will build info in the semantic version (ie. "MinimumApiVersion": "4.1.0-beta.5+38a2d2d90049a9ad00e11d5e7ef638380ecb380c") cause problems if the user was on the same version but it didn't match or something?
I wouldn't think so based on when we've discussed the build info before, but wanted to double check
Presumably you know which methods you want to change the sounds of, so just add in transpilers to those methods.
I'm guessing chu wants to account for mods too
i dont know, not without another mod telling me they want to change this sound
So you're worried about adding a transpiler even if no mod has opted into changing that sound? Why?
The transpiler doesn't have to cost anything significant if no mod has made a change for that site.
Yeah, currently replacing sound cues is a very targeted thing, like if I know what cue I want a replacement for I can do it specifically for that, but creating a system that lets you do any on the fly is... I dunno seems impossible to me lol
Without rewriting a lot of the game anyways
oh look, finally a use case for custom content pack models
I think ppl will forgive you if you just roll that instead of using CP assets tbh
I wouldn't say impossible, but content patchers are either going to (a) pick from a list of known sound triggers that can be changed, or (b) point to an actual method in actual code somewhere, and personally I consider (b) to be madness, you cannot trust content pack authors to understand anything about the game code.
So assuming you're going with (a), just transpile all those known triggers, period, and the transpilers are no-ops if nothing has opted into that trigger.
Or C - ask somebody (you most likely) every time they want to patch a specific sound instance and then also every time the game updates and breaks it for them
theres 1131 hits for game1.playsound in the decompile 
Just transpile every method in memory
(Or use an infix if we were on newer versions of harmony...)
Just bundle your own version of Harmony and break everyone else's Harmony mods
im begining to think inspecting stacktrace is less sinful 
(Oh look, work stuff finally finished building)
There are a lot of sound triggers, yes. But turning that into something comprehensible is the point of a framework mod.
Otherwise you're just asking content patchers to do the work, and they may as well write their own transpilers in that case.
at least it'll be simple to abort
(I started when I started chatting here... yes it took 30min)
What's it building on, a toaster?
Inspecting the stacktrace is a bad idea. It'll make testing/debugging a nightmare, for one. Also, it's slow - you're adding a ton of overhead to every single sound cue.
That's a lot of content 
It's your mod, of course, and there's all kinds of madness out there that's probably far worse, but I wouldn't write stacktrace dependent code no matter how low the stakes were.
this is why i gotta sanity check with ppl here 
hides the spacecore link I posted earlier
back to ModThatChangesTheShippingBinSoundsToSomethingElse
Gotta love explaining patch names in their class name
Question I should have asked a while ago: Does the Ldarg start its count at 1 or 0?
0 - for non static methods it will always be this
(this being the object the method was called on)
class name that tells a tale of tragic romance
then 1 is the like Farmer who, Vector2 tile, etc, right?
Yeah
laughs in this is how I name my methods to avoid writing comments
For static methods though things will start at 0 though
instance methods basically have their "real" 0th parameter be this
i think Ldarg_0 is farmerrenderer in that method
public void drawHairAndAccesories so not static
static methods just have 0th param actually be the 0th one in code
Thanks! 🙂 I was just making sure I wasn't totally reading everything wrong!
Why not have an internal JSON dictionary (your own mod data) with a list of the types/method names to patch, and their "friendly" trigger name? That way the code isn't doing anything obnoxious at runtime, but it still only takes a few seconds for you to incorporate a new trigger. It makes your life (pretty) easy as a maintainer without pushing the responsibility of reading the source code and getting everything right onto random content pack authors.
i onlyh just woke up and barely followed what i was backreading but iwant you to know i will absolve you of any sins for any crimes you commit. i think you should do the weirdest and most sinful option personally
Just fyi for the person doing this
Do not rely on stack traces for release code
thank u for the vip ticket to hell button
(are you gonna take advice from someone who wakes up at 3 pm? /cheapshot)
It's not reliable in release mode
i have night shift responsibilities
Also would you take advice from someone who has a can of soda next to a roll of lead?
probably, i don't trust people who put canned meat inside working fridges though
tbh at this point i would just put that into a constants file that i update whenever someone requests a new thing of me
I don't get the roll of lead reference.
so that ppl dont explod thing by editing a json
Works just as well, I only suggested an internal file so that if some other user or mod author desperately wants to add something on their own, they can.
But yeah, not much different from a big pile o' constants.
Reality for whom/what, what's the significance?
that's atra's workspace, right now
is the lead sealed or not
and is the soda open or not
do mods have to target net6.0? Like is it acceptable to use a higher version?
no
No, it's not.
Until MonoGame updates, you're stuck on 6.0.
You can use a higher language version, but not target a higher net version
damn I wanted some of that new stuff 😦
you can use higher C# lang versions if you want
I don't even know how to find out what's different between versions lol, it all seems kind of cryptic to me
I too would like frozen dictionaries and abstract statics, but they are too fancy for Stardew.
but no go on higher than net 6 target
New quote added by chu2.718281828459045235360287471 as #6248 (https://discordapp.com/channels/137344473976799233/156109690059751424/1304541113755111475)
so we have button's last will and testament, and the sin absolver
mmm i eat json for lunch
personally im a fan caseys idea of auto transpiling every method that calls playsound. just call your function instead with an extra param that includes the source, ez
Button needs someone to absolve her of the crimes Avi has committed with the CP Harmony stuff
i dont need absolving if i never felt guilt
i never committed any cp harmony crimes
my harmony crimes are my own 
(1) crime, one skip prefix, that i set to last priority 
i'm sure this will be fine
Why so smol Discord
in SpaceCore link I posted earlier
ooo it works!!
How do we use debug commands to alter the 2nd screen for testing. Isn't it debug screen_1?
hey everyone, someone reported that : " I keep getting "Chatacter_Toddler_Male_Light_Winter has no Alternative Textures for this season" for some reason. Anyone know what that's about? "
On my AT mod for toddlers, but they aren't supposed to have winter sprites (or portraits). I wondered if it was a known issue (like, the game auto making winter variations or something), but i asked for a full log in case it's some mod interaction
So, my transpiler did something out of the index (this is following the example I was given and the documents I was reading of how to write the transpiler)
try
{
CodeMatcher matcher = new(instructions, generator);
matcher = matcher.Start()
.MatchStartForward(new CodeMatch[]{
new(
OpCodes.Call,
AccessTools.Method(
typeof(FarmerRenderer), nameof(FarmerRenderer.drawHairAndAccesories),
new Type[]{
typeof(SpriteBatch), typeof(int), typeof(Farmer),
typeof(Vector2), typeof(Vector2), typeof(float), typeof(int),
typeof(float), typeof(Color), typeof(float)
}
)
),
new(OpCodes.Ldarg_S, "position"),
new(OpCodes.Ldarg_S, "origin")
})
.SetInstruction(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ModEntry), nameof(ChangeActualOrigin))));
return matcher.Instructions();
}
catch (Exception err)
{
SMonitor.Log($"Error in ShirtDrawTranspiler:\n{err}", LogLevel.Error);
return instructions;
}```
Out of index usually means you failed to match the desired place to insert your code
I see!
I think it might be Ldarg_S not taking a string 
also why are your param load after the func call
Give it the actual number (as an sbyte)
unless those are params for another fn call afterwards
like ldarg_s, (sbyte)4?
They are just there as I found them in the example of how to make one; I take it I understood it wrong?
You need to give the CodeMatch I same order they appear in IL
i don't know exactly, but in the unpack the male toddler is now just "Toddler.png" and "Toddler_dark.png" so... is that it?
As it is written now you are matching for
- Call of FarmerRenderer.drawHairAndAccessories, the overload with that particular set of arguments
- Ldarg_S position
- Ldarg_S origin
Ok! Good, that's what I was trying to do.
I don't think those args r even correct tbh, does drawHairAndAccessories have overloads?
If it doesn't u can omit the list of types
After match u r replace the method call with ur own, presumably a method that has all the same args plus FarmerRenderer at 0, since both original and new are Call, something u can do is to set just the Operand to your method
the thing i am confuse about is that
i thought u r transpile drawHairAndAccessories
not transpile a method that calls drawHairAndAccessories
Oh it's screen=1 not screen_1...
I am trying to transpile this one:
public void drawHairAndAccesories(SpriteBatch b, int facingDirection, Farmer who, Vector2 position, Vector2 origin, float scale, int currentFrame, float rotation, Color overrideColor, float layerDepth)
```
This is the whole patch:
[HarmonyPatch(typeof(FarmerRenderer), nameof(FarmerRenderer.drawHairAndAccesories))]
public class FarmerRenderer_drawHairAndAccesories_Patch
{
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
SMonitor.Log($"Transpiling FarmerRenderer.drawHairAndAccesories");
try
{
CodeMatcher matcher = new(instructions, generator);
matcher = matcher.Start()
.MatchStartForward(new CodeMatch[]{
new(
OpCodes.Call,
AccessTools.Method(
typeof(FarmerRenderer), nameof(FarmerRenderer.drawHairAndAccesories) //,
// new Type[]{
// typeof(SpriteBatch), typeof(int), typeof(Farmer),
// typeof(Vector2), typeof(Vector2), typeof(float), typeof(int),
// typeof(float), typeof(Color), typeof(float)
// }
)
),
new(OpCodes.Ldarg_S, (sbyte)4),
new(OpCodes.Ldarg_S, (sbyte)5)
})
.SetInstruction(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ModEntry), nameof(ChangeActualOrigin))));
return matcher.Instructions();
}
catch (Exception err)
{
SMonitor.Log($"Error in ShirtDrawTranspiler:\n{err}", LogLevel.Error);
return instructions;
}
}```
what does the IL code you're trying to patch look like in ILSpy
IL_04f5: ldarg.s position
IL_04f7: ldarg.s origin
IL_04f9: call valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2 [MonoGame.Framework]Microsoft.Xna.Framework.Vector2::op_Addition(valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2, valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2)
IL_04fe: ldarg.0```
I am trying to put a different vector2 in at origin (which is what the old code was doing)
this was not at all what you were trying to do 
What's the difference between floors.png and Flooring.png? The latter seems to just be a more complete version of the former, but is the former used at all?
What would be a better way to do this?
i think you can insert instruction here
another Vector2::op_Addition basically
rn the C# is
position + origin + positionOffset + rotationAdjustment + new Vector2(16f * scale + (float)(num3 * 4), 56f * scale + (float)(num4 * 4) + (float)heightOffset.Value * scale)
the goal would be
position + origin + ModSpecialAdjustment() + positionOffset + rotationAdjustment + new Vector2(16f * scale + (float)(num3 * 4), 56f * scale + (float)(num4 * 4) + (float)heightOffset.Value * scale)
addition takes 2 vector2 on stack and push 1 back, so u need to find place to insert your adjustment vector2 followed by Vector2::op_Addition
i dont have examples of this for u but it should be doable 
I will give it a go!
it'll prob be more convienant to use MatchEndBackwards
https://harmony.pardeike.net/api/HarmonyLib.CodeMatcher.html#HarmonyLib_CodeMatcher_MatchEndBackwards_HarmonyLib_CodeMatch___
but up to you how u wanna do things
you know, looking around the unpacked content i'm starting to think Floors is unused hahah
Yeah, I get the feeling it's an older version that just became deprecated and CA forgot to remove
we've got TileSheets/Floors, TerrainFeatures/Flooring, and Maps/floors_2
I am willing to try all the directions!
Flooring seems to be for placed craftable floors, and floors_2 for indoors floor-painting
Floors apparently no references in game code or data files
perfect blue-berry 
should we poke pathos about removing Floors for 1.6.13 lol
i thought 1.6.13 was already out
it'd have to be 1.6.14
wow time flies. 1.6.15 then
i'm gonna win the bet, we're gonna land on 1.6.15
(watched paprika last night but red isn't very chic 😌 )
My mod keeps expanding in scope and I'm getting increasingly intimidated lmao
1.6.17 - recipes now use a proper data model format, every existing clickCraftingRecipe mods simultaneously explodes
I'm starting to think we'll end up on .20 with this speed
stick us back in beta, this baby needs to cook some more
I mean it certainly doesn't seem to be touched anywhere.
Nor does the vast majority of things in TileSheets, actually?
i was testing to see how many chaotic mods i can get away with and still load in mobile, but because the vers are so out of wack, i have given up for now
your search includes /, most string references would include \\
yeah
also some things likely have their tilesheet name to load constructed on the fly
OH FUCK
I still have all my changes to furniture.png saved
I thought I was gonna have to redo all of it lmao
remember to backup your work, save progress with source control, and work in a folder that isn't going to be removed or replaced 🥳
Nah, just a sheet of lead on the table next to my open cola
Lol.
My source control is my backup.
My photographic memory is my backup
Make sure to keep reminding us about that, it's hard for those of us without photographic memories to remember.
focus doesn't backup his backup 
the multiverse is my backup, if I lose my files I simply travel to another world that still has my files and kill the me that lives there
couldn't you just ask him for like. a usb stick
.... good point. Sorry Selph no 63528
where would be the fun then?
hm are there version control for image
or do u just make the photoshop undo history your backup
just git commit your psd? lol
Yes, it's called file1.png, file2.png, file3.png...
untitled tile sheet
Of course, you can check it into VC too (I do), you just won't get diffs.
I'm not kidding about the sequential version control, either; that's what you actually see with any kind of audiovisual media.
friendly source control software like Fork will give you a preview comparison of flat images at least, i doubt any will preview a psd though
yea ig theres not really anything u can do about diff of binary
could be like my clip studio paint, force me to make a file called (backup) because my desktop didn't register the update
There are screendiffing tools, so in theory the technology exists, but I'm not sure I've ever seen it used for that purpose.
Clearly Adobe just needs to switch their format to XML.
can you smell that? it's the smell of .psdx
yeah screen diffs are a thing
smells like defeat
they'll revive swf just for u
With .pngx and .jpgx hot on the heels.
the world yearns for SVG
every bitmap image can be represented with a sufficiently large svg
please mercy, i don't want to use illustrator for sprites
I haven't actually looked up reverse rasterization to see if it's a thing, but I'll bet it's a thing.
just write your svgs by hand
that's worse than making tmx files by hand
which wouldnt even be that bad all things considered
There's an example here with a disturbingly smooth vectorized phone: https://en.wikipedia.org/wiki/Vector_graphics#Conversion
CorelDRAW being the first on the software list, now there's a blast from the past.
Omg its so smooth
oh right
Github onion skin is pretty good
fingers crossed for you 
(slides in for a second, uh, am i missing more syntax on patch summary <unique id> cause i'm not getting the load of text for loaded/applied anymore, and they're for sure applied
)
Log Info: SMAPI 4.1.6 with SDV 1.6.13 build 24313 on Microsoft Windows 10 Home, with 8 C# mods and 2 content packs.
is your id not .ME instead of .MM
(i may be stupid)
halloween event got me screwed up doing debugging for mothman ig
(I moved the cola once I realized)
It's a great artificial sweetner if you ignore the health effect
HmmmMmmmmmMmmm
Re: image diffs earlier, github and gitlab both will show diffs for like pngs and stuff
Maybe that was already mentioned
Does anyone know how I can create a class variable in C# using libharmony? Would this be possible? I need to create a NetMutex variable in the StardewValley.Objects.Furniture class. My goal is to make the furniture locked in the cabins so that other players cannot remove the player's items. Would it be possible for me to implement the same feature as BedFurniture?
in BedFurniture
[XmlIgnore]
public NetMutex mutex = new NetMutex();
you don't need harmony to extend a class, can just do it
(they're not extending, they're adding a member to an existing class)
but in your case u can just use ConditionalWeakTable i think
(which seems like cecil devilry)
ConditionalWeakTable<Furniture, NetMutex> furnitureMutexes
i feel like there's easier ways of preventing other players from interacting with furniture in a cabin. a netmutex is likely not it
The idea is to implement the mutex in Furniture to block the items, just like you do with the bed.
if not mutex then u could store the owner player id in mod data
and patch the method that let you move furniture, return if player id mismatch
i don't think you even need the moddata property, just check the cabin owner id from the location
it won't block players who don't have the mod, though, ofc
but if u keep it u can block ppl from moving other placed objects everywhere 
you could but thats beyond their goal
Yeah, you can't add member variables to a class with harmony. (Just Cecil, which Pathos refuses to supoprt
) You can use ConditionalWeakTable like mentioned before to mimic it, but that serialize it if you need to. SpaceCore has an API for registering new variables to attach during serialization though
(You could also just patch the xml serializer at runtime like SpaceCore does)
(But that's kinda scary)
I prefer to do something that only the host needs, as the idea is to protect items on vanilla servers.
I don't think you can do that
And adding a new net field would prevent players without the mod from loading it anyways
again, nailing a netmutex to an existing class sounds like overkill for blocking players from moving items in cabins not owned by them
to say nothing of patching the xml serialiser
stardew is a very client trusting game
I don't think it's possible to prevent clients from removing the furniture without having the mod too
You could theoretically just re-add it when that happens, but then the client still has a new copy of the item
Actually...
Would it be possible to create a lock for the cabin?
Hmm. Probably not. In theory you could redirect the farmer to somewhere else if they try to enter someone else's cabin with some invasive multiplayer patches, but that would probably confuse the other client a lot
I once tried to lock the inventory, but it gave me a lot of problems.
Block while in someone else's cabin
Hmm, can't use Furniture.AllowLocalRemoval since that's not synced or saved
CanBeGrabbed is ignored (probably since it's an object field)
Yes, I have tried this CanBeGrabbed field several times but nothing happens and I can still grab the items.
There is an incredibly hacky way to make it where nobody could move the furniture at all even without your mod (by putting a dummy entry in Furniture.sittingFarmers), but I can't think of a way to do it for everyone except the player owning the location - without the player having the mod too at least
<..< my eyes are swimming with code i have so many edits i have to do and test
worse part is all tests seem to work smapi not even giving me yellow warning its going to well im concerned that its not gona work when i get done
question if i use action: include does it support when statements?
Yeah
mmm from the included json not within the argument
What is this Furniture.sittingFarmers for?
A question about the mutex, this issue of it being initiated using [XmlIgnore]
Is this something to do with multiplayer?
Or something else?
that prevents it from being part of save serializer
XmlIgnore has to do with the save serializer, which I don't know enough about to know why you would intentionally remove stuff from it
Although I suppose for this I kinda get it, you wouldn't want to save with a player sitting in it and then load with one not in it but have it stuck locked
If I just created the variable normally in my class, public NetMutex mutex = new NetMutex();
And used the variable to lock the furniture, applying it to all the modifications I need to make
In the initNetFields() method
.AddField(mutex.NetFields, "mutex.NetFields");
In the DayUpdate() method
mutex.ReleaseLock();
And several other methods, like AttemptRemoval, updateWhenCurrentLocation
That have things to do with the mutex, would that make the furniture the same as the bed?
Some net types are automatically serialized aren't they?
it is kind of concerning that you are design mod that doesnt expect all players to install same version of 
Which would piss off the serializer if you aren't registering it with SpaceCore
wouldnt the other client still need the mod in the first place to care about the new mutex anyway?
Yeah I really do wonder what would happen in this game that's seemingly not driven by host authority lol
My goal is to make an anticheat, which serves to protect players from everything, including mobile players, who unfortunately cannot use mods.
Maybe it would be fine on the side of the mod holder but break on the non-modded
could just aggressively crash game if they dont have it installed 
i was worried that's your goal hahah
if the other player does not have the mod then i dont know where the netmutex would even sync to in the first place, im pretty sure it wont just create a new netmutex for them
in other words, the other client can just ignore it
this mod should serve ur purposes
I would say if you're gonna play with mobile players, don't play modded lmao
that too its just bad time all around 
Wait the 12-34 months for Zane to decide if they're gonna actually make SMAPI mobile for 1.6.9/10/11/12/13
I managed to protect the chests using mutex, and the mode needs to be on the host only.
If the other player doesn't have the mod, they'll get the dreaded no cabins available thing (or is it connection failed?) from net field mismatches
That's a problem for any mod who adds netfields
Why wouldn't it be the same with furniture?
chests already have mutexes
you just cant add a completely new mutex and expect the client to somehow magically get and respect it
You can expect it, but it won't happen 
certified
message
Who knows, maybe one day Erick will implement mutex in furniture. ç.ç
!officialbug
If you've checked that it's not a mod bug:
- Report gameplay bugs to the Stardew Valley developers here: https://forums.stardewvalley.net/forums/12/ (do a quick search first so you don't report something they're already looking into).
- Report typos or translation errors here: https://forums.stardewvalley.net/forums/32/
Alternatively, you can emailsupport@stardewvalley.net
i dont see why he would
Worth a shot to the suggestion forums
Just make a really good case for adding new content and it might happen, despite everything a couple new things have trickled in lol
The thing casey is suggest earlier with sittingFarmer is basically, find a existing netfield that has furniture movement blocking feature, and repurpose it
That's prob the only viable way, even if it's big hacks
Did he not imagine that there would be certain thieving players entering our game just to troll us and remove our furniture?
Sdv isn't built to be multiplayer pvp
The game didn't even have multiplayer in the first place lmao
It didn't even start with multiplayer lol
its inherently a "trust the client bc you trust your friends" setup
If your friends can't be trusted to not troll you, you've either given them the wrong impression about you or they're not your friends
I think the separate money is the only pvp-ish feature in vanilla right
Don't they also need to be ticked
calling that pvp is a big stretch
This is such a bad idea
Vague gestures at competition let's say 
Separate money is PvP in the same way separate bank accounts in a relationship is PvP
yeah ive never personally used it for competitive purposes
mostly just "i wanna be able to buy what i want without accidentally ruining my partners financial plans too"
competitive pvp is fighting for the last $20 in a shared money farm
If anything, it makes you get more money technically doesn't it?
Oh does it
Or does it evenly split?
I thought it tracked who tossed what into bin
I did multiplayer like one time and it's been a while lmao
Mismatched netfields is a terrible idea
i also thought it tracked, but ive never paid attention and only used it once
If you're lucky you just prevent clients from joining
in one playthru rather, that didnt last too long
Button was my last hope, who else even plays multiplayer lmao
If you're unlucky you randomly crash the game and get on my shit list
It tracks
Tl;dr stardew not designed for assholes
Competitive parsnip growing and chicken petting
Find better friends
i thought avi played multiplayer but i might be making that up. sorry avi to be assigned multiplayuer player if not
Oh ok, so it "could" be "competitive"
I would play mp with you, Button
I really wanted a Stardew Valley MMO, each one on their own private farm, and just the community town, with item exchange and everything, it would be perfect.
anything can be competitive if you have enough of a competitive spirit
I do think it'd be qol to not accidentally ruin ur friend's interior design so I support you making this mod
yeah you would absolutely not get Stardew Valley MMO while expecting only the host to have some mods
It's just technical limits with how mod and multiplayer mix
If we had any amount of off work awake hours that overlapped
Just track every piece of furniture placed in every house/cabin and when one is broken, delete it from the players inventory and place it back down in the location
If you want a stardew mmo I suspect you start by "writing a new multiplayer backend"
i would like to say id play MP with anyone in here i personally know but also the actual likelihood of it would be "probably not but its 100% not personal"
I don't think people here play game period
I also disliked the way sdv days interacted with scheduling a block of time for coop
It's not like minecraft where u can be like lemme login and see who is around
it would be a pretty big blocker for an mmo for sure too
For example, I signed up for a month at Bisect, to have a 24-hour server, then 2 days passed, and they stole everything there, chests, and furniture... people gave up playing on my farm.
stardew just straight up is not designed with that kind of server usage in mind
Time cycle in SDV is one of my least favorite features of any game like it
you will not be able to prevent those sorts of things while also supporting every other client being completely vanilla
it's not designed with multiplayer in mind at all
there'd also not really be a way to prevent a client that isnt vanilla but modded to be able to ignore any of your safety checks from doing the same things
I mean in theory there is a way to do a dedicated server
My anticheat requires the person to have the mod to enter, if that is the case, I have implemented that.
if they are required to have a mod to enter, then you can implement your mutexes so long as you serialize them properly and whatnot
I could trivially make an empty mod with your unique ID lol
but that also still doesnt prevent them from having another mod alongside it that just overrides your anticheat mod
or yeah, faking having your mod in the first place
But also like
Find frens in same timezone 
I would rather only play with people I trust, says former modder with no free time
"former"
i thought that was a threat at first bc of that typo
I can build a client that automates the mod process, like Minecraft's tclient, but with security features, a websocket server that generates random IDs that will work for that player at that specific moment, so the software would obtain a secret password and connect to the websocket, which would return the IDs, and rewrite the mods' manifests, in addition to doing a checksum on the DLL, verifying that the DLL has not been modified, nor any config that is in the mod, then the game would open.
what stops one from adding another mod that stops yours from working
Damn, why not just make your own farming game at that point
Yeah, C# is way to easy too decompile to worry about that
also like, you can do whatever you want, sure. this kind of all goes way beyond just "can i add a mutex to stop an unmodded client from doing this" though
What is the target audience you have in mind here 
(Side note, I kinda hate when people say that as if it's at all comparable to making an overhaul type mod)
But the anticheat would block any unauthorized mod from entering
If I really want to play coop but had to do all that to join your farm
Fair, it's just a lot of work for one thing
What happens if they make it where your mod can't detect theirs
You can harmony patch other mods
I'd just start my own farm in #1139016532966506576
the only answer that works is proper server-side validation of things the clients do, but good luck with that hah
plays sudoku instead
Yeah, too much of the game does stuff client side
Would my stupid code finish running in the next decade pleassssseeeeee
Like, when you swing your pickaxe on a rock, the destruction and item spawning is handled client side
Unlike, say, Minecraft
In this case, it's no use, because the anticheat is made to work on the host, what it does is detect the mods that are on the clients, and compare them with the list of allowed mods and if it's different, it kicks the person, but if I put dynamic IDs in the anticheat, it would make it much more difficult.
What prevents a custom smapi build which doesn't tell you all the mods installed
That would be very easy to do
"it's no use" is very apt here
I miss sudoku
Not saying it isn't worth making an anticheat, but someone determined could easily bypass
custom SMAPI is probably more hassle than Harmony patching SMAPI not to report your mod
True
Custom smapi is ez
Yes
You just fork it and pathos is amazing and puts everything in nice to understand places
Unless it's in SCore
But I imagine that these "Furniture Thieves" are not mod developers, so just blocking the mutex would be enough to stop, at least most of them.
But if you want to distribute it, it's easier for someone to make a mod than a custom SMAPI version
idk about you, i already have a modding setup prepared, but don't have the SMAPI repo cloned
Say is there way to make a HarmonyMethod from a delegate that has to access some value I assign at runtime
I have the smapi repo cloned
I don't think so
Why do you want this
I think i need to make that delegate static somehow 
Harmony can only ever call static methods as patches
Using an obfuscator, wouldn't that leave the dll protected?
has to do with its serialization stuff
Obfuscation is not security
I was trying to automate a bunch of similar transpilers
why not just dynamically create the method at runtime and send it to a patcher. you dont need to patch right on gamelaunched
There is no way to secure Stardew multiplayer. It's fundamentally insecure. Just don't play with people you don't trust.
Obfuscation just changes methods names and stuff
I guess it's time to source gen?
I've worked in obfuscated code before, it's not very insurmountable
To write these very similar transpiler static methods ahead of time
yeah i've written a bunch of Minecraft mods back when deobfuscation wasn't a thing
I read obfuscated JavaScript for my day job. It doesn't stop me at all.
unless im misunderstanding it doesnt seem that different from what BETAS does
Isn't there some way to protect a dll?
Hmmmm
i dont know what you mean by attributes in this context but good luck
Chue means decorators of course
Well I just need some way to put in 2 strings at compile time 
i thought you said you assigned them at runtime
Yesterday I was doing CallerFilePath which I understand to be that
Nah, that is compile time
I did, but I do know about them prior
It's just some static consts
So C# is the worst language for anyone who wants to protect their code, because everything in it becomes a DLL.
(to be clear, i know what an attribute is obv, just didnt know what chu meant with regards to how they'd help what they want to do)
But like a list of strings u know
I don't want to write a different transpiler method per string here
You can also like, perhaps, make your transpiler call a static method
That takes a string as a parameter
Yeah that's the backup plan 
what's like, the big picture goal here chu
can't you just invoke your patch method once for each string in a list?
Is the sound cue shenanigans button
(Wait till you learn about decompiling native code.)
but what're you trying to do with these transpilers
I am give up on custom asset bs for now so I have a constant list of (methodinfo, old cue, new cue)
I want to transpile the method at methodinfo and replace old cue with new cue
And in this case I just want to be able to reuse some code
Rather than make 1 static transpiler method per thing
i dont see why you couldnt do that in a for loop by storing the current list element in a static variable at each iteration
i think im confused on why you'd need attributes or anything then and can't just for each over your list and generate patches
Wouldn't the static variable just end up on the last thing though
You can also inject the methodbase and switch over that lol
By time HarmonyMethod is evaluated
Unless it is different for transpiler somehow 
Where they r immediately eval for some reason
Perhaps I am tunnel visioning here 
to be clear when I say generate patches I mean by constructing the actual patch method itself from the ground up too, and putting your string in there
not just calling Harmony.Patch in a for loop and calling it a day
Is it some emit IL thing button 
i have no friends, but i was testing spami modded with a mobile join
that's what I do for BETAS
BETAS just creates post fixes and prefixes but there's no reason you can't create transpilers
Ok I'll steal your homework 
Huh that's cool
you do have to emit all your own il though unless there's a better way I don't know about
And create the method signature yourself
It should actually be a lot easier for transpilers though since you don't have to worry about getting the parameters correct
there was, of course, no documentation I could find on the Patch factory method I employed with Harmony so there very well may be a better way
So u could make functools.partial in C# this whole time 
i haven't the faintest what that means
It's the thing where u bind arguments to a function
Chu really likes goofy currying stuff.
And produce a new function that no longer requires the 2 arguments
i will take your word for it then
But look a usecase that isn't covered by local methods!
unless that's in response to the parameters thing in which case I just meant transpilers all typically have the same parameters that don't need to match the function you're patching
Covered by lambdas, I'd say, but sure.
The problem was need for static method in a patch
also I'm gonna put "Huh that's cool" on my resume
"Volunteer Supervisor, signed off on my codework with a nod and a soda in hand contaminated by lead"
the way around the static method thing is that you still make a static method
It wasn't in response to that
it just returns a DynamicMethod
I see what he means though, a curry would be a lot more straightforward than ILGenerator business.
all the relevant stuff should be in my DynamicPatcher.cs I don't think I left anything in ModEntry
(Not to mention, a lot faster, but it probably only needs to run once)
feel free to copy as much or as little as you'd like
Yeah I see how it work ty 
Once unless someone else repatches a method, I think. Iunno
It's definitely probably not the most performant maybe but it's fiiiiiine
If it's only done on startup then meh. Atra has a fit over that stuff but I think no one else does.
atra said it was cool and is not allowed to take it back now
I think he meant "cool" as in "interesting" and not "copacetic".
(Atra doesn't care anymore)
I'll still take it
Cool code is cool.
Performance in stardew is ducked nine ways to Sunday already so I don't care lol
You say this, but then every few days you like to get deeply involved in one of these problems...
One day I'll break free for good
it probably does recreate all the il emit stuff every time my custom asset is invalidated and I unpatchall tho
you know what a Switch is?
Thing I buy at home depot for a dollar
yeah you got it
They made a second one. I hear it controls two outlets
I want a curry
This has been out for a while now actually, they even go up to 4
spicy or bust
Spicyyyyyyyy
love of curry, the vast variations of curry--
what regional variant of curry
Oh. Rainnnnn
idk what region it is, that golden curry block i get at the asian grocery store with like a solid 2 tablespoons of gochujang usually does it though, i could probably make an entire expansion on all the variations on curry 
(I am. I can do two things at once.)
im not. im retired
Since when?
mac has killed button
since atra changed the definition of retired
(but realistically, i probably am on "minimal work" mode until around mid december)
Technically, Atra's definition of retirement tracks with that of most actual retirees, except that he was never making money off it to begin with.
atra r u done with aquarium
(No)
Also need to PR pathos to fix the lookup for fish data for fish with special gsq
Fish with special GSQ? You're going to break my fish stuff, aren't you.
Is this GetFish affecting?
No, it's just that lookup anything currently displays the wrong thing in that case
Nothing to do with game code at all, just a lookup anything display issue
Oh, never mind then.
ah, things arbitrarily not tokenising. my beloved
@tardy adder: check if I broke something with pdw (22h ago)
@next plaza Hey Casey, sorry to bother you - I spotted a comment on Spacecore's Nexus that I'm not sure if you've seen, and it seemed like decent critique. I know you're taking a step back at the moment, but I wanted to make sure this didn't get swallowed by time.
Weird tbh
Report it to pathos
Isn't that a UI Info Suite 2 issue?
unfortunately it's a phat mod with a phatter content pack
(iirc casey has already noticed this anyway and its a UIIS2 thing)
and im lazy
What is {{PATH}} suppose to resolve to
Not sure! Wasn't my comment, just wanted to make sure it didn't disappear! But if it's being looked at, we're all good. ¯_(ツ)_/¯
game content asset key root, but that's not particularly important. no tokens resolve in these nested data models
Not to put too fine a point on it, but I think if we wanted to read Nexus comments, we'd read Nexus comments.
This be weird though
That does sound like bug yes but I remember it working fine for machine data which was also very nested
Tis was back in 1.6.8 though, several versions ago
Yeah I would ask you to backdate everything and test in 1.6.8 but that seems like hell
#making-mods-general message
Knew I had seen it, didn't realize it was from yesterday lol
Join me in sock knitting while waiting for code to finish?
IL decompiled code is a gateway to madness
(for context array is never used anywhere else below)
Not sure about this instance but I've found the compiler itself likes to do that a lot.
Like, if I declare a simple struct type and write one statement initializing a few properties, the emitted IL has two locals for that struct.
The last few lines assign the second local struct to the first local struct and then return the second local struct. Utterly pointless.
Just so I make sure I am understanding this correctly:
IL_04f5: ldarg.s position
IL_04f7: ldarg.s origin
IL_04f9: call valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2 [MonoGame.Framework]Microsoft.Xna.Framework.Vector2::op_Addition(valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2, valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2)
Call Valuetype is adding the first two together, right?
ValueType (the type) is not part of the call, it's just saying that the referenced type happens to be a value type.
But, yes, it's calling the static op_Addition method that is generated from the operator + definition.
So I want to insert after that one, then. And then, I add my vector2 method, and then, I do another op_addition?
Not clear to me what you're asking. You can of course chain op_Addition calls as long as you respect the stack.
here is what I did, but it breaks CLR:
CodeMatcher matcher = new(instructions, generator);
matcher = matcher.Start()
.MatchStartBackwards(new CodeMatch[]{
new(
OpCodes.Call,
AccessTools.Method(
typeof(FarmerRenderer), nameof(FarmerRenderer.drawHairAndAccesories)
)
),
new(OpCodes.Ldarg_S, (sbyte)4),
new(OpCodes.Ldarg_S, (sbyte)5)
})
.Advance(1)
.SetInstruction(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ModEntry), nameof(ChangeActualOrigin))))
.SetInstruction(new CodeInstruction(OpCodes.Add));
return matcher.Instructions();
respect the stack. worship the stack. forfeit all working memory to the stack.
Jokes on you my memory doesn't work
I literally responded to it yesterday?
I don't touch FarmerRenderer, but as I said, respect the stack; after one op_Addition there is already a value on the stack, so if I'm reading this correctly there should only be one ldarg before the call.
In my mind, what I was doing here was finding the match, advancing one, to get past the op_addition of the first two, then, add my method, which yields a vector2, then Add the two. I guess that's not what I did?
It would be easier to see what's going on if we could see the transpiled IL (using Harmony debug) as opposed to the original IL + transpiler code.
So, not the ILSpy code, then, generate some from VS?
Just slap on a [HarmonyDebug] attribute so you can see the final IL emitted.
https://harmony.pardeike.net/api/HarmonyLib.HarmonyDebug.html
You'll still get the debug output even if the IL is an invalid program.
Oops, couldn't parse that file. Make sure you share a valid SMAPI log.
Uh oh
Yeah, so I see this:
IL_03DF: ldarg.1
IL_03E0: ldloc.s 8 (Microsoft.Xna.Framework.Graphics.Texture2D)
IL_03E2: ldarg.s 4
IL_03E4: ldarg.s 5
IL_03E6: call static Microsoft.Xna.Framework.Vector2 Microsoft.Xna.Framework.Vector2::op_Addition(Microsoft.Xna.Framework.Vector2 value1, Microsoft.Xna.Framework.Vector2 value2)
IL_03EB: ldarg.0
IL_03EC: ldfld Microsoft.Xna.Framework.Vector2 StardewValley.FarmerRenderer::positionOffset
IL_03F1: call static Microsoft.Xna.Framework.Vector2 Microsoft.Xna.Framework.Vector2::op_Addition(Microsoft.Xna.Framework.Vector2 value1, Microsoft.Xna.Framework.Vector2 value2)
I'm not sure if the transpiler is even inserting into the right place, but assuming it is, there are two (wrong, ignore; however, there is no reference to ldarg.s before the first op_Addition and then two more values (ldarg.0 and ldfld) before the second. Which means that (a) the result of the first addition doesn't contribute to the second addition, and (b) there's an extra argument left on the stack.ModEntry.ChangeActualOrigin anywhere which is suspicious)
After a call or callvirt, the arguments are consumed, and any return value goes onto the stack in their place.
solved: tokenising a key in a dict will prevent values from being tokenised
not sure if this is documented/expected behaviour?
log: https://smapi.io/log/4293a8cedbc94fff81cb9bf1724973a9
patch export: https://smapi.io/json/none/574c964a8d8f46e7adbb4c496f8f75d8
min repro solution + content pack:
I took out the Advance, it no longer makes the CLR error, just a out-of-index error.
i feel dumb lol >.> but im getting smarter just gota remember when copy and pasting things to change the path data ....
Actually, I might've been hasty at identifying the problem earlier since the ldfld is going to load a field from the ldarg and therefore is probably OK. That's my mistake.
But I don't see any reference to your ChangeActualOrigin anywhere in the IL output; I'm not sure where the transpiler even is.
You also probably don't want SetInstruction? That's going to overwrite whatever is there. Are you trying to add new instructions, or replace the ones there?
I kind of want to replace the origin there, like (i think) the previous transpiler did
Does anyone have an example of using ModBuildConfig's new <ContentPacks> feature? I am investigating adding support for it to ModManifestBuilder.
uuuuuuhhhhhh since no one's posted may as well post my shitty mod lol: https://github.com/zombifier/My_Stardew_Mods/blob/master/SpookyVoidChickens/SpookyVoidChickens.csproj
I believe you can also include more than one
I'm not too keen on learning FarmerRenderer myself, all I can say is that from the log that was posted earlier, there's no evidence of the transpiler having done anything at all. Maybe [HarmonyDebug] wasn't added to the right place? (It should be added to the transpiler method)
I just wanted to see someone using it in production so I know I'm setting up my test project in a sane way.
I put it at the top of the thing:
[HarmonyDebug]
[HarmonyPatch(typeof(FarmerRenderer), nameof(FarmerRenderer.drawHairAndAccesories))]
public class FarmerRenderer_drawHairAndAccesories_Patch
{
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{```
I'd try putting it on the transpiler method, though not sure it'll make a difference.
I assume this isn't a new issue? If so, can you report it on the GitHub repo? I'll take a look once the dust settles for 1.6.9+.
Another thing I see is the use of OpCodes.Add, which is simply not the same thing as calling the static op_Addition method. OpCodes.Add is for primitive arithmetic.
You sure this method is called ChangeActualOrigin? It's definitively not in the debug output.
I see! How does one call the op addition method?
It's a (static) method, you have to get the MethodInfo for it and call like any other method.
I see! THanks!
Hmm. I could probably just do like xml <ContentPacks Include="SomePath" Version="Update" /> since ModManifestBuilder runs before ModBuildConfig's deploy task. 🤔
And have it open that ContentPack's manifest and update its version.
I just need to test if I can then write back to Version so MBC sees the correct value and not "Update"
(Little tweak in the next 1.6.x update: entering an invalid debug command will now list similar command names.)
(Would be cool to have the git feature that automatically enters in the most likely command after n seconds 😛 )
I'm...mostly kidding
(Probably not a good idea, since some debug commands do fun things like clearing all your mail flags.)
This is so handy! I am always typing debug farmhouseupgrade instead of debug houseupgrade
Machine Terrain Framework now has an item query that straight up just simulates the vanilla crab pot logic, down to professions and bait effects. now you can make higher tier crab pots if you want
https://www.nexusmods.com/stardewvalley/mods/22975
(I don't usually post minor updates for my mods here, but I took enough psychic damage looking at the crab pot code I thought I deserve it)
(Got it. It should pick the most dangerous command and automatically run it.)
Delete mail flags! Remoce all of networldstate!
i haven't tried this behaviour on any earlier versions of CP, so i'm not aware if it's a regression or not. i'll post a report soon though, thanks 🥪
it does this? I feel like I'd set my computer on fire if it does
I know it suggests similar commands, but I'd not want it to straight up just run a command lol
I set it to two seconds
you mean you're typing debug farmhouseupgrade instead of debug hu 
Yeah of course...I definitely use the shortest way of typing every debug command...
oh to mourn for those wasted keystrokes
Join the rest of us who have the game debug commands memorized lol
I can't remember them when they're so short xD
wow lol
this looks very convenient, if not for my unwillingness to have a machine correct me in any capacity
I enjoy it when the compiler tells me I'm a bad programmer and should feel bad
Because I am a bad programmer and it's nice the compiler noticed before the code crashed over something stupid
if only VS autocomplete didn't give up on backspace and ignore you until you've deleted all the way to the last operator
compilers give advices, like friends. this command autorun takes my fingers and presses my keyboard for me, like a work adversary
if only VS somehow had the same beautiful fuzzy matching as VSCode
(for legal reasons that was a joke. I do not have an arch nemesis at work)
why not
that doesn't try and complete stnr to include some obnoxious security package class type with a name longer than my file instead of realising I was trying to write 'string'
(not any human ones anyway)
(sounds like the nemesis is in chat)
(So the cat.)
(I dunno if you can consider the normal animosity of cats as nemesis)
I decided to test my patch without any inserts or SetInstructions. Without anything, there are no errors. Does this then mean I have codematched poorly?
Do you have a "throw or log if not match" clause
yes.
Could need to be more explicit with the match
It was throwing earlier the same error as the smapi was throwing (both were happing)
have you walked through your transpiler with debug steps to check your indexes and methodinfos are resolving correctly?
if not, offer an explanation of up to 200 words
(30 mins, 5 marks)
so this is like a call valuetype [MonoGame.Framework]Microsoft.Xna.Framework.Vector2
Opcodes.call, Vector2
Sorry, what does resolving mean?
(I did debug earlier today, but not recently)
that they return a value you want, such as a methodinfo with the correct signature
as in solving an equation, resolving an operation
(Also, I am an amazing writer; could give 200 word bullshit excuse easily in 5 mins! 🙂 )
Up to 200 words? "Don't wanna"
0 marks
I never debug my transpilers lmao
Neither do I. Either they are perfect on the first try or I throw a fit and do something else instead
you sound like my transpilers
(I actually have a very good rate of transpiker right on the first try.)
i have just done a (narrowly tailored) skipping prefix for my current thing and i feel bad about it. but this also feels like a rare case where a transpiler would be worse
im a strong proponent of "transpilers are always the best" so i cant agree
skipping prefix is better. think of all the transpilers you're preventing
the two genders
if i ever find out someone is prefix skipping my carefully crafted, artisanally made transpiler, im unpatching all of their stuff
Lol
i fully intend to skip clickCraftingRecipe for loc 2.0.
no i will not include any crafting behaviours.
flashbacks to DTZ breaking my entire mod over a prefix it didn't even need to do
Have you considered a nice warm soak in Epson salts
is that a loc ingredient
no, my printer is using those rn
enjoying a relaxing acid bath atm
also ichor if you're willing to expose your crimes may i ask for curiosity's sake what function you are skipping and for why
coming back for update my mod. is SV .net 5 or 6 again?
6
i'm not american and i don't intend to change that 😌
patching Object.drawPlacementBounds to change what is rendered in the red/green preview square for my item specifically
?? since when is lox american
i don't know anywhere else in the world that calls it that. norway maybe?
what else would you call it...
lox is yiddish, innit
'smoked salmon'? lol
lox is not smoked salmon, though
you can smoke lox. but you dont have to
its cured
the word itself does also come from yiddish yes

i've never heard of unsmoked lox
well, thats what lox is
its just cured salmon
a lot of times people do make smoked lox but its not the original lox and is just a different variety of it
definitely not american, in any case
anyway, the important thing is skip-prefixing seemed less fraught than transpiling into Object.draw, which actually draws the item into the colored preview box
think of all the fun you're missing out writing IL though
who wants to write boring ol normal C# nowadays
heyo random question, so like, say I'm making a mod and I want to add a recipe to a shop at the start of year 2 using content patcher. would in my shops.json file I just put
"IsRecipe": true,
"When {
"Condition: y 2": true
}
I know in json assets, you had the "PurchaseRequirements" field but I'm not sure how that translated over to content patcher
you can juset set the Condition field on the shop entry to "YEAR 2" (i think thats the gsq format anyway)
oh pog that's even easier
yeah its YEAR 2
tyvm
the Condition field takes a Game State Query which determines whether or not the item is sold
i didnt notice you wrote Condition inside your When though dont do that
just use the Condition field in the shop entry itself
Hmm what would be a better practice
having custom maps dumped into my mod or already having the assets there but accessing the loads requires the mod be active?
oh you don't? Is that true for conditions in other places too?
like gift tastes for unlockable npcs after they move to town and the like?
a Condition field is a vanilla field thaty some vanilla things have. nothing to do with content patcher
When fields go at the same level as Action
Condition and When are similar ideas but different fields, any CP patch can have a When but not all things have a Condition
https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide/tokens.md
Can read more about When on the CP docs
When is for content patcher, and determines which parts of your mod CP applies to the game content.
Condition is for the game, and determines which parts of the existing game content apply/are used.
(Conditions on that page is the basic info and the rest of the page is about the tokens you can use in CP, with many being good for When)
ohhh okay
Irony.
You're reading it incorrectly. You can't call a type, only a method. (The debug output/log/etc. you're reading might show the type first, but there will always be a method call after.)
can we add comment in manifest file?
hi, if i made a mod where shop selling unobtained furniture statue, will it affect gameplay in the future or it's safe because its only for visual? furniture like Solid Gold Lewis, Statue Of Perfection, Soda Machine etc
what do you mean by only visuals? are you adding furniture items that look identical to those items to the shop?
if you're actually adding those items to a shop to sell, then it will affect gameplay in the sense you let players access those items outside of their intended means
just so you know, 1.6.9 added ||a shop which will sell items like this which are only obtainable once and which you somehow lose||
Hello @ivory plume would it be ok to get these in FarmerRenderer made public?
private Rectangle shirtSourceRect;
private Rectangle hairstyleSourceRect;
private Rectangle hatSourceRect;
private Rectangle accessorySourceRect;
internal Vector2 rotationAdjustment;
internal Vector2 positionOffset;```
Done in the upcoming Stardew Valley 1.6.14.
Mmm, publicly mutable state, and on the FarmerRenderer to boot. I too like to live dangerously.
Okay not a code question, however -- do folks have a rhyme or reason to determining how npcs feel about new objects/determing gift tastes? I'm definitely trying to base off of existing preferences, but was curious
ey if you install mods its your own fault 
tbh i base it on lore, my mushroom mod makes it so everyone except uh, demetrius, linus, and the wizard hate it 
I think wether their status(child vs adult, profession, personality) makes them like/dislike something. if not, I just leave the general gift tastes from vanilla
makes sense. I'm just trying to figure out how I want to approach different items
to be fair, because they're cooking recipes I feel like the stakes are a little bit lower, cause I don't think gifting is people's first inclination with cooked items
But ¯_(ツ)_/¯
Thank you both
(tbh, that is my first inclination with cooked items)
possibly, i did make the mistake of adding the whole artisan category to a liked/loved taste and that was a mistake
the one or two foods i will keep on me the most are the ones that are the most universally applicable for gifting
oop
Can anyone tell me the reason why Ridgeside Village's custom boots cannot be edited?
(please use the smapi uploader when posting logs or json)
Idk I will probably just extensively consult the wiki and go with my gut. E.g., Caroline doesn't especially like oranges but she loves tea and her sunroom as well as curry and tropical curry, maybe she'll love this citrusy orange scone with her tea
Log Info: SMAPI 4.1.6 with SDV 1.6.13 build 24313 on Microsoft Windows 11 Home, with 29 C# mods and 12 content packs.
I can edit SVE's custom boots just fine.
are you ensuring that your mod loads after RSV?
May I ask how to do that?
one of the easier ways is to just set a dependency in your manifest
Ohhh, okay, I'll try doing that then.
Thank you!
Thank you! It seems to have worked. 👌🏼
Update: The next ModManifestBuilder will let you just do xml <ItemGroup> <ContentPacks Include="[CP] Thing" /> </ItemGroup> and it will automatically update the version in manifest.json and also fix it so ModBuildConfig doesn't whine about the version not matching.
I think I figured out how to fix msbuild using the wrong DLL version too, when MMB updates.
is there a way to abort loading of my mod when a specified other mod is loaded?
I don't want the new VPR to be loaded if people forgot to delete old complementary mods for it
e.g. if (Helper.ModRegistry.IsLoaded("grapeponta.VibrantPastoralSVE"))
you can just stop it from doing anything and log a warning or error or something
Hello all, I need a lil example how to add vanilla ocean fish to a custom map. I get only trash by fishing.
what are you trying to do currently?
I'm working on a custom map. It should add a new small location with a beach. With berry bushes, a few trees and spawning items. My only problem to get fish inside this new area. I can only catch trash in the water.
Trash is extremely prevalent in farm maps*, did you already set the fish in your new location?
How to do this? Do I have to change this in .tmx or in the .json?
JSON is a standard format for machine-readable text files that's used by Stardew Valley mods.
If you need help with a JSON file, you can upload it to smapi.io/json to see automatic validation and share the link here.
When making mods, it's recommended to edit your files in a text editor with JSON support, such as VS Code, Notepad++, or Sublime Text. These programs will check for syntax errors.
I tried to add it with both. And I ended up to much confused. And I didn't found a simple example for vanilla fish's.
Last I tried was to load the fishponddata inside my mod folder again.
Mm if you did a data/location edit it's fairly simple lemme grab my example
My tmx for my maps are completely blank save for the dialogue actions for flavor text
Thank you I will check it out!
[[Modding:Location_data]] right?
Yes. I will start again with this fishing topic. Clearing my exploding brain and start again
Damn, I'm trying to parse a json with comment with python, but it does not work, so I check Stack overflow, and they do not like comments in json ("that's not json, duh")
gonna go around the issue with a good old s = re.sub("\\/\\/.*\n", "\n")
ohno
"$schema": "https://raw.githubusercontent.com/Leroymilo/FurnitureFramework/main/doc/schemas/content.json",