fheroes2 icon indicating copy to clipboard operation
fheroes2 copied to clipboard

Improve road network and verify object placement immediately

Open idshibanov opened this issue 1 month ago • 2 comments

Relates to #10340 .

Implemented a new RoadBuilder helper that replaces WorldPathfinder with a BFS-style search optimized for ingame roads. In addition I added transactions to NodeCache to allow to preplan roads before actually placing objects. This should further eliminate cases where map generation fails due to unreachable object.

This will enable us to fill empty areas with decorative/flavour objects.

In addition, this PR exposes map helper internals to set roads directly, getting 25% speed up on average. (Currently every single road tile placement triggers multiple updates to other tiles in the area which tanks the generator performance when applying mass changes to road network. )

idshibanov avatar Nov 16 '25 01:11 idshibanov

@Districh-ru or @ihhub is there a way to run something like updateRoadSpritesAround from map_format_helper but across the whole map rather than tile-by-tile?

Underlying updateRoadSpritesInArea does it in a radius but I'm not sure if setting radius to mapWidth / 2 is correct approach.

idshibanov avatar Nov 16 '25 01:11 idshibanov

Hi @idshibanov, the current road placing works with the road sprites from original assets that do not cover all possible road connections. So our editor has almost the same bugs when placing roads. The road placing mars the tile as the road and then the updateRoadSpritesInArea() updates the road sprites around this tile to find the road sprites that fits the around tile that can have roads. And to avoid some incorrect road connections we do update the road around in two steps, starting from the center (where the road was just placed). These two steps are needed because roars are positioned between two tiles - all horizontal roads has sprite on the tile where the road is and a sprite at the lower tile and there may be also sprites of the road end that is also placed on tiles without road.

But updateRoadSpritesInArea() just calls updateRoadOnTile() for all tiles around without forcing of placing a new road. We can try to use updateRoadSpritesInArea for the whole map and, if needed, update or make a modified copy of updateRoadSpriteOnTile().

Some time ago I started to update the roads placing and plan to finish it in this year. :) My idea is to make 256 road objects that corresponds to the roadDirections in the current tile. So there will be no need of complex logic to place the road - just check the around tiles to calculate the "directions". Each object will contain one or more sprites in a tile to cover all possible road connections.

Districh-ru avatar Nov 16 '25 07:11 Districh-ru

Hi @idshibanov , is it expected that this PR should fix all road connections?

ihhub avatar Dec 10 '25 01:12 ihhub

Hi @idshibanov , is it expected that this PR should fix all road connections?

More like building valid paths. There are a lot of cosmetic sprite issues that should be new sprites drawn as mentioned in the previous comments here. As a workaround I could fix the junctions as a separate pass but it's not worth spending time on it right now.

idshibanov avatar Dec 10 '25 02:12 idshibanov

@idshibanov , many thanks for the updates!

ihhub avatar Dec 10 '25 02:12 ihhub

There are a lot of cosmetic sprite issues that should be new sprites drawn as mentioned in the previous comments here.

@idshibanov , Im willing to make new road sprites. If you make a simple sketch of what you want, it is not that hard to make.

An example of a tile request:

road tile request

Would result in something like this:

Road Cross

PusshPop avatar Dec 10 '25 22:12 PusshPop

Excellent @PusshPop! I made this issue to track it: https://github.com/ihhub/fheroes2/issues/10430.

idshibanov avatar Dec 10 '25 22:12 idshibanov