Difference between revisions of "User:DavidJCobb/Stack dumping"

Corrections.
imported>DavidJCobb
imported>DavidJCobb
(Corrections.)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''Stack dumping''' is a Papyrus event that can cause unpredictable and potentially severe errors in a player's savegame. My understanding of the phenomenon is as follows:
'''Stack dumping''' is a Papyrus warning that indicates that the script engine has been given too many tasks to run at once.
 
{{InDepth|Previously, it was thought that stack dumping indicated the ''termination'' of stacks, i.e. the game engine randomly throwing out paused script tasks. However, Bethesda's own description of the phenomenon in the Fallout 4 CK wiki suggests that this is merely a warning system.}}


== Overview ==
== Overview ==
Whenever the game engine calls a function, a ''call stack'' is generated. When that function calls another function, the callee is added to the caller's call stack. Papyrus can only have a certain number of call stacks running at a time; if too many stacks accumulate, some may be ''suspended'' (paused). Stacks may also be suspended for other reasons:
Whenever the game engine calls a function, a ''call stack'' is generated. A call stack keeps track of the function's state -- which functions have been called (if X calls Y, Y is added to the X call stack), and what values their variables have. Papyrus can only have a certain number of call stacks running at a time; if too many stacks accumulate, some may be ''suspended'' (paused). Stacks may also be suspended for other reasons:


* A function that calls [[Wait - Utility|Utility.Wait(''n'')]] will suspend its call stack for ''n'' seconds.
* A function that calls [[Wait - Utility|Utility.Wait(''n'')]] will suspend its call stack for ''n'' seconds.
Line 9: Line 11:
* Some events' handlers cannot run concurrently with themselves. If the event occurs several times in a short period, only one call to its event handler will run immediately; the other calls will exist as suspended stacks.
* Some events' handlers cannot run concurrently with themselves. If the event occurs several times in a short period, only one call to its event handler will run immediately; the other calls will exist as suspended stacks.


If too many suspended stacks accumulate, the Papyrus engine will not be able to hold them all; suspended stacks will be selected at random and discarded, and information about those stacks will be printed to the Papyrus logs, prefixed by this message:
If too many suspended stacks accumulate, information about those stacks will be printed to the Papyrus logs, prefixed by this message:


<pre>Suspended stack count is over our warning threshold, dumping stacks:</pre>
<pre>Suspended stack count is over our warning threshold, dumping stacks:</pre>


This means that if a mod has a problem that leads to stack dumping, that mod will interfere with itself, with other mods, and with Bethesda-authored scripts (because Papyrus doesn't care where the problem is coming from; it'll dump as many stacks as it can, indiscriminately, until it feels safe). The problem will have unpredictable consequences, which may or may not break other content or otherwise lead to save corruption. As a modder, the best approach to take here is the maximally cautious one, because even if a stack dumping issue doesn't wreck ''your'' savegame, it could wreck someone else's. If your mod has a flaw that leads to stack dumping, fixing that needs to be a high priority.
Save corruption has been observed following messages of this kind, but the exact nature of those problems isn't known. According to Bethesda's description of this phenomenon in the Fallout 4 CK wiki, stack dumping is just a warning system, and no action is taken at that stage. Whether this error is harmless or not, it very often ''does'' indicate a problem with a mod trying to do too much processing at once.


== Specific methods to minimize stack dumping ==
== Specific methods to minimize stack dumping ==
Line 38: Line 40:


== Miscellaneous facts ==
== Miscellaneous facts ==
* RegisterForSingleUpdate(''n'') does ''not'' create a stack and suspend it for ''n'' seconds. I have confirmed this experimentally.
* RegisterForSingleUpdate(''n'') does ''not'' create a stack and suspend it for ''n'' seconds. The stack is only created when it's time to run. I have confirmed this experimentally.


== Code snippets ==
== Code snippets ==
These code snippets have not been tested directly, and the benefits are purely theoretical. The only way to know for sure if they'll help is to devise stress tests for whatever you're trying to do. Run a stress test with code that doesn't use these methods, and a stress test with code that does, and see what code breaks first and worst.
These code snippets have not been tested directly, and the benefits are purely theoretical. The only way to know for sure if they'll help is to devise stress tests for whatever you're trying to do. Run a stress test with code that doesn't use these methods, and a stress test with code that does, and check the logs to see what code dumps stacks first and worst.


=== Process a task OnHit, and wait for X seconds during or after the task ===
=== Process a task OnHit, and wait for X seconds during or after the task ===
Anonymous user