Roads that bend the path
A road is only a road if the pathfinder wants it. Getting there meant deleting the field the whole system stood on.
Roads are in. You paint them, they tier up, and they change where people walk.
That last clause is the feature. It’s also the one that nearly didn’t happen.
A road nobody prefers is decoration
The naive version is easy. Give each tile a movement cost, make road tiles cheap, let A* do the rest. I had that working in an afternoon and it looked completely fine.
It wasn’t. Haulers walked straight past a paved route to cut the corner through the grass, and they were right to. The saving was real but small, and the diagonal beat it. A road that only wins on a dead straight run is a road nobody uses.
Two things fixed it.
The heuristic had to know roads exist. A* only finds the cheapest path if its estimate never overshoots what’s actually left to travel. Mine assumed ordinary ground, so the moment a road made travel cheaper than ordinary, the search began discarding better routes before it had walked them. The estimate now takes its floor from the cheapest movement anywhere in the world, whatever that currently is. Lay a better tier and the pathfinder’s sense of how good things could get moves with it.
Diagonals had to be thick. A one-tile diagonal road is, to a grid, a staircase with gaps in it, and walkers slip off it at every step. The brush now lays diagonals two tiles wide, so the route is continuous to the thing walking it and not only to the eye.
Deleting the field it was built on
Somewhere in the middle of this I deleted Tile.movement_cost.
It had been there since the first week and it was a lie. What a tile costs to cross is the terrain, plus the road, plus whatever else is pushing on that spot. Keep a cached number and the things it derives from, and you have to hold them in step forever. Something always drifts. Now the cost is worked out in one place and there’s no copy of it left to rot.
That’s the most satisfying kind of work on this project and it never shows up in a screenshot.
The art nearly broke on a technicality
Every road tier has its own art, and the tiles autotile: each piece picks its shape from its neighbours so a run reads as continuous. The first build produced a paved path made entirely of end caps, as though every tile were alone in the world.
The autotiler was looking at the wrong layer. Roads sit on the flooring layer, and the neighbour test was asking the layer above it, which is empty.
One line. Two hours.
How I know it works
Not by watching a colonist walk. They had somewhere to be either way, so that proves nothing. The game can be asked directly for the path between two points and how much of it is paved, so the test is the same route queried before and after the road goes down. Paved tiles up, cost down, or it isn’t done.