-
Notifications
You must be signed in to change notification settings - Fork 25
Papyrus API
JC API is declared by the following:
- Instanceable containers, an objects of:
JArray,JMap,JFormMap,JIntMap.Instanceablemeans you can create multiple instances of arrays, maps and form-maps (i.e. the same way you can have multiple arrays and strings in Papyrus) -
JValue- in the OOP world, we say thatJArray,JMap,JFormMapandJIntMapare inheriting theJValuefunctionality. - Global containers -
JDBandJFormDB. Unlike instanceable containers, there is only one instance of them so you do not have to create them (a.k.a. singletons - OOP remember). - Utility, JC installation validation -
JContainers
To use any instanceable object, you must first create (instantiate) it with the object function or
retrieve it from somewhere:
int array = JArray.object()
int map = JMap.object()
int anotherArray = JDB.solveObj(".myArray")Any function that returns an object actually returns its identifier. An identifier is a unique number that ranges from -2^31 to +2^31. There is also the concept of zero identifier which points to a non-existing object. All containers are distinguished by their identifiers.
Once created, you may put data in the array or the map:
JArray.addStr(array, "it’s me")
JArray.addForm(array, GetTargetActor())
JMap.setInt(map, "health", GetTargetActor().getAV("health"))And read the data back:
string text = JArray.getStr(array, 0)
form actor = JArray.getForm(array, 1)
int health = JMap.getInt(map, "health")JArray is an ordered collection (array) of values. It is dynamically resizeable, and can store any
number of values of any combination of types.
All of them are associative containers (sets of keys and values where each key is associated
with one value). Each key must be unique within a given container. In a JMap, a key is a string,
in a JFormMap it is a form (a form is any actor, item, quest, spell - almost everything in Skyrim)
and in a JIntMap the key is, obviously, an integer value.
int map = JMap.object()
JMap.setForm(map, "me", GetTargetActor())
form actor = JMap.getForm(map, "me")JValue is an interface that shows what common functionality JArray, JMap and JFormMap share.
For example, each of them can be emptied, serialized and deserialized to/from JSON and more.
int array = JArray.object()
int map = JMap.object()
-- equivalent ways to do same things.
-- all count functions return zero as new containers are empty
JValue.count(array) == JArray.count(array) == JValue.count(map)
-- write container content into file:
JValue.writeToFile(map, "map.txt")
JValue.writeToFile(array, "array.txt")JDB is a global entry point - you put information or some value in it under a string key , and
then you can access the key and its value from any script in the game. There is only one JDB in
the game (ie its singleton), so each time you access it you access that one, single JDB. It is
also an associative container like JMap, but the script interface is slightly different.
Typical JDB usage would involve:
- Put data into
JDBusing the followingJDBfunctions:setObjor thesolve*Setterfunctions - Read the data back using
solve*Getterfunctions
Example of a JDB already filled by different users:
{
"vMYC": {
"characterCount": 11,
"some-array": []
},
"SWPR": [],
}Important
Choose your root key name carefully to avoid clashes with rest of
JDBandJFormDBroot keys used by other users (mod authors).
More examples:
JDB.solveIntSetter(".vMYC.characterCount", 11, true)
int count = JDB.solveInt(".vMYC.characterCount")int property potionsArray
int function get()
return JDB.solveObj(".SWPR.deadlyPotions")
endfunction
function set(int object)
JDB.solveObjSetter(".SWPR.deadlyPotions", object, true)
endfunction
endpropertyProvides a convenient way to associate values with a form. You may find it looking like a mix of
JMap and JDB - like JDB, there is only one JFormDB in the game, and like JMap it is
associative container. It also supports path resolving. To store or retrieve value a form and
string path must be passed:
-- store...
form me = GetTargetActor()
JFormDB.setFlt(me, ".yourModFormStorage.valueKey", 10)
JFormDB.setStr(me, ".yourModFormStorage.anotherValueKey", "name")
-- and retrieve values
float value = JFormDB.getFlt(me, ".yourModFormStorage.valueKey")A string path must consist of formStorageName and valueKey.
-
valueKeyis a key used to retrieve a value or create{valueKey, value}association for a form. -
formStorageNameis aJFormMapcontaining{formKey, {valueKey, value}}associations. It was added to avoid possible collisions: one mod may occasionally override value written by another mod if simple paths without storage name part were allowed. The fact that it is a separate storage makes it possible to access that storage, delete it without any risk to delete another mod data:
-- Will destroy everything "yourModFormStorage" contains
JDB.setObj("formStorageName", 0)How the set* functions work internally:
Once a value gets assigned via JFormDB.set*(formKey, ".formStorageName.valueKey", value),
JFormDB looks for formStorageName in JDB (creating it if not found) and then looks for
the JMap entry associated with that form key (creating it if not found) and then creates a
{valueKey, value} pair.
Slightly more advanced usage:
-- Will destroy everything associated with 'me' form in "yourModFormStorage" storage
JFormDB.setEntry("yourModFormStorage", me, 0)
-- Custom entry type
JFormDB.setEntry("yourModFormStorage", me, JArray.object())