egametang/ET · warning · Exception
rcBuildContours: Bad outline for region {i}, contour simplif
Error message
rcBuildContours: Bad outline for region {i}, contour simplification is likely too aggressive. What it means
Thrown in rcBuildContours when a region has holes (nholes > 0) but its outline is null. With no enclosing outline, holes cannot be merged. The comment in source explains this happens when contour simplification settings are too aggressive, causing a region's outline to become self-overlapping and disappear.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastContour.cs:953
}
// Finally merge each regions holes into the outline.
for (int i = 0; i < nregions; i++)
{
RcContourRegion reg = regions[i];
if (reg.nholes == 0)
continue;
if (reg.outline != null)
{
MergeRegionHoles(ctx, reg);
}
else
{
// The region does not have an outline.
// This can happen if the contour becaomes selfoverlapping because of
// too aggressive simplification settings.
throw new Exception("rcBuildContours: Bad outline for region " + i
+ ", contour simplification is likely too aggressive.");
}
}
}
}
return cset;
}
}
}View on GitHub (pinned to 5cab01f7a8)
Solutions
- Lower maxSimplificationError to preserve outline fidelity.
- Reduce maxEdgeLength so outline edges are not over-merged.
- Raise minRegionArea to eliminate tiny hole-bearing regions.
- Switch region partitioning strategy if the geometry persistently produces bad outlines.
Example fix
// before cfg.maxSimplificationError = 2.5f; cfg.maxEdgeLength = 200; // after cfg.maxSimplificationError = 1.1f; cfg.maxEdgeLength = 20;
Defensive patterns
Strategy: validation
Validate before calling
if (cfg.maxSimplificationError > 2.0f) Debug.LogWarning("Aggressive simplification may erase outlines leaving holes");
if (cfg.maxEdgeLength > 100) Debug.LogWarning("Large maxEdgeLength may collapse outlines"); Try / catch
try { var cset = RecastContour.BuildContours(ctx, chf, maxError, maxEdge, buildFlags); }
catch (Exception e) when (e.Message.Contains("Bad outline"))
{ /* lower maxSimplificationError / maxEdgeLength, retry */ } Prevention
- Keep maxSimplificationError modest (< 1.5) for complex geometry.
- Limit maxEdgeLength to prevent outline collapse.
- Raise minRegionArea to remove hole-bearing micro-regions.
- Switch partitioning strategy if outlines persistently degrade.
When it happens
Trigger: High maxSimplificationError collapsing a region's outline while its holes survive; maxEdgeLength too large merging outline edges into degenerate paths; very small/thin regions.
Common situations: Tuning maxSimplificationError up for fewer vertices until outlines self-intersect; aggressive contour settings on intricate geometry.
Related errors
- rcBuildContours: Multiple outlines for region {cont.reg}.
- rcBuildHeightfieldLayers: Region ID overflow.
- rcBuildCompactHeightfield: Heightfield has too many layers {
- 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/537d6d3220e4b146.
Report an issue: GitHub.