refactor: 资源按 游戏/壁纸 分层,预设拆进各自壁纸目录
- assets/<游戏>/<壁纸>/{effects,images,audios}/,每档壁纸自包含
- 每档壁纸自带 preset.js:用 import.meta.url 推导自身资源路径,目录可整体搬走;
目录名用显示名(含「」),代码键用稳定 id(xilian/kv37,与 WE 属性值绑定)
- preset-store.js -> presets.js:静态 import 两份预设并建 id 索引
- 新增 CONTEXT.md 术语表与 ADR-0001/0002
- 新增 check-paths / compare / heatmap 三个验证工具;serve.mjs 改为每帧强制动画相位归零
验证:check-paths 11/11 路径存在(含此前零引用的 昔涟.flac);浏览器 0 个真实 404;
与基线 worktree 同冻结设置对拍,9 对跨版本比较中 4 对逐像素完全相同(差异 0),
其余 ≤0.19/255,远低于基线自身的双模态抖动(2.27/255)。
This commit is contained in:
1 parent
399f99edd7
commit
09ff322fe8
29 files changed
+388
-127
No files matched your search
@@ -0,0 +1,49 @@
|
||||
// 静态检查:每份 preset.js 里声明的每一个资源路径是否真实存在。
|
||||
// 这能抓到"运行时才会暴露"的拼写错误(比如某首备用 BGM 从未被加载过,写错了也不会有人发现)。
|
||||
// 用法:node tools/check-paths.mjs
|
||||
|
||||
import { stat } from "node:fs/promises";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { glob } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const root = resolve("dist");
|
||||
const presetFiles = [];
|
||||
for await (const f of glob("assets/**/preset.js", { cwd: root })) presetFiles.push(f);
|
||||
|
||||
let ok = 0;
|
||||
let bad = 0;
|
||||
|
||||
for (const rel of presetFiles.sort()) {
|
||||
const mod = await import(pathToFileURL(resolve(root, rel)).href);
|
||||
const preset = mod.default;
|
||||
const urls = [];
|
||||
const walk = (value, path) => {
|
||||
if (typeof value === "string" && /^(file|https?):/.test(value)) urls.push([path, value]);
|
||||
else if (value && typeof value === "object") {
|
||||
for (const [k, v] of Object.entries(value)) walk(v, `${path}.${k}`);
|
||||
} else if (Array.isArray(value)) value.forEach((v, i) => walk(v, `${path}[${i}]`));
|
||||
};
|
||||
walk(preset, preset.id);
|
||||
|
||||
console.log(`\n${rel} (id=${preset.id}, name=${preset.name})`);
|
||||
for (const [path, url] of urls) {
|
||||
const u = new URL(url);
|
||||
if (u.protocol !== "file:") {
|
||||
console.log(` ? ${path} -> 非本地路径,跳过: ${url}`);
|
||||
continue;
|
||||
}
|
||||
const file = fileURLToPath(u);
|
||||
const info = await stat(file).catch(() => null);
|
||||
if (info?.isFile()) {
|
||||
console.log(` ok ${path} (${(info.size / 1024).toFixed(1)} KB)`);
|
||||
ok++;
|
||||
} else {
|
||||
console.log(` MISSING ${path} -> ${file}`);
|
||||
bad++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n${ok} 个路径存在,${bad} 个缺失`);
|
||||
process.exit(bad ? 1 : 0);
|
||||
Reference in new issue
Block a user