From 74defa0a5347a802de9ce40c21245093724c58f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:58:20 +0000 Subject: [PATCH 1/7] Initial plan From d29458bc217d6eed32f2adf7a8ddc9d2aedd5471 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 11:18:27 +0000 Subject: [PATCH 2/7] Add lakes as movable, toggleable layer in map layers panel Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/ee056fa6-a52a-4abf-98d8-ff91ec027763 Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/modules/io/load.js | 1 + public/modules/ui/hotkeys.js | 1 + public/modules/ui/layers.js | 28 ++++++++++++++++++++++++---- src/index.html | 8 ++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/public/modules/io/load.js b/public/modules/io/load.js index f1ee17e4c..3d41752f3 100644 --- a/public/modules/io/load.js +++ b/public/modules/io/load.js @@ -434,6 +434,7 @@ async function parseLoadedData(data, mapVersion) { // turn on active layers if (hasChild(texture, "image")) turnOn("toggleTexture"); if (hasChildren(terrs.select("#landHeights"))) turnOn("toggleHeight"); + if (isVisible(lakes)) turnOn("toggleLakes"); if (hasChildren(biomes)) turnOn("toggleBiomes"); if (hasChildren(cells)) turnOn("toggleCells"); if (hasChildren(gridOverlay)) turnOn("toggleGrid"); diff --git a/public/modules/ui/hotkeys.js b/public/modules/ui/hotkeys.js index 4b1e626d5..8dd54f022 100644 --- a/public/modules/ui/hotkeys.js +++ b/public/modules/ui/hotkeys.js @@ -61,6 +61,7 @@ function handleKeyup(event) { else if (key === "%") toggleAddMarker(); else if (code === "KeyX") toggleTexture(); else if (code === "KeyH") toggleHeight(); + else if (code === "KeyQ") toggleLakes(); else if (code === "KeyB") toggleBiomes(); else if (code === "KeyE") toggleCells(); else if (code === "KeyG") toggleGrid(); diff --git a/public/modules/ui/layers.js b/public/modules/ui/layers.js index f2f04a4be..96877e9c4 100644 --- a/public/modules/ui/layers.js +++ b/public/modules/ui/layers.js @@ -11,6 +11,7 @@ function getDefaultPresets() { "toggleBurgIcons", "toggleIce", "toggleLabels", + "toggleLakes", "toggleRivers", "toggleRoutes", "toggleScaleBar", @@ -22,6 +23,7 @@ function getDefaultPresets() { "toggleBurgIcons", "toggleCultures", "toggleLabels", + "toggleLakes", "toggleRivers", "toggleRoutes", "toggleScaleBar", @@ -31,6 +33,7 @@ function getDefaultPresets() { "toggleBorders", "toggleBurgIcons", "toggleLabels", + "toggleLakes", "toggleReligions", "toggleRivers", "toggleRoutes", @@ -40,19 +43,21 @@ function getDefaultPresets() { provinces: [ "toggleBorders", "toggleBurgIcons", + "toggleLakes", "toggleProvinces", "toggleRivers", "toggleScaleBar", "toggleVignette" ], - biomes: ["toggleBiomes", "toggleIce", "toggleRivers", "toggleScaleBar", "toggleVignette"], - heightmap: ["toggleHeight", "toggleRivers", "toggleVignette"], - physical: ["toggleCoordinates", "toggleHeight", "toggleIce", "toggleRivers", "toggleScaleBar", "toggleVignette"], + biomes: ["toggleBiomes", "toggleIce", "toggleLakes", "toggleRivers", "toggleScaleBar", "toggleVignette"], + heightmap: ["toggleHeight", "toggleLakes", "toggleRivers", "toggleVignette"], + physical: ["toggleCoordinates", "toggleHeight", "toggleIce", "toggleLakes", "toggleRivers", "toggleScaleBar", "toggleVignette"], poi: [ "toggleBorders", "toggleBurgIcons", "toggleHeight", "toggleIce", + "toggleLakes", "toggleMarkers", "toggleRivers", "toggleRoutes", @@ -63,6 +68,7 @@ function getDefaultPresets() { "toggleBorders", "toggleBurgIcons", "toggleLabels", + "toggleLakes", "toggleMilitary", "toggleRivers", "toggleRoutes", @@ -75,13 +81,14 @@ function getDefaultPresets() { "toggleBurgIcons", "toggleIce", "toggleEmblems", + "toggleLakes", "toggleRivers", "toggleRoutes", "toggleScaleBar", "toggleStates", "toggleVignette" ], - landmass: ["toggleScaleBar"] + landmass: ["toggleLakes", "toggleScaleBar"] }; } @@ -709,6 +716,18 @@ function toggleRelief(event) { } } +function toggleLakes(event) { + if (!layerIsOn("toggleLakes")) { + turnButtonOn("toggleLakes"); + $("#lakes").fadeIn(); + if (event && isCtrlClick(event)) editStyle("lakes"); + } else { + if (event && isCtrlClick(event)) return editStyle("lakes"); + $("#lakes").fadeOut(); + turnButtonOff("toggleLakes"); + } +} + function toggleTexture(event) { if (!layerIsOn("toggleTexture")) { turnButtonOn("toggleTexture"); @@ -979,6 +998,7 @@ function moveLayer(event, ui) { // define connection between option layer buttons and actual svg groups to move the element function getLayer(id) { + if (id === "toggleLakes") return $("#lakes"); if (id === "toggleHeight") return $("#terrs"); if (id === "toggleBiomes") return $("#biomes"); if (id === "toggleCells") return $("#cells"); diff --git a/src/index.html b/src/index.html index e4958414e..30408f7c8 100644 --- a/src/index.html +++ b/src/index.html @@ -497,6 +497,14 @@ data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style" id="mapLayers" > +
  • + Lakes +
  • Date: Wed, 22 Apr 2026 12:08:59 +0000 Subject: [PATCH 3/7] Reposition Lakes after Heightmap in panel and add e2e tests Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/000c5f7d-f7b5-44cd-9924-84f1a8877e63 Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- src/index.html | 16 +++--- tests/e2e/lakes-layer.spec.ts | 103 ++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 tests/e2e/lakes-layer.spec.ts diff --git a/src/index.html b/src/index.html index 30408f7c8..f32c80ed0 100644 --- a/src/index.html +++ b/src/index.html @@ -497,14 +497,6 @@ data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style" id="mapLayers" > -
  • - Lakes -
  • Heightmap
  • +
  • + Lakes +
  • { + test.beforeEach(async ({ context, page }) => { + await context.clearCookies(); + + await page.goto("/"); + await page.evaluate(() => { + localStorage.clear(); + sessionStorage.clear(); + }); + + await page.goto("/?seed=test-seed&width=1280&height=720"); + + // Wait for map generation to complete + await page.waitForFunction(() => (window as any).mapId !== undefined, { + timeout: 60000, + }); + + // Wait for any post-generation rendering to settle + await page.waitForTimeout(500); + }); + + test("lakes toggle button hides and shows the #lakes SVG group", async ({ + page, + }) => { + const lakes = page.locator("#lakes"); + + // Open the options panel (layers tab) so the toggle button is reachable + await page.evaluate(() => (window as any).showOptions()); + + // Lakes should be visible by default + await expect(lakes).toBeVisible(); + + // Click the toggle button to hide; wait for jQuery fadeOut to complete + await page.locator("#toggleLakes").click(); + await expect(lakes).toBeHidden(); + + // Click again to show; wait for jQuery fadeIn to complete + await page.locator("#toggleLakes").click(); + await expect(lakes).toBeVisible(); + }); + + test("KeyQ toggles the lakes layer", async ({ page }) => { + const lakes = page.locator("#lakes"); + + // Lakes should be visible by default + await expect(lakes).toBeVisible(); + + // Press Q to hide lakes; wait for jQuery fadeOut to complete + await page.keyboard.press("q"); + await expect(lakes).toBeHidden(); + + // Press Q again to show lakes; wait for jQuery fadeIn to complete + await page.keyboard.press("q"); + await expect(lakes).toBeVisible(); + }); + + test("Lakes panel entry is positioned just after Heightmap", async ({ + page, + }) => { + const [lakesIndex, heightmapIndex] = await page.evaluate(() => { + const items = Array.from( + document.querySelectorAll("#mapLayers > li") + ) as HTMLElement[]; + return [ + items.findIndex((li) => li.id === "toggleLakes"), + items.findIndex((li) => li.id === "toggleHeight"), + ]; + }); + + expect(lakesIndex).toBe(heightmapIndex + 1); + }); + + test("dragging Lakes below Heightmap in panel moves #lakes after #terrs in SVG", async ({ + page, + }) => { + // Confirm initial SVG order: #lakes is before #terrs (rendered behind heightmap by default) + const initialOrder = await page.evaluate(() => { + const viewbox = document.getElementById("viewbox")!; + const ids = Array.from(viewbox.children).map((el) => el.id); + return { lakes: ids.indexOf("lakes"), terrs: ids.indexOf("terrs") }; + }); + expect(initialOrder.lakes).toBeGreaterThanOrEqual(0); + expect(initialOrder.terrs).toBeGreaterThanOrEqual(0); + expect(initialOrder.lakes).toBeLessThan(initialOrder.terrs); + + // Simulate what moveLayer does when the user drags Lakes below Heightmap: + // panel item "toggleLakes" is now after "toggleHeight" → el.insertAfter(#terrs) + await page.evaluate(() => { + const $ = (window as any).$; + $("#lakes").insertAfter($("#terrs")); + }); + + // After move: #lakes should be after #terrs in SVG → renders on top of heightmap + const newOrder = await page.evaluate(() => { + const viewbox = document.getElementById("viewbox")!; + const ids = Array.from(viewbox.children).map((el) => el.id); + return { lakes: ids.indexOf("lakes"), terrs: ids.indexOf("terrs") }; + }); + expect(newOrder.lakes).toBeGreaterThan(newOrder.terrs); + }); +}); From c8ff7ba558675447f72cdfe7d35d3c145a01aa12 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 12:40:38 +0000 Subject: [PATCH 4/7] Remove toggleLakes from the landmass preset Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/d15d8549-f004-4431-9be6-a5a9069e7fac Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/modules/ui/layers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/modules/ui/layers.js b/public/modules/ui/layers.js index 96877e9c4..10123b386 100644 --- a/public/modules/ui/layers.js +++ b/public/modules/ui/layers.js @@ -88,7 +88,7 @@ function getDefaultPresets() { "toggleStates", "toggleVignette" ], - landmass: ["toggleLakes", "toggleScaleBar"] + landmass: ["toggleScaleBar"] }; } From ca62139f387699c7fab1a77193761407ee22c0cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 12:44:23 +0000 Subject: [PATCH 5/7] Move #lakes SVG group after #terrs so lakes render above heightmap by default Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/cd73e8fd-9235-4ea0-b026-0490582c209f Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/main.js | 2 +- tests/e2e/lakes-layer.spec.ts | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/public/main.js b/public/main.js index 033181cbf..6786852a6 100644 --- a/public/main.js +++ b/public/main.js @@ -40,10 +40,10 @@ let legend = svg.append("g").attr("id", "legend"); let ocean = viewbox.append("g").attr("id", "ocean"); let oceanLayers = ocean.append("g").attr("id", "oceanLayers"); let oceanPattern = ocean.append("g").attr("id", "oceanPattern"); -let lakes = viewbox.append("g").attr("id", "lakes"); let landmass = viewbox.append("g").attr("id", "landmass"); let texture = viewbox.append("g").attr("id", "texture"); let terrs = viewbox.append("g").attr("id", "terrs"); +let lakes = viewbox.append("g").attr("id", "lakes"); let biomes = viewbox.append("g").attr("id", "biomes"); let cells = viewbox.append("g").attr("id", "cells"); let gridOverlay = viewbox.append("g").attr("id", "gridOverlay"); diff --git a/tests/e2e/lakes-layer.spec.ts b/tests/e2e/lakes-layer.spec.ts index b2555c25f..0d9a19102 100644 --- a/tests/e2e/lakes-layer.spec.ts +++ b/tests/e2e/lakes-layer.spec.ts @@ -72,10 +72,10 @@ test.describe("Lakes layer", () => { expect(lakesIndex).toBe(heightmapIndex + 1); }); - test("dragging Lakes below Heightmap in panel moves #lakes after #terrs in SVG", async ({ + test("dragging Lakes above Heightmap in panel moves #lakes before #terrs in SVG", async ({ page, }) => { - // Confirm initial SVG order: #lakes is before #terrs (rendered behind heightmap by default) + // Confirm initial SVG order: #lakes is after #terrs (rendered above heightmap by default) const initialOrder = await page.evaluate(() => { const viewbox = document.getElementById("viewbox")!; const ids = Array.from(viewbox.children).map((el) => el.id); @@ -83,21 +83,21 @@ test.describe("Lakes layer", () => { }); expect(initialOrder.lakes).toBeGreaterThanOrEqual(0); expect(initialOrder.terrs).toBeGreaterThanOrEqual(0); - expect(initialOrder.lakes).toBeLessThan(initialOrder.terrs); + expect(initialOrder.lakes).toBeGreaterThan(initialOrder.terrs); - // Simulate what moveLayer does when the user drags Lakes below Heightmap: - // panel item "toggleLakes" is now after "toggleHeight" → el.insertAfter(#terrs) + // Simulate what moveLayer does when the user drags Lakes above Heightmap: + // panel item "toggleLakes" is now before "toggleHeight" → el.insertBefore(#terrs) await page.evaluate(() => { const $ = (window as any).$; - $("#lakes").insertAfter($("#terrs")); + $("#lakes").insertBefore($("#terrs")); }); - // After move: #lakes should be after #terrs in SVG → renders on top of heightmap + // After move: #lakes should be before #terrs in SVG → renders behind heightmap const newOrder = await page.evaluate(() => { const viewbox = document.getElementById("viewbox")!; const ids = Array.from(viewbox.children).map((el) => el.id); return { lakes: ids.indexOf("lakes"), terrs: ids.indexOf("terrs") }; }); - expect(newOrder.lakes).toBeGreaterThan(newOrder.terrs); + expect(newOrder.lakes).toBeLessThan(newOrder.terrs); }); }); From dcd976c5d5d1910bbfd94931ad2e864077b76924 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 13:13:04 +0000 Subject: [PATCH 6/7] Add water mask to #lakes group so inner lake islands are visible Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/d8572ce6-aa57-4ce6-b9bc-7b83354a19de Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/main.js | 2 +- public/modules/dynamic/auto-update.js | 5 +++++ src/renderers/draw-features.ts | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/public/main.js b/public/main.js index 6786852a6..9d99bf188 100644 --- a/public/main.js +++ b/public/main.js @@ -43,7 +43,7 @@ let oceanPattern = ocean.append("g").attr("id", "oceanPattern"); let landmass = viewbox.append("g").attr("id", "landmass"); let texture = viewbox.append("g").attr("id", "texture"); let terrs = viewbox.append("g").attr("id", "terrs"); -let lakes = viewbox.append("g").attr("id", "lakes"); +let lakes = viewbox.append("g").attr("id", "lakes").attr("mask", "url(#water)"); let biomes = viewbox.append("g").attr("id", "biomes"); let cells = viewbox.append("g").attr("id", "cells"); let gridOverlay = viewbox.append("g").attr("id", "gridOverlay"); diff --git a/public/modules/dynamic/auto-update.js b/public/modules/dynamic/auto-update.js index 775a76a6d..98b910b46 100644 --- a/public/modules/dynamic/auto-update.js +++ b/public/modules/dynamic/auto-update.js @@ -1112,4 +1112,9 @@ export function resolveVersionConflicts(mapVersion) { zone.cells = unique(zone.cells); }); } + + // ensure lakes group has water mask so inner islands are not hidden by lake fill + if (!lakes.attr("mask")) { + lakes.attr("mask", "url(#water)"); + } } diff --git a/src/renderers/draw-features.ts b/src/renderers/draw-features.ts index dbbb079cb..1704af508 100644 --- a/src/renderers/draw-features.ts +++ b/src/renderers/draw-features.ts @@ -42,6 +42,9 @@ const featuresRenderer = (): void => { html.landMask.push( ``, ); + html.waterMask.push( + ``, + ); const lakeGroup = feature.group || "freshwater"; if (!html.lakes[lakeGroup]) html.lakes[lakeGroup] = []; From 7a4cf60986f00974ff6ee8aafd98841b286dfffe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 13:20:59 +0000 Subject: [PATCH 7/7] Move #lakes mask to index.css instead of JS attribute Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/4a790923-83ed-4063-8813-c0702329794e Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/index.css | 4 ++++ public/main.js | 2 +- public/modules/dynamic/auto-update.js | 5 ----- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/public/index.css b/public/index.css index c46fded9a..8d5ed9053 100644 --- a/public/index.css +++ b/public/index.css @@ -133,6 +133,10 @@ a { fill-rule: evenodd; } +#lakes { + mask: url(#water); +} + #lakes, #coastline, #armies, diff --git a/public/main.js b/public/main.js index 9d99bf188..6786852a6 100644 --- a/public/main.js +++ b/public/main.js @@ -43,7 +43,7 @@ let oceanPattern = ocean.append("g").attr("id", "oceanPattern"); let landmass = viewbox.append("g").attr("id", "landmass"); let texture = viewbox.append("g").attr("id", "texture"); let terrs = viewbox.append("g").attr("id", "terrs"); -let lakes = viewbox.append("g").attr("id", "lakes").attr("mask", "url(#water)"); +let lakes = viewbox.append("g").attr("id", "lakes"); let biomes = viewbox.append("g").attr("id", "biomes"); let cells = viewbox.append("g").attr("id", "cells"); let gridOverlay = viewbox.append("g").attr("id", "gridOverlay"); diff --git a/public/modules/dynamic/auto-update.js b/public/modules/dynamic/auto-update.js index 98b910b46..775a76a6d 100644 --- a/public/modules/dynamic/auto-update.js +++ b/public/modules/dynamic/auto-update.js @@ -1112,9 +1112,4 @@ export function resolveVersionConflicts(mapVersion) { zone.cells = unique(zone.cells); }); } - - // ensure lakes group has water mask so inner islands are not hidden by lake fill - if (!lakes.attr("mask")) { - lakes.attr("mask", "url(#water)"); - } }