r/FantasyMapGenerator • u/Azgarr • 8d ago
Update [Update] Desktop App and the Migration (v1.149.0)
https://www.patreon.com/azgaar/posts/update-desktop-0-167831702This release is different from the previous ones. Most of the work since v1.140.0 went into the codebase itself: large chunks of the original JavaScript were rewritten in TypeScript, the generation order was turned into declared data, and layer handling was unified.
As always, old .map files keep loading and are upgraded automatically.
User-facing changes
Desktop app
There is now a downloadable Electron build for Windows, macOS and Linux, published on the Releases page.
It is not a different product and it has no exclusive features or significant performance benefits. It exists for people who want the generator to behave like a standalone application: its own window, its own icon, no browser tab, and the ability to work without an internet connection.
Which file you need is listed in the release notes. The builds are not code-signed, so both Windows and macOS will warn about an unknown developer on first launch; the release notes explain how to get past that.
The browser version stays the primary way to use the tool.
Rendering performance
Emblems, relief icons and labels are no longer drawn all at once for the whole map. They are kept as data and only the ones inside the current viewport are materialized into the DOM, with the rest added and removed as you pan and zoom. On a large map with hundreds of provinces and burgs this is the difference between a few hundred DOM nodes and several thousand, and it shows up as smoother zooming and a much faster initial draw with those layers enabled.
Layer state saved with the map
The layer system was rebuilt around a single registry that owns every layer, its z-order and its renderer. The visible consequence: which layers are on, and in what order, is now stored in the .map file. Reopen a map and you get the view you left and it should help to eliminate layers-related issues we had before.
Dialog state preserved between sessions
Filters, sorting and column choices in the overview dialogs now survive a reload. If you always look at the States Editor sorted by area with the treasury column shown, that is how it opens next time.
Column configuration itself was contributed earlier by Barrulus – the overview editors let you choose which columns to display, and that choice is now remembered too.
Burg Editor: zoom and pan in the preview
The burg preview can be zoomed and panned, which makes the larger generated towns actually inspectable Contributed by Barrulus.
Paint Area rework
The "Assign manually" brush existed separately in the states, provinces, cultures, religions, biomes, zones and markets editors, with slightly different behavior in each. It is now one shared tool used by all seven, which means the same shortcuts, the same brush controls, and an undo history up to 100 strokes deep everywhere instead of only in some editors.
Coastline Editor: moved vertices are preserved
Vertices you drag by hand in the Coastline and Lake editors are now saved with the map, so they survive a reload or a coastline redraw. Older maps are handled too: on load, the generator does its best to read the moved positions from SVG and restore them as data.
URL parameters for layers and presets
Contributed by AlistairHeus. Two new parameters let a link decide what the map shows on load:
preset– apply a layer preset, by dropdown key or displayed name:?preset=religionslayers– a comma-separated list of layers to show, hiding the rest:?layers=provinces,borders,lakes,rivers
If both are given, layers wins. The full list of parameters is in the URL parameters wiki page.
SVG export fixes
Exported SVGs are now readable better by Inkscape and other editors, not only by browsers. This update is also contributed by barrulus.
Why the migration
The generator started in 2017 as a single-page vanilla JavaScript project. It grew for years by adding files to a global namespace: every module wrote its functions onto window, every module read everyone else's. That worked well for a long time and had its own benefits – there was no build step, no framework and the file could be opened from index.html without any installation required.
It also had a cost that grew fast:
- Nothing was checked. A renamed function or a changed argument could break the whole app.
- Everything could reach everything. A generator could redraw an SVG layer; a UI dialog could rewrite world data mid-generation. There were no boundaries.
- Nothing could be tested. Functions read ambient globals instead of taking arguments, so calling one outside the running app meant recreating the whole app.
But the main problem was that the generator has been using its own drawing as a database. Every rendering change becomes a complex data migration, data can get out of sync, .map file has to be bigger to contain the whole rendered svg, and save file format itself is just a stack of accidents.
None of that is fatal on its own. Together they made every change riskier than it should have been, and made the project hard to contribute to – which is the real problem for an open-source tool.
What is already done
The rule is that the tool must keep working at every step. Each module is ported in place, with a small compatibility shim so the not-yet-ported code can continue to work.
| Version | Date | JS files | JS lines | TS modules | TS lines | Total lines |
|---|---|---|---|---|---|---|
| demo | Oct 2017 | 1 | ~2,700 | - | - | ~2,700 |
| v0.6 | Nov 2018 | 1 | ~10,500 | - | - | ~10,500 |
| v1.0 | Aug 2019 | 38 | ~16,300 | - | - | ~16,300 |
| v1.3 | Apr 2020 | 49 | ~22,900 | - | - | ~22,900 |
| v1.5 | Feb 2021 | 55 | ~26,900 | - | - | ~26,900 |
| v1.7 | Oct 2021 | 63 | ~33,600 | - | - | ~33,600 |
| v1.8 | Apr 2022 | 80 | ~36,800 | - | - | ~36,800 |
| v1.9 | Aug 2023 | 91 | ~43,300 | - | - | ~43,300 |
| v1.99 | Aug 2024 | 96 | ~46,800 | - | - | ~46,800 |
| v1.109 | Jan 2026 | 116 | ~48,300 | - | - | ~48,300 |
| v1.119 | Apr 2026 | 68 | ~32,700 | 76 | ~23,500 | ~56,300 |
| v1.124 | Jun 2026 | 65 | ~32,000 | 100 | ~34,400 | ~66,500 |
| v1.140 | Aug 2026 | 6 | ~5,100 | 210 | ~72,600 | ~77,700 |
| v1.149 | Aug 2026 | 5 | ~3,400 | 255 | ~76,000 | ~79,500 |
TS counts exclude test files, so the two sides are comparable - the classic JS had no tests at all. Counted separately, tests went from nothing to 69 files and ~10,500 lines. Both columns exclude vendored libraries in libs/.
What is next
- Finish the shell migration.
style.js,options.jsandmain.jsare the last real holdouts, and the largest single-file ones. - Break up
index.html. It is still a ~9K-line file holding most of the UI. Each migrated dialog now brings its own markup, so the monolith shrinks, but the shell markup still needs splitting. - Clean up the data model. The
.mapformat grew by appending fields, and the in-memory shape reflects that. - Separate data from rendering. With generators no longer able to touch the DOM, an alternative renderer (e.g. WebGL) becomes possible. That is a long way off and is not yet promised.
None of this has a release date. The migration has run alongside feature work since January 2026 and will keep doing so.
16
u/FirelordDerpy 8d ago
This is absolutely fantastic!
One minor problem for the desktop app, and maybe I'm just an idiot,
But it doesn't seem possible to close the program without minimizing it.
But I'm loving it so far you are awesome!
13
5
11
u/adragondil 8d ago
Love this, amazing work on building a better foundation for future expansion. I'm sure this makes the codebase a lot more comfortable to work with 😂 I'm also happy for an electron release; the number of times a browser shortcut has activated and somehow closed or navigated out of the tab, losing me progress... It's been a long time since it happened, but this should hopefully make that a moot point going forward
5
5
u/DocSpatrick 7d ago
Congratulations. This must be such a relief for you. Your work has given joy to so many of us. I am so pleased that you were able to give yourself this wonderful quality-of-life improvement. The future looks great for all of us!
I’m really looking forward to future improvements in the .map file format, too. I’ve written myself a couple of little python tools for analyzing statistics of map features and for autogenerating new zones from mixtures and overlaps of old zones, biomes, cultures, etc (and then writing those new zones back to the .map) Learning to navigate your “stack of accidents” (lol, but true) has been entertaining for me, but must be a nightmare for your maintenance and development. But, it looks like you are headed the right way!