Builtin Library
README.md
io.luau (procNode)
Run a function of a Luau module on the CPU and answer what it returns. The module is required, the function read by name, and the function called with the arguments; the result is cached by the module's checksum, the function name and the arguments, so a module edit re-cooks it.
Built from op.cpu.call of require on the module, a member read of the function by name, and op.cpu.call of that function (op.cpu.read when live names a digest). Both calls run on the CPU, so a graph holding this node shows a CPU call wherever it sits.
local label = g.io.luau({ module = "@builtin::systems.procgen.nodes.instances.pack.pack", fn = "nameOf", args = { 3 }, returns = { "String" } }).value
What a function receives and returns
A number, text or vector reaches the function as itself. A Geometry reaches it as an object of its columns, read to the CPU first (as they stand on the device when device is on):
geometry:count(class)is how many elements the class holds.classis"point","vertex","edge","primitive"or"detail".geometry:column(class, name)is the column of that class and name, or nil where the Geometry holds none.geometry:column("point", "P")holds the positions.- A column answers
column:count()(its elements),column:type()("Vec3"),column:lanes()(the numbers one element holds, 3 for a Vec3) andcolumn:read(), every number of it in one flat list, element after element: a grid of six points reads 18 numbers from itsP.
A function answers by returning values, one for each type in returns. A Geometry is returned as one built from flat lists, proc.geometry.new({ positions = { ... }, indices = { ... } }), with normals and uvs optional, and is declared "Geometry" in returns: value is then that Geometry, its point P column holding the positions.
-- The module /source/shapes.module:
local proc = require("@builtin::systems.procgen.proc")
local M = {}
function M.heights(geometry)
local positions = geometry:column("point", "P"):read()
local low, high = math.huge, -math.huge
for i = 2, #positions, 3 do
low, high = math.min(low, positions[i]), math.max(high, positions[i])
end
return low, high
end
function M.triangle(size)
return proc.geometry.new({ positions = { 0, 0, 0, size, 0, 0, 0, size, 0 }, indices = { 0, 1, 2 } })
end
return M
local range = g.io.luau({ module = "/source/shapes.module", fn = "heights", args = { points }, returns = { "Float", "Float" } }).values
local triangle = g.io.luau({ module = "/source/shapes.module", fn = "triangle", args = { 2 }, returns = { "Geometry" } }).value
Inputs
module(AssetRef<module>, default ""). The module that holds the function: its identity, path, AssetRef or guid. It is recorded as a dependency of the graph.fn(String, default ""). The name of the module's function to call.args(List<Value>, optional). The values the function is called with, in order. A device column is passed as a reference to its buffer.returns(List<TypeName>, optional). The procgen types of the values the function returns, in order.ceilingMs(Float, default 0, at least 0). The CPU time the function may run for, in milliseconds, counting the work it runs in any coroutine it resumes and in any task it starts while the call lasts; a call past it is refused. The time it waits on a frame, a program build, a read-back or a task, and the time its thread waits for a core on a busy machine, are not counted. 0 leaves the runtime's default ceiling.device(Bool, default false). On, a Geometry inargsreaches the function as it stands on the device, its columns left where they are; off, its columns are read to the CPU first.live(String, default ""). The name of a function of the module that answers a digest of the statefnreads, called with the same arguments. A call that names one reads state outside the graph, such as entities in the scene: the graph's live digest folds the digest in, so a Generator cooks it again when that state changes. Left empty, the call reads nothing the graph does not hold.pure(Bool, default false). On, whatfnreturns is a function ofargsalone and the call changes nothing: a call whose arguments are known while the graph is planned is made then, once, and its results stand in the plan as constants.curves(Bool, default false). On, an animated value amongargsreachesfnas the curve it is, andfnanswers with what follows it: a curve, or a field reading it as a live value, so a later time is presented on the device without a cook. Off, it reachesfnas the value it holds at the cook's time.
Outputs
value: the first returned value.values: every returned value, in order.