egametang/ET · critical · Exception
rcBuildPolyMesh: Too many vertices {maxVertices}
Error message
rcBuildPolyMesh: Too many vertices {maxVertices} What it means
rcBuildPolyMesh sums the vertex count across every contour in the input contour set before allocating the polymesh. Because internal indices pack into 16 bits, a combined vertex total of 0xfffe (65534) or more is rejected up front. The throw is a hard capacity guard at allocation time, before any polygon work begins.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMesh.cs:996
mesh.borderSize = cset.borderSize;
mesh.maxEdgeError = cset.maxError;
int maxVertices = 0;
int maxTris = 0;
int maxVertsPerCont = 0;
for (int i = 0; i < cset.conts.Count; ++i)
{
// Skip null contours.
if (cset.conts[i].nverts < 3)
continue;
maxVertices += cset.conts[i].nverts;
maxTris += cset.conts[i].nverts - 2;
maxVertsPerCont = Math.Max(maxVertsPerCont, cset.conts[i].nverts);
}
if (maxVertices >= 0xfffe)
{
throw new Exception("rcBuildPolyMesh: Too many vertices " + maxVertices);
}
int[] vflags = new int[maxVertices];
mesh.verts = new int[maxVertices * 3];
mesh.polys = new int[maxTris * nvp * 2];
Array.Fill(mesh.polys, RC_MESH_NULL_IDX);
mesh.regs = new int[maxTris];
mesh.areas = new int[maxTris];
mesh.nverts = 0;
mesh.npolys = 0;
mesh.nvp = nvp;
mesh.maxpolys = maxTris;
int[] nextVert = new int[maxVertices];
int[] firstVert = new int[VERTEX_BUCKET_COUNT];View on GitHub (pinned to 5cab01f7a8)
Solutions
- Reduce tile size so each tile's contour set has far fewer than 65534 vertices.
- Increase rcConfig.cellSize so each voxel covers more world area, shrinking contour vertex counts.
- Verify you passed a properly partitioned CompactHeightfield (use RC_PARTITION_WATERSHED or RC_PARTITION_MONOTONE) so large regions are split.
- If a deliberately large mesh is required, split the world into multiple Detour tiles and build a DtNavMesh from the tile set instead of one monolithic polymesh.
Example fix
// before: one giant tile
rcConfig cfg = new() { cellSize = 0.1f, tileSize = 0 };
// after: tile the world and cap per-tile vertex counts
rcConfig cfg = new() { cellSize = 0.2f, tileSize = 64 };
// build each tile separately, then assemble into DtNavMesh Defensive patterns
Strategy: validation
Validate before calling
// Before calling rcBuildPolyMesh, sum contour vertices and reject early
int totalVerts = 0;
for (int i = 0; i < cset.conts.Count; i++)
if (cset.conts[i].nverts >= 3)
totalVerts += cset.conts[i].nverts;
if (totalVerts >= 0xfffe)
throw new InvalidOperationException($"rcBuildPolyMesh input too large: {totalVerts} verts. Tile the world or raise cellSize."); Prevention
- Always set rcConfig.tileSize for large worlds so no single build approaches 65534 vertices.
- Log total contour vertex counts during bake to catch runaway geometry early.
- Profile cellSize against your largest level before shipping.
When it happens
Trigger: Calling rcBuildPolyMesh(ctx, cset, nvp) where the sum of cset.conts[*].nverts over all non-null contours (nverts >= 3) reaches or exceeds 65534. This is driven purely by the input ContourSet density.
Common situations: Baking a single oversized navmesh tile from a very large or geometrically complex level; cellSize too small producing huge contour counts; merging many disjoint walkable regions into one tile; feeding un-partitioned geometry (no region/watershed partitioning) so contours stay enormous.
Related errors
- rcBuildPolyMesh: The resulting mesh has too many vertices {m
- rcBuildPolyMesh: Too many polygons {mesh.npolys} (max:{maxTr
- rcBuildPolyMesh: The resulting mesh has too many polygons {m
- addEdge: Too many edges ({edges.Count / 4}/{maxEdges}).
- rcBuildPolyMeshDetail: Shrinking triangle count from {ntris}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/c3e9a514df8614bd.
Report an issue: GitHub.