Version 2.5.0 makes editing large maps much faster. Until now, nearly every edit on a map with brush strokes, fault lines or custom rivers ended in something close to a full regeneration, however small the edit, and the wait grew with every stroke on the map. Now only the part of the map that changed is recalculated and redrawn, and the result is the same as regenerating the whole map.
These times were measured in Foundry on a 3210 x 2400 map with 7,158 brush strokes and 46 custom rivers. They are the processing times, and do not include the 2 second pause between finishing a stroke or moving a node and the change being applied, which has not changed.
- Finishing a brush stroke: from over 6 seconds to about 0.2 seconds.
- Undoing or redoing a brush stroke: from about 6 seconds, spread over two steps, to about 0.2 seconds in one.
- Moving a custom river node, and undoing it: from 7.4 and 6.7 seconds to 0.22 and 0.24 seconds.
- Loading a map, and changing the seed or a slider: these still regenerate the whole map, but replaying the brush strokes, the largest part of that on a map with many strokes, is about four times faster. On this map the replay takes 3.6 seconds.
- Painting with the brush: each map layer now sends only the rows that changed to the graphics card instead of the whole layer, which helps most on large maps.
> Note: A few small changes to existing maps may occur. Procedural rivers, the ones traced from spring pins rather than drawn by you, are now each traced independently of the others, so where the terrain left a river a choice between equally low neighbouring pixels it may take a slightly different route. Any difference is small and was not visible when comparing maps by eye.
IMPROVEMENTS
- Land masks can now be renamed, and switched between land and ocean, using the new Edit button in the Land Masks list or by double-clicking one of the mask's nodes.
- Each entry in the Land Masks list now has a green line for land or a red line for ocean, so you can tell them apart once they have been renamed.
- A region or land mask that you stop drawing before it has three nodes is now discarded, rather than being left in its list as a shape that cannot be edited or completed. Undo and Redo still work as normal, so a shape shortened by Undo can still be brought back with Redo.
- The Undo and Redo highlight for a land mask change now says "Land Mask" instead of the generic "Vector Edit".
- Guided mode's Scene toolbar now has the same pause toggle and Apply Changes button as the Features toolbar, so you can insert and drag land mask nodes without waiting for the terrain to regenerate after each one.
- Changing tool or finishing an edit session now always turns automatic terrain generation back on. Previously it stayed paused, so the next tool you opened could start out paused without you noticing.
- Finishing a brush stroke on a map with faults or manual rivers, and undoing or redoing a brush stroke, no longer replays the map's whole brush history, and now refreshes only the part of the map that changed instead of recalculating the climate and repainting the whole map. The result is the same as a whole-map refresh.
- Adding, moving or deleting a fault line or manual river, or its nodes, changing a fault's strength, and undoing or redoing any of these, no longer regenerate the whole map. Only the part of the map that changed is recalculated and repainted, and the result is the same as a full regeneration. Changing a setting such as the seed, sea level or a climate slider, and editing a Guided mode land mask, still regenerate the whole map.
- Replaying a map's brush strokes, which happens when a map loads and whenever a full regeneration is needed, is about four times faster. The terrain it produces is unchanged.
- Redrawing part of the map after an edit, whether a brush stroke while you paint, undoing or redoing one, or moving a fault or river node, now updates only the rows of each map layer's image that changed, instead of copying and re-uploading the whole image every time.
- Keeping edits quick uses extra memory: on a map of this size about 38 MB for a copy of the brushed terrain, up to 64 MB for undo data, and a 31 MB working copy that is released after 30 seconds without an edit. If the browser cannot supply the memory, the module falls back to the slower method instead of failing.
BUG FIXES
- Undoing or redoing a change to a Guided mode land mask (such as moving or adding a node) now regenerates the terrain to match. Previously the mask shape moved but the terrain stayed as it was until something else triggered a redraw.
- Each node you place while drawing a land mask is now its own Undo step, the same as when drawing regions, routes, and fault lines. Previously Undo skipped over them and stepped back to an earlier, unrelated change, which could remove several shapes at once or bring back a mask you had deleted.
- Switching tool, or entering 3D view, while a land mask is still being drawn now completes the mask and regenerates the terrain. Previously the terrain was left out of date until something else triggered a redraw.
- Clicking or double-clicking a node, pin, label, or decoration without dragging it no longer counts as an edit. Previously it added an empty Undo step and, for land masks, fault lines, and custom rivers, triggered a terrain regeneration. The pointer now has to move a few pixels before an item starts to drag.
- Undo, Redo, and deleting a fault line or manual river from its list now respect the paused state instead of regenerating the terrain straight away. Apply Changes also no longer stays lit after a regeneration has already picked the changes up.
- Entering 3D view while automatic generation is paused now applies the pending changes first, so the 3D scene matches the map.
- Editing a river, a fault line, or a river source pin no longer changes the route of unrelated rivers elsewhere on the map. Previously every procedural river drew from one shared sequence of random choices, so a change that altered the length of one river gave every river traced after it different choices, and about a third of the map's rivers could be redrawn along different routes.
UNDER THE HOOD
A fuller account of how these changes work, and how they were tested, is in the technical write-up in the repository's Discussions.
- BrushEngine: the stamp loop was rewritten, with output bit-for-bit identical to before. Stroke settings are resolved once per stamp, each row only visits the pixels that can lie inside the brush circle, and distances use exactHypot, an inline copy of V8's two-argument Math.hypot.
- BrushLayerCache: the brush engine keeps a second copy of the terrain with every brush stroke applied, updated as strokes are finished, undone and redone, so a rebuild copies it instead of replaying the history. It falls back to a full replay whenever it cannot be trusted or its memory cannot be allocated.
- ProceduralOrchestrator.rebuildChangedTerrain and BufferDiff: a rebuild is built off to the side and compared bit for bit with the working terrain, so the climate, river and repaint stages run only over what differs. A repaint whose highest point moved covers the whole map, because land shading depends on it.
- ProceduralOrchestrator.canSkipBaseRegeneration: compares a description of everything the base terrain depends on (describeGenerationInputs) with the one recorded after the last full generation, and skips regenerating the base terrain when only strokes, faults, rivers or pins changed.
- RegionUploadResource: a subclass of PIXI 7's BufferResource that copies and uploads only the changed rows of a layer, and sends the whole texture whenever it cannot be sure the GPU copy matches. It is written against PIXI 7.
- ProceduralEngine.generateRivers: each river now draws its random choices from a stream of its own (riverTracePrng), seeded from the map seed and the pixel index of its spring, instead of one stream shared by every river. Editing one river no longer shifts the choices of the rivers traced after it.
- RenderTimer: full renders, refreshes, undo and redo each finish with one console summary of every phase's time and share of the total, including the canvas repaint, which the individual phase logs did not cover.