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

  1. Apply the same fixes as error 300: tile the world and/or increase cellSize to keep nverts well under 65535.
  2. 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.
  3. 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

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


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/3c023f333f98cd9e. Report an issue: GitHub.