egametang/ET · warning · Exception
rcBuildContours: Multiple outlines for region {cont.reg}.
Error message
rcBuildContours: Multiple outlines for region {cont.reg}. What it means
Thrown in rcBuildContours during region hole-merging when a region (cont.reg) already has an outline contour and a second positive-winding (outline) contour is encountered for the same region. Each region should have exactly one outline; a second indicates the region topology is inconsistent (region IDs were not partitioned cleanly).
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastContour.cs:903
{
// Collect outline contour and holes contours per region.
// We assume that there is one outline and multiple holes.
int nregions = chf.maxRegions + 1;
RcContourRegion[] regions = new RcContourRegion[nregions];
for (int i = 0; i < nregions; i++)
{
regions[i] = new RcContourRegion();
}
for (int i = 0; i < cset.conts.Count; ++i)
{
RcContour cont = cset.conts[i];
// Positively would contours are outlines, negative holes.
if (winding[i] > 0)
{
if (regions[cont.reg].outline != null)
{
throw new Exception(
"rcBuildContours: Multiple outlines for region " + cont.reg + ".");
}
regions[cont.reg].outline = cont;
}
else
{
regions[cont.reg].nholes++;
}
}
for (int i = 0; i < nregions; i++)
{
if (regions[i].nholes > 0)
{
regions[i].holes = new RcContourHole[regions[i].nholes];
for (int nh = 0; nh < regions[i].nholes; nh++)
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Raise minRegionArea to discard tiny regions that fragment into multiple outlines.
- Reduce contour maxSimplificationError (less aggressive simplification) to avoid splitting outlines.
- Adjust region partitioning method (e.g., switch watershed -> monotone) for cleaner IDs.
- Increase maxEdgeLength so contour edges merge rather than fragmenting.
Example fix
// before cfg.minRegionArea = 2; cfg.maxSimplificationError = 2.0f; // after cfg.minRegionArea = 64; cfg.maxSimplificationError = 1.1f;
Defensive patterns
Strategy: validation
Validate before calling
if (cfg.minRegionArea < 16) Debug.LogWarning("Tiny minRegionArea can fragment regions -> multiple outlines");
if (cfg.maxSimplificationError > 1.5f) Debug.LogWarning("High simplification error may split outlines"); Try / catch
try { var cset = RecastContour.BuildContours(ctx, chf, maxError, maxEdge, buildFlags); }
catch (Exception e) when (e.Message.Contains("Multiple outlines"))
{ /* raise minRegionArea, lower maxSimplificationError, retry */ } Prevention
- Raise minRegionArea to drop tiny fragmented regions.
- Lower maxSimplificationError to avoid outline fragmentation.
- Tune maxEdgeLength and region partitioning method.
- Validate region count after partitioning.
When it happens
Trigger: Region partitioning (watershed/monotone/layer) producing fragmented regions that share an ID; aggressive contour simplification splitting one region into multiple outlines; thin region slivers.
Common situations: Very low minRegionArea allowing tiny regions; contour maxSimplificationError / maxEdgeLength interacting badly with complex geometry; watershed noise on nearly-planar scenes.
Related errors
- rcBuildContours: Bad outline for region {i}, contour simplif
- 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/ebc9cc6bb779028d.
Report an issue: GitHub.