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.
Five control layers, only one of them shapes land
Yes, this is Unity’s built-in Terrain type
Height range is 105 m. One generated TerrainData asset drives the ground.
About 1.76 m per sample. The comment argues for 513, but the live constant is still 257.
Meadow, rock, dry grass, and a registered-but-zeroed snow layer.
Three detail prototypes placed with density maps and slope/moisture rules.
Six terrain tree prototypes, also duplicated as GameObjects because manual batch capture does not render Terrain instances.
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.
The proposed fundamentals versus current reality
| Fundamental | Unity control | Current implementation | Status | Actual next move |
|---|---|---|---|---|
| Demote blobs to intent | Write any normalized height array through SetHeights. | Basin and channel intent still use analytic fields, but shoulders, ridges, rock texture, and fractures are non-Gaussian. | Partial | Keep 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. | Partial | Introduce material-dependent repose: soil ≈26°, coarse talus ≈33–34°. |
| Add anisotropy | Height 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. | Present | Drive anisotropy from structural direction and drainage, not only decorative fracture noise. |
| Six-octave domain-warped fBm | Fully possible before SetHeights. | FractalNoise is ordinary Perlin fBm, usually 2–4 octaves, frequency ×2.03. No domain warp. | Missing | Add low-frequency vector warp, then a six-octave residual with steep amplitude falloff. |
| Hydraulic erosion, 150–400k droplets | CPU C# array pass, Burst/Jobs later if needed. | Already active: 150,000 droplets, 34-step lifetime, sediment capacity, erosion/deposition, evaporation, radius-2 brush. | Present | Do not “port” it. Parameterize it and preserve its drainage during later smoothing. |
| Thermal erosion / talus | Neighbor relaxation over the height array. | Already active immediately after hydraulic erosion: 34° repose, two iterations, four-neighbor transfer. | Present | Split soil and rock behavior; expose iteration count and repose angles. |
| Curvature-driven rock | Compute 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. | Missing | Retain convex + steep faces as rock; suppress rock in concave depositional hollows. |
| Flow-accumulation moisture | Compute 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. | Missing | Replace the proxy with drainage area, wetness index, and sediment deposition. |
| Ecology follows land history | Use 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. | Partial | Make one terrain-analysis product authoritative across all placement systems. |
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.
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.
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.
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.
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.
