Geometry Nodes is Blender speaking Houdini's language with its own accent: geometry flows through nodes, data rides on the geometry, and the artist gets sliders instead of vertices. Learn the accent and you've learned half of proceduralism everywhere.
Destructive modeling edits the thing. Procedural modeling edits the recipe. A Geometry Nodes tree is a recipe: geometry enters, each node transforms it, geometry exits - and because the recipe is live, changing an early step (the input curve, the density value) re-cooks everything downstream instantly. The payoff is the same as in Houdini: when level design moves the canyon, you move a curve, not two hundred rocks.
The corollary that trips artists over: selection basically doesn't exist here. You can't grab "those three points." Instead you describe which points qualify - "points where the slope is under 30 deg" - and the description keeps working when the terrain changes. Procedural selection is a rule, not a click.
An attribute is data stored on geometry: every point carries a position, maybe a color, maybe a density float you invented. A field (the diamond sockets) is a question asked of every element at once: "what's your position?", "what's your index?", "what does the noise texture say at your location?" - evaluated per-point wherever you plug it in.
The relationship: fields compute, attributes remember. A field is a formula; capturing or storing it (Capture Attribute / Store Named Attribute) freezes the answer onto the geometry so a later node - or the exporter, or a shader - can read it back. If you know Houdini: fields ~= what a wrangle computes on the fly; stored attributes ~= @attrs. If you don't: a field is a spreadsheet formula, an attribute is paste-values.
The "hello world" of proceduralism, done properly. New Geometry Nodes modifier on your terrain, then:
Group Input (terrain) +- Distribute Points on Faces [Poisson Disk, Density Max, Seed] +- density <- Noise Texture -> Map Range (clumpy, not uniform) +- density <- Normal.Z < threshold ? 0 : 1 (nothing on cliffs) +- Instance on Points +- instance <- Collection Info [rocks collection, Separate Children + Pick Instance] +- rotation <- Align Euler to Vector (surface normal) + Random Euler Z +- scale <- Random Value (0.7-1.4) [same Seed input] +- Realize Instances? - NO (see export section) +- Group Output
Read the spine and notice: every art-direction lever is a field feeding density or a random value with a seed. Clumping is a noise texture; keep-off-the-cliffs is a question about the normal; variety is a collection of rocks picked per-instance. Nothing here is rock-specific - swap the collection and it scatters trees, debris, or mushrooms. That's the tell of a good procedural tool: the nouns are replaceable.
Select your scatter nodes -> Ctrl+G to make a group -> expose sockets in the N-panel. What you expose is a design decision, and the discipline is Houdini's HDA discipline exactly:
Mark the group as an asset (right-click -> Mark as Asset) and it appears in the Asset Browser for the whole team - congratulations, you've shipped a tool without writing a line of Python.
Geometry Nodes output is Blender-side magic; engines see whatever you bake. Three exits, in order of preference:
First big Geometry Nodes win I saw in production: a junior TA replaced a level team's hand-placed cable runs with a curve-driven cable tool - sag, clamps, seed. The tool took a week. The number that made leadership care: cable placement went from "two days per level, redone every layout change" to "drag the curve." Nobody upstairs understood fields. Everybody understood two days becoming zero.