Bug fixes, cleanup, and a byte-identical performance win from a full-codebase
review. One behaviour change: rivers are now continuous (see Fixed).
Fixed
- Rivers are continuous source→mouth polylines again. They were traced
highest-flux-first, which shattered every river into 2-cell fragments — harmless
on the rendered map (the pieces tile), butTerrainResult.riversand its
serialisation were fragmented, with per-fragment widths. Now traced
headwaters-first, andRiver.widthcomes from the downstream (mouth) end.
This changesriversoutput for a given seed. WorldMapConfig.from_dictno longer crashes on noisy payloads. Astr,
None,NaN, orinfvalue now coerces to a finite number (or the field
default) and clamps, instead of raisingTypeError— honouring the documented
"safe for sloppy LLM/JSON input" contract.edge_falloffwas applied squared in multi-continent worlds; now applied
once. (Only affectedcontinents>1withedge_falloff≠1.0; no preset uses that.)- Smart labels no longer misalign colour/style when a region or feature has an
empty name, and features never get an empty name.
Changed
- Lloyd relaxation vectorised (
np.bincount) — ~24% faster world generation,
byte-identical output. Removed dead energy bookkeeping from the label placer
(and made its inner loop scan only overlapping labels); de-cubed the dungeon
extra-corridor loop.
Added
to_json/from_jsononRegion,Road,CellSummary, andWorldMapConfig
(parity with the other public dataclasses), and exportedget_theme,
theme_names,DEFAULT_THEME.