{"record":{"id":"4d765601b4772fd1","repo":"egametang/ET","slug":"could-not-allocate-a-tile","errorCode":null,"errorMessage":"Could not allocate a tile","messagePattern":"Could not allocate a tile","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.recast/Scripts/Core/Share/Detour/DtNavMesh.cs","lineNumber":476,"sourceCode":"        public long AddTile(DtMeshData data, int flags, long lastRef)\n        {\n            // Make sure the data is in right format.\n            DtMeshHeader header = data.header;\n\n            // Make sure the location is free.\n            if (GetTileAt(header.x, header.y, header.layer) != null)\n            {\n                throw new Exception(\"Tile already exists\");\n            }\n\n            // Allocate a tile.\n            DtMeshTile tile = null;\n            if (lastRef == 0)\n            {\n                // Make sure we could allocate a tile.\n                if (0 == availableTiles.Count)\n                {\n                    throw new Exception(\"Could not allocate a tile\");\n                }\n\n                tile = availableTiles.First?.Value;\n                availableTiles.RemoveFirst();\n                m_tileCount++;\n            }\n            else\n            {\n                // Try to relocate the tile to specific index with same salt.\n                int tileIndex = DecodePolyIdTile(lastRef);\n                if (tileIndex >= m_maxTiles)\n                {\n                    throw new Exception(\"Tile index too high\");\n                }\n\n                // Try to find the specific tile id from the free list.\n                DtMeshTile target = m_tiles[tileIndex];\n                // Remove from freelist","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.recast/Scripts/Core/Share/Detour/DtNavMesh.cs#L458-L494","documentation":"DtNavMesh.AddTile with lastRef == 0 allocates a fresh tile from the free-list (availableTiles). When the list is empty, all m_maxTiles slots are in use and no tile can be assigned; the add fails. This is a capacity limit on the DtNavMesh, set at construction via the mesh params maxTiles.","triggerScenarios":"Calling AddTile(data, flags, 0) more than maxTiles times without matching RemoveTile; loading a navmesh whose tile count exceeds the mesh's configured maxTiles.","commonSituations":"maxTiles sized too small for the world; tiles added but never removed on unload; streaming that exceeds the pre-allocated slot count at peak.","solutions":["Increase the DtNavMesh maxTiles (passed at DtNavMesh construction) above peak live tile count.","Ensure RemoveTile is called on unload so slots return to the free-list.","Track live tile count and shed/defer loads when near capacity."],"exampleFix":"// before: mesh built with too few tiles\nvar mesh = new DtNavMesh(new DtNavMeshParams { ... maxTiles = 512 });\nforeach (var d in allData) mesh.AddTile(d, 0, 0); // overflows\n\n// after: size to peak, and remove before re-adding\nvar mesh = new DtNavMesh(new DtNavMeshParams { ... maxTiles = 4096 });","handlingStrategy":"validation","validationCode":"if (mesh.GetTileCount() >= meshMaxTiles)\n    throw new InvalidOperationException(\n        $\"DtNavMesh at capacity ({mesh.GetTileCount()}/{meshMaxTiles}); remove a tile or raise maxTiles.\");\nmesh.AddTile(data, flags, 0);","typeGuard":null,"tryCatchPattern":"try { return mesh.AddTile(data, flags, 0); }\ncatch (Exception e) when (e.Message == \"Could not allocate a tile\")\n{ /* evict a tile, then retry once, or report capacity */ }","preventionTips":["Size DtNavMesh maxTiles above peak live tile count.","Always pair AddTile with RemoveTile.","Track live count and defer loads when near capacity."],"tags":["capacity","detour-navmesh","runtime"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}