How to avoid gaps between tiles in a recast graph

How can I avoid these kind of gaps between tiles on terrain? Why wouldn’t it try to generate closer seams?

Sometimes it just generates a single plane in one tile, even though the terrain clearly has more elevated detail.
The problem is that the pathfinder will try to find a path around this big gap.

These are my settings:


I am not sure what could cause that, I haven’t seen it before. Maybe tweak the terrain sample size?
I assume this is in between 2 tiles, right?

Yes, the navmesh doesn’t care much about elevation differences, only if it is walkable ground or not. You can force it to generate a navmesh which more closely follows the elevation by reducing the tile size.

Yeah, it is on all the tile borders. If it doesn’t care about elevation of terrain, tile borders create serious pathfinding problems. We have a large desert and often the moving character would stop and tries to find the path via a long detour along the tile border.
If pathfinding would work, the tile border gaps would be acceptable. But this way it’s like unintended holes in the navmesh.

Yeah that’s odd, because even if it doesn’t care much about elevation, adjacent tiles should still line up. I’m not quite sure what is happening in your case.

They often don’t line up. Here is another situation:

I’m using RelevantGraphSurface objects to define the areas where to generate the navmesh.

Another example:

Sometimes the tiles just don’t line up.

Interesting, it looks like the ‘max edge length’ setting is not being applied at all tile edges… Though even when it was applied it didn’t look particularly even…

It looks like the max edge length is not considered at all. There are many edges much longer than 5.

The max edge length will not split every edge, it will only split those along the navmesh border and (I think, though I might be wrong, it was a long time since I looked at that code) along tile borders.

It would be great if you could find out whether this is a bug, as I have to decide either to wait for a fix or find another solution. Using smaller tiles would be very annoying, as I’d have to add a ton more RelevantGraphSurface objects.

Hi Aron, do you have an update for me on this?


I have not been able to replicate this in my test scenes. Would it be possible for you to share a small example scene with me so that I could reproduce the bug?

Hi Aron,

It took a while to prepare the test project, since there are so many things to do.
I stripped out everything unnecessary, kept only the terrain and the navmesh relevant objects in there. I added an object “check_navmesh_around_here” to indicate where one of the bugs are clearly visible.
On the A* object please load the mesh from the cache.

I uploaded it to my Dropbox at:

This bug is really important for the project, because it makes the graph really buggy in some areas.

Thanks for investigating it!

I would like to bump this up, as it’s really critical for our project.


Ok. It seems it is not a bug as such, it is a scenario that I had not planned for however. The tile border will sometimes be split into smaller segments by the rasterization process, especially if obstacles are near it (not necessarily intersecting it). If the other tile does not have any obstacles the tile border will not be split.

I have introduced support for splitting long edges along tile borders now, so reducing the max edge length a bit will split those borders and make it follow the terrain a lot better.

Before (note the large seam in the middle of the image):


That looks much better indeed. I also noticed that adjusting the max edge length has no effect whatsoever.

I have sent you a link to a bleeding edge version with these changes included.
It also includes some earlier improvements to recast graph scanning performance for large graphs which I think you will like. It is maybe around 100 to 300 times faster at scanning that map on my computer compared to the version you used previously.

Awesome. I will give this a try and report back the results.

I remembered now that I didn’t actually check if the correct connections were formed this time… but I think they should be…