SuperElitist Posted December 7, 2019 Share Posted December 7, 2019 I'm looking at an idea for an Action Boy/Girl rank 4. I know it's en vogue to hate on constantly-running scripts, but what's the likely actual impact of a script that fires every second or so, checks if the player ran out of AP, rolls a die, and restores all AP on success? Oh and doesn't check again for a few seconds. Link to comment Share on other sites More sharing options...
SKKmods Posted December 7, 2019 Share Posted December 7, 2019 That sort of frequent polling should be done at the C++ game level rather than in abstracted script, which is why perk entry points exist. One script firing a timer every second will not screw a game, but consider the hundreds of scripts already running in a game, plus all the inconsidrate mod authors who are "only just" and that buildup is what causes script lag to give scripting a bad name. Learn more HERE. Link to comment Share on other sites More sharing options...
niston Posted December 7, 2019 Share Posted December 7, 2019 The impact of a continuously running script (such as a perpetual loop) is that it gets baked into the save. This is also and especially true if you put a Wait() call into the loop, as latent function calls are ALSO baked into the save. Uninstalling your function, or trying to upgrade it, w/o further measures will be extremely problematic and will likely end up a case for Fallrim Tools. One more thing: Perpetually running loops that have no .Wait() or similar call in them, will of course hog the Papyrus engine. This may prevent other scripts from executing timely, or executing at all - Which yields completely unpredictable results. And because a running loop gets baked into your save, it will resume running and hogging Papyrus as soon as you load that save. Thus, that perpetually running, Papyrus hogging loop will ruin any saves made from the moment on it is first executed. As a consequence, it does not take a "script heavy mod" to ruin your game. A single script w/ 6 lines of code can wreck your game perfectly fine. But I digress. A script function being triggered, say every 60 seconds (or even once every second), from a timer is not continuously running. Hence it will NOT get baked into the save, unless the function is executing at the very exact moment you make the save. If you reload such a save, the function will then resume running from the save once, until it completes. If the .PEX containing the function was upgraded, the upgraded version of the function will then execute the next time the timer fires. See also https://www.creationkit.com/fallout4/index.php?title=Papyrus_FAQs Link to comment Share on other sites More sharing options...
SuperElitist Posted December 9, 2019 Author Share Posted December 9, 2019 I suppose I could have been misunderstood because I said "fires every second or so", but what I should have said is "runs on a 1 second timer"--no one runs unbound while loops in Papyrus anywhere, right? But I guess the question should have been more: what is the likely compute cost of the following code fragment? Event OnTimer(int aiTimerID) If (aiTimerID == tick_timer_id) If (OwnerRef.GetValue(ActionPointAV) < APMinThreshold.Value) Self.StartTimer(CooldownLength.Value, tick_timer_id) If (Utility.RandomFloat() < ChanceToRestore.Value) OwnerRef.RestoreValue(ActionPointAV, 999) ; assuming AP gets damaged and can be restored. EndIf Else Self.StartTimer(TickLength.Value, tick_timer_id) EndIf EndIf EndEvent I don't really have a clear picture on what Papyrus' processing overhead is like. In C++, code like this would probably be measured in microseconds--getting the random number would probably take longer than everything else combined. I guess I could whip up a test script and start piling on meaningless work until it starts to lag... But I was hoping people here might be able to provide some exposition on just how fast Papyrus can execute a couple calls to the game engine and a couple booleans. Link to comment Share on other sites More sharing options...
SuperElitist Posted December 9, 2019 Author Share Posted December 9, 2019 Oh and SKK, I fully agree and I would love a perk entry point for "ran out of AP"! Link to comment Share on other sites More sharing options...
SKKmods Posted December 9, 2019 Share Posted December 9, 2019 Rule of thumb, each function call takes 1 display frame because Papyrus script execution is bound to frame rate, as demonstrated by the Script Lag Detector (downtown, where all the lights are bright). What we don't know is the script/threading model to understand how many scripts can run in parallel at 1 function call per frame before the papyrus subsystem runs out of resource budget, and what flood handling is/does. Run Fallrim ReSaver, look at how many scripts are active in a save game, and shudder at our ignorance on the real time platform design: forgive us, for we know not what we do. If you step though the base game script there is a bunch of effort to limit the number of actor/object attached scripts in the active area around the player (RE system, EM system, Settlement system & etc), so it is clearly a material consideration. If an SKK mod depended on a continuous 1 second timer it would never be published, there are several like that decomposing on the cutting room floor. But that's just my quality threshold. Link to comment Share on other sites More sharing options...
niston Posted December 9, 2019 Share Posted December 9, 2019 Some use a while loop w/ a call to Wait() for uninstalling stuff, such as removing unresolvable workshop menu entries, after the plugin has been removed. This can be done, so that no uninstall chem is required. It works because, as mentioned, the running loop gets baked into the saves. So the uninstall code can execute even after it's plugin and pex files have been removed. Of course, the uninstaller loop is supposed to terminate, once the code has performed it's clean-up duties... On the subject of script execution budget, there are ini Settings to adjust the time slice given to Papyrus engine per frame. But, as SKK already pointed out, Papyrus is tied to the framerate, so you can't put arbitrary values and expect it to work. There's also some memory allocation related settings. Kinggath has posted some more details about this on his SS forums. KG's Link eludes me atm, but here's an older post on reddit that's been written for Skyrim, but still holds true for FO4. What you can do to find out more about the performance of a particular script of yours is, you can use script profiling: https://www.creationkit.com/fallout4/index.php?title=StartScriptProfiling_-_Debug From experience, even on my ancient Core 2 Duo/Radeon HD 6850 machine, script budget is rarely* a problem (decidedly less so than badly written script code). But I suppose console is different, as the frame rate there is just 30FPS instead of 60, if I'm not mistaken. So, as Papyrus gets one time slice per Frame, only half the number of time slices are available to Papyrus per Second, compared to PC platform. Now I don't care about console the slightest, but SKK for example has a large console user base, so he will be much more wary about this than I am. Another thing that follows from the tied-to-framerate-thing is that, the quicker the GPU renders the 60 frames in one second, the more remainder-of-that-second will be theoretically available to Papyrus (minus other things the game needs time for per frame), if you want to change the time slice duration. Something I'd still like to point out is, the number of attached scripts by itself is not very meaningful in terms of processor usage. You can have 1000 scripts attached to 1000 objects, all doing mostly nothing. They won't use up much processing power. But if you have 1000 scripts with 1000 timers firing every second, you're very likely going to destroy the game. On a side note, there is something about large numbers of rapidly firing timers that can trigger the dreaded "You cannot assign any settler at any settlement to anything anymore, they will just run up to the object you assigned and then immediately walk away" bug. I can msg you the name of a mod that will reliably trigger the bug if you pick up/drop/take from or put into container/put on conveyor belts large (>500) numbers of the objects that it provides. It will also completely freeze the game once you try to pick up thousands of the mod's items from a container. All because it spins up an obscene amount of rapidly firing timers to cast AoE damage (which, for some reason doesn't even work) if you do that. I resent the experience of having to do Nuka World for a second time because of the settler-breaking-bug to this day, and have vowed to remake the otherwise great functionality the mod in question provides. Some day. * If you employ some common sense and don't dial every setting up to ULTRA, like Todd did with his Tesla. Link to comment Share on other sites More sharing options...
SuperElitist Posted December 10, 2019 Author Share Posted December 10, 2019 Thank you guys so much! This is exactly the kind of exposition I was looking for. SKK, I will try to keep that in mind when I'm coding. As an aside, I sang that song earlier tonight! niston, that is indeed a good reason to use a while loop. In any event, I concocted an alternative, but it has a problem which i'll discuss it in a new thread. Link to comment Share on other sites More sharing options...
Recommended Posts