From 8b605a4cae0b3bda55e9c710d8288453d9992455 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 8 Apr 2026 16:00:57 +0200 Subject: [PATCH] fix: horizontally flip tile images + negate rotation UB's tiles were authored for a mirrored-X rendering space. Instead of mirroring coordinates (which breaks positioning), flip each tile image horizontally during pre-processing and negate the cell rotation angles to compensate. Cell and object positions remain direct (no mirroring). Co-Authored-By: Claude Opus 4.6 (1M context) --- static/script.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/static/script.js b/static/script.js index 9dfaab4f..7a3062ac 100644 --- a/static/script.js +++ b/static/script.js @@ -3607,13 +3607,18 @@ const DUNGEON_DISPLAY_COLORS = { stairs: { r: 180, g: 160, b: 80 }, // yellowish stairs }; -// Process a tile image: make white transparent, remap UB colors +// Process a tile image: flip horizontally (UB tiles authored for mirrored-X), +// make white transparent, remap UB colors function processTileImage(img) { const c = document.createElement('canvas'); c.width = 10; c.height = 10; const ctx = c.getContext('2d'); + // Flip horizontally: tiles were designed for UB's mirrored-X coordinate system + ctx.translate(10, 0); + ctx.scale(-1, 1); ctx.drawImage(img, 0, 0, 10, 10); + ctx.setTransform(1, 0, 0, 1, 0, 0); const imageData = ctx.getImageData(0, 0, 10, 10); const d = imageData.data; @@ -3857,13 +3862,14 @@ function updateRadarWindow(msg) { const cellSize = 10 * scale; // each cell is 10 game units const hasTiles = dungeonTileCanvases && Object.keys(dungeonTileCanvases).length > 0; - // Normalize rotation value to radians (same as UB's DungeonCell.cs) - // Raw value is quaternion W component: 1→180°, ~0.707→-90°, ~-0.707→90°, 0→0° + // Normalize rotation value to radians (from UB's DungeonCell.cs) + // Negated because tile images are horizontally flipped to compensate + // for UB's mirrored-X authoring space function cellRotation(rot) { - if (Math.abs(rot - 1) < 0.01) return Math.PI; + if (Math.abs(rot - 1) < 0.01) return Math.PI; // 180° = -180°, same if (Math.abs(rot + 1) < 0.01) return Math.PI; - if (rot < -0.70 && rot > -0.8) return Math.PI / 2; - if (rot > 0.70 && rot < 0.8) return -Math.PI / 2; + if (rot < -0.70 && rot > -0.8) return -Math.PI / 2; // negated + if (rot > 0.70 && rot < 0.8) return Math.PI / 2; // negated return 0; }