Builtin Library
README.md
Scatter (node)
A scattering node: its init.luau holds the graph that does the work, so the declared inputs are this node's inputs
and the declared output is this node's output. The node is its pipeline, in one self-contained asset.
It makes points on the surface (points.on_surface, area-weighted), gives every point its own random yaw, lean and
scale (instances.randomize_transform), and places the source on those points (instances.on_points). The
transform is read from the same point cloud the instances sit on, so each copy takes the pose of its own point.
A node is findable by what it does: the procgen toolbox's searchNodes with the query scatter lists it as
Scatter. Editing this node's init.luau cooks again every graph that calls it.
Inputs
surface(Geometry): what the copies land on.source(Geometry): the shape being copied.count(Int, default 200): how many.seed(Int, default 1): changes the arrangement.scaleMin/scaleMax(Float, defaults 0.8 and 1.4): per-copy size range.tilt(Float, default 8.6, 0 to 90): degrees of random lean.
Output
instances: a population, the points each carrying the source as itsMesh, withorientandscale.
Calling it
The node's graph is built with proc.graph("Scatter"), so a graph built the same way calls it by that name or by its
asset, with inputs the wired node ids and params the rest:
local proc = require("@builtin::systems.procgen.proc")
local g = proc.graph("rockyField")
g:node("ground", "mesh.grid")
g:node("rock", "mesh.box")
g:output("instances", g:node("rocks", "Scatter", { surface = "ground", source = "rock" }, { count = 20 }))
local rocks = proc.eval(g, "output:instances")
asset.resolve("@builtin::systems.procgen.examples.ops.Scatter", "procNode") in place of "Scatter" names the same
node.
Authoring a node
A node is a graph returned from a .procNode's init.luau (proc.define). asset.create("procNode", name)
scaffolds that shape, and procNode.assetType/README.md describes what a node states and how graphs call it.