egametang/ET · warning · Exception
rcBuildCompactHeightfield: Heightfield has too many layers {
Error message
rcBuildCompactHeightfield: Heightfield has too many layers {tooHighNeighbour} (max: {MAX_LAYERS}) What it means
Thrown at the end of rcBuildCompactHeightfield when a compact-cell neighbour span index (lidx) exceeded MAX_LAYERS during neighbour connectivity. MAX_LAYERS caps how many overlapping walkable spans can stack in a single XZ cell of the compact heightfield; exceeding it means the voxelization produced too many stacked walkable layers for the configuration.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastCompact.cs:159
int lidx = k - nc.index;
if (lidx < 0 || lidx > MAX_LAYERS)
{
tooHighNeighbour = Math.Max(tooHighNeighbour, lidx);
continue;
}
RecastCommon.SetCon(s, dir, lidx);
break;
}
}
}
}
}
}
if (tooHighNeighbour > MAX_LAYERS)
{
throw new Exception("rcBuildCompactHeightfield: Heightfield has too many layers " + tooHighNeighbour
+ " (max: " + MAX_LAYERS + ")");
}
return chf;
}
private static int GetHeightFieldSpanCount(RcHeightfield hf)
{
int w = hf.width;
int h = hf.height;
int spanCount = 0;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
for (RcSpan s = hf.spans[x + y * w]; s != null; s = s.next)
{
if (s.area != RC_NULL_AREA)View on GitHub (pinned to 5cab01f7a8)
Solutions
- Increase walkableHeight so closely-stacked spans merge into fewer layers.
- Decrease voxel cell size (cs) / cell height (ch) to better separate the layers spatially.
- Increase walkableClimb to merge small steps that spawn extra layers.
- Simplify the source geometry to remove redundant overlapping walkable surfaces.
Example fix
// before cfg.walkableHeight = 0.1f; // tiny -> many stacked spans cfg.cs = 0.3f; // after cfg.walkableHeight = 1.5f; // merge thin layers cfg.cs = 0.2f; // finer voxels separate real layers
Defensive patterns
Strategy: validation
Validate before calling
// Sanity-check config before building.
if (cfg.walkableHeight < cfg.ch * 2) Debug.LogWarning("walkableHeight very small -> many layers");
if (cfg.ch > cfg.walkableHeight) Debug.LogWarning("cell height > walkableHeight may stack layers"); Type guard
// No type guard (config-tuning). Treat as runtime config validation.
Try / catch
try { RcCompactHeightfield chf = RecastCompact.BuildCompactHeightfield(ctx, walkableHeight, walkableClimb, hf); }
catch (Exception e) when (e.Message.Contains("too many layers"))
{ /* raise walkableHeight / lower cs,ch and retry */ } Prevention
- Increase walkableHeight to merge closely-stacked spans.
- Decrease cell size/height for finer vertical separation.
- Increase walkableClimb to absorb small steps.
- Simplify geometry with many overlapping walkable surfaces.
When it happens
Trigger: A scene with many overlapping walkable surfaces in the same column (stairs, ramps, thin floors) combined with a small walkableHeight and/or large voxel cell size that stacks spans; geometry with near-coincident walkable planes.
Common situations: Cell height too large relative to floor spacing; walkableHeight too small so multiple thin ledges each qualify as walkable; dense multi-floor geometry.
Related errors
- rcBuildContours: Multiple outlines for region {cont.reg}.
- rcBuildContours: Bad outline for region {i}, contour simplif
- rcBuildHeightfieldLayers: Region ID overflow.
- removeVertex: Too many polygons {mesh.npolys} (max:{maxTris}
- ERR_LocationLockOwnerMismatch
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/b90bf3a82649d3eb.
Report an issue: GitHub.