Navigation run time baking after switching from 64pixel tile size to 32pixel size issue

Godot Version

v4.4.stable.mono.official.4c311cbee

Question

Hey all,

I had my navigation working perfectly with 64 pixel size tile maps, when I switched to 32 pixel size there is a massive spacing from the collision shapes.

64 pixel size nav regions:

32 pixel size nav regions with two different implementations of collisions (probably not relevant as the issue is the same either way):


You can see my nav region creation is related to the tile pixel size so logically would not be affected. I’ve tried modifying the border size, baking rect, and offset however they dont seem to have much if any effect. Previously it was very noticeable when the values changed.

var bakingBoundRectOffset = 2 * tilePixelSize;
		var newNavigationPolygon = new NavigationPolygon();
		newNavigationPolygon.AgentRadius = 5;
		var bakingRect = new Rect2(new Vector2(globalOrigin.X - bakingBoundRectOffset, globalOrigin.Y - bakingBoundRectOffset),
									horizontalSideLength + (2 * bakingBoundRectOffset),
									verticalSideLength + (2 * bakingBoundRectOffset));
		testrects.Add(bakingRect);
		newNavigationPolygon.BakingRect = bakingRect;
		newNavigationPolygon.BorderSize = 2 * tilePixelSize;
		var sourceGeometry = new NavigationMeshSourceGeometryData2D();
		var onParseDoneCallable = Callable.From(() => OnChunkSourceGeometryParsed(newNavigationPolygon, sourceGeometry));
		NavigationServer2D.ParseSourceGeometryData(newNavigationPolygon, sourceGeometry, GetChildTileMapLayer(InternalMap.TileMapLayerType.Object), onParseDoneCallable);

Hopefully someone has a good idea, is it related to cell size? I’ve left the default 1.0 value as changing it either made the nav regions stay the same or disappear completely.

Thanks for your time!

Edit:
Further investigation has made me assume it has something to do with how the source geometry is parsed. My obstructions seem to have a 16 pixel offset on all sides causing this spacing:

Does anyone know how this could happen? The TileMapLayer has a tile size of 32x32 and my parse and bake code don’t make changes to much other than the polygon:

var sourceGeometry = new NavigationMeshSourceGeometryData2D();
var onParseDoneCallable = Callable.From(() => OnChunkSourceGeometryParsed(newNavigationPolygon, sourceGeometry));
NavigationServer2D.ParseSourceGeometryData(newNavigationPolygon, sourceGeometry, GetChildTileMapLayer(InternalMap.TileMapLayerType.Object), onParseDoneCallable);

private void OnChunkSourceGeometryParsed(NavigationPolygon polygon, NavigationMeshSourceGeometryData2D sourceGeometry){
		var onBakeDoneCallable = Callable.From(() => OnChunkBakingDone(polygon));
		NavigationServer2D.BakeFromSourceGeometryData(polygon, sourceGeometry, onBakeDoneCallable);
}

Edit 2: Not so much an offset but every obstruction is treated as 64x64 even when I change the tilemap layer tile size to anything, 16x16 even has 64x64 obstructions in the source geometry. I don’t see anything that could be setting this value, totally stuck now. @smix8 you know pretty much everything about the navigation; if you have a moment do you know why obstructions would be staying at 64x64 even when the TileMapLayer sent as source geometry is smaller?

Figured it out; I was looking through navmesh_parse_source_geometry in tile_map_layer.cpp and saw it was using collision polygon points to build the outlines, so I looked around in the settings for that Tile Map Layer till I found the cause. The physics layer for the tileset that I was using as collision was still sized at 64 pixels (recreation, it wasn’t skewed like the image before I fixed it):


So I resized it down to fit the tile:

This took me way too long to figure out, but it seems like a mistake in the editor, the physics layer should probably resize if the tile itself is resized. I don’t think I manually set the physics layer size per tile.

I am too late to the party but glad you figured it out.

In general when facing such broken 2d navmesh polygon “stars” that is the common result of outlines stacking inside each other. Outlines in general are brittle to stacking because they are interpreted even/odd. Aka the first, outer most outline is “solid”, the next outline that is fully inside that outline is understood as a “hole”, and so forth. That is why it is ok to have outlines partly overlap (they are merged in this case) as long as they are not fully inside other outlines as that makes the algorithm flip the meaning of the outline. Note that traversable outlines and obstruction outlines are merged in different passes, so it is ok to have those two kinds of outlines overlap, just don’t stack e.g. obstruction outlines within themself. That is likely what happenend here with the tilemap cell and broke the navmesh result.