ForgeFX Simulations
Mentor analysis · worker-facing · 28 July 2026

The CLI Is a Door, Not a Terrain Tool

Cross-reference of the near-field terrain prescription against the controls actually available in Forge Valley’s Unity 6 scene, its built-in Terrain component, the current batch-mode builder, Unity-MCP, and Unity’s new experimental official CLI.

Verdict: the engine can do nearly all of the prescribed work. The limiting factor is not Unity Terrain. It is that our useful terrain variables are buried as private constants inside one 4,875-line build method, while the command line exposes only “build everything.” Worse, the current source already contains hydraulic and thermal erosion, so “port the unused machinery” is now stale advice.
01 · What we actually have

Five control layers, only one of them shapes land

Unity Terrain
Heightfield, splats, details, trees, sampling
C# TerrainData API
Full procedural control of arrays and placement
Current builder
Power spectrum, erosion, splats, ecology — hard-coded
Unity-MCP CLI
Scene/object/script bridge; no terrain-specific tool
Official Unity CLI
Not installed here; pipeline package absent
Core distinction. Unity Terrain supplies the data structures. C# supplies the sculpting. The CLI merely invokes C# or talks to a running Editor. Installing a newer CLI does not create erosion, curvature, flow accumulation, or domain warping by itself.
02 · Scene receipt

Yes, this is Unity’s built-in Terrain type

Terrain footprint
450 × 450 m

Height range is 105 m. One generated TerrainData asset drives the ground.

Height samples
257²

About 1.76 m per sample. The comment argues for 513, but the live constant is still 257.

Surface paint
512² × 4

Meadow, rock, dry grass, and a registered-but-zeroed snow layer.

Ground cover
512² × 3

Three detail prototypes placed with density maps and slope/moisture rules.

Forest
2,976

Six terrain tree prototypes, also duplicated as GameObjects because manual batch capture does not render Terrain instances.

Renderer
HDRP

The manifest carries URP and HDRP; the builder requests HDRP/TerrainLit.

Direct receipts: TerrainData.heightmapResolution, alphamapResolution, size, SetHeights, SetAlphamaps, SetDetailLayer, treePrototypes, and SetTreeInstances are all used in the current builder.

03 · Prescription cross-check

The proposed fundamentals versus current reality

FundamentalUnity controlCurrent implementationStatusActual next move
Demote blobs to intentWrite any normalized height array through SetHeights.Basin and channel intent still use analytic fields, but shoulders, ridges, rock texture, and fractures are non-Gaussian.PartialKeep broad authored intent; remove any Gaussian that survives as a visible pedestal.
Clamp soil slopes near 25–26°Read local slope with GetSteepness; relax height samples before upload.Thermal erosion uses one 34° angle of repose for all material, two passes.PartialIntroduce material-dependent repose: soil ≈26°, coarse talus ≈33–34°.
Add anisotropyHeight synthesis is arbitrary C#; directional kernels and warped coordinates are available.Two directional Perlin fracture fields already run at 4.1×1.4 and 1.6×4.6.PresentDrive anisotropy from structural direction and drainage, not only decorative fracture noise.
Six-octave domain-warped fBmFully possible before SetHeights.FractalNoise is ordinary Perlin fBm, usually 2–4 octaves, frequency ×2.03. No domain warp.MissingAdd low-frequency vector warp, then a six-octave residual with steep amplitude falloff.
Hydraulic erosion, 150–400k dropletsCPU C# array pass, Burst/Jobs later if needed.Already active: 150,000 droplets, 34-step lifetime, sediment capacity, erosion/deposition, evaporation, radius-2 brush.PresentDo not “port” it. Parameterize it and preserve its drainage during later smoothing.
Thermal erosion / talusNeighbor relaxation over the height array.Already active immediately after hydraulic erosion: 34° repose, two iterations, four-neighbor transfer.PresentSplit soil and rock behavior; expose iteration count and repose angles.
Curvature-driven rockCompute Laplacian/profile curvature from the height array; write splat weights.Rock uses slope, elevation, patch noise, and normalized erosion loss. Curvature is used only to suppress spikes.MissingRetain convex + steep faces as rock; suppress rock in concave depositional hollows.
Flow-accumulation moistureCompute D8/D∞ flow over the heightfield; feed alphamaps and detail maps.“Moisture” is an authored sine-creek distance plus low elevation. It is not flow accumulation.MissingReplace the proxy with drainage area, wetness index, and sediment deposition.
Ecology follows land historyUse the same derived maps for splats, details, trees, rocks, and water routing.Trees respond to slope/elevation and stand noise; details respond to slope/elevation and coarse moisture. Systems share a hand-authored creek curve, not a hydrology field.PartialMake one terrain-analysis product authoritative across all placement systems.
04 · The wavelength problem

The current grid cannot honestly carry the whole near field

What 257 means

Across 450 m, adjacent samples are 1.758 m apart. Nyquist says features below about 3.5 m cannot be represented at all; visually stable features need more than two samples, so the practical geometric floor is closer to 5–7 m. That leaves most of the 0.5–5 m band to normal maps, detail meshes, decals, rocks, litter, and vegetation — not the terrain heightfield.

What 513 would mean

