Jump to content
  • entries
    44
  • comments
    150
  • views
    14,448

On Script-Heavy Mods and Engine Overload


Myst42

1,415 views

PART I: Concepts.
_________________

Much has been said about "script heavy" mods and how they can break your game. But over the years, the notion that scripts can break your game has become less and less of an understood phenomenon, and more of a creepy boogeyman to scare children away from using scripted mods.

I'm here to shed some light on this matter, not because I'm an expert nor because "I know it all", but instead, because I've investigated this phenomenon, I've witnessed how it works with my own eyes, and I've learnt to take measures on how to solve it most of the times.
This article may be of beginner level to some, but I intend it both, to help beginner modders learn something, and to attempt to make normal users understand a bit more about why their game could be "broken" and why it's not because of "script heavy mods' fault".

First of all I have to say one very important thing: THERE ARE NO SCRIPT-HEAVY MODS.
- "But Myst, everyone knows if you install mods with scripts, you can break your game"
Lies.

Scripts won't break your game. Bad coding, however, can, and it poses a real danger, but that's not something that happens because of "scripts being scripts", it happens because a modder makes a mistake and publishes a mod with bad coding.

Second, we should clarify what does people understand by "breaking one's game".
Because this notion may seem generic and common, but it may be different for everyone. Some people says it relates to having frequent CTDs, while others, such as myself think it relates to when the game's scripts seemingly stop working and you can't do anything because scripts dont do what they're supposed to do.
I have experienced this kind of "broken game" myself as well, and I also fought to understand the reasons for it, and ultimately, fix them.
Script lag, is one thing, but CTDs and broken quests are a completely different one, and it's usually related to stuff such as a bad load order, mod incompatibilities, corrupt assets (IE missing textures or broken nifs) or bad graphic settings but neither of these has anything to do with scripting.
Alternatively, some scripts can cause CTDs, but that's a rare thing and it's usually related to other types of bad coding which I wont refer to on this article.

Third, there is another misconception on what a "script heavy mod" even is. Because it can be

  1. A mod with many scripts.
  2. A mod with LONG scripts.
  3. A mod with complex scripts that interact with many things
  4. A mod with scripts that never stop running in the background


And here's the shocker, because NONE of the above constitutes ANY kind of danger to the game.

A friend developed an entire mod to test the effects of scripts on the game and try to pinpoint an exact cause of script issues, it was designed to overload the game in every possible way as described by the "script heavy" myth, and his results concluded that the game can candle thousands and thousands of instances of scripts simultaneously in the background, and keep running without even coming close such a thing a s "limit". The mod was designed to push Skyrim's script engine's limits beyond what any combination of mods can ever achieve.

PART II: How It Happens
________________________

What was found after such testing, however, is that there is a situation that DOES exist, and can be mistaken for a "broken game" because in practice, it is.
I will not describe every possible case of "bad code", because I'm certain there's more than one screw up that can cause game issues, but I will talk about one of the most frequent ones which is by far, one, if not the most common reason of script issues.

And now, I'm referring to something I call "script saturation" although I'm not sure if that's the correct term.
This phenomenon, occurs when the game is receiving lots and lots of simultaneous script calls per second.
As a result, a chain of events begins to occur.

  • First,you'll notice the game can start lagging in terms of scripted events. If something was supposed to happen when you get hit, you'll notice it happens later, if you use a scripted spell, the effect will also come with a delay. This lag can be something tolerable, or it can be massive and you end up seeing the effects of a script, as far as 5 minutes later, or more.
  • Second, if you have enabled the log in your Skyrim.ini, you'll notice the existence of the infamous stack dumps. Stack dumps, arent a problem per-se, but they are warning you of the current script saturation you're experiencing.
  • Script saturation, in the internal mechanics of the game, means you're getting too many script calls and the game isn't capable of answering them all in time, so it stores pendant calls for the next frame in hope it can finish in time, so as described by the wiki (somewhere I can't recall), the game delays the execution of scripts. The visual result was evident since you started seeing script lag occur and stuff happening seconds, to minutes after they were supposed to.


PART III: Why it Happens - Section A): Fundaments of Script Lag
________________________

- "I knew it!, I knew script heavy mods existed, you're just trying to confuse me!"
Technically, a form of "script heavy" mod can exist, but I just call that BAD CODE.
See, the thing is, it doesnt happen because "a mod has many scripts" or because "the scripts run in the background" or "are too long". It doesnt happen either because "you have too many mods" or "you combined more than 2 or 3 script-heavy mods in one install".
It happens EXCLUSIVELY for the action of a single, lone script, which can come from anywhere, at any time.
Any script can have bad coding, and size doesnt matter.

If you want an example, here is one:

Spoiler

ScriptName BadEffectScript Extends ActiveMagicEffect

Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
    Utility.Wait(5.0)
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    Utility.Wait(5.0)
EndEvent


The pevious script, has only 2 events, and does absolutely nothing in practice. But what it does do, is cause an event to get locked on processing as soon as it arrives.
Now, during a battle, a concentration spell can spam these events dozens of times each frame, and the longer such concentration spell is held on the bearer of this script, the more script calls that begin to accumulate on them, until at a given moment, the barrier will be breached and your papyrus log will generate a stack dump.
When that happens, if you were expecting something to happen with the script, say a shader apply, you'd notice shaders begin being applied later.
And this is how a single script with 2 spammy events and no precaution, can generate script spam and slow down your script engine.
Notice it's not long, it's not complex, it doesnt even do anything it just spams events.
The probem is that the more events that get spammed, the more likely the game gets saturated, and other scripted mods will suffer the script lag as well.

PART III: Why it Happens - Section B): "A Broken Game"
______________________

The game, can normally recover from these kinds of situations, after all, no mod is going to have a concentration spell casted on an actor during the entire game... right?...
Wrong.
Some mods, use mechanics that do apply constant effects on the player, ALL the time. And if you have a mod that's set to respond to these events, if it's not set correctly, there's a chance it will get saturated.
The first part was correct, the game DOES try to recover from stressful scripting situations, and it does this by simply finishing answering all the script calls untill the demand is back to what it can answer on a single frame, AKA a relaxed environment.
It's simple, the stress rises up, the game deals with it as best as it can, then the stress ends and the engine can relax again.

But what if it never relaxes?

This is when the real danger of event spammers comes into play.

It happens when you have a stressful situation that generates enough script calls to saturate the engine, and you dont ever get to the moment when it finishes answering them all.
I dont know the exact number, but as a mental exercise, lets say the game can answer 100 script calls per second, from a single concentration magic effect.
Now, picture that you have a combination of mods, that allows an event spammer as described above, coupled with a stressful situation, say a dragon, 2 companions and 6 mages.
Suddenly, you're no longer receiving 100 script calls or less per second but 400 instead.
The game will queue 300 to be answered on the next time, but when that time comes, we will get another 400
By the third time it checks, you will be getting a total sum of 900 delayed calls because it can only answer 100 each time.
And the lower your framerate, the less actual execution time the script engine has to catch up with the increasing demand.

Now imagine the "battle" never ends, and you get this eternal event spam.
You're never ever going to see scripts working again because the lag is infinite.
This is close to what happens when you have an event spammer mod combined with a mod that creates a concentration, or cloak effect, being permanently applied to the player, since more than a few mods apply unseen effects on the player.
This is the reason why scripts stop working and people say their game is "broken".

PART IV. How to Fix It
________________________

The solution, for mod makers, is simple, for mod users, not so much as they have yet to learn to identify a troublesome mod and either fix it or remove it.
But for modders, it begins by knowing the first rule, which is: BEWARE of event spammers.
Try not to use those kinds of events at all, avoid effects that cause repeated calls such as cloaks or concentration type effects if possible, but if you absolutely MUST use those kinds of events/effects, you should always use an EVENT FILTER, like this:

Spoiler

ScriptName BadEffectScript Extends ActiveMagicEffect

;;===========================;;
Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
    GoToState("Busy")
    Utility.Wait(5.0)
    GoToState("")
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    GoToState("Busy")
    Utility.Wait(5.0)
    GoToState("")
EndEvent

;;===========================;;
State Busy

Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
EndEvent

EndState
;;===========================;;

The above example is a State filter, and it will ensure only one event is processed at a time, and when it's done, the gate will be opened for another event.

Alternatively, a Bool filter also works

Spoiler

ScriptName BadEffectScript Extends ActiveMagicEffect

Bool BusyMagic = False
Bool BusyHit = False

;;===========================;;
Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
    If BusyMagic == False
        BusyMagic = True
        Utility.Wait(5.0)
        BusyMagic = False
    EndIf
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    If BusyHit == False
        BusyHit = True
        Utility.Wait(5.0)
        BusyHit = False
    EndIf
EndEvent
;;===========================;;

The second example is not as effective as the first one since it still has code inside, but it will reduce script spam.

Note that none of these methods is flawless. Even when using them, mods are still likely to get a stack dump or two every once in a while, but by reducing their capacity to spam, you will ensure that the game's load can be overcome more than 90% of the times.

So you see, scripts are not evil, but we have to be careful about how we design our mods because it's very easy to screw up and end up regretting it later. Most people never bothers to understand the mechanic of this phenomenon, and when their game malfunctions, they look for the causes of it on myths such as "scripts being evil" when it's not about having many scripts, or complicated scripting. A single mod is more than capable of "breaking" one's game under certain circumstances.

0 Comments


Recommended Comments

There are no comments to display.

×
×
  • 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