Jump to content

Recommended Posts

  • 2 weeks later...

i had made this post in the sexlab forum because my users were blaming sexlab, though now i believe it to be an issue with the new papyrusutil.

 

http://www.loverslab.com/topic/16623-skyrim-sexlab-sex-animation-framework-v159-updated-0811/?p=896141

 

long story short - ai packages added via ActorUtil are not being saved/loaded/reapplied after restarting the skyrim client and zoning into where the ai is. in the papyrusutil in sexlab 1.58b this was not a problem.

 

also the quitting/starting skyrim seems to be important, which i think means the relevant data is not hitting disk? or being loaded from it?

 

1.58b

  1. cast spell that applies DoNothing package
  2. walk out
  3. save game
  4. quit skyrim
  5. start skyrim
  6. load game
  7. walk in
  8. ai still standing there waiting for you.

 

1.59

  1. cast spell that applies DoNothing package
  2. walk out
  3. save game
  4. quit skyrim
  5. start skyrim
  6. load game
  7. walk in
  8. ai no longer has DoNothing and has probably gone home.

what i assume was happening in older versions is that the game would reapply the package every so often, because in older versions ai with DoNothing would still move a little after fast forwarding time in the same room as them.

 

downgrading sexlab - papyrusutil by proxy - the issue goes away.

Link to comment

The new version does not save overrides, quitting the game will remove any overrides you've placed on an actor. This was done intentionally as I think it's more important to ensure no errant scripts can leave an NPC permanently damaged. For example; if you were to apply a DoNothing package to an actor, they save and quit and uninstall the mod, or the mod bugs out and forgets to remove the DoNothing from the actor, that actor is now permanently stuck doing nothing. Though admittedly it started with laziness and I later added this rationale onto it.

 

Meanwhile it's a rather simple thing for the mods using the package overrides in question to simply reapply any overrides at game load. This is more inline with the rest of Papyrus where things like ini and game setting changes done via scripts do not keep after quitting the game. It promotes what I'd consider better practices when dealing with aspects that could potentially break the game.

 

That's my reasoning in any case, feel free to disagree and make a case for adding override saving between game loads and I'll consider it.

Link to comment

infinite NPC in bondage without creating aliases for each one to apply packages.

 

that is my only argument. that and, broken backwards compatibility. i'd hate for the weight i gained while working on these mods to be for naught.

 

personally i find the quest alias binding system kind of broken in its own right.

 

oh and doing something in a game, hitting save, hitting load, and not having it, feels really bad.

Link to comment

Applying the package at game load would still be backwards compatible, people using older versions of PapyrusUtil it would simply be an unnecessary step.

 

Doing so should be rather simple as well, you only need a single player alias to do so. Wherever you are adding packages to an actor, also add that actor to a StorageUtil.FormListAdd(MyQuest, "DoNothing", ActorRef, false). Then within a single Player ReferenceAlias on a quest add the event OnPlayerLoadGame() or if you have a MCM script you could simply add it to that script which has a OnGameReload() event, and loop through that form list, adding the DoNothing package to each entry. Remove them from the FormList when no longer overriding. 

Link to comment

but now we've lost the concepts of:

 

  1. infinite. now i'm stuck at a 128 limit (right? cause arrays). which is a lot of npcs, but still.
  2. saved state being saved.
  3. save game load being delayed by a papyrus script instead of a native plugin?

people know, if they remove a mod from their save, their save is not clean and potentially broken. if they dont know, somebody will remind them for you when they post on the forum. it happens every day. its a fact of life for skyrim save files. mods that dont suck (like i feel, mine) provide a way to undo what they do to actors, so if they want to uninstall they can cast a reversal spell on the npc and get rid of the mod.

 

don't gimp us bro, don't gimp us!

Link to comment

I'm not seeing any of those issues in this case.

 

1. StorageUtil FormLists aren't limited to 128, they never have been; you're thinking of Papyrus arrays. 

2. I fail to see how saved states enter into this at all. The actors being overridden would be tied to your formlist, if bouncing between multiple save states where varying actors have overrides, this can be solved by simply adding ActorUtil.RemoveAllPackageOverride(DoNothing) before you FormList loop to ensure only actors in that save state's formlist have the package.

3. You're talking a second of delay in the worst case of scenarios, fractions of a second in most cases. Doing a simple loop through a form list at game load should be a non issue.

 

Some people may know, but the fact that some people are smart enough to know how the inner workings of modding work  doesn't mean everybody does, and even if everybody did know it's still no excuse for skipping error correcting. Accounting for potential errors in a mod you're creating takes minutes of your time, while not doing so can cause hours of your own time later providing support, hours of the people experiencing such errors trying to figure it out, or potentially no time as they simply decide "fuck it" and stop using the mod instead.

 

