From 1180d23728a51e1c70d7b9b10d818a1b9755c65c Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 16 Jul 2026 01:50:10 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=95=EC=88=98=ED=98=95=20UI=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=ED=91=9C=EA=B8=B0=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/integer-format.md | 18 ++++++++++++++++++ tools/deck/gen-slaydeck.mjs | 16 ++++++++++++++++ tools/verify/integer-format.mjs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 docs/integer-format.md create mode 100644 tools/verify/integer-format.mjs diff --git a/docs/integer-format.md b/docs/integer-format.md new file mode 100644 index 0000000..37f7a34 --- /dev/null +++ b/docs/integer-format.md @@ -0,0 +1,18 @@ +# Integer Formatting Rules + +MapleStory Worlds may serialize numeric properties as strings such as `1.0`. +This is valid numeric data, but it must never be used directly for UI entity +names or paths because `Card1.0` and `DmgPop_1.0` do not exist. + +- Use `self:IntStr(value)` for every numeric suffix in a UI path or entity name. +- Use `string.format("%d", math.floor(value or 0))` or `FormatNumber` for an + integer shown in UI text. +- Do not concatenate `tostring(number)` into a `/ui/...` path. +- `tools/deck/gen-slaydeck.mjs` normalizes exact integer strings such as `0.0` + to `0` when regenerating `Global/common.gamelogic`. + +Run this check after editing card-controller UI paths: + +```powershell +node tools/verify/integer-format.mjs +``` diff --git a/tools/deck/gen-slaydeck.mjs b/tools/deck/gen-slaydeck.mjs index 3c8cc28..dfc56d5 100644 --- a/tools/deck/gen-slaydeck.mjs +++ b/tools/deck/gen-slaydeck.mjs @@ -213,6 +213,21 @@ function writeCodeblocks() { writeFileSync('RootDesk/MyDesk/SlayDeckController.codeblock', JSON.stringify(combat, null, 2), 'utf8'); } +function normalizeIntegerStrings(value) { + if (Array.isArray(value)) { + for (let index = 0; index < value.length; index++) normalizeIntegerStrings(value[index]); + return; + } + if (value == null || typeof value !== 'object') return; + for (const [key, child] of Object.entries(value)) { + if (typeof child === 'string') { + value[key] = child.replace(/^(-?\d+)\.0+$/, '$1'); + } else { + normalizeIntegerStrings(child); + } + } +} + function patchCommon() { const common = JSON.parse(readFileSync(COMMON_FILE, 'utf8')); const entity = common.ContentProto.Entities.find((e) => e.path === '/common'); @@ -220,6 +235,7 @@ function patchCommon() { entity.jsonString['@components'] = [ { '@type': 'script.SlayDeckController', Enable: true, Energy: 0, MaxEnergy: 3, Turn: 0, TweenEventId: 0 }, ]; + normalizeIntegerStrings(common); JSON.parse(JSON.stringify(common)); writeFileSync(COMMON_FILE, JSON.stringify(common, null, 2), 'utf8'); } diff --git a/tools/verify/integer-format.mjs b/tools/verify/integer-format.mjs new file mode 100644 index 0000000..5e99fc5 --- /dev/null +++ b/tools/verify/integer-format.mjs @@ -0,0 +1,31 @@ +import { readFileSync, readdirSync } from 'node:fs'; +import { join } from 'node:path'; + +const cbDir = 'tools/deck/cb'; +const files = readdirSync(cbDir).filter((name) => name.endsWith('.mjs')); +const violations = []; + +for (const file of files) { + const source = readFileSync(join(cbDir, file), 'utf8'); + const matches = source.match(/["']\/ui\/[^"']*["']\s*\.\.\s*tostring\(/g) || []; + for (const match of matches) violations.push(`${file}: ${match}`); +} + +const generator = readFileSync('tools/deck/gen-slaydeck.mjs', 'utf8'); +if (!generator.includes('normalizeIntegerStrings(common)')) { + violations.push('gen-slaydeck.mjs: common.gamelogic integer-string normalization is missing'); +} + +const common = readFileSync('Global/common.gamelogic', 'utf8'); +const commonIntegerDecimals = common.match(/(? 0) { + violations.push(`Global/common.gamelogic: integer decimal values ${commonIntegerDecimals.length}`); +} + +if (violations.length > 0) { + console.error('UI path integer formatting violations:'); + for (const violation of violations) console.error(`- ${violation}`); + process.exit(1); +} + +console.log(`integer format: UI path tostring violations 0, common integer decimals 0 (${files.length} modules checked)`);