Jump to content

Fighting the Slavery/Tryout Stutter


Recommended Posts

Those five form list are all Scanner Lists for Legion.esm' date=' Powder Ganger Tryout, Violet's Scanner in Fiends Tryout, Kahn's Tryout, and Sexout Rapist. Not good.

[/quote']

Ā 

Not good indeed. Only I have no idea how that can be happening. Well, I have some, but their credibility varies from "Shut up!" to "No way!" to "You're fucking nuts!"

Before I get to the ideas, let's see what happens in Tryout's scripts.

Ā 

Basically, they follow this pattern:

int init

begin ScriptEffectStart
 if (0 == init)
   set init to 1




 endif
end

Ā 

So we can see they should clear their lists at least once, on the first run, when the "init" variable is zero. At the same time, we see on your screenshot that doesn't happen. So here's the ideas:

1) The scripts don't run at all because the game has a limit on the number of simultaneously running scripts (that is, scheduled to run at 1 frame) and you've reached it.

2) The scripts do run, but get interrupted somehow before they make it to their cleanup blocks.

3) The scanner filled the lists with 21573 entries in one go.

4) The "init" variable is not zero on the first run.

5) The list references in the scanner list and those in spell scripts differ.

Ā 

The first two can be tested by inserting a debug logging code to the beginning and the end of the scripts, e.g.:

begin ScriptEffectStart
printc "SES: IN"
 if (0 == init)
   ...
 endif
printc "SES: OUT"
end

Link to comment

If RemoveMe does not remove a CIOS'd spell as I believe, then I can think of some more scenarios.

Ā 

1 - Since RemoveMe doesn't remove the spell and the spell is always cast on the player it would result in countless copies of the spell sitting there trapped in ScriptEffectUpdate repeating RemoveMe.

Ā 

2 - Since RemoveMe doesn't remove the spell, perhaps the engine looks at the player and says, he already has that effect, so the next time the scan target spell is cast, it's ignored (THIS IS VERY LIKELY)

Ā 

3- In either of the above cases, the engine could be re-using the script variables EVEN if it's using multiple copies of the spell on the player... resulting in init always being == 1 on any spell after the first.

Link to comment
If RemoveMe does not remove a CIOS'd spell as I believe' date=' then I can think of some more scenarios.

Ā 

1 - Since RemoveMe doesn't remove the spell and the spell is always cast on the player it would result in countless copies of the spell sitting there trapped in ScriptEffectUpdate repeating RemoveMe.

Ā 

2 - Since RemoveMe doesn't remove the spell, perhaps the engine looks at the player and says, he already has that effect, so the next time the scan target spell is cast, it's ignored (THIS IS VERY LIKELY)

Ā 

3- In either of the above cases, the engine could be re-using the script variables EVEN if it's using multiple copies of the spell on the player... resulting in init always being == 1 on any spell after the first.[/quote']

RemoveMe doesn't remove Spells, I've accidently tried that a few times when changing Token scripts to Spells :)

This is part of the reason I do this on many of my scripts to mske sure when I've added a spell it has time to be there to be detected before I add it a second or 3rd time on the next run, it seems to have solved a few instances of what seems like multiple spells added for me, and spells added to the wrong Actor/Object because rZActor hadn't loaded on the first scan, and I'm pretty sure from what I've seen if the same spell is added twice the variables are overwritten. I've also had cases where I couldn't somehow couldn't remove spells with Dispel due to I suspect screwy stuff like adding twice.

Set rZActor to GetSelf
Set iCount to iCount + 1
if rZActor && iCount >= 9
    Set iCount to 0
    if rZActor.IsSpellTarget TestSpell < 1
         rZActor.CIOS TestSpell
    endif
endif

Link to comment

Right, I made a debug version of Legion's script. It's two versions - one with RemoveMe and the other one with Dispel, and that's the only difference. I did scof at the main menu and then loaded a savegame in Gomorrah Courtyard.

Expect A LOT of spam in the console as each begin/end block prints several messages every time it's executed.

Ā 

astymma is right about RemoveMe not stopping the spell (and frankly, that's what alerted me when I first saw it in the code, but then I thought I don't know something). However, my log shows that in case of an already running script, CIOS stops the currently running script and starts a new one, and script variables are not reused.

Ā 

EDIT: Made version 2 - added ScriptEffectFinish blocks and a debug message before calling CIOS, so the picture is more detailed now.

z117_SexoutLegion_scanner_dbg.v2.zip

Link to comment

Right' date=' I made a debug version of Legion's script. It's two versions - one with RemoveMe and the other one with Dispel, and that's the only difference. I did scof at the main menu and then loaded a savegame in Gomorrah Courtyard.

Expect A LOT of spam in the console as each begin/end block prints several messages every time it's executed.

Ā 

[b']astymma[/b] is right about RemoveMe not stopping the spell (and frankly, that's what alerted me when I first saw it in the code, but then I thought I don't know something). However, my log shows that in case of an already running script, CIOS stops the currently running script and starts a new one, and script variables are not reused.

Ā 

EDIT: Made version 2 - added ScriptEffectFinish blocks and a debug message before calling CIOS, so the picture is more detailed now.

Ā 

I'm glad to see that you're observing is what I observed and is what the engine is supposed to be doing. The correct engine procedure for a scripted effect is to stop the same effect if it's running and start a new copy. It's kind of why my pseudo code above STARTED with copying the list members to a completely new list. To be perfectly honest, I'm beginning to think that that is ALL the scan target spells should be doing... copy the list to a quest variable and then empty the scan target list.... and that's it. Just grab the id's, clean the list and tell something else to process it. This system we currently have is just WAY too susceptible to timing conflicts and instability. Now, I'm quite sure that we can stay within the script effect start-update-finish framework and make something work... but do we want to? Especially when we don't have to. If we simply copied any targets to a list and the processed it outside of the scripted handler at our leisure, we'd still be handling all of the id's in a timely manner but we'd also be avoiding issues with keeping the scan target lists properly cleaned and ready for new scan targets.

Link to comment

To be perfectly honest, I'm beginning to think that that is ALL the scan target spells should be doing... copy the list to a quest variable and then empty the scan target list.... and that's it.

I'm all for refactoring the spells in their current form, but I'm definitely not for copying, because it would require more memory (one more formlist) and twice as much per-frame loop iterations if you're going to process them in one go. And if you're going to save on per-frame iterations by processing one list item per ScriptEffectUpdate block run (with or without copying), consider this:

1) if you look at my log for the RemoveMe version, you'll see that ScriptEffectUpdate manages to run 30-65 times between the scanner runs (and there's no big difference between 10 and 1 Hz - just search for "gonna set the scanner"),

2) when I stand in front of Lucky 38, the scanner fills the lists with 75 items per run, and I don't use a population-increasing mod.

That means that you must not forget to remove both your list and spell from the scanner lists in the ScriptEffectStart block and then add them back after you've processed the list so that the scanner won't call you while you're processing the list, otherwise you may (and in my case, will) end up with a slowly but surely growing list.

Ā 

If I were writing the spells, I would process the targets in a ScriptEffectStart block (since all the "processing" does is cast another spell that does the actual job) and unconditionally clear the list and dispel the spell in a ScrptEffectUpdate block. Something like this:

Ā 

begin ScriptEffectStart
	if no need to process the targets (e.g. init != 0)
		return
	endif

	int L_process_targets
	set L_process_targets to 1

label L_process_targets
	ref tgt
	set tgt to ListRemoveNth targets 0
	if tgt != 0
		if target meets conditions (not IsSpellTarget whatever, etc.)
			tgt.cios whatever
		endif

		goto L_process_targets
	endif

end


begin ScriptEffectUpdate
	int L_cleanup
	set L_cleanup to 1

label L_cleanup
	if (ListRemoveNth targets 0) != 0
		goto L_cleanup
	endif

	dispel ThisSpell
end

Ā 

Ā 

But before worrying about refacoring, I'd rather wait until wardminator or anyone else who experiences evergrowing lists post their logs.

Just grab the id's, clean the list and tell something else to process it.

But that's exactly what the spells do now: they grab IDs one by one (in a loop), tell something else to process them (CIOS, in the same loop), and then clear their list (after the loop; not optimal, but that's not the point now).
Link to comment

OK, I am going to try this once more. I tried to post about this once before, but it is taking me some time to get accustomed to the new website.

Ā 

I edited all the scripts for every mod that uses the scanner. None are written correctly as what I believe to be the way Prideslayer said they are supposed to be written. I believe Halstrom can correct me if I am wrong about this or not, but everyone of the scanner scripts for all the plug-ins that use the scanner omit this line...

Ā 

Set nCount to ListGetCount MySexoutScanList

The resulting list clearing portion of the script should look like this...

Ā 

Label MyLabel
Set nCount to ListGetCount MySexoutScanTargets
If nCount > 0
    ListRemoveNth MySexoutScanTargets 0
    goto MyLabel
endif

None of them look like this and as a result, the scanners that are clearing their list are not clearing them completely. Since rewriting all these scripts to resemble this, Sexout with all the plug-ins that use the scanner has never run better in my game. The same day I rewrote those scripts, I was able to run the game for more than 3 hours straight without so much as a hiccup. I have never been able to go more than an hour before while running Sexout... ever. That alone should tell you something.

Ā 

If you want to change the script framework, that is your prerogative, but astymma is very much right about the current system is very susceptible to timing conflicts and instability.

Link to comment

OK, I am going to try this once more. I tried to post about this once before, but it is taking me some time to get accustomed to the new website.

Ā 

I edited all the scripts for every mod that uses the scanner. None are written correctly as what I believe to be the way Prideslayer said they are supposed to be written. I believe Halstrom can correct me if I am wrong about this or not, but everyone of the scanner scripts for all the plug-ins that use the scanner omit this line...

Ā 

Set nCount to ListGetCount MySexoutScanList

The resulting list clearing portion of the script should look like this...

Ā 

Label MyLabel
Set nCount to ListGetCount MySexoutScanTargets
If nCount > 0
    ListRemoveNth MySexoutScanTargets 0
    goto MyLabel
endif

None of them look like this and as a result, the scanners that are clearing their list are not clearing them completely. Since rewriting all these scripts to resemble this, Sexout with all the plug-ins that use the scanner has never run better in my game. The same day I rewrote those scripts, I was able to run the game for more than 3 hours straight without so much as a hiccup. I have never been able to go more than an hour before while running Sexout... ever. That alone should tell you something.

Ā 

If you want to change the script framework, that is your prerogative, but astymma is very much right about the current system is very susceptible to timing conflicts and instability.

I can't help you with the scanner bit, none of my stuff uses it, I've been thinking of using it one day to create a couple of resource formlists like SexoutSDataMalesWithin20feet, SexoutSDataRapistsWithin20feetĀ or similar so other mods could maybe avoid using the scanner and just use that formlist.

Link to comment

I can't help you with the scanner bit, none of my stuff uses it, I've been thinking of using it one day to create a couple of resource formlists like SexoutSDataMalesWithin20feet, SexoutSDataRapistsWithin20feetĀ or similar so other mods could maybe avoid using the scanner and just use that formlist.

Well, you'll run into the same issue we're currently discussing except it would all be in SCR instead of the mods AND the mods would have to keep their own lists of which actors they've processed from your lists and which they haven't. So basically, abstracting TO SCR would create more work instead of less. All we really need to hammer out is how each mod should be properly clearing its scan result targets so their lists don't grow beyond their ability to process them.

Link to comment

Well, you'll run into the same issue we're currently discussing except it would all be in SCR instead of the mods AND the mods would have to keep their own lists of which actors they've processed from your lists and which they haven't. So basically, abstracting TO SCR would create more work instead of less. All we really need to hammer out is how each mod should be properly clearing its scan result targets so their lists don't grow beyond their ability to process them.

True

Link to comment

Archived

This topic is now archived and is closed to further replies.

  • 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