-
Notifications
You must be signed in to change notification settings - Fork 23
Papyrus API
JC API is declared by the following:
- Instanceable containers, an objects of:
JArray
,JMap
,JFormMap
,JIntMap
.Instanceable
means 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
,JFormMap
andJIntMap
are inheriting theJValue
functionality. - Global containers -
JDB
andJFormDB
. 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
JDB
using the followingJDB
functions:setObj
or thesolve*Setter
functions - Read the data back using
solve*Getter
functions
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
JDB
andJFormDB
root 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
endproperty
Provides 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
.
-
valueKey
is a key used to retrieve a value or create{valueKey, value}
association for a form. -
formStorageName
is aJFormMap
containing{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())