diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index b027f814..f01a2390 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ # These are supported funding model platforms - +github: Azgaar patreon: Azgaar diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..698d23ae --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,89 @@ +# Fantasy Map Generator + +Azgaar's Fantasy Map Generator is a client-side JavaScript web application for creating fantasy maps. It generates detailed fantasy worlds with countries, cities, rivers, biomes, and cultural elements. + +Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. + +## Working Effectively + +- **CRITICAL**: This is a static web application - NO build process needed. No npm install, no compilation, no bundling. +- Run the application using HTTP server (required - cannot run with file:// protocol): + - `python3 -m http.server 8000` - takes 2-3 seconds to start +- Access at: `http://localhost:8000` + +## Validation + +- Always manually validate any changes by: + 1. Starting the HTTP server (NEVER CANCEL - wait for full startup) + 2. Navigate to the application in browser + 3. Click the "►" button to open the menu and generate a new map + 4. **CRITICAL VALIDATION**: Verify the map generates with countries, cities, roads, and geographic features + 5. Test UI interaction: click "Layers" button, verify layer controls work + 6. Test regeneration: click "New Map!" button, verify new map generates correctly +- **Known Issues**: Google Analytics and font loading errors are normal (blocked external resources) + +## Repository Structure + +### Core Files + +- `index.html` - Main application entry point +- `main.js` - Core application logic +- `versioning.js` - Version management and update handling + +### Key Directories + +- `modules/` - core functionality modules: + - `modules/ui/` - UI components (editors, tools, style management) + - `modules/dynamic/` - runtime modules (export, installation) + - `modules/renderers/` - drawing and rendering logic +- `utils/` - utility libraries (math, arrays, strings, etc.) +- `styles/` - visual style presets (JSON files) +- `libs/` - Third-party libraries (D3.js, TinyMCE, etc.) +- `images/` - backgrounds, UI elements +- `charges/` - heraldic symbols and coat of arms elements +- `config/` - Heightmap templates and configurations +- `heightmaps/` - Terrain generation data + +## Common Tasks + +### Making Code Changes + +1. Edit JavaScript files directly (no compilation needed) +2. Refresh browser to see changes immediately +3. **ALWAYS test map generation** after making changes +4. Update version in `versioning.js` for all changes +5. Update file hashes in `index.html` for changed files (format: `file.js?v=1.108.1`) + +### Debugging Map Generation + +- Open browser developer tools console +- Look for timing logs, e.g. "TOTAL: ~0.76s" +- Map generation logs show each step (heightmap, rivers, states, etc.) +- Error messages will indicate specific generation failures + +### Testing Different Map Types + +- Use "New Map!" button for quick regeneration +- Access "Layers" menu to change map visualization +- Available presets: Political, Cultural, Religions, Biomes, Heightmap, Physical, Military + +## Troubleshooting + +### Application Won't Load + +- Ensure using HTTP server (not file://) +- Check console for JavaScript errors +- Verify all files are present in repository + +### Map Generation Fails + +- Check browser console for error messages +- Look for specific module failures in generation logs +- Try refreshing page and generating new map + +### Performance Issues + +- Map generation should complete in ~1 second for standard configurations +- If slower, check browser console for errors + +Remember: This is a sophisticated client-side application that generates complete fantasy worlds with political systems, geography, cultures, and detailed cartographic elements. Always validate that your changes preserve the core map generation functionality. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b254d0ad..acedeb18 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -14,8 +14,8 @@ # Versioning - diff --git a/LICENSE b/LICENSE index 45f950ac..4b0e677e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright 2017-2021 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com +Copyright 2017-2024 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -14,6 +14,7 @@ copies or substantial portions of the Software. You can produce, without restrictions, any derivative works from the original software and even reap commercial benefits from the sale of the secondary product. +The derivates include created maps, map images, screenshots, videos, and other materials. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,4 +22,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index efd8224e..3ab245b2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua) - # Fantasy Map Generator Azgaar's _Fantasy Map Generator_ is a free web application that helps fantasy writers, game masters, and cartographers create and edit fantasy maps. @@ -8,19 +6,17 @@ Link: [azgaar.github.io/Fantasy-Map-Generator](https://azgaar.github.io/Fantasy- Refer to the [project wiki](https://github.com/Azgaar/Fantasy-Map-Generator/wiki) for guidance. The current progress is tracked in [Trello](https://trello.com/b/7x832DG4/fantasy-map-generator). Some details are covered in my old blog [_Fantasy Maps for fun and glory_](https://azgaar.wordpress.com). -[![preview](https://cdn.discordapp.com/attachments/587406457725779968/594840629213659136/preview1.png)](https://i.redd.it/8bf81ir2cy631.png) +[![preview](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/9502eae9-92e0-4d0d-9f17-a2ba4a565c01)](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/11a42446-4bd5-4526-9cb1-3ef97c868992) -[![preview](https://cdn.discordapp.com/attachments/587406457725779968/594840633911279636/preview2.png)](https://cdn.discordapp.com/attachments/515359185664344071/593888810782162964/The_Wichin_Island_sepia.png) +[![preview](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/e751a9e5-7986-4638-b8a9-362395ef7583)](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/e751a9e5-7986-4638-b8a9-362395ef7583) -[![preview](https://cdn.discordapp.com/attachments/587406457725779968/594840632296734720/preview3.png)](https://cdn.discordapp.com/attachments/515359096925454350/593891237984206848/The_Wichin_Island_-_diplomacy.png) +[![preview](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/b0d0efde-a0d1-4e80-8818-ea3dd83c2323)](https://github.com/Azgaar/Fantasy-Map-Generator/assets/26469650/b0d0efde-a0d1-4e80-8818-ea3dd83c2323) Join our [Discord server](https://discordapp.com/invite/X7E84HU) and [Reddit community](https://www.reddit.com/r/FantasyMapGenerator) to share your creations, discuss the Generator, suggest ideas and get the most recent updates. -Contact me via [email](mailto:azgaar.fmg@yandex.by) if you have non-public suggestions. For bug reports please use [GitHub issues](https://github.com/Azgaar/Fantasy-Map-Generator/issues) or _#bugs_ channel on Discord. If you are facing performance issues, please read [the tips](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Tips#performance-tips). +Contact me via [email](mailto:azgaar.fmg@yandex.com) if you have non-public suggestions. For bug reports please use [GitHub issues](https://github.com/Azgaar/Fantasy-Map-Generator/issues) or _#fmg-bugs_ channel on Discord. If you are facing performance issues, please read [the tips](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Tips#performance-tips). -Electron desktop application is available in [releases](https://github.com/Azgaar/Fantasy-Map-Generator/releases). Download archive for your architecture, unzip and run. - -Pull requests are highly welcomed. The codebase is messy and requires re-design, but I will appreciate if you start with minor changes. Check out the [data model](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Data-model) before contributing. +Pull requests are highly welcomed. The codebase is messy and requires re-design. I will appreciate if you start with minor changes. Check out the [data model](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Data-model) before contributing. You can support the project on [Patreon](https://www.patreon.com/azgaar). diff --git a/components/slider-input.js b/components/slider-input.js new file mode 100644 index 00000000..f1732027 --- /dev/null +++ b/components/slider-input.js @@ -0,0 +1,78 @@ +{ + const style = /* css */ ` + slider-input { + display: flex; + align-items: center; + gap: .4em; + } + `; + + const styleElement = document.createElement("style"); + styleElement.setAttribute("type", "text/css"); + styleElement.innerHTML = style; + document.head.appendChild(styleElement); +} + +{ + const template = document.createElement("template"); + template.innerHTML = /* html */ ` + + + `; + + class SliderInput extends HTMLElement { + constructor() { + super(); + this.appendChild(template.content.cloneNode(true)); + + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + + range.value = number.value = this.value || this.getAttribute("value") || 50; + range.min = number.min = this.getAttribute("min") || 0; + range.max = number.max = this.getAttribute("max") || 100; + range.step = number.step = this.getAttribute("step") || 1; + + range.addEventListener("input", this.handleEvent.bind(this)); + number.addEventListener("input", this.handleEvent.bind(this)); + range.addEventListener("change", this.handleEvent.bind(this)); + number.addEventListener("change", this.handleEvent.bind(this)); + } + + handleEvent(e) { + const value = e.target.value; + const isNaN = Number.isNaN(Number(value)); + if (isNaN || value === "") return e.stopPropagation(); + + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + this.value = range.value = number.value = value; + + this.dispatchEvent( + new CustomEvent(e.type, { + detail: {value}, + bubbles: true, + composed: true + }) + ); + } + + set value(value) { + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + range.value = number.value = value; + } + + get value() { + const number = this.querySelector("input[type=number]"); + return number.value; + } + + get valueAsNumber() { + const number = this.querySelector("input[type=number]"); + return number.valueAsNumber; + } + } + + customElements.define("slider-input", SliderInput); +} diff --git a/icons.css b/icons.css index ae40ee00..4740f091 100644 --- a/icons.css +++ b/icons.css @@ -253,7 +253,7 @@ .icon-coa:before {content:'\f3ed'; font-size: .9em; color: #999;} /* '' */ .icon-half:before {font-weight: bold;content:'½';} .icon-voice:before {content:'🔊';} - +.icon-robot:before {content:'🤖';} .icon-die:before {content:'🎲';} .icon-button-die:before {content:'🎲'; padding-right: .4em;} .icon-button-power:before {content:'💪'; padding-right: .6em;} diff --git a/index.css b/index.css index 558728b7..373bf63c 100644 --- a/index.css +++ b/index.css @@ -122,10 +122,6 @@ a { fill: none; } -#biomes { - stroke-width: 0.7; -} - #landmass { mask: url(#land); fill-rule: evenodd; @@ -170,6 +166,7 @@ t, #texture, #landmass, #vignette, +#gridOverlay, #fogging { pointer-events: none; } @@ -190,20 +187,12 @@ t, font-size: 0.8em; } -#statesBody { - stroke-width: 3; -} - #statesHalo { fill: none; stroke-linecap: round; stroke-linejoin: round; } -#provincesBody { - stroke-width: 0.2; -} - #statesBody, #provincesBody, #relig, @@ -258,7 +247,6 @@ i.icon-lock { cursor: pointer; } -#routeEditor > *, #labelEditor div { display: inline-block; } @@ -357,6 +345,14 @@ text.drag { font-weight: bold; } +button.ui-button:disabled { + filter: brightness(0.95); +} + +button.ui-button:disabled:hover { + cursor: default; +} + .ui-dialog, #optionsContainer { user-select: none; @@ -437,6 +433,14 @@ button.options:hover { margin: 0.8em 0 0 0; } +#options .tip { + color: #444; + font-size: 0.9em; + font-family: sans-serif; + font-style: italic; + margin-left: 0.5em; +} + #aboutContent { text-align: justify; } @@ -518,7 +522,53 @@ input[type="color"]::-webkit-color-swatch-wrapper { font-size: smaller; } +#options input[type="text"] { + border: 0px; + width: 62%; + font-size: smaller; +} + +#options output { + text-align: right; + font-size: smaller; +} + +#options input[type="number"] { + font-size: 0.8em; + border: 0; + text-align: right; + background-color: transparent; + width: 3.3em; +} + +#options input[type="number"]::-webkit-inner-spin-button, +#options input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +#options input[type="number"] { + appearance: textfield; + -moz-appearance: textfield; +} + +#options input[type="number"]:hover { + outline: 1px solid var(--dark-solid); +} + +#options input.paired { + text-align: center; + background-color: white; +} + +#options input.long { + width: 100%; + background-color: white; + text-align: left; +} + #options input[type="range"] { + width: 100%; height: 8px; background: 0; appearance: none; @@ -561,55 +611,7 @@ input[type="color"]::-webkit-color-swatch-wrapper { height: 2px; } -#options input[type="number"] { - font-size: 0.8em; -} - -#options input[type="text"] { - border: 0px; - width: 62%; - font-size: smaller; -} - -#optionsContent output { - text-align: right; - font-size: smaller; -} - -#optionsContent input[type="number"] { - border: 0; - text-align: right; - background-color: transparent; - width: 3.3em; - -moz-appearance: textfield; -} - -#optionsContent input[type="number"]::-webkit-inner-spin-button, -#optionsContent input[type="number"]::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; -} - -#optionsContent input[type="number"]:hover { - outline: 1px solid var(--dark-solid); -} - -#optionsContent input.paired { - text-align: center; - background-color: white; -} - -#optionsContent input.long { - width: 100%; - background-color: white; - text-align: left; -} - -#optionsContent input[type="range"] { - width: 100%; -} - -#optionsContent select { +#options select { width: 100%; } @@ -634,19 +636,6 @@ input[type="color"]::-webkit-color-swatch-wrapper { transform: translate(0px, 1px); } -#styleElements input[type="range"] { - width: 64%; -} - -#styleElements select { - width: 64%; -} - -#styleElements input[type="number"] { - width: 6em; - border: 0; -} - #styleSelectFont > option { font-size: 2em; } @@ -685,6 +674,7 @@ input[type="color"]::-webkit-color-swatch-wrapper { border: none; padding: 0.45em 0.75em; margin: 0.4em 0; + white-space: nowrap; font-family: var(--monospace); animation: glowing 2s infinite; } @@ -717,9 +707,6 @@ input[type="color"]::-webkit-color-swatch-wrapper { padding: 0.45em 0.75em; margin: 0.35em 0; transition: 0.1s; - font-size: 1em; - text-transform: capitalize; - overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -734,9 +721,9 @@ input[type="color"]::-webkit-color-swatch-wrapper { background-color: var(--header-active); } -#toolsContent div { +#toolsContent > .grid { display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(3, 1fr); margin: 0.2em 0; } @@ -758,7 +745,7 @@ input[type="color"]::-webkit-color-swatch-wrapper { #viewMode > button { padding: 0.35em; - margin: 0.2em 0.3em 0.6em 0.3em; + margin: 0.3em 0.3em 0.6em 0.3em; float: left; width: 30.7%; } @@ -783,7 +770,7 @@ fieldset { text-overflow: ellipsis; } -.tabcontent .buttonoff { +.tabcontent li.buttonoff { background-color: var(--bg-disabled); color: #444444aa; } @@ -1261,7 +1248,6 @@ i.resetButton:active { padding: 0; height: 2px; background: #d4d4d4; - top: -0.35em; position: relative; appearance: none; -webkit-appearance: none; @@ -1526,20 +1512,6 @@ div.states > .burgCulture { width: 6em; } -div.states .burgPopulation { - width: 4.8em; -} - -div.states .burgType { - width: 3em; -} - -div.states .burgType > span { - padding: 0 1px; - color: #6e5e66; - transition: 0.2s; -} - div.states span.inactive { color: #c6c2c2; } @@ -1610,6 +1582,7 @@ div.states > .riverType { #burgBody > div > div, #riverBody > div, +#routeBody > div, #lakeBody > div { padding: 0.1em; } @@ -1617,6 +1590,7 @@ div.states > .riverType { #riverBody div.label, #riverBody input, #riverBody select, +#routeBody div.label, #lakeBody div.label, #lakeBody input, #lakeBody select { @@ -1624,6 +1598,12 @@ div.states > .riverType { width: 7em; } +#routeBody input, +#routeBody select { + display: inline-block; + width: 10em; +} + #stateNameEditor div.label, #provinceNameEditor div.label, #regimentBody div.label, @@ -1829,11 +1809,6 @@ div.editorLine { padding: 0px 3px !important; } -#unitsBody > div > * { - display: inline-block; - margin-bottom: 0.2em; -} - .unitsHeader { margin: 0.8em 0 0 -1.1em; font-weight: bold; @@ -1845,28 +1820,21 @@ div.editorLine { margin: 6px 0 0 6px; } -#unitsBody > div > div { +#unitsBody label { + display: inline-block; width: 9em; } -#unitsBody > div > input[type="range"] { - width: 7em; -} - #unitsBody > div > select, #unitsBody > div > input[type="text"] { - width: 12em; -} - -#unitsBody > div > input[type="number"] { - width: 4.35em; -} - -#unitsBody > div > input, -#unitsBody > div > select { + width: 14.4em; border: 1px solid #e9e9e9; } +#unitsBody input[type="range"] { + width: 9em; +} + #unitsEditor i.icon-lock-open, #unitsEditor i.icon-lock { color: #626573; @@ -1876,12 +1844,6 @@ div.editorLine { margin: 0.4em 0 0 -0.9em; } -#barBackColor { - width: 3.5em; - padding: 0px; - height: 1.2em; -} - #ruler { cursor: move; fill: none; @@ -1921,18 +1883,6 @@ div.editorLine { stroke: #737373; } -#scaleBar { - stroke: none; - fill: none; - cursor: pointer; -} - -#scaleBar text { - fill: #353540; - text-anchor: middle; - font-family: var(--serif); -} - #militaryOptionsTable select { border: 1px solid #d4d4d4; } @@ -2199,7 +2149,7 @@ svg.button { #worldControls input[type="number"] { border: 1px solid #e5e5e5; padding: 0px; - width: 3.2em; + width: 4em; } #worldControls i.icon-lock-open, @@ -2258,10 +2208,6 @@ svg.button { fill: blue; } -#globeOutline { - fill: url(#temperatureGradient); -} - #globeArea { fill: white; fill-opacity: 0.3; @@ -2272,6 +2218,11 @@ svg.button { stroke-width: 0.2; } +#globePrimeMeridian { + stroke: blue; + stroke-width: 1.4; +} + #globeEquator { stroke: red; stroke-width: 1.4; @@ -2393,6 +2344,57 @@ svg.button { background: #ccc; } +.separator { + display: flex; + align-items: center; + text-align: center; + + font-style: italic; + font-weight: bold; + color: #222; + margin: 0.8em 0 0 0; +} +.separator::before, +.separator::after { + content: ""; + flex: 1; + border-bottom: 1px solid #333; +} +.separator:not(:empty)::before { + margin-right: 0.25em; +} +.separator:not(:empty)::after { + margin-left: 0.25em; +} + +@keyframes clockwiseBorderPulse { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +#chat-widget-container { + user-select: none; +} + +#chat-widget-minimized { + animation: fadeIn 1s ease-in; + transform: scale(0.65); + opacity: var(--bg-opacity); +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: var(--bg-opacity); + } +} + @media print { div, canvas { diff --git a/index.html b/index.html index ba433e21..60f71c30 100644 --- a/index.html +++ b/index.html @@ -11,8 +11,8 @@ name="description" content="Free web app that helps fantasy writers, game masters, and cartographers create and edit fantasy maps" /> - + - + - + - - - - - - - + + + + + + @@ -366,7 +370,9 @@ - + + + @@ -378,7 +384,7 @@ - +
Azgaar's
@@ -436,7 +442,7 @@ + + + + + + Terracing + + + + + + + Reduce layers + + + + + + + Simplify line + + + + + + + Line style + + + + + + + Color scheme + + + + + + + Opacity - - 0.4 + @@ -838,8 +878,7 @@ Column items - - 8 + @@ -854,8 +893,7 @@ Opacity - - 1 + @@ -882,7 +920,7 @@ Image - @@ -966,8 +1004,7 @@ Blur - - 50px + @@ -992,8 +1029,7 @@ Pattern opacity - - 0.2 + @@ -1029,6 +1065,13 @@ + + + + + + + @@ -1041,6 +1084,15 @@ id="styleGridSizeFriendly" data-tip="Distance between grid cell centers (in map scale)" > + + + @@ -1057,8 +1109,7 @@ Size - - .25 + @@ -1086,8 +1137,7 @@ Size - - + @@ -1096,23 +1146,14 @@ > Density - - .4 + - Fill + Fill color #5E4FA2 @@ -1122,7 +1163,7 @@ - Stroke + Stroke color #5E4FA2 @@ -1134,8 +1175,16 @@ Stroke width - - 1 + + + + + + + + Letter spacing + + @@ -1168,7 +1217,7 @@ Font - + @@ -1180,7 +1229,7 @@ - + @@ -1220,16 +1269,14 @@ Fill opacity - - 0.3 + Labels size - - 8 + @@ -1246,8 +1293,7 @@ Body opacity - - + @@ -1256,77 +1302,30 @@ - 10 + Halo opacity - - 1 + Halo blur - - 4 - - - - - - - Terracing - - - 0 - - - - - Reduce layers - - - 5 - - - - - Simplify line - - - 0 - - - - - Line style - - - - - - - Color scheme - - - + @@ -1335,62 +1334,36 @@ Fill opacity - - 1 + Box Size - - 3 + - State Size + State size - + - Province Size + Province size - + - Burg Size + Burg size - + @@ -1446,6 +1419,83 @@ + + + + Size + + Bar + + Font + + + + + + Position + + x + + y + + + + + + Label + + + + + + + Back opacity + + + + + + + Back fill + + + + + + + + Back stroke + + + + + Width + + + + + + Back padding + + + + + + + + + + Back filter + + 10K @@ -1534,7 +1596,7 @@ - + Year and era @@ -1578,10 +1640,10 @@ Cultures number - + - + @@ -1607,53 +1669,41 @@ - + States number - - - - - + + - + Provinces ratio - - - - - + + - + Size variety - - - - - + + - + Growth rate - - - - - + + @@ -1674,14 +1724,17 @@ data-tip="Define how many organized religions and cults should be generated. Cultures will have their own folk religions in any case" > - + Religions number - - - - - + + @@ -1710,22 +1763,16 @@ > Interface size - - - - - + + Tooltip size - - - - - + + @@ -1745,11 +1792,8 @@ Transparency - - - - - + + @@ -1792,6 +1836,17 @@ + + + Azgaar assistant + + + + + Speaker voice @@ -1955,8 +2010,8 @@ @@ -1964,23 +2019,16 @@
-

Click to configure:

-
- +
Edit
+
- - - - - - - - -
- -

Click to overview:

-
- - - - + + + + + + +
-

Click to regenerate:

-
+
Regenerate
+
+ + + + + - - - - - - - - +
-

Click to add:

-
+
Add
+
- - + +
-

Click to create a new map:

-
- - +
Show
+
+ + +
+ +
Create
+
+ +
@@ -2219,8 +2277,7 @@

- Fantasy Map Generator is a - free + Fantasy Map Generator is an open source @@ -2239,7 +2296,7 @@

Join our Discord server and Reddit community to ask - questions, get help and share maps. + questions, get help and share maps. The created maps can be used for free, even for commercial purposes.

@@ -2437,15 +2494,15 @@

-
-
+ +
+
+ +
+ Presets: + + + + +
+ + + @@ -2716,7 +2829,7 @@
Type:
- + -
+
Icon:
- +
👑
@@ -3485,10 +3644,10 @@ >
-
-
Emblem:
- - +
+
Emblem:
+
+
@@ -3496,7 +3655,7 @@
- + @@ -4450,7 +4545,7 @@