Difference between revisions of "User:DavidJCobb/Miscellany"

6,503 bytes added ,  16:51, 18 January 2015
USKP forums have a lot of stuff to learn from. Dug up some old info and jammed it onto this page.
imported>DavidJCobb
m
imported>DavidJCobb
(USKP forums have a lot of stuff to learn from. Dug up some old info and jammed it onto this page.)
Line 27: Line 27:


=== Detecting references created at run-time ===
=== Detecting references created at run-time ===
:''Source:'' [http://afkmods.iguanadons.net/index.php?/topic/3941-how-to-distinguish-run-time-created-actors-from-hand-placed-ones/ AFKMods: How to distinguish run-time created actors from hand-placed ones ? ]
:''Source:'' [http://afkmods.iguanadons.net/index.php?/topic/3941-how-to-distinguish-run-time-created-actors-from-hand-placed-ones/ '''AFKMods:''' How to distinguish run-time created actors from hand-placed ones ? ]


If the reference is an Actor, you can't! The base game can create actors to fill quest aliases, it seems.
If the reference is an Actor, you can't! The base game can create actors to fill quest aliases, it seems.


As for other kinds of references? I'll look into that later.
As for other kinds of references? I'll look into that later.
== Papyrus errors ==
Samples of Papyrus logs and errors that I haven't often seen posted on the web, along with meanings when known.
=== Baked script data is outdated ===
:''Source:'' [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-4#entry149601 '''AFKMods:''' The critter thread]
<pre>warning: Function &lt;name&gt; in stack frame &lt;number&gt; in stack &lt;number&gt; differs from the in-game resource files - using version from save</pre>
Occurs when an old version of a script is baked into a savegame.
=== Baked script data malfunctioning badly enough to be dropped ===
:''Source:'' [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-7#entry149925 '''AFKMods:''' The critter thread]
<pre>[02/09/2014 - 03:33:25PM] error: Failed to read basic script data for critterFish attached to  (FF002ABA)
[02/09/2014 - 03:33:25PM] error: Unable to load object 0x1305E1E0 from save game
[02/09/2014 - 03:33:25PM] Errors occurred while loading the Papyrus save game data</pre>
Occurs when old script data (baked into a savegame) has malfunctioned badly enough for the game engine to just throw it out.
== Fun with multi-threading! ==
"Fun" may not be the right word to use here, actually.
=== Conditions are interruptible ===
::''Source:'' [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-7#entry149921 '''AFKMods:''' The critter thread]
Conditions like the following are inherently unreliable due to how Papyrus handles threading.
  If kMyObjectReference && !kMyObjectReference.isDeleted() && !kMyObjectReference.isDisabled()
  EndIf
<code>IsDeleted()</code> and <code>IsDisabled()</code> are delayed functions (as opposed to [[:Category:Non-delayed Native Function|non-delayed functions]]), so Papyrus may actually pause the current script ''in the middle of this If statement'' to run them. During that time, another thread can set the ObjectReference variable to None. Per the scripter's comments in the source, this can lead to two kinds of errors:
* <code>kMyObjectReference.IsDisabled()</code> gets treated as <code>None.IsDisabled()</code>. This is invalid and returns <code>None</code>.
* That returned <code>None</code> is then inverted with <code>!</code>, which is also invalid. This yields Papyrus log errors of the form:
*: <pre>warning: Assigning None to a non-object variable named "::temp33"</pre>
The lesson to learn here is that even a single If statement can be interrupted and hosed by multithreading.
Makes me wonder if something like the following might work:
  If kMyObjectReference && !kMyObjectReference.isDeleted() && kMyObjectReference && !kMyObjectReference.isDisabled()
  EndIf
=== Delayed functions are interruptible ===
Just about every native function that isn't [[:Category:Non-delayed Native Function|listed here]] is interruptible. Every moment you call these functions is a moment your script can be interrupted. This produces all sorts of "fun" oddities.
<ul>
  <li><code>Delete()</code> is a delayed function. Your attempt to delete an object can be interrupted by another attempt to delete that same object, resulting in your interrupted call failing (it's treated as <code>None.Delete()</code>).</li>
  <li>
      The <code>x</code>, <code>y</code>, and <code>z</code> "properties" on ObjectReferences [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-8#entry150159 are actually interruptible functions]. As such, code blocks like the following can fail:
      <source lang="Papyrus">Int iCoordX = kMyObjectReference.x ; due to multi-threading, this code may be interrupted here...
Int iCoordY = kMyObjectReference.y ; ...and by the time the code resumes, kMyObjectReference could've been screwed with</source>
  </li>
</ul>
=== Other things to remember ===
* Cross-script function calls are interruptible. Your precious <code>Debug.Trace(...)</code> statements actually ''can'' affect things.
== Unsorted facts ==
* If you wish to borrow critter behaviors for a script, be careful. I've been reading through USKP discussions and apparently, Bethesda's critter scripts were broke as ''hell.'' Seems like the USKP rebuilds most critter behaviors almost from scratch.
* [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-3#entry149560 "Translate routines will operate properly in unloaded areas."] This, in regards to animating and moving critters like moths.
** Even though translations work in unloaded cells without 3D loaded, [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-4#entry149598 "<code>StopTranslation()</code> requires the cell attached and loaded 3D. There's no reason for it, but it throws an error without it!"]
*** ''The use case dealt with here involves deleting an object when its cell is exited (e.g. going from an exterior to an interior), when that object is being translated.''
** [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-4#entry149599 There is reason to doubt that translate routines actually do operate properly in unloaded areas.] It's possible that they don't properly unlock the translated object (allowing for deletion) unless the cell is attached.
* [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-2#entry149454 When an ingredient is sold or consumed, "it will have the deleted flag set already, and won't have a parent cell or 3D."]
*[http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-6#entry149699 Critter animations]: butterflies and moths use <code>fTakeOff</code>, while dragonflies and fireflies can use <code>fTakeOff</code> or <code>TakeOff</code>.
*You cannot [[GetAnimationVariableFloat - ObjectReference|get animation variables]] for an object [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-9#entry150430 if its 3D isn't loaded].
=== Unsorted edge-cases ===
* Be careful about handling things OnCellAttach and OnCellDetach in Riften. [http://afkmods.iguanadons.net/index.php?/topic/3781-the-critter-thread/page-8#entry150257 The city's walkways have you cross back and forth across a cell boundary.]
** ''The use case dealt with here involves deleting critters when you leave their containing cells. The scripter's attempted solution was to add a timed delay (using OnUpdateGameTime) to the deletion. Return to the cell before the timer has elapsed, and the critter is reused -- the deletion is canceled.''
Anonymous user