At 513² the spacing becomes 0.879 m. Geometry can then begin to carry roughly 2–4 m gullies, banks, scarps, and talus breaks. It still cannot model overhangs or sub-meter debris. Those remain mesh territory. The source comment already makes this case, but the constant does not implement it.

Highest-value contradiction: the code comment says “513 halves that to 0.88 m,” while HeightResolution = 257. The diagnosis asks for structure in the exact band the chosen resolution suppresses. Fixing the basis without fixing the sampling rate will produce a mathematically richer blur.
05 · What the command lines expose

Three CLI paths, three very different jobs

A. Current production path: Unity Editor batch mode

Unity -batchmode -quit -projectPath unity -executeMethod NatureLandscapeBuilder.BuildFromCli

This is the path that actually builds Forge Valley. It can reach the entire Unity C# API because it executes our code. But its public control surface has one verb and zero terrain parameters. Every experiment requires editing private constants, recompiling, rebuilding the entire scene, capturing, validating, and measuring.

B. Installed path: Unity-MCP CLI 0.86.1

The project includes AI Game Developer / Unity-MCP. Enabled tools cover asset lookup and modification, materials, prefabs, GameObject/component operations, scenes, isolated screenshots, arbitrary script execution, tests, and tool listing. There is no first-class “terrain sculpt,” “heightmap,” “erosion,” “splat,” or “flow map” command.

Important: component modification can change scalar Terrain settings. Bulk terrain arrays still belong in purpose-built C# called through script execution or a custom command.

C. New path: official experimental Unity CLI

Unity’s new CLI manages Editors, modules, projects, authentication, and opening projects. Editor control requires the separate com.unity.pipeline package, which exposes a local HTTP API and custom commands.

On this machine the unity binary is not installed and com.unity.pipeline is absent from the project manifest. So it currently exposes no controls to Forge Valley. Installing it would improve orchestration and discoverability, not terrain math.

06 · The right intersection

Turn terrain fundamentals into explicit engine commands

Separate intent, process, and appearance

Create three deterministic products: base intent height, eroded height, and derived terrain maps. Save each as an artifact so a judge can tell whether a failure came from sculpting, erosion, or material/ecology mapping.

Make a typed terrain recipe

Move the load-bearing constants out of the monolith into a serializable recipe: resolution, world scale, warp strength, octave spectrum, soil and rock repose, droplet count, lifetime, erosion/deposition rates, smoothing thresholds, and seed. Keep safe ranges and reject recipes that violate them.

Expose narrow commands, not arbitrary sliders

Publish commands such as terrain.generate, terrain.erode, terrain.analyze, terrain.paint, terrain.scatter, and terrain.capture. Each command should read/write named artifacts and print a machine-readable receipt.

Use Unity Terrain where it is strong

Keep the heightfield for continuous land, built-in terrain layers for broad surface response, detail prototypes for grass, and tree instances for player builds. Use authored/scanned mesh cliffs, boulders, deadwood, creek banks, and near-field debris where a heightfield or top-down splat cannot represent the form.

Make one hydrology analysis authoritative

Compute slope, curvature, flow direction, flow accumulation, wetness, and sediment balance once. Feed those same maps to material splats, grass, shrubs, tree vigor, rock exposure, and creek routing. This is the control intersection that gives the land history rather than merely adding noise.

07 · Pass-barred exercises

Five exercises that prove control, not motion

1. Resolution substitution

Render identical 257 and 513 recipes with no other changes.

Pass: at least one 2–5 m drainage or talus feature survives in all three judged orbits at 513 and is absent or aliased at 257.

2. Warp substitution

Compare ordinary fBm with domain-warped fBm, holding spectrum and seed fixed.

Pass: reduced silhouettes stay stable while mid-scale contour direction becomes visibly non-isotropic; no new pillow field appears.

3. Dual-repose slope audit

Run 34° uniform repose against 26° soil + 33° talus.

Pass: soil slopes cluster below 26–28°, rock faces remain steeper, and depositional aprons appear without flattening ridge relief.

4. Hydrology truth test

Replace sine-distance moisture with computed flow accumulation and wetness.

Pass: every wet patch connects upslope to contributing area; no moist island sits on a convex shoulder; water never climbs.

5. Coupled-map ablation

Toggle slope-only splats versus slope + curvature + flow + sediment.

Pass: rock concentrates on steep convex erosion zones, grass on concave depositional zones, and the worst navigation view clears A6 60.

Registered prediction

If 513 sampling, warped spectrum, dual-repose erosion, and shared hydrology-derived maps are all active and the weakest view still fails A6 60, the “missing land history” diagnosis is wrong. Stop adding procedural complexity and move the investigation to material scale, lighting, or camera evidence.

08 · Decision

Do not install a CLI and call that progress

The production unlock is a parameterized terrain pipeline with inspectable intermediate maps. The official Unity CLI plus Pipeline package is worth adding after those commands exist because it gives us a standard transport, discovery, JSON output, and CI integration. Before that, it only wraps the same monolith in newer syntax.

Recommended order: raise the heightfield to 513 → add domain warp → split thermal repose by material → compute curvature and flow accumulation → make those maps authoritative for splats and ecology → expose each stage as a typed command → then bind the command set to Unity Pipeline and Unity-MCP.