egametang/ET · warning · Exception
removeVertex: Too many polygons {mesh.npolys} (max:{maxTris}
Error message
removeVertex: Too many polygons {mesh.npolys} (max:{maxTris}. What it means
Thrown inside removeVertex (RecastMesh) when the number of generated polygons (mesh.npolys) exceeds maxTris during vertex removal and re-triangulation. Removing a shared vertex can fan out into many triangles; if the surrounding geometry is dense, the re-triangulation overflows the allocated polygon buffer.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMesh.cs:958
}
}
}
// Store polygons.
for (int i = 0; i < npolys; ++i)
{
if (mesh.npolys >= maxTris)
break;
int p = mesh.npolys * nvp * 2;
Array.Fill(mesh.polys, RC_MESH_NULL_IDX, p, (p + nvp * 2) - (p));
for (int j = 0; j < nvp; ++j)
mesh.polys[p + j] = polys[i * nvp + j];
mesh.regs[mesh.npolys] = pregs[i];
mesh.areas[mesh.npolys] = pareas[i];
mesh.npolys++;
if (mesh.npolys > maxTris)
{
throw new Exception("removeVertex: Too many polygons " + mesh.npolys + " (max:" + maxTris + ".");
}
}
}
/// @par
///
/// @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper
/// limit must be restricted to <= #DT_VERTS_PER_POLYGON.
///
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
public static RcPolyMesh BuildPolyMesh(RcTelemetry ctx, RcContourSet cset, int nvp)
{
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_POLYMESH);
RcPolyMesh mesh = new RcPolyMesh();
mesh.bmin = cset.bmin;
mesh.bmax = cset.bmax;
mesh.cs = cset.cs;View on GitHub (pinned to 5cab01f7a8)
Solutions
- Increase the maxTris / detail polygon budget passed to the mesh builder.
- Reduce tile size so each tile's polygon count stays under the limit.
- Simplify source geometry or increase contour simplification to lower polygon density.
- Avoid manually removing highly-shared vertices; let the builder choose removables.
Example fix
// before int maxTris = nvp * 4; // too small for dense tile // after int maxTris = Math.Max(nvp * 4, expectedPolyCount * 2); // and/or reduce cfg.tileSize
Defensive patterns
Strategy: validation
Validate before calling
int maxTris = Math.Max(nvp * 4, expectedPolyCount * 2);
if (maxTris < mesh.npolys + safetyMargin) throw new InvalidOperationException("maxTris too small for vertex removal"); Try / catch
try { RecastMesh.RemoveVertex(...); }
catch (Exception e) when (e.Message.Contains("Too many polygons"))
{ /* increase maxTris budget or reduce tile size, retry */ } Prevention
- Allocate a generous maxTris/detail polygon budget relative to expected density.
- Reduce tile size to cap per-tile polygon count.
- Increase contour simplification to lower polygon density.
- Avoid removing highly-shared vertices; let the builder choose.
When it happens
Trigger: Removing a vertex shared by many polygons in dense mesh detail; maxTris (derived from the detail/triangle budget) too small for the fan-out; large complex contours feeding BuildPolyMesh.
Common situations: High-detail input meshes producing dense polymes; tile size too large concentrating polygons; nvp config causing many-triangle fans.
Related errors
- rcBuildHeightfieldLayers: Region ID overflow.
- invalid capacity: {capacity}
- rcBuildCompactHeightfield: Heightfield has too many layers {
- rcBuildContours: Multiple outlines for region {cont.reg}.
- rcBuildContours: Bad outline for region {i}, contour simplif
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/17c900a201ac8156.
Report an issue: GitHub.