This isn't Gimping anything, as far as I can see from how you've described the issue this is a completely simple and solvable issue with just 6-7 lines of code that both maintains backwards compatibility and benefits the mod by having less potential for game breaking errors to occur. I'll even write the lines of Papyrus for you if you'd like.

Link to comment

I'm not seeing either of those issues. In this case.

 

2. I failed to see how saved states enter into this at all. 

 

 

you hit save. you hit load. you don't get what you saved. that's kind of bad game mechanics. your solution replaces the best possible performance scenario (native code) with probably-blocking scripting. (i am also a little worried about the papyrus side applying things to unloaded actors. its not historically well handled)

 

can i hack around you with this? yes.

could you fix this? yes.

 

unfortunately, you have the upper hand being the maintainer that i bound myself to. we had a similar discussion last month about backwards compatibility, you argued strongly about adding a new optional param to some functions because it would break mods (due to my misunderstanding of papyrus compiling). except it has gone and happened anyways just in a different place of the code. is it going to be a common thing? to be losing features without even a major release version number bump?

Link to comment

In what way do you not get what you saved? You absolutely do. There is absolutely zero realistic draw back here unless 0.2 seconds of papyrus parsing vs 0.02 seconds of native parsing is somehow utterly destructive to everything.

Link to comment
; // Call from whenever you need to actually add the package to an actor
; // Either as a seperate function like this, or just copy paste the
; // StorageUtil line to come just before/after wherever you call AddPackageOverride()
function AddDoNothing(Actor ActorRef)
	ActorUtil.AddPackageOverride(ActorRef, DoNothing, 100)
	StorageUtil.FormListAdd(MyQuest, "DoNothing", ActorRef, false)
	ActorRef.EvaluatePackage()
endFunction

; // Pick either one of these two events
; // Option 1, in a ReferenceAlias script attached to a single alias filled with the Player:
event OnPlayerLoadGame()
; // Option 2, in an already existing MCM script add/append
event OnGameReload()
	parent.OnGameReload() 

; // Same loop code for both event options
	ActorUtil.RemoveAllPackageOverride(DoNothing)
	int i = StorageUtil.FormListCount(MyQuest, "DoNothing")
	while i
		i -= 1
		Actor ActorRef = StorageUtil.FormListGet(MyQuest, "DoNothing", i) as Actor
		ActorUtil.AddPackageOverride(ActorRef, DoNothing, 100)
		ActorRef.EvaluatePackage()
	endWhile
endEvent

This would make everything functionally indistinguishable from PapyrusUtil 2.3 and 2.6.

 

Back when we talked about adding additional arguments to some functions, you argued it's better to make progress than be held back. You weren't wrong about that, it was just applying that logic in the scope of that debate then that I disagreed with - an incremental update shouldn't force mass backwards breaking recompiles for every mod making use of it or major api changes.

 

Overall not saving package overrides to saves is an incredibly minor change, there are very few mods that even make use package overrides to begin with, and the majority of those wouldn't be majorily affected by this change and those that are can implement a quick and easy solution (as seen above) that makes the change completely imperceptible. So why bother with the change at all then and I don't just add saving back in? Because as you argued back then, progress. Not saving the overrides promotes better usage practices to avoid bugs, means less data being saved into the skse file for a lower chance of corruption, and as an added bonus contributes to a simplified code base for PapyrusUtil as a whole.

Link to comment

 OnGameReload, FormListCount is returning 0. Later after the game is established, it returns the actual count.

Event OnGameReload()
	parent.OnGameReload()
	Debug.Trace("DISPLAY MODEL GAME LOAD")
	DM.FixBoundActors()
EndEvent
Function FixBoundActors()
	;; as of papyrusutil 2.5+/sexlab 1.59 ai packages are no longer
	;; reapplied magically on game load.

	Int a = 0
	Int len = FormListCount(self,"dcdm_BoundActors")
	Actor who

	Debug.Trace(len + " actors marked as willbound.")

	While a < len
		who = FormListGet(self,"dcdm_BoundActors",1) as Actor
		Debug.Trace("Applying Display Model Packages to " + GetActorName(who))
		BehaviourLockdown(who)
		BehaviourReapply(who)
		a += 1
	EndWhile

	Return
EndFunction

[08/20/2014 - 02:05:25AM] DISPLAY MODEL GAME LOAD

[08/20/2014 - 02:05:25AM] 0 actors marked as willbound.
 
then later my mcm lists all the actors in the list.
 
Function ShowPageBound()
	SetTitleText("Will Bound Actors")

	Int a = 0
	Int len = FormListCount(DM,"dcdm_BoundActors")
	Actor who

	While a < len
		who = FormListGet(DM,"dcdm_BoundActors",a) as Actor
		AddToggleOption(DM.GetActorName(who),True)
		a += 1
	EndWhile

	Return
EndFunction

and this works just fine.

 

i've tried with both None and the Quest Controller as the target of FormList* functions (these copy pastes using the quest controller. i used None first.). same result. data not available yet, i assume.

 

so...?

Link to comment

Would have to see where you're adding the actors to the form list to say. Looking at your source code I'd assume you'd want to be adding them to the FormList in dcdm_QuestController.BehaviourRemember()

 

 

 

 OnGameReload, FormListCount is returning 0. Later after the game is established, it returns the actual count.

 

 

If you mean it works fine after playing the game some on the patched version, but not when immediately loading from a save that wasn't adding to the formlist; then of course the formlist starts out empty, as you wouldn't have been filling it in a previous version.

Link to comment

 

If you mean it works fine after playing the game some on the patched version, but not when immediately loading from a save that wasn't adding to the formlist; then of course the formlist starts out empty, as you wouldn't have been filling it in a previous version.

 

god. i'm not the tool you think i am.

 

an actor is added to the form list every time the spell is cast, there are six actors in my form list in my save game. the data is apparently not yet accessible at OnGameReload, yet it is accessible 4 seconds later by the time i open up the mcm menu.

 

  1. rebuild mod
  2. start new game
  3. cast on six actors
  4. save game
  5. load game
  6. OnGameReload() - empty data set.
  7. whatever skyrim does between that and giving me game control
  8. OnConfigOpen - data set available.

 

 

 

Link to comment

 

If you mean it works fine after playing the game some on the patched version, but not when immediately loading from a save that wasn't adding to the formlist; then of course the formlist starts out empty, as you wouldn't have been filling it in a previous version.

 

god. i'm not the tool you think i am.

 

My apologies if I'm coming off like that or hostile in any way, it's not my intention. I'm not trying to come off as hostile just trying to explain my reasons the change and understand yours so I can help you.

 

an actor is added to the form list every time the spell is cast, there are six actors in my form list in my save game. the data is apparently not yet accessible at OnGameReload, yet it is accessible 4 seconds later by the time i open up the mcm menu.

  • rebuild mod
  • start new game
  • cast on six actors
  • save game
  • load game
  • OnGameReload() - empty data set.
  • whatever skyrim does between that and giving me game control
  • OnConfigOpen - data set available.

The data is loaded by SKSE first thing when loading a save, or atleast should be, I use some storageutil functions triggered by OnGameReload() in SexLab, so not sure why that would be the case here.

 

Try sticking the loop in the dcdm_OnSpellCast OnPlayerLoadGame() instead, that should trigger sooner, and not lock up MCM's setup process unnecessarily.

Link to comment

But to be honest, sleeping on the issue some and seeing your problems with it has made me start to reconsider adding back in override saving. I disagree with the need for override saving, but I'd rather things not be a major hassle for modders either. I'll poke around and if I can come up with a decent solution for reincluding override saving I'll do so.

Link to comment

i was hoping to refrain from the player alias, my save and some users have reported that PlayerAlias is not being filled when they add the mod to their game mid-play, but works when the save is fresh from the start. then when ForceRefTo with PlayerRef, not being saved or reloaded later. even the PlayerAlias on the MCM quest isn't filled for some inexplicable reason, though it is identical to the documentation and identical to the other mods i've made which *are* being properly filled.

 

i may have better luck if i create a new maintenance quest with a new alias that is manually started by the reset option in mcm, something fresh in everyones saves, maybe.

Link to comment

But to be honest, sleeping on the issue some and seeing your problems with it has made me start to reconsider adding back in override saving. I disagree with the need for override saving, but I'd rather things not be a major hassle for modders either. I'll poke around and if I can come up with a decent solution for reincluding override saving I'll do so.

 

is there a way without breaking the api where an option could be provided such that you have to explicitly declare that the packages should be saved? by default leaving it how you want, but then anyone willing to do the api research can find how to make it persist, then with a footnote "dont be retarded, provide a proper uninstall for your mod"

 

AddPackageOverridePersist()?

 

*shrug*

Link to comment

 

But to be honest, sleeping on the issue some and seeing your problems with it has made me start to reconsider adding back in override saving. I disagree with the need for override saving, but I'd rather things not be a major hassle for modders either. I'll poke around and if I can come up with a decent solution for reincluding override saving I'll do so.

 

is there a way without breaking the api where an option could be provided such that you have to explicitly declare that the packages should be saved? by default leaving it how you want, but then anyone willing to do the api research can find how to make it persist, then with a footnote "dont be retarded, provide a proper uninstall for your mod"

 

AddPackageOverridePersist()?

 

*shrug*

 

I've added back in override saving for packages, the implementation is a bit different on the backend however, so test this version out with your mod and let me know how it goes.

 

It's just updated dll file, overwrite the one from 2.6

 

- attachment removed so other people don't keep using a potentially buggy dll -

Link to comment

so far, so good. i've repeated the steps i listed in the first post several times and things seem to be restoring the way they should be.

 

while you have your hands in there, i'll propose a bug that i have noticed since even before the rewrite. it may have nothing to do with ActorUtil, but i figured to propose it anyway just in case its a way the packages are reapplied.

 

---

 

normally when an actor has a DoNothing-like package they will not move, ever. just stand there dumbfounded. which is perfect, that is how it is suppose to be. HOWEVER, if you fast-forward time while in the same room/area/cell/thing as an actor with this package, when the fast forwarding ends, they will actually jump to a different spot than where you left them, the distance they travel being related to how long you fast-forward. now, when you get control back of the game, they still have their DoNothing state, but after skipping 4 hours they more or less have traveled 4 feet. this happens with complete disregard of their DontMove and Restrained states as well.

 

the behaviour suggests that for the microtime while the game does the fast forward skipping hour by hour, the actors are running their default packages during the "what did you guys do during that time" calculation and try to walk home. i base this theory on that the ones that do not live in my house all have inched towards the front door. but as soon as the game gives control back bam the package stack we expect snaps into effect again. this only happens if you are in the same cell, if you walk outside, fast-foward, and come back in, nothing has changed.

 

i assume that that is an engine or deeper-game problem and not something you can deal with, unless you know of the package override states being suspended or something during fast-fowarding time. i checked, just to see if your re-implementation solved a latent bug, but it still happens.

Link to comment

normally when an actor has a DoNothing-like package they will not move, ever. just stand there dumbfounded. which is perfect, that is how it is suppose to be. HOWEVER, if you fast-forward time while in the same room/area/cell/thing as an actor with this package, when the fast forwarding ends, they will actually jump to a different spot than where you left them, the distance they travel being related to how long you fast-forward. now, when you get control back of the game, they still have their DoNothing state, but after skipping 4 hours they more or less have traveled 4 feet. this happens with complete disregard of their DontMove and Restrained states as well.

 

the behaviour suggests that for the microtime while the game does the fast forward skipping hour by hour, the actors are running their default packages during the "what did you guys do during that time" calculation and try to walk home. i base this theory on that the ones that do not live in my house all have inched towards the front door. but as soon as the game gives control back bam the package stack we expect snaps into effect again. this only happens if you are in the same cell, if you walk outside, fast-foward, and come back in, nothing has changed.

 

i assume that that is an engine or deeper-game problem and not something you can deal with, unless you know of the package override states being suspended or something during fast-fowarding time. i checked, just to see if your re-implementation solved a latent bug, but it still happens.

Probably has more to do with how you're setting up the DoNothing package itself, what the conditions, sequence, and flags you have setup on it to accomplish the "do nothing"-ness, there is lots of ways to go about it, or maybe just the Skyrim engine itself.

 

The saved data in ActorUtil doesn't go away or anything during wait/sleep; though it's possible it might pause all AI for the duration and afterwards do a different sort of package evaluation that ActorUtil doesn't hook into when deciding the actors location after the wait/sleep.

 

Ultimately you're better off using quest aliases for the DoNothing packages, they aren't very hard to implement, and then use ActorUtil for the varying Bound packages you have set up to lay on top of the DoNothing provided by a quest alias. Doing it this way ensures that even if the wait/sleep causes them to skip their override packages, they still have native DoNothing package forced on them through the conventional means.

 

Duplicate how the DoNothing packages in SexLab are setup, with your own custom faction rank of  1 set in the conditions, then on the Quest alias make it empty and optional, add the DoNothing package that has a faction condition of rank 1, add that faction to the quest alias, and then duplicate that alias 126 times (or 127, it crashes if you try and go above that, but I can't remember if it crashes at 128 or when doing more) On the quest with the aliases, set a script that loops through the number of aliases you have using Quest.GetNthAlias() storing each DoNothing alias into an array. Finally when binding an actor with your mod, loop through that array using ReferenceAlias.ForceRefIfEmpty() until the actor is able to fill one, once they fill an alias, set their faction rank to 1 and evaluate package so they use the one attached to their alias. If limiting the number of actors that can be bound to 128 is just absolutely a no go to you, than simply add the DoNothing through ActorUtil as well as a precaution incase all 128 aliases are claimed.

 

This is exactly how SexLab adds it's DoNothing package during scenes, and I've never had a problem with. If you need examples of this look at "SexLabDoNothing" package, "SexLabAnimatingFaction" faction, "SexLabThread00" quest for examples of alias setup (only you'll want 128-ish rather than just 5, not as tedious as it sounds there is a CK hotkey to duplicate an alias repeatedly) and then for scripting to fill the actors into an alias for the package look at sslThreadModel.psc's function PickAlias().

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use