#Add bin merging (+ any other major Aemulus features still missing) to Reloaded II / PersonEssentials
4401 messages · Page 5 of 5 (latest)
was the reloaded template updated to include bmd merging
i need to make the DLL for signature skills+ again
It's part of essentials, which then uses the emulator via dependency
not sure what you mean
did the visual studio config template get updated to include bmd merging
because i just downloaded it again and there wasn't an update
you'd probably want to update the file emulation submodule, and then add the bmd interface as a project reference
oh you do have to define it
yeah i was looking at mudkips template thing and the _PakEmulator is a variable that gets declared & set from a TryGetTarget call
so you'd need to do something like this (or however its done in your files) just for BMD emu instead
ill change the warning later, but yeah
mudkips template was too good
where tf is crifsv2 hook
oh i never download it, duh
hmmmmmmmmmmmmmmmmmm
if it weren't working, it would put the original skill desc
but it's blank..........
oh every skill desc is blank hahaha
ok i can confirm that the issue still happens when not using the api
i think bmd emulator might be broken
alright i think i know what’s happening
seems like the dummy file is all that’s being loaded
Update: BonQ just didn't have the Persona Essentials update, everything is fine
are there any plans for general binary patching in the future?
or would it have to be a case by case basis
like ftds and ps_model.bin files
Yes, my idea was that it would work like tbl merging does where it just automatically happens; Persona Essentials looks for files of the formats that we add support for and then just merges them
In theory it shouldn't be hard to do, it's not really any different from tbls. It might just be a bit time consuming to implement depending on the number of different binary formats there are that need it
I actually had this idea just now and I think just a pure generic binary diff method is the best
some files are too small and some formats are a complete fucking mess to map out (like P5R .PDD files)
so just byte diffing the entire file is the best way to go about it and with such a generic approach many more files can be supported and then later if needed, dedicated code
@true bronze
Yeah you can totally do that, you'd just wait to map out a list of either every file or every file extension that should be diffed so it doesn't try to do stuff that shouldn't be touched
yeah I do think that files for merging should be explicitly listed and not just let it diff every file ever
well I did try taking a stab at it but i cant say I understand the complexity of the tbl merger being split across 10 different functions across 5 different files so i'm not having much luck lmao
well I got something but its not properly diffing and its just taking whichever file was put last lmao
which is weird because i just re-used an existing resolver that shouldve done byte by byte diffing

@true bronze hi lemme know when you're online so I can pick your brain, don't worry I don't intend to make you work again after the suffering you got put through lmao, but you understand this code and you might know what went wrong
Sorry, I was busy yesterday but maybe I can help tonight (12ish hours from now)
ah, im glad you said a time
because timezone moment
ill have to set an alarm clock then lmao
thatd be like 5am for me
Maybe if you can just describe what's going on now I can help, I'm on the bus to work so I've got some time
in the event that you're free before I join the land of the living, I made a commit to a fork
Can be later than that, that's 7pm for me so just some time after (but not too much after)
it just takes the last file from the mods
in this case im trying with a .pdd file
if 2 or more mods have the same file, it just puts the "last" one in cache
no merging happening
That code seems fine glancing over it
what i did was copypaste existing tbl merge code
make it only be 1 section and made the section solver just return the whole file
If you haven't already, try stepping through it in a debugger. See if the patch is being made, etc
im using one of the tbl resolvers that just does byte by byte comparison
so in theory it should've been fine
You can run the patching stuff through unit tests which should make it easier
i've no idea how to use that!
There's a tests project in the solution, go into that, copy an existing test and run it with your stuff
There is one more thing. With the normal tbls I think it reads the length of the segment from the TBL, did you do something to change that so the length is just the length of the whole file?
yes
@true bronze ping pong
Cool, I'll have another look over it now
Did you try going through with a debugger yet?
I've never used a debugger so no
You could do that but a debugger is going to be better imo
Are you using vs? Ig I can try and explain what to do
yeah i do use vs lol
cool
but since most of the stuff I do doesnt involve reloaded there's never been a situation where itd be useful
(I've been using rider for a bit now, that's why I was checking)
fair
Yeah so using unit tests is probably a good way to start, having to start the game to debug gets a bit annoying for something like this
oh god lmao
In the Persona.Merger.Tests project there are some tests you can just copy off
i was just booting the game and then comparing file in cache
I mean it works
But if you just want to test the file patching part you can do it with unit tests
Basically just go to one of these and copy an existing test and change it so it's using your GenericPatcher or whatever you called it instead of that one
Then right click on one of the lines and go breakpoint->Insert breakpoint
Then you can right click in the test and choose debug tests to debug stuff
i see
I had another look over the code and I don't see anything that looks like it would break things. You are doing some kinda pointless stuff though since you've just copy pasted existing code. You've got a bunch of loops which are pointless since there's only ever one "segment". Also passing in a tbl type to patch generic eeveen though it's generic. Stuff like that
i mean, yeah, the goal was to get something working first and worry about the uglyness later
but clearly we didnt even get past the first step

yeah fair
well I don't really have any suggestions other than use debugger
I'd need to do the same myself to say anything more
now that i think about it, unit testing doesnt seem to output any files?
it just compares to an existing output file
you can make it if you want
the idea is someone manually merged the filees then it compares what the code outputs to that
this makes no sense
ah, I guess it does im just not thinking about it the same way
regardless it is generating patches
but not applying them correctly i guess?
actually, how does it know where to apply these patches
i dont see an address here or some sort
now im even more confused
i put a breakpoint before the final patched file
and it does roughly look how i expect it to
so where is this going wrong

If the unit tests give you the right file theen presumably you are somehow not registering that patched file to be loaded
You could try using a debugger and doing basically the same thing but in the actual persona essentials code. Just add a Debugger.Launch somewhere in the code so it launches it when you start the game
So the patch is right but the outputted file is wrong?
wait
yes
the outputted file is like
it took the last file in the candidates list
and then just output that
but my tests did produce a valid file like I would have expected a merge to work
and i merged 2 files because i dont trust a single file merge
(i.e. what if it just copies whole file)
im making my own merged file now for the assert
but based on what ive seen im confident its correct
Yeah that looks fine
after is mod 1, after2 is mod 2, and after3 would be merged output
Actually is using P5RTblPatcher with TblType.Exist right?
I thought you had some GenericPatcher or something
i set exist to just be "compare all bytes"
anyway lemme grab clean files and remake the mod files to make sure the output is actually correct
ah k
okay the assert was failing because of a 00 vs a 0D
i think setting the generic patcher to be all u16s and/or all u32s would catch these errors
regardless this doesnt explain the actual merging being wrong
or rather, the final output not being merged
but the file im getting from tests is correct save for this one byte
i changed the resolve to be all ints but now it just wrote random junk at EoF instead of padding and that causes the assert to trip
lol its diff every time
cool
now to figure out why its not working
well, i have progress
the game is crashing now!
the unit test succeeds but the game explodes
oh wait, could be visual tbl moment lemme check
it was indeed
anyway merging works now as expected
but this code is all very ugly lmao
im gonna commit this and then go back to sleep

few things to note, this needs to be moved out of p5r specific code lol
at least I made sure to make the resolvers generic
alright I've mostly cleaned it up and I'm pretty happy with it so far, even added a bunch of files to P5R, can easily be added to P3P/P4G but I know nothing about what generic file merging people might need in those games so unless people wanna send me some filepaths P5R is all we'll get lmao
P5R does also have some files that could be merged but they're inside PAKs which would involve pak merging and i've no clue what that's all about
anyway
It shouldn't be that different, it looks like what you did to merge the lose files is basically just copy pasted from one of the other file mergers. If you just do the same thing but with the Paked version of that (like CachePakedBf) I don't think it'll be that hard to do
hi @true bronze (or anyone who has access to the p4 modding channels/mods P4G) I need you to relay this info for me and collect the filepaths needed
What (binary) files still need merging? I've added generic file merging need the following details
- Full Filepath
- Is the file inside of pak/bin (does it need to use PAK merging?)
- Is the File 4 byte aligned or 2 byte aligned?
- Does the file specifically need individual byte by byte merging? (only applies if there would be mods that only edit 1 byte of said file)```
I'd ask about P3P but given P3R exists I don't think anyone unfortunately gives a shit anymore lol
fortunately most stuff for P4G also applies to P3P anyways. I do personally still care for P3P since it's still the best way to play FEMC route, but the number of people who care about that game is not very high lol
The main things I care about are ftds and ctds but they have an actual format so I wouldn't use this generic stuff for them, I'd make another thing that interprets them, at least mostly properly. There are some other files though
For P4G:
facility/cmbroot/ps_model.bin
For P3P:
data/facility/combine.bin/ps_model.bindata/facility/elvgirl.bin/ps_model.bindata/facility/elvgirl_m.bin/ps_model.bindata/init_2.bin/init/cmm.bin/*.dat(there are a heap of them)data/init_2F.bin/init/cmm.bin/*.dat(same stuff but for femc)
I think ps_model.bin is the most important out of those, no idea if there's anything actually interesting in those .dat files.
I also don't know about whether they're 2 or 4 byte aligned or wheetheer they need byte by byte merging. I just know that (at least ps_model.bin) is actually used by people and would benefit from merging. Hopefully someone who knows the format can say what they should be
well, for those last two, how would you implement that

some type of regex search thing?
Could just type out a list of them
There aren't that many, I just didn't want to type out a list
I think the file names should be the same between thee 2 and 2F bins
because i did think of something like this for P5R and typing them all out is stupid lmao
p5r has a bin file that controls NPCs in the fields
it could benefit from merging but i am not typing out every field id path
Then some kinda regex probably makes sense
Crifs probably has something in its api that just lists all files
Only thing is that's not going to work with stuff in paks, for them you might just have to hardcode (or make in a configuration somewhere) stuff
Well I'm going to sleep so good luck if you try doing stuff
added (untested) generic merging to p3p/p4g but it still needs the regex thing
pls send help
@true bronze ping pong, see above
@true bronze so i THINK I tracked down where the problem with the tbl merging code is
its this piece of code
LengthAfterPatch = newSegment.Length```
this here is the problem
because the length of the tbl is being set to whatever the modded tbl's is every time
so whats happening is
expanded tbl > sets "after" length to bigger
non expanded tbl mod goes after > length now "truncated" back to original
so something in this code (or something that uses it) needs to be changed so that it goes through all the length values and only uses the biggest one
instead of always using the "current" or "last" one
@cedar shuttle might have an idea of where the relevant code is? unless you don't remember since its been so long since you first made this

What you say isn't too unreasonable though.
IIRC I make a diff file from original to every modded TBL
Then apply them in load order.
it is whats happening, thats why we have to use a workaround
Any bytes beyond original length are appended.
But I'm surprised there's a truncation.
have to use an unmodified (but expanded) tbl as the last mod in the list because otherwise it gets truncated
That does sound like a bug; not in diff library but in essentials' merging stuff.
I know what when I port this diff library to Rust eventually I'll need to give more real use examples; it's not clear from the readme how to properly use.
Do also note, that whether you want 'expanded' or 'original size' as the final result also depends on input.
For instance suppose you have a segment which has an num_items followed by the items. If num_items is part of the patch, then whether the data is truncated or not is not relevant; because game would stop reading at num_items.
(Generic examples, but there can be cases like this)
Really ought to have a set of examples and guidelines around this.
[In this specific example I gave, you'd want to preserve max value for num_items]
well in this case, there is no "count" for any of them
they just have a "total size" value and then do length/sizeof(data) to get number of blocks
Yup
I'm guessing 'total size' has wrong value
Does the payload size have the wrong length? hmmm
this is the unmodified tbl from the game
this is from "Mod A", this one has 2 expanded sections
this is from "Mod B", this does not expand
if you do mod A then mod B, the end result is truncated and all of the "expanded" data from mod A is completely lost
a unit test doesnt help here lol
its going to tell/show me what I already know
oh, this is odd
I got a half working result

so I did a little bit of trolling
maybe a lot
I added this in the merger code
basically i cycle through all the patch lenght values to grab the biggest one, and then only ever use that new biggest value
this almost works
the tbl has 2 expanded sections
expanded section 1 merged without issues
the second one kind of half merged?
the total length value is correct
but it didnt write the extra data because the last tbl had no new data in that group
so it has original data only with expanded length value
(which causes the stream to go past EoF when trying to read)
actually its even worse than that because this one truncated even earlier than the original existing data lol
well, ill push the half fix into my fork for now
nvm it was a copypasta moment and was using generic merging, using the proper merging goes back to everything being truncated
this is so sad
I made some progress
changing this variable to the "newLength" variable I created "fixes" the truncating issue
but instead now all the extra data is all 00s
when there was actual data in there
so now its correctly "sized" but the data itself is still gone
@cedar shuttle does the patch data struct contain what offset it goes into? I think the final "thing" that could solve this would be to completely reorganize the patches by offset
nvm i got it
IT LIVES
this did what I wanted to
patches.Sort((a, b) => a.SegmentDiffs[x].LengthAfterPatch.CompareTo(b.SegmentDiffs[x].LengthAfterPatch));```
sorting patches based on ending segment length
I want to unalive myself but at least this pesky pesky bug is dealt with
this took forever between finding and fixing this bug and implementing the generic merging lmao
if anyone wants to test for the moment
this has generic file merging and the tbl merging bug fixed
(I set the version of this to 2.7.9 so it can be differentiated from current release, but I'll leave it at 2.8.0 when this update is actually out so it autopupdates properly)
I still need help on the whole regex thing for inside the pak files for the generic merging
Oh
Did you find out if crifs has some thing for listing all the files? I feel like it must
i have no idea how to use crifs
Just look at the API, see what functions it has
Just type in criFsApi. and look at the auto complete (there definitely is an instance of it in Persona Essentials, idk what exactly it'd be called though)
@true bronze so now I ask the burning question, if a suggested solution is to pad original tbl to match new lenght, where does this need to happen? because I can assure I tried that within the ApplyPatch function itself (where I put the sorting) and it has no effect there, and any other relevant places outside I don't know if they have access to the patches/are in same scope to grab longest patch
It would need to be before the patches are created, I assume that already happened by the time you're applying them (I'm on mobile rn and don't really want to check)
If you can't work out where that is I'll try to when I get home.
@true bronze no success on my end, letting you know before I log off lol
Ah right, I forgot about doing that. I guess I can have a quick look now
I'm fairly sure it should be this line in the PatchTable function of the TblMergers
for (var x = 0; x < candidates.Count; x++)
patches.Add(patcher.GeneratePatch(await File.ReadAllBytesAsync(candidates[x])));
If you changed the byte[] passed into GeneratePatch then I think that would work.
I feel like you've probably already tried that though
I realized where a mistake is potentially being made
both the original file and the candidates need to be padded to the len of biggest candidate
because if original file isnt padded, those 00s count as a patch
so whichever padded file comes after the actual expanded file is going to have those 00s count as part of the patch
so this results in an expanded file but the extra data was all lost anyway so the end result is the same
@true bronze any luck?
Oh, did you want me to do something? I thought you'd worked out the solution and assumed you'd try to fix it yourself
no lmao
the only thing I got working was denied
so
unless one of you figure something out, this is never going anywhere
So this wasn't it?
what if you only padded the files if none of the earlier ones were already padded to the necessary length
like maybe theres a value that tracks the length of padding and only pads when
wait
With that I'm also not sure why the original file would even be used. You should only need the edited ones. Everything in the original would always be merged over so there's just no point to have it in the first place
nvm what i was just thinking
if you have a file thats length x, and then another thats padded to x + whatever, the second file would pad over the first still
so hmm
so, how dead is it
gonna assume then that this is never getting fixed, and by extension then the PR with the generic merging never merged then
If you're still relying on me to fix it then I wouldn't say dead, but I also kinda doubt I'll do it anytime particularly soon.
I haven't had much desire to do any modding for a while now, particularly the boring stuff like this. Coming back from work and on the weekend I don't really feel like doing more coding.
I do have two weeks off around Christmas so I wouldn't be surprised if I do a decent bit of modding stuff around then. I'm not going to make any promises though, we'll see what happens.
I think the fix is probably something that anyone with some c# knowledge and persistence could do fwiw. I doubt there's much, it anything, that requires my knowledge specifically.
I probably could do it quicker than someone new but nothing that you'd need is locked behind a black box.
well, everything i've tried from the side of persona essentials has been a complete dud, aside from the proposed "temporary" solution that sewer doesnt like
idea: treat the extended part almost like its own tbl with "default" values all zeroed out, and then sorta...stitch it onto the rest of the tbl after theyve both been patched?
should account for the issue of the patching code mistaking padding for another patch
i just woke up theres prob something simpler im not thinking of
you can always have it be it's own separate mod no? it doesn't have to be in pessentials
I think that's pretty close, if not the same to, one of the suggestions in the pr for this. I'm not sure if it's one of the things dc's already tried, seems like they've tried a lot so I wouldn't be too surprised if it is...
It could although it's going to be weird if some files automatically merge with Persona Essentials and some need an additional dependency. If the merging stuff were a separate mod (not a bad idea, Persona Essentials arguably does way more stuff than it actually should) then it'd probably be a dependency of Persona Essentials so people have the merging transitively and existing mods don't break if it's completely removed from PE.
It might be more effort than it's worth for just this though. If the real concern is generic merging being blocked by the extended tbl thing I think you should just remove that part from the pr and leave it as a separate issue. I don't think the two have any dependency on each other
Oh, I just noticed I assigned the issue to myself in June... I guess I should be the one to fix it lol
I'm going to have a little look now to see if I can just save you the trouble of splitting out the pr or whatever.
I seem to have fixed the thing, at least according to the one unit test dc wrote. Basically, instead of replacing the entire segment with the one written by the patch, which may be smaller, you just write into the last version of the patched file. If that writes less bytes than the length of the whole thing then those bytes it didn't write are just untouched rather than being effectively deleted.
I feel like that's probably a confusing explanation but if anyone really carees they can just look at the code when I put it up, assuming it does work
Here it is, I'd appreciate if anyone could try it out. tbh I don't remember what mods you need to enable and in what order to test it out and I don't really want to work it out 😅
In theory it does work based on the unit test but I definitely want confirmation that it holds true when launching the game with heaps of mods and things
@hoary cypress test this out, fixes expanded tbl bug meaning no need for workaround mod
Ohhhh cool. Is it the same as the wip one you gave? Or some tweak in this ver?
yeah the unit test was made with this in mind
it has ->
normal file -> expanded -> normal
so if the final output isnt expanded, then the test fails because it means the file got truncated
well, testing it myself, at a glance, it seems to work?
I'll report soon
testing now
@dark tree
denuvo locked me out
gg
@dark tree okay, i confirmed it works
nice
@true bronze so unless something we haven't seen crops up, we're good to go, although not sure how we'd handle getting this into the PR
Awesome, I'm glad it's working. I'll push my change up into your pr in a little bit.
what happens if you have an extended tbl followed by a longer extended tbl
In theory it should be fine. Someone could test if they want to be sure though
It uses the length of the largest segment then just writes everything into that so it shouldn't matter how long the segment is or how many different lengths there are
then yeah, should be fine
woo 🎉
I've pushed my change
did @cedar shuttle check it yet?
I saw the commit, just didn't deep dive into it yet
did you look yet
@dark tree @true bronze I'll release whenever you guys feel like it.
I really do think additive is better than replacing, but ultimately it's up to you folks, so let it rip.
Go for it
cool
i feel like this update should probably be announced/mentioned somewhere
@devout crystal generic merging is out
is there any merging left to do?
also i love how i look back in this post and dc’s doing the tinybuild hello neighbor thing with sewer and “did you look yet” 😭
@true bronze hi can you make an announcement for this lol
For the changes, it's this
fixed merging bug that caused expanded files to be truncated if they were not last when merging, causing crashes
added generic file merging, following files will be merged
P3P
- data\facility\combine.bin\ps_model.bin
- data\facility\elvgirl.bin\ps_model.bin
- data\facility\elvgirl_m.bin\ps_model.bin
P4G
- facility\cmbroot\ps_model.bin
P5R
- CALENDAR\CLDWEATHER.BIN
- RESOURCE\RESRCNPCEXIST.BIN
- EVENT\EVTDATEOFFTABLE.BIN
- EVENT\EVTDATETABLE.BIN
- EVENT\EVTDDDECOTABLE.BIN
- EVENT\EVTFADEOUTTABLE.BIN
- INIT\PMCHATINVITE365TBL.DAT
- RESOURCE\RESRCNPCTBL.BIN
- BUSTUP\DATA\BUSTUP_PARAM.DAT
- FONT\ASSIST\MSGASSISTBUSTUPPARAM.DAT
- INIT\SHDPERSONA.PDD
- INIT\SHDPERSONAENEMY.PDD```
(i asked max but he said to ask you instead lol)
Ok
With the visual tbl stuff is that mods that add new skills?
I want to have some kind of non technical example of what expanded tbl bug being fixed means.
tbh I don't really remember
basically adding new entries to a tbl beyond the existing limit, in the case of VISUAL this is just positioning data for players/enemies/personas during battle, but this affect anything that could be expanded if multiple mods affected the same tbl
people just need to know that this means they no longer have to use "workaround" mods to fix crashes related to this (visual is just the immediately relevant example)
this isnt like high priority but like what would it take to force msg indices
Not much, have a look at the code for procedures if you want, it'll be something similar.
Basically, look for a prefix in the message name (pretty sure it's just _index_x for procedures, I'd do the same for messages) and if it's there you add it to that specific place in the list of messages instead of just adding to the end.
This would all just be in script tools
a lot of msgs have the id in the label, esp for events, so maybe i go by that schema?
If we can trust that those always actually correlate to the correct id then sure. You don't want to break any original messages
Imo it's better to just have a unique prefix to be safe. I really doubt any original message ends in _index_123
fair
i dont think index is important in a lot of cases which is why it feels low priority but i do know that like jazz club for example uses rng to decide a msg index to call
no lol
i dont have a case on hand immediately but i can tell you they dont always respect this
ive seen a message with the same label as previous one but with _ at the end
if there can be an edge case, always assume atlus did it somewhere
i misspoke (i have been drinking)
though yeah a custom label param would be better anyway
bf emulator does it already so its probably better for consistency

