Skip to content
Rosso Porko edited this page Oct 5, 2021 · 5 revisions

Overview

Since version 3.0 of JContainers there is embedded support for Lua 5.1. Benefits of using it:

  • Any standard Lua library functionality is available (bitwise operations, math, string manipulation, operating system facilities and etc)
  • seek, sort (in beta) JArray with user specified predicate
  • move some cumbersome Papyrus code into more compact Lua (see the frostfall.uuid () function example below)

Important

Lua feature status is highly experimental. Its API may change when more functionality is added.

You can invoke any Lua expression with one of the JValue.evalLuaFlt/Int/Str/Form/Obj functions:

float pi = JValue.evalLuaFlt(0, "return math.pi")
JValue.evalLuaInt(0, "return bit.bxor(8, 2, 10)") -- returns 8 xor 2 xor 10
obj = [
        {   "theSearchString": "a",
            "theSearchForm" : "__formData|A|0x14"
        },
        {   "theSearchString": "b",
            "theSearchForm" : "__formData|A|0x15"
        }
]

-- returns 1 - an array index where `arrayItem.theSearchString == 'b'`
JValue.evalLuaInt(obj, "return jc.find(jobject, function(x) return x.theSearchString == 'b' end")

You can write your own functionality in the Data/SKSE/Plugins/JCData/lua/FOLDER/init.lua where FOLDER can be some name. For example in the Data/SKSE/Plugins/JCData/lua/frostfall/init.lua file you can have the following code:

-- frostfall module depends on jc.count function from 'JCData/lua/jc/init.lua'
local jc = jrequire 'jc'

local frostfall = {}

function frostfall.countItemsLessAndGreaterThan(collection, less, greater)
    return jc.count(collection, function(x)
       return x < less and x > greater
    end)
end

-- generates random guid-string (may return 'd6cce35c-487a-458f-bab2-9032c2621f38' once per billion years)
function frostfall.uuid()
   local random = math.random
   local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
   return string.gsub(template, '[xy]', function (c)
       local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
       return string.format('%x', v)
   end)
end

return frostfall

And in your Papyrus code:

 JValue.evalLuaInt(obj, "return frostfall.countItemsLessAndGreaterThan(jobject, 60, -5)")
 string guid = JValue.evalLuaStr(0, "return frostfall.uuid()")

Collection operators

This feature allows you to apply a function of two arguments cumulatively to the items of collection, from left to right, so to reduce the collection to a single value. For example:

obj = [1,2,3,4,5,6]
-- will return 6
JValue.evalLuaFlt(obj, "return jc.accumulateValues(jobject, math.max)")
-- returns 21, summ
JValua.evalLuaFlt(obj, "return jc.accumulateValues(jobject, function(a,b) return a + b end)")

obj = [
  {"magnitude": -9},
  {"magnitude": 11},
  {"magnitude": 3}
]
-- returns 11 - the maximum value
JValue.evalLuaFlt(obj, "return jc.accumulateValues(jobject, math.max, '.magnitude')")

obj = {
  "a": 10,
  "c": "x"
}
-- concatenates keys - and returns "ac" sting
JValue.evalLuaString(obj, "return jc.accumulateKeys(jobject, function(a,b) return a .. b end)")