egametang/ET · error · Exception
Buffer too small
Error message
Buffer too small
What it means
During monotone region partitioning of a tile-cache layer (DtTileCacheBuilder.BuildTileCacheRegions/MarkRectArea region sweep), each distinct region needs a unique id. Region ids are stored in a byte, so the partition supports at most 254 active regions; when regId reaches 255 the builder aborts with 'Buffer too small'. It means the layer's walkable spans fragment into more monotone regions than the encoding can address.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Detour.TileCache/DtTileCacheBuilder.cs:137
}
// Create unique ID.
for (int i = 0; i < sweepId; ++i)
{
// If the neighbour is set and there is only one continuous
// connection to it,
// the sweep will be merged with the previous one, else new
// region is created.
if (sweeps[i].nei != 0xff && prevCount[sweeps[i].nei] == sweeps[i].ns)
{
sweeps[i].id = sweeps[i].nei;
}
else
{
if (regId == 255)
{
// Region ID's overflow.
throw new Exception("Buffer too small");
}
sweeps[i].id = regId++;
}
}
// Remap local sweep ids to region ids.
for (int x = 0; x < w; ++x)
{
int idx = x + y * w;
if (layer.regs[idx] != 0xff)
layer.regs[idx] = (short)sweeps[layer.regs[idx]].id;
}
}
// Allocate and init layer regions.
int nregs = regId;
DtLayerMonotoneRegion[] regs = new DtLayerMonotoneRegion[nregs];View on GitHub (pinned to 5cab01f7a8)
Solutions
- Reduce the tile dimensions (smaller cs/ch tileSize) so each layer holds fewer fragmented regions.
- Simplify collision geometry feeding the rasterizer to cut down on tiny walkable islands.
- Move/lower obstacle density so a single tile isn't carved into >254 regions.
Example fix
// before: large tile, dense obstacles
var cp = new DtTileCacheParams { width = 256, height = 256, ch = 0.2f, cs = 0.3f, ... };
// after: smaller tile per layer reduces region fragmentation
var cp = new DtTileCacheParams { width = 128, height = 128, ch = 0.2f, cs = 0.3f, ... }; Defensive patterns
Strategy: validation
Validate before calling
// Heuristic guard before building a tile-cache layer:
// keep per-tile walkable fragmentation well under 254 regions.
// Validate tile size vs geometry density in your bake config.
if (tileWidth * tileHeight > MaxCellsPerTile)
throw new InvalidOperationException(
"Tile too large/dense; reduce tileSize or cs to keep monotone regions < 255."); Try / catch
try { cache.BuildNavMeshTile(ref); }
catch (Exception e) when (e.Message == "Buffer too small")
{ /* re-bake this tile smaller or simplify its geometry */ } Prevention
- Keep tile footprint modest so each layer fragments into < 255 monotone regions.
- Simplify collision geometry to reduce tiny walkable islands.
- Avoid packing many obstacles into a single tile.
When it happens
Trigger: Building a tile-cache layer whose walkable area is highly fragmented: many disjoint walkable islands, thin corridors, or heavy obstacle carving within one tile. Triggered by DtTileCache.BuildNavMeshTile -> builder region step on such a layer.
Common situations: Tile size too large relative to geometry complexity; many small obstacles carved into a single tile; noisy heightfield with many isolated ledges; cell size too coarse creating fragmentation.
Related errors
- Too few salt bits: {m_saltBits}
- Out of storage
- slot index {slotIndex} exceeds capacity {self.Capacity}
- invalid capacity: {capacity}
- slot index {slotIndex} exceeds capacity {self.Capacity}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/87f4a90830782f72.
Report an issue: GitHub.