egametang/ET · critical · Exception
rcBuildPolyMesh: The resulting mesh has too many vertices {m
Error message
rcBuildPolyMesh: The resulting mesh has too many vertices {mesh.nverts} (max {MAX_MESH_VERTS_POLY}). Data can be corrupted. What it means
After detail work and just before returning, rcBuildPolyMesh verifies the final vertex count does not exceed MAX_MESH_VERTS_POLY (0xffff = 65535). This is a post-condition integrity check: the mesh data may already be corrupted because 16-bit index fields overflowed, hence the 'Data can be corrupted' message.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMesh.cs:1200
if (mesh.verts[va + 0] == 0 && mesh.verts[vb + 0] == 0)
mesh.polys[p + nvp + j] = 0x8000 | 0;
else if (mesh.verts[va + 2] == h && mesh.verts[vb + 2] == h)
mesh.polys[p + nvp + j] = 0x8000 | 1;
else if (mesh.verts[va + 0] == w && mesh.verts[vb + 0] == w)
mesh.polys[p + nvp + j] = 0x8000 | 2;
else if (mesh.verts[va + 2] == 0 && mesh.verts[vb + 2] == 0)
mesh.polys[p + nvp + j] = 0x8000 | 3;
}
}
}
// Just allocate the mesh flags array. The user is resposible to fill it.
mesh.flags = new int[mesh.npolys];
if (mesh.nverts > MAX_MESH_VERTS_POLY)
{
throw new Exception("rcBuildPolyMesh: The resulting mesh has too many vertices " + mesh.nverts
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
}
if (mesh.npolys > MAX_MESH_VERTS_POLY)
{
throw new Exception("rcBuildPolyMesh: The resulting mesh has too many polygons " + mesh.npolys
+ " (max " + MAX_MESH_VERTS_POLY + "). Data can be corrupted.");
}
return mesh;
}
/// @see rcAllocPolyMesh, rcPolyMesh
public static RcPolyMesh MergePolyMeshes(RcTelemetry ctx, RcPolyMesh[] meshes, int nmeshes)
{
if (nmeshes == 0 || meshes == null)
return null;
View on GitHub (pinned to 5cab01f7a8)
Solutions
- Apply the same fixes as error 300: tile the world and/or increase cellSize to keep nverts well under 65535.
- Treat as a defect indicator if it persists — the post-condition should be unreachable when the entry guard works, so verify contour partitioning and tile size are correct.
- Capture telemetry (log cset total nverts at entry) to confirm which tile overflows and adjust its bounds.
Defensive patterns
Strategy: validation
Try / catch
// Treat as a build-time failure: don't ship a possibly-corrupt mesh
try { rcBuildPolyMesh(ctx, cset, nvp, out mesh); }
catch (Exception e) when (e.Message.Contains("Data can be corrupted")) {
Log.Error($"Navmesh build produced corrupt data: {e.Message}");
// do NOT use mesh; re-bake with coarser settings
} Prevention
- Treat 'Data can be corrupted' throws as defects, not recoverable states — never use the partial mesh.
- Keep total nverts well under 65535 via tiling.
- Add CI bake tests that fail when vertex counts exceed 80% of the limit.
When it happens
Trigger: Reached at RecastMesh.cs:1200 in the primary build path. Fires when, after edge-vertex removal and mesh finalization, nverts grew beyond 65535 — indicating internal vertex addition during simplification/removal exceeded the index field width.
Common situations: Same class as error 300/301 but manifesting later: oversized tiles, too-small cellSize, or geometry where vertex removal/reinsertion inflates the count. Typically indicates the upstream capacity guard (300) was bypassed by a code path that added vertices after the initial allocation.
Related errors
- rcBuildPolyMesh: Too many vertices {maxVertices}
- rcBuildPolyMesh: The resulting mesh has too many polygons {m
- rcBuildPolyMesh: Too many polygons {mesh.npolys} (max:{maxTr
- 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/3c023f333f98cd9e.
Report an issue: GitHub.