User:QQuix/Dynamic and Non-dynamic references

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search

Foreword[edit | edit source]

These are my notes on Dynamic and Non-dynamic references

I am half the time doing some test or another and keep reaching conclusions (some interesting ones, some not so much), but most of the time I don't write them down and forget about them in a few days.

I think that at least part of the conclusions might be useful for the community, but I did not write a regular WIKI article because (1) most of what I conclude is derived from tests and may not apply in all situations and (2) I don't have the writing skills to write a proper, non-bylined article.

So I decided to compromise by creating this personal page to work as a notepad where I will write down my notes on Dynamic and Non-dynamic references, including some of the basics already present throughout the WIKI. Anyone willing to rewrite the contents into a proper article is welcome to do so. I may doing it myself some day.

Contributions[edit | edit source]

  • Please, use the talk page to suggest new info about the subject and/or propose tests about some behavior of Dynamic and Non-dynamic references

Some disclaimers[edit | edit source]

  • Be aware that this is a Work In Progress and the contents may change as a result of additional tests and contributions.
  • Most of what is here is not new, and is written one way or another across the CS WIKI.
  • Some is based on general tests. May not be true under different conditions.
  • The notes do not include info related to enchantment, spells, or any magic in general, as I am not familiar with these aspects of the game.
  • The text structure may be messy at first (it is a notepad, after all).

Introduction[edit | edit source]

First, make sure you read Modding Terminology, particularly the topics Dynamic Content and Dynamic Items.

The basics[edit | edit source]

  • Non-dynamic references are references placed in the world in the CS (e.g. vanilla buildings, trees, NPCs)
  • Dynamic references are objects created in the world, dynamically (as the name says), during the game. (e.g. items dropped from inventories, references created with PlaceAtMe, spawned actors).

Although they are called dynamic and non-dynamic "items", the concepts are not restricted to (carriable) items. In this sense, there may be dynamic and non-dynamic statics (!), flora, furniture, NPCs etc. So, I will use dynamic and non- dynamic "references" as a general term for them.

Dynamic and Non-dynamic references[edit | edit source]

Dynamic x Non-dynamic references[edit | edit source]

  • Dynamic references have a FormID starting with 0xFF. Non-dynamic references have a FormID starting with the mod index of the mod that added it.
  • When picked up and dropped, non-dynamic references keeps their original FormID while non-dynamic references receive a new one each time.


Non-dynamic references[edit | edit source]

  • A non-dynamic reference is created in the CS when the modder drops an object in the render window. The CS assigns a FormID starting with the mod index of the active esp (usually 01, like "01002AF9"). The assigned FormID can be seen at the top right corner of the Reference window. The mod index will be adjusted when the game is loaded, based on the load order.
  • A non-dynamic reference keeps its original FormID when picked up and dropped by the player


Dynamic references[edit | edit source]

Creation[edit | edit source]

Dynamic references are created by:

  • Script functions [PlaceAtMe], [Drop], [DropMe]
  • The player dropping items from the PC inventory
  • Actors spawning from a spawn point
  • When a new reference is created during the game, it receives a FormID starting with 0xFF.
OBSE's GetSourceModIndex returns the value in the first byte, so "If reference.GetSourceModIndex == 255" will tell if a reference is dynamic or not.
  • When a dynamic reference is picked up, its FormID is discarded. When dropped, it receives a new FormID, which, most likely, will not be the same as before (see next).
  • A free FormID is reused only if it is after/higher than the last one in use. Free FormIDs in the middle of the series are not reused. Example: Drop 3 items. Lets say they receive FormIDs 11,12 and 13. If you pick #13 up and drop it again, it will be 13 again, one higher than the last used (which is now #12). If you pick #12 up and drop it again, it will be FormID 14, one higher than the last used (#13).


Ref variables and FormIDs of dynamic items[edit | edit source]

  • When a dynamic item is removed from the world (moved to a container, deleted etc), any ref variable containing its FormID becomes invalid. OBSE's IsFormValid returns 0 in this case.
  • When a dynamic item is moved to a container, a Ref Variable containing its FormID is not invalidated immediately. It remains intact for the rest of the frame. It turns to Null in subsequent frames.
  • Functions using the null Ref Variable either are ignored or produce undesirable results. Didn’t experience any CDT with the few functions tested.
  • GetSelf returns 0 if applied to a Dynamic reference, even thou the reference does have a FormID.


Notes on behaviors common to both[edit | edit source]

Script variables[edit | edit source]

Script variables were reset in the following situations:
  • Dynamic item dropped into the world by script (Drop or DropMe)
Script variables were not reset in the following situations:
  • Dynamic item dropped into the world by the player (shift-click item in inventory)
  • Non-dynamic item dropped into the world (either by script or by the player)
  • RemoveAllItems [to container]


Script blocks[edit | edit source]

OnDrop block[edit | edit source]

This block did run in the following situations:
  • Player drops the item in game (runs OnLoad block also)
  • Player opens a container and selects the item
  • RemoveAllItems [to container in same cell] (runs immediately)
  • RemoveAllItems [to container in hidden cell] (runs after 5-60 seconds or when destination container activated)
This block did not run when items were dropped/removed by the following script functions:
  • Drop xItemObj 1 – in the NPC script (runs OnLoad block instead)
  • MyNPC.drop MyItemObj 1 - in an activator script (runs OnLoad block instead)
  • Player.drop MyItemObj 1 - in an activator script (runs OnLoad block instead)
  • DropMe – in the Item Script (runs OnLoad block instead)
  • RemoveMe [to container in same cell]
  • RemoveMe [to container in hidden cell]
  • RemoveItem MyItemObj 1 (makes sense, as item is destroyed)
  • RemoveAllItems (makes sense, as item is destroyed)


OnAdd block[edit | edit source]

When picking up items from the world, when the OnActivate block runs, the OnAdd block does not run.
This block did run in the following situations:
  • Player picks up an item in game and the item does not have an OnActivate block
  • Player opens a container and selects the item
  • Using MyItem.Activate MyNPC01 0 - the OnActivate block does not run (flag=0), the OnAdd block runs
  • Added to containers by AddItem
  • Added to containers by RemoveAllItems [to container]
  • Added to containers by RemoveMe [to container]
This block did not run in the following situations:
  • the player picks up an item in game and the item has an OnActivate block
  • Using MyItem.Activate xNPC01 1 - the OnActivate block runs (flag=1), the OnAdd block does not run. If the script does not have an OnActivate block or the OnActivate block does not have an Activate function, the game freezes.


TODO

  • More tests with functions using the null Ref Variable
  • Cell reset
  • Non-Dynamic items in invalidated containers/cells
  • A new page for Persistent x Non-persistent references ??