Synthesis-Collective / SynthEBD

Port of zEBD to Mutagen
31 stars 7 forks source link

Patcher takes a long time to start up #106

Closed Piranha91 closed 1 year ago

Piranha91 commented 1 year ago

Opening a new issue from discussion in previous issue

ghost commented 1 year ago

Thanks Piranha. Trying to launch latest version now, but can't find the log file. Where is it being written?

Piranha91 commented 1 year ago

Should just be in the root logs folder (the one that opens when you go to the status menu and click “open log folder”). It writes when the program finishes initializing (when the SynthEBD window appears on screen).

ghost commented 1 year ago

Got it, I feared not being able to get the log file since loading never finishes with all bodyslides enabled, but we have good news, latest version fixed the infinite loading time :)

Here's the log: StartupLog.zip

Seems the biggest culprit is the large specific npc assignments I have. Patcher took one hour to process this time with latest version 😮 . On v0.9.6.4, loading takes at max 20 min.

Piranha91 commented 1 year ago

I made a small set of changes to the UI code in 0.9.7.3. I think I'll need to do a major overhaul over the coming week or two to get the UI to actually perform well, but in the meantime can you let me know if this speeds up initialization at all for you?

ghost commented 1 year ago

Looking good, loading time has been cut by almost half 👍 Loading is taking 1 hour now, instead of more than 2 hours before.

Bodyslides taking 4 min. Asset packs are taking 1-2 min on average. Head Parts took 10 min. Specific NPC Assignments took 23 min. Huge improvement. Last version was taking 1 hour to process. Consistency took 2min.

Piranha91 commented 1 year ago

Tried to address this in 0.9.8. Hopefully it works better for you - let me know if you run into any issues as it's a pretty extensive refactor.

ghost commented 1 year ago

Great job, it takes less than 10s to start now 😮 I'll let you know if I run into any UI issue, but so far, so good. Thanks a lot :)

ghost commented 1 year ago

Well, spoke to soon. Looks like BodySlide import is broken now. The exported .json gets imported but no changes happen. If I try to import a second time, it crashes:

SynthEBD has crashed with the following error:
Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at System.Collections.ObjectModel.Collection`1.Insert(Int32 index, T item)
   at SynthEBD.VM_BodySlideExchange.ImportBodySlide(ObservableCollection`1 bodySlides, BodySlideSetting importedBS, VM_BodySlidePlaceHolder targetPlaceHolder) in D:\a\SynthEBD\SynthEBD\SynthEBD\Classes_Aux\ViewModels\VM_BodySlideExchange.cs:line 332
   at SynthEBD.VM_BodySlideExchange.ImportGendered(ObservableCollection`1 currentBodySlides, List`1 importedBodySlides, List`1 multiplexWarnings) in D:\a\SynthEBD\SynthEBD\SynthEBD\Classes_Aux\ViewModels\VM_BodySlideExchange.cs:line 318
   at SynthEBD.VM_BodySlideExchange.Import() in D:\a\SynthEBD\SynthEBD\SynthEBD\Classes_Aux\ViewModels\VM_BodySlideExchange.cs:line 269
   at SynthEBD.VM_BodySlideExchange.<>c__DisplayClass1_0.<.ctor>b__1(Object _) in D:\a\SynthEBD\SynthEBD\SynthEBD\Classes_Aux\ViewModels\VM_BodySlideExchange.cs:line 33
   at SynthEBD.RelayCommand.Execute(Object parameter) in D:\a\SynthEBD\SynthEBD\SynthEBD\GUI_Aux\RelayCommand.cs:line 29
   at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

SynthEBD Version: 0.9.8

Run Mode: Standalone

Patcher Settings Creation Log:
Found settings source path at C:\Modding\MO2\SynthEBD_v0.9.8-vanilla\Settings\SettingsSource.json
Source Settings: 
Load Settings from Portable Folder: False
Portable Folder Location: 

Patcher Environment Creation Log:
Found environment source path at C:\Modding\MO2\SynthEBD_v0.9.8-vanilla\Settings\EnvironmentSource.json
Source Settings: 
Skyrim Version: SkyrimSE
Game Environment Directory: C:\program files (x86)\steam\steamapps\common\Skyrim Special Edition\Data

Patcher State:
Main Settings:
Validation Disabled: False
Apply Assets: True
Apply BodyShapes via: None
Apply Height: True
Apply Head Parts: True
Use Consistency: True
Mod Manager Type: None
Primary Config Files
MixIn Config Files
Male BodyGen Configs
Female BodyGen Configs
Male BodySlides: 78 (16) annotated
Female BodySlides: 1748 (23) annotated
Height Configs: 1
Eyebrows: 0 HeadParts
Eyes: 0 HeadParts
Face: 0 HeadParts
FacialHair: 0 HeadParts
Hair: 0 HeadParts
Misc: 0 HeadParts
Scars: 0 HeadParts

Current NPC Info: Null
ghost commented 1 year ago

By the way, were there any tweaks to the patching process itself? It's significantly faster now 😀 I'd say 40-50% faster.

ghost commented 1 year ago

Found another issue, image previews are not loading anymore:

image

Edit. Strangely enough, Demoniac works. Mature Skin doesnt... 🤔

image

ghost commented 1 year ago

Another one, former hidden bodyslides aren't hidden anymore. Hide toggle doesn't matter:

image

Piranha91 commented 1 year ago

For the first issue, it’s not that the image preview isn’t working but rather than the file path is broken (you can tell from the red border). It’s expecting Data as the root folder, so the path would start with Textures\BPFS rather than BPFS. I was a bit confused by this last night because I noticed in some config files it started the correct way (and worked) and in others it started directly with the prefix (and failed). Did it used to allow you to start directly with the prefix? I don’t think it was ever supposed to, but it was getting very late last night when I noticed and I didn’t have time to dig in.

The second one is definitely a bug. If you click “Hide Preset” it’ll hide correctly, but upon reload the hide behavior gets overruled by the No Descriptors behavior. I’ll have that fixed in the next release, thanks. Will also take a look at the bodyslide import; I forgot to test that.

There were some slight tweaks to the patching code but nothing major. I also thought it seemed to be running faster which is funny because the tweaks were mostly to improve readability and updatability rather than performance :)

Noggog commented 1 year ago

It’s expecting Data as the root folder, so the path would start with Textures\BPFS rather than BPFS

There's some standardization mechanics within AssetLink that does processing on asset paths to get a DataRelativePath.
https://github.com/Mutagen-Modding/Mutagen/blob/48c4cf497e2a5fff8fdc1070218740a4ca4760f2/Mutagen.Bethesda.Core/Plugins/Assets/AssetLink.cs#L48

Perhaps this can be refactored out to be exposed for common usage

ghost commented 1 year ago

There's something really crazy going on then. My 0.9.7.3 folder has all of those asset packs with the \Textures\ prefix. I unzipped the new 0.9.8 and copied over the Settings folder. After patching with the 0.9.8 version, I can see that the \textures\ prefix was removed for some of them 😕 I didn't touch those .jsons 🤣 Will investigate a bit more to see if I can somehow reliably reproduce that...

Piranha91 commented 1 year ago

Sounds like something might be getting changed by reference instead of creating a new variable. I’ll take a look tonight or over the weekend. Not surprised the small bugs are cropping up; it was a fairly extensive overhaul…

Piranha91 commented 1 year ago

There’s definitely a spot on the patcher side where I could incorporate that - right now I’m doing it by hand. I think in this case the problem is inverted - the expected path is Textures\A\B.dds and the supplied path is (erroneously) A\B.dds. Is the asset link functionality able to supply the missing data sub folder based on the file extension?

Piranha91 commented 1 year ago

Ah I think I know what's happening - in previous versions, the Patcher side of SynthEBD was getting copies of AssetPacks that were "dumped" from the UI as separate entities. The patcher would apply TrimPaths, use them to patch NPCs, and then discard them. Now the Patcher is pulling them directly from the Settings, so when the TrimPaths are applied they're immediately baked in. I'll just make the patcher clone each config file as a fresh object at the start. Thanks for calling my attention to this one - obviously a big problem if it had made it into 1.0 :)

Piranha91 commented 1 year ago

Bugs referenced above should be fixed in 0.9.8.1.

Also, just a heads up - there's a new unintended but IMO beneficial behavior in 0.9.8. Before if a user installed your config file before importing your bodyslides, the annotations would be wiped from their subgroups immediately. Now, as long as the user doesn't click on the subgroup to bring it into the UI, the annotations persist and if the user clicks "Run", the run will stop and tell them they have subgroups referencing descriptors that don't exist. Now the user has an opportunity to either import your descriptors or go to the asset pack misc menu and click "Delete Missing Body Shape Descriptors" if they don't want them after all. Or they can bring the normal map subgroups into the UI one-by-one I suppose.

ghost commented 1 year ago

Hi Piranha, testing the new 0.9.8.2 version, the app crashes when cloning any bodyslide preset:

SynthEBD has crashed with the following error: Object reference not set to an instance of an object. at SynthEBD.VM_BodySlideSetting.Clone() in D:\a\SynthEBD\SynthEBD\SynthEBD\Classes_Core\ViewModels\OBody SubModels\VM_BodySlideSetting.cs:line 151 at SynthEBD.VM_BodySlideSetting.<.ctor>b__913(Object ) in D:\a\SynthEBD\SynthEBD\SynthEBD\Classes_Core\ViewModels\OBody SubModels\VM_BodySlideSetting.cs:line 97 at SynthEBD.RelayCommand.Execute(Object parameter) in D:\a\SynthEBD\SynthEBD\SynthEBD\GUI_Aux\RelayCommand.cs:line 29 at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated) at System.Windows.Controls.Primitives.ButtonBase.OnClick() at System.Windows.Controls.Button.OnClick() at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

SynthEBD Version: 0.9.8.2

Run Mode: Standalone

Patcher Settings Creation Log: Found settings source path at C:\Modding\MO2\SynthEBD_v0.9.8.2-vanilla\Settings\SettingsSource.json Source Settings: Load Settings from Portable Folder: False Portable Folder Location:

Patcher Environment Creation Log: Found environment source path at C:\Modding\MO2\SynthEBD_v0.9.8.2-vanilla\Settings\EnvironmentSource.json Source Settings: Skyrim Version: SkyrimSE Game Environment Directory: C:\program files (x86)\steam\steamapps\common\Skyrim Special Edition\Data

Patcher State: Main Settings: Validation Disabled: False Apply Assets: True Apply BodyShapes via: None Apply Height: True Apply Head Parts: True Use Consistency: True Mod Manager Type: None Primary Config Files MixIn Config Files Male BodyGen Configs Female BodyGen Configs Male BodySlides: 39 (8) annotated Female BodySlides: 858 (692) annotated Height Configs: 1 Eyebrows: 0 HeadParts Eyes: 0 HeadParts Face: 0 HeadParts FacialHair: 0 HeadParts Hair: 0 HeadParts Misc: 0 HeadParts Scars: 0 HeadParts

Current NPC Info: Null

Piranha91 commented 1 year ago

Thanks again for the catch! Should be fixed in v0.9.8.3.

ghost commented 1 year ago

Thanks Piranha! Found another issue with the UI:

https://imgur.com/cd6tblO

Didn't test all fields, but notes and names are lost when moving subgroups.

Piranha91 commented 1 year ago

Thanks! I think this was actually the manifestation of a related issue where if a subgroup is the currently open subgroup in the UI, it's supposed to save before being copied to its new location (and wasn't). Should be fixed in 0.9.8.4.

Piranha91 commented 1 year ago

Closed due to patcher no longer taking a long time to start up :)