Skip to content
ryobg edited this page Feb 15, 2018 · 3 revisions

Object persistence

Every container object persists in save file until the container gets destroyed. When a save is performed, all objects are saved and all objects are restored when the save file gets loaded.

JSON serialization

The feature allows store or load of containers content (and every containers they reference) into, or from, a JSON-formatted, UTF-8 encoded, without BOM, file.

Most of the Papyrus-JSON conversion is straightforward:

Papyrus JSON
JArray array, []
JMap object, {}
JFormMap object, {"__metaInfo": {"typeName": "JFormMap" } }
JIntMap object, {"__metaInfo": {"typeName": "JIntMap" } }
Form string, "__formData|PluginName.esp|formId" or "__formData||formId" in case of dynamic, 0xff* forms. formId is a hex number prefixed with 0x or a decimal number.
Integer number
Real number
String string
None null
Integer, if true then 1 otherwise 0 boolean, JSON -> Papyrus direction only
Link string, "__reference|.path.to[10].another.object"

JSON is a tree structure, but JC also allows graphs, either cyclic or no. JC does not create duplicates during serialization - if an object was already serialized, and can be met few times during serialization traversal, a link to already serialized object gets created. For example, an array which references itself will be encoded into:

["__reference|"]

Another example:

{
  "key1": [[]],
  "link-to-inner-array": "__reference|.key1[0]"
}

And in a result of this:

int playerData = JMap.object()
JMap.setForm(playerData, "actor", Game.GetPlayer())
JMap.setForm(playerData, "name", Game.GetPlayer().GetName())
JMap.setInt(playerData, "level", Game.GetPlayer().GetLevel())
JValue.writeToFile(playerData, JContainers.userDirectory() + "playerInfo.txt")

we'll got a file at MyGames/Skyrim/JCUser/playerInfo.txt containing the following lines:

{
    "actor": "__formData|Skyrim.esm|0x14",
    "name": "Elsa",
    "level": 2
}

And the corresponding deserialization example:

int data = JValue.readFromFile(JContainers.userDirectory() + "playerInfo.txt")
int level = JMap.getInt(data, "level")
form player = JMap.getForm(data, "actor")
string name = JMap.getStr(data, "name")