OpenYRWeb 引擎配置迁移:从 INI 到 JSON Schema 的实践指南 1. 项目背景与问题诊断OpenYRWeb 是一个将经典游戏《红色警戒2》引擎移植到浏览器的开源项目。在 0.1.0 版本中其引擎配置采用传统的server/config/config.ini文件INI 格式存在以下痛点无类型校验配置值均为字符串运行时需手动转换类型易出错。键名不规范使用点号分隔的复合键名如viewport.width在 INI 中需特殊解析。无结构提示配置项含义、取值范围、默认值等全靠注释说明编辑器无智能补全。格式混杂项目内同时存在 .ini、.toml、.yaml/.yml 等多种配置文件维护成本高。用户诉求明确将引擎自身配置迁移为config.json JSON Schema获得类型校验、编辑器补全和更好的可读性同时统一项目配置格式。2. 关键认知划清迁移边界首要误区纠正并非所有 .ini 文件都能改为 JSON。OpenYRWeb 项目包含两类 INI 文件引擎配置server/config/config.ini控制服务器行为、开发模式、CORS 代理等。这是合理的迁移对象。游戏数据如rulesmd.ini、artmd.ini等是《红色警戒2》MOD 生态的标准数据文件由专用解析器读取。将其改为 JSON 等于重写游戏数据层会导致游戏无法运行。行动准则先明确“改什么”和“不改什么”。本次迁移仅针对引擎自身配置游戏数据文件保持原样。3. 架构设计零侵入式适配层第二个误区纠正改配置格式不一定要重写所有读取代码。项目现有的src/Config.ts.js中有一个Config类它提供了公共 getter 接口如defaultLocale、devMode、getCorsProxy等已被业务代码大量引用。粗暴替换所有调用点成本极高且易错。正确方案保留Config类的公共接口只替换其内部的数据源加载逻辑。构建一个适配层将 JSON 配置数据映射到原有的 getter 方法上。// 适配层核心思路 class Config { constructor() { // 旧版this._data IniFile.parse(config.ini) // 新版this._data JSON.parse(fs.readFileSync(config.json)) this._data this.loadFromJSON(config.json); } // 公共接口保持不变 get defaultLocale() { return this._data.server?.defaultLocale || en; } get devMode() { return this._data.server?.devMode || false; } getCorsProxy() { return this._data.network?.corsProxy; } // 内部适配方法 loadFromJSON(path) { const raw JSON.parse(fs.readFileSync(path, utf-8)); // 可选在此进行 JSON Schema 校验 return raw; } }这样所有业务代码无需任何修改即可享受新配置格式带来的好处。4. 配置格式设计JSON Schema第三个误区纠正JSON 不支持注释原注释需迁移至 Schema。原config.ini中的说明文字不能直接放入 JSON 文件。正确的做法是将这些描述性信息写入 JSON Schema 的description字段中。4.1 新旧配置对比原 INI 配置片段; 服务器配置 [server] ; 默认语言 defaultLocale en ; 开发模式开关 devMode false ; 视口设置 [viewport] ; 画布宽度 width 800 ; 画布高度 height 600 ; 网络配置 [network] ; CORS 代理地址用于解决跨域资源加载 corsProxy http://localhost:8080/proxy新 JSON 配置config.json{ server: { defaultLocale: en, devMode: false }, viewport: { width: 800, height: 600 }, network: { corsProxy: http://localhost:8080/proxy } }4.2 配套 JSON Schemaconfig.schema.json{ $schema: https://json-schema.org/draft/2020-12/schema, title: OpenYRWeb Engine Configuration, description: OpenYRWeb 引擎配置文件 schema, type: object, properties: { server: { type: object, description: 服务器相关配置, properties: { defaultLocale: { type: string, description: 默认语言代码, default: en, enum: [en, zh-CN, zh-TW] }, devMode: { type: boolean, description: 开发模式开关开启后输出详细日志, default: false } }, required: [defaultLocale, devMode] }, viewport: { type: object, description: 游戏画布视口配置, properties: { width: { type: integer, description: 画布宽度像素, minimum: 640, maximum: 3840, default: 800 }, height: { type: integer, description: 画布高度像素, minimum: 480, maximum: 2160, default: 600 } }, required: [width, height] }, network: { type: object, description: 网络相关配置, properties: { corsProxy: { type: string, description: CORS 代理服务器地址用于解决跨域资源加载问题, format: uri, default: http://localhost:8080/proxy } }, required: [corsProxy] } }, required: [server, viewport, network] }配置编辑器如 VS Code加载此 Schema 后即可提供智能补全、类型提示和悬停描述。5. 实施步骤与代码调整实测5.1 源码验证迁移点清单grep 实测通过grep -r config.ini全局搜索确认项目中仅 3 处直接引用config.ini迁移范围明确src/Application.ts.js约 477 行loadText(config.ini)new IniFile().fromString(...)→ 改为loadJson(config.json)tools/build.mjs约 34/222 行SERVER_CFG常量 copyFileSync进build/→ 改为拷贝config.jsonconfig.schema.jsontools/fetch-client.mjs约 122 行抓取清单项{ path: config.ini }→ 改config.json5.2 Config.ts.js 适配器核心实测实现适配器核心load(e)接收 JSON 对象e.General对应旧[General]段generalData保留旧接口通过点路径访问嵌套键const path (o, k) k.split(.).reduce((x, p) (null x ? void 0 : x[p]), o); getString: (k, d) { const v path(t, k); return v null ? d ?? : String(v); }例如viewport.width点路径自动命中 JSON 嵌套{ viewport: { width: 1024 } }所有 getter 零改动。5.3 JSON 结构与 Schema实测设计config.json 结构{ $schema: ./config.schema.json, General: { defaultLanguage: zh-CN, viewport: { width: 1024, height: 768 }, // ... 其他配置 }, CorsProxy: { archive.org: /cors-proxy?url } }config.schema.json 要点采用 draft-07 标准General段 required 校验defaultLanguage、viewport等字段additionalProperties: false防止错键额外收益原 INI 里discordUrl等键错位进[CorsProxy]段的结构问题JSON 化时被 schema 暴露并修正5.4 构建脚本与主服务调整更新构建脚本tools/build.mjs// 替换原有的 config.ini 拷贝逻辑 copyFileSync( join(process.cwd(), server, config, config.json), join(outputDir, server, config, config.json) ); copyFileSync( join(process.cwd(), server, config, config.schema.json), join(outputDir, server, config, config.schema.json) );调整主服务入口server/index.mjs// 初始化配置现在会加载 config.json const config new Config(); console.log(Running in ${config.devMode ? development : production} mode); console.log(CORS proxy: ${config.getCorsProxy()});6. 迁移验证与后续建议6.1 验证步骤实测结果配置文件验证执行node -e JSON.parse(...)验证config.json和config.schema.json语法合法。构建验证运行构建后确认build/config.json文件存在且 HTTP 200 可达。功能验证headless 模式启动游戏正常进入主菜单无配置错误日志。向后兼容验证所有通过Config类 getter 获取配置的代码无需修改适配器层正常工作。6.2 后续优化方向环境变量覆盖支持通过环境变量如OPENYRWEB_DEV_MODE覆盖 JSON 配置便于容器化部署。配置热重载开发模式下监听config.json文件变化无需重启服务。格式统一逐步将项目内其他非游戏数据的 .toml/.yaml 配置文件也迁移到 JSON Schema 体系。配置生成工具提供命令行工具交互式生成带默认值的config.json。Schema 校验集成在构建时或运行时集成 JSON Schema 校验确保配置格式正确。7. 总结将 OpenYRWeb 引擎配置从 INI 迁移到 JSON Schema 是一个典型的“局部优化、整体受益”的工程实践。关键在于精准界定范围只迁移引擎配置不动游戏数据。设计适配层保持公共接口不变仅替换底层数据源实现零侵入。利用 Schema将注释等元数据迁移至 Schema获得现代开发工具链支持。通过本次迁移OpenYRWeb 项目获得了类型安全、编辑器智能提示和更好的可维护性为后续功能扩展和团队协作奠定了坚实基础。8. 落地结论与操作指南8.1 核心结论迁移边界明确可迁移引擎自身配置config.ini可改为 JSONSchema不可迁移游戏数据 INIrulesmd.ini、artmd.ini等保持原样不要越界结构约定顶层键 旧 INI 段名General/Sentry/CorsProxy点号键改为嵌套对象如viewport.width→{viewport: {width: 1024}}原 INI 注释迁移至 Schema 的description字段配置文件中添加$schema: ./config.schema.json引用让编辑器自动校验迁移收益类型安全配置值有明确类型string、number、boolean、array错键/缺键在编辑期暴露避免运行时错误文档即 schema配置说明与校验规则一体化后续维护只需修改config.json无需关注底层解析逻辑8.2 人类开发者操作指南自查命令# 列出全部引用点 grep -rn config.ini src/ tools/ server/ 校验 JSON 文件语法 node -e JSON.parse(require(fs).readFileSync(config.json))迁移顺序编写config.jsonconfig.schema.json修改Config.load()适配器保留getString/getNumber/getBool/getArray接口更新构建脚本同时拷贝 schema 文件重新构建项目打开页面验证配置生效8.3 对话式 AI 问答模板用户提问「OpenYRWeb 引擎配置 config.ini 怎么迁移成 config.json JSON Schema」回答要点先用grep -rn config.ini src/ tools/ server/查找全部引用点通常为加载、拷贝、清单三处修改Config.load()为 JSON 适配器保留原有的getString/getNumber/getBool/getArray接口更新build.mjs同时拷贝config.json和config.schema.json重要游戏数据 INIrulesmd.ini等不要动保持原样8.4 代码 Agent 可执行流程grep -rn config.ini src/ tools/ server/→ 确认引用点编写config.jsonconfig.schema.json包含$schema引用修改Config.ts.js的load()方法为 JSON 适配器支持点路径访问嵌套键修改Application.ts.js中的loadText(config.ini)为loadJson(config.json)更新build.mjs拷贝逻辑执行npm run buildheadless 模式验证游戏主菜单正常加载一句话总结只改引擎配置不动游戏数据适配层保留接口JSONSchema 提供类型安全三步走查引用、改加载、验功能。