VCMI 模组文件格式(mod.json)完全指南:字段详解、内容声明与仓库发布

发布时间:2026/10/12 3:20:29
VCMI 模组文件格式(mod.json)完全指南:字段详解、内容声明与仓库发布 游戏开发【免费下载链接】vcmiOpen-source engine for Heroes of Might and Magic III项目地址https://gitcode.com/gh_mirrors/vc/vcmi点击查看免费下载VCMI 是《英雄无敌 III》的开源引擎重制版其强大的模组系统允许玩家与开发者通过纯 JSON 配置扩展生物、英雄、城镇、魔法、地图对象乃至游戏规则本身。每个模组的入口都是一个名为mod.json的描述文件它既是模组的身份证也是引擎加载模组内容的目录。本文以 VCMI 官方文档 docs/modders/Mod_File_Format.md 为主体结合仓库中的 JSON Schemaconfig/schemas/mod.json与引擎源码lib/modding/ModDescription.cpp、lib/modding/ModManager.cpp完整讲解 mod.json 的每一个字段并给出可直接套用的完整示例。读完本文你将掌握如何编写一份合法的 mod.json 元信息如何声明模组内容与游戏设置如何实现多语言翻译以及如何通过仓库字段让模组进入 VCMI Launcher 的在线列表。一、mod.json 的角色与目录结构在开始写字段之前先明确 mod.json 在整个模组体系中的位置。根据 docs/modders/Readme.md创建一个模组需要在数据目录的Mods/下建立一个子目录目录名即模组标识符例如Mods/myMod/在模组主目录中放置mod.json所有内容放入Content/子目录也可以用一个.zip压缩包整体替代该目录。一个典型的模组目录结构如下Mods/ myMod/ mod.json Content/ config/ - json 配置文件 data/ - 散装文件主要是位图.bmp、.png、.pcx maps/ - 模组新增或修改的 h3m 地图 music/ - 音乐文件支持 Mp3 与 ogg/vorbis sounds/ - 音效文件wav 格式 sprites/ - 动画与图集H3 的 .def 文件或 VCMI 的 .json 文件 video/ - 视频文件.bik、.smk、.ogv、.webm引擎侧通过ModManager的getModDefinitionFile见 lib/modding/ModManager.cpp按Mods/模组ID/mod路径定位 mod.json再由ModDescription类解析其中的字段。值得注意的是mod.json 中的元信息字段name、version、author等是模组校验和的一部分任何修改都会改变模组指纹见 lib/modding/ContentTypeHandler.cpp。二、模组描述字段元信息以下字段描述这个模组是什么。全部字段都可以出现在 mod.json 中其中name、modType、version、author是 Schema 强制要求的必填项见 config/schemas/mod.json。2.1 基础身份字段{ // 模组名称。没有硬性长度限制但建议不超过 ~30 个字符 // 以便在 Launcher 的有限空间内完整显示 name : My test mod, // 较长的模组描述无长度限制会显示在 Launcher 中。 // 该字段使用 .mdMarkdown格式。 // 对主模组main mods而言更推荐使用独立的 description.md 文件详见下文 description : My test mod that add a lot of useless stuff into the game, // 作者可以是昵称、真名或团队名称 author : Anonymous, // 模组使用的许可证全名。仅当你是模组作者、 // 或已获得原作者授权使用该许可证时才应填写 licenseName : Creative Commons Attribution-ShareAlike, // 用户可以查看许可证条款与全文的 URL licenseURL : https://creativecommons.org/licenses/by-sa/4.0/, // 模组主页或论坛帖链接供玩家联系作者 contact : http://example.com, // 模组当前版本最多 3 段数字、点号分隔格式 A.B.C version : 1.2.3 }仓库中的官方示例 Mods/vcmi/mod.json 就使用了这套字段name为 VCMI essential filesversion为 1.5author为 VCMI Teamcontact指向 VCMI 官方论坛。从源码实现看ModDescription::getVersion()通过CModVersion::fromString()解析版本号引擎用它做版本比较与更新检测isUpdateAvailable()会比较本地与仓库版本见 lib/modding/ModDescription.cpp。2.2 模组类型 modTypemodType决定模组的分类Schema 中给出了完整的枚举见 config/schemas/mod.jsonTranslation, Town, Test, Templates, Spells, Music, Maps, Sounds, Skills, Other, Objects, Mechanics, Interface, Heroes, Graphical, Expansion, Creatures, Compatibility, Campaigns, Artifacts, AI, Resources, Demo其中部分类型会带来额外的运行时行为这是最容易踩坑的地方Translation翻译模组此类模组仅在玩家使用该模组的基础语言见下方language字段时才会生效。此外如果子模组submod声明了 Translation 类型它会被隐藏在 UI 中并自动在玩家使用模组基础语言时激活——这为模组提供了按语言提供本地化资源的能力。Compatibility兼容性模组此类模组同样隐藏在 UI 中并且当它的全部依赖模组都处于激活状态时会被自动激活。它的设计用途是在模组之间提供兼容性补丁。这些行为在引擎源码中均有对应实现ModDescription提供了isTranslation()、isCompatibility()、isDemoSupport()三个判定方法见 lib/modding/ModDescription.cpp而依赖解析器在判定模组可用性时会专门检查Translation 模组的基础语言是否与当前首选语言一致见 lib/modding/ModManager.cpp// Mod is resolved if it has no dependencies or all its dependencies are already resolved auto isResolved - ModResolveStatus { if (mod.isTranslation() CGeneralTextHandler::getPreferredLanguage() ! mod.getBaseLanguage()) return ModResolveStatus::BROKEN; ... };即翻译模组只有在玩家首选语言与模组基础语言一致时才被视为可用否则会被标记为 BROKEN依赖解析失败。2.3 基础语言 language// 模组的基础语言指应用本地化之前的语言。默认情况下 VCMI 假定为英语。 // 该属性主要服务于翻译模组 language : englishlanguage的可选值即 VCMI 支持的 28 种语言标识见 config/schemas/mod.jsonbelarusian、bulgarian、czech、chinese、tchinese、dutch、english、filipino、finnish、french、german、greek、hungarian、italian、japanese、korean、latvian、lithuanian、norwegian、polish、portuguese、romanian、russian、serbian、spanish、swedish、turkish、ukrainian、vietnamese。源码中ModDescription::getBaseLanguage()的默认值正是english见 lib/modding/ModDescription.cpp与文档描述完全一致。2.4 依赖、软依赖与冲突// 运行本模组所必需的其他模组列表 depends : [ baseMod ], // 若下列模组处于启用状态则它们应在本模组之前加载 // 本模组将覆盖来自其软依赖模组的任何冲突项 softDepends : [ baseMod ], // 不能与本模组同时启用的模组列表 conflicts : [ badMod ]三者分别对应源码中ModDescription构造时解析的depends、softDepends、conflicts三个集合见 lib/modding/ModDescription.cpp。需要注意两个引擎自动补全的隐式依赖除core模组外所有模组都会被自动加入core依赖子模组ID 含.会自动依赖其父模组与顶级父模组getParentID()/getTopParentID()。另外loadModList()会把列表中的所有 ID 转为小写后存入集合因此依赖列表中大小写不敏感见 lib/modding/ModDescription.cpp。2.5 引擎版本兼容性 compatibility// 本模组支持的 vcmi 引擎版本范围 compatibility : { min : 1.2.0, max : 1.3.0 }min为最低兼容的引擎版本格式major.minor.patch指定后更早的引擎版本将不支持该模组max同理指定后更晚的引擎版本将不支持。引擎侧的ModDescription::isCompatible()实现如下见 lib/modding/ModDescription.cppbool ModDescription::isCompatible() const { const JsonNode compatibility getLocalValue(compatibility); if (compatibility.isNull()) return true; // 未声明 compatibility 视为兼容 auto vcmiCompatibleMin CModVersion::fromString(compatibility[min].String()); auto vcmiCompatibleMax CModVersion::fromString(compatibility[max].String()); bool compatible true; compatible (vcmiCompatibleMin.isNull() || CModVersion::GameVersion().compatible(vcmiCompatibleMin, true, true)); compatible (vcmiCompatibleMax.isNull() || vcmiCompatibleMax.compatible(CModVersion::GameVersion(), true, true)); return compatible; }也就是说未填写compatibility的模组默认与所有引擎版本兼容填写后引擎会与自身版本做双向比较不满足则模组无法启用。2.6 更新日志 changelog// 每个版本的变化/新特性列表 changelog : { 1.0 : [ initial release ], 1.0.1 : [ change 1, change 2 ], 1.1 : [ change 3, change 4 ] }键为版本号字符串值为该版本的变更说明字符串数组会展示在 Launcher 的模组详情中。2.7 安装后保持禁用 keepDisabled// 若为 true模组安装后不会被自动启用 keepDisabled : false对应源码ModDescription::keepDisabled()见 lib/modding/ModDescription.cpp。仓库中的真实用例是 Mods/roe-demo/mod.jsonRoE 演示版支持模组声明了keepDisabled : true因为它只对拥有 RoE 演示版数据的玩家有意义不应在安装后默认激活。2.8 游戏设置覆盖 settings// 模组修改的游戏设置列表。字段取值参考 VCMI 安装目录/config/gameConfig.json settings : { combat : { goodLuckDice : [] // 禁用幸运 } }settings允许模组直接修改游戏全局设置其取值结构对应 config/gameConfig.json 中的设置项。Schema 还允许它写成指向设置文件的路径数组形式见 config/schemas/mod.json。引擎在加载时遍历所有激活模组将它们的settings依次加载进设置处理器for(const TModID modName : getActiveMods()) { const auto mod getModInfo(modName); if (!mod.getLocalConfig()[settings].isNull()) LIBRARY-settingsHandler-loadBase(mod.getLocalConfig()[settings]); }见 lib/modding/CModHandler.cpp。Mods/roe-demo/mod.json 中还有一个完整的 settings 用例它通过textData : { faction : 8 }调整文本数据并通过mapFormat : { armageddonsBlade : { supported : false }, shadowOfDeath : { supported : false } }声明不支持末日之刃与死亡阴影地图格式——这正是用 settings 适配游戏行为的典型场景。三、模组内容声明字段本地 mod.json以下字段只存在于本地 mod.json 中用于声明模组携带的内容。它们的值可以是指向配置文件的路径数组也可以直接内嵌一个 JSON 对象做小规模改动。官方文档给出的完整骨架如下{ // 下面的区块描述模组新增内容的配置文件。 // 可以按任意方式拆分成多个文件但推荐的组织方式是 // 每个对象生物/英雄等一个文件。 // 或者对于小型改动可以直接把改动内嵌在这里例如 // creatures : { core:imp : { health : 5 }} // 城镇/阵营配置文件列表 factions : [ config/faction.json ], // 英雄职业配置文件列表 heroClasses : [ config/heroClasses.json ], // 英雄配置文件列表 heroes : [ config/heroes.json ], // 技能配置文件列表 skills : [ config/skills.json ], // h3c 战役的地区campaign regions配置文件列表 campaignRegions : [ config/campaignRegions.json ], // 生物配置文件列表 creatures : [ config/creatures.json ], // 宝物配置文件列表 artifacts : [ config/artifacts.json ], // 本模组定义的地图对象 objects : [ config/objects.json ], // 本模组定义的魔法 spells : [ config/spells.json ], // 地形配置文件列表 terrains : [ config/terrains.json ], // 道路配置文件列表 roads : [ config/roads.json ], // 河流配置文件列表 rivers : [ config/rivers.json ], // 战场配置文件列表 battlefields : [ config/battlefields.json ], // 战场障碍物配置文件列表 obstacles : [ config/obstacles.json ], // 地图图层配置文件列表 mapLayers : [ config/mapLayers.json ], // 本模组定义的随机地图模板RMG templates templates : [ config/templates.json ], // 可选主要用于翻译模组。 // 定义由模组翻译为基础语言language 字段指定的字符串 translations : [ config/englishStrings.json ] }注意Schema 中可声明的内容类型实际上比文档骨架更多还包括spellSchools魔法学派、scripts脚本、biomes生物群系、bonuses加成、resources资源等见 config/schemas/mod.json可根据模组需要选用。3.1 内容路径的解析规则内容文件路径相对于模组的Content/目录解析。以官方基础模组 Mods/vcmi/mod.json 为例它声明了factions : [ config/towerFactions ], creatures : [ config/towerCreature ], spells : [ config/spells ],这些路径即Mods/vcmi/Content/config/下的 JSON 文件实际文件不要求.json扩展名引擎按内容类型解析。Mods/roe-demo/mod.json 则展示了更复杂的组织方式——把factions、creatures、heroes、terrains、objects、spells、artifacts、heroClasses、battlefields、obstacles、biomes全部声明齐全每个类型按子目录再拆分文件objects : [ config/roe-demo/patched-objects/banks.json, config/roe-demo/patched-objects/dwellings.json ]3.2 内容类型与玩法影响引擎在判定一个模组是否影响玩法时会检查以下键是否存在见 lib/modding/ModDescription.cppstatic const std::array keysToTest { artifacts, battlefields, creatures, factions, heroClasses, heroes, objects, obstacles, mapLayers, rivers, roads, settings, skills, spells, terrains, };只要任一内容键非空affectsGameplay()即返回true模组会被标记为影响游戏玩法。这决定了模组在多人游戏/联机场景中的校验权重——ModVerificationInfo会携带impactsGameplay标志见 lib/modding/ModDescription.cpp。3.3 内嵌小改动与文件声明二选一Schema 的fileListOrObject定义见 config/schemas/mod.json表明内容字段的值既可以是路径数组也可以是内嵌对象。文档给出了内嵌方式的示例// 直接内嵌对核心生物 imp 的修改把生命值改为 5 creatures : { core:imp : { health : 5 } }这种形式适合小型改动大型内容则强烈建议拆分为独立文件每个对象一个文件便于维护与减少模组冲突。关于core:imp这类标识符的详细规则core:指 H3 原生对象、mod:object指其他模组的对象、mod.submod:object指子模组对象参见 docs/modders/Readme.md。四、多语言翻译字段除上述字段外可以为 VCMI 支持的任意语言添加一个同名的顶层区块。如果存在该区块Launcher 会用它显示翻译后的模组信息游戏则会用其中列出的 JSON 文件把模组翻译成指定语言。language : { name : translated name, description : translated description, author : translated author, translations : [ config/language.json ] }其中language是 VCMI 支持的语言标识同 2.3 节列表例如russian、polish、chinese。该区块支持的可选属性还包括changelog该语言的更新日志与skipValidation为true时跳过该语言翻译 JSON 文件的校验见 config/schemas/mod.json。仓库中的真实范例是 Mods/vcmi/mod.json 中密集的语言区块例如chinese : { skipValidation : true, translations : [ config/translations/chinese.json ] }同时它还在顶层声明了基础语言的翻译文件translations : [ config/translations/english.json ]引擎加载翻译的机制见 lib/modding/CModHandler.cpp会按模组基础语言与玩家首选语言两个维度分别加载翻译覆盖void CModHandler::loadTranslation(const TModID modName) { const JsonNode translations modContent.at(modName); LIBRARY-generaltexth-loadTranslationOverrides(modName, getModInfo(modName).getBaseLanguage(), translations[translations]); LIBRARY-generaltexth-loadTranslationOverrides(modName, LIBRARY-generaltexth-getPreferredLanguage(), translations[LIBRARY-generaltexth-getPreferredLanguage()][translations]); }在模组内容聚合阶段引擎还会并行组装基础语言翻译、首选语言翻译、回退翻译当首选语言 ≠ 基础语言时使用基础语言文件兜底三份数据见 lib/modding/CModHandler.cpp确保任何语言环境下都有可用的译文。翻译工作流的完整说明参见 docs/translators/Translations.md。五、模组仓库字段远程 repository以下字段只存在于远程仓库的模组描述中通常不会出现在本地 mod.json 里它们是 VCMI Launcher 在线安装模组的数据来源{ // 描述该模组的 mod.json 的 URL mod : https://raw.githubusercontent.com/vcmi-mods/vcmi-extras/vcmi-1.4/mod.json, // 玩家可以用来下载模组的 URL download : https://github.com/vcmi-mods/vcmi-extras/archive/refs/heads/vcmi-1.4.zip, // 下载包的近似大小单位兆字节 downloadSize : 4.496 }这三个字段分别对应ModDescription读取仓库配置时的getRepositoryValue()路径见 lib/modding/ModDescription.cpp。引擎侧ModsStorage在构造时会同时接收本地已安装模组列表与仓库列表两份数据用mergeModDescriptions等机制合并模组信息见 lib/modding/ModManager.h。downloadSize的 Schema 描述为按 zip 算法压缩后的近似体积单位 MB见 config/schemas/mod.json。说明本文中的 URL 仅为文档示例格式实际发布流程要求模组托管在 VCMI 官方模组组织vcmi-mods下的仓库中并向 vcmi-mods-repository 提交 PR详见 docs/modders/Readme.md。六、模组长描述description.md对于更长的模组描述文档推荐提供名为description.md的文件。该文件使用 Markdown 格式允许任意长度并支持多语言。详细约定见 docs/modders/Readme.md若mod.json与description.md同时提供了描述Markdown 版本优先并覆盖description.md中存在对应语言的那些语言不要把模组名称作为description.md的标题——Launcher 会自动把模组名附加在描述顶部大部分 Markdown 语法都可用但有两项限制顶级标题保留给翻译区块必须使用#(一个空格)(语言 ID)的形式如# english暂不支持内嵌图片新增description.md后由于每日自动更新机制玩家端最长可能需要一天后才在 Launcher 中看到新描述。description.md的预期格式# english (description in English) # polish (description in Polish) # czech (description in Czech)引擎解析该文件的方式与mergeModDescriptions一致按\n#切分段落用首行匹配语言 ID 并写入对应语言的description字段见 lib/modding/ModDescription.cpp。模组展示层的getLocalizedDescription()也遵循首选语言 → 英语 → 基础描述的回退顺序见 lib/modding/ModDescription.cpp。七、最小可用示例与验证7.1 最小化 mod.json根据 docs/modders/Readme.md一份最小的 mod.json 只需要四个必填字段name、modType、version、author其中文档示例省略了author但 Schema 将其列为必填{ name : My test mod, version : 1.00, modType : Graphical, author : Anonymous, contact : http://www.contact.example.com }7.2 完整示例含全部核心能力综合本文所有内容一个功能完整的 mod.json 可以是{ name : My test mod, description : My test mod that add a lot of useless stuff into the game, author : Anonymous, licenseName : Creative Commons Attribution-ShareAlike, licenseURL : https://creativecommons.org/licenses/by-sa/4.0/, contact : http://example.com, version : 1.2.3, modType : Creatures, language : english, depends : [ baseMod ], softDepends : [ baseMod ], conflicts : [ badMod ], compatibility : { min : 1.2.0, max : 1.3.0 }, changelog : { 1.0 : [ initial release ], 1.0.1 : [ change 1, change 2 ], 1.1 : [ change 3, change 4 ] }, keepDisabled : false, settings : { combat : { goodLuckDice : [] } }, factions : [ config/factions.json ], heroClasses : [ config/heroClasses.json ], heroes : [ config/heroes.json ], skills : [ config/skills.json ], campaignRegions : [ config/campaignRegions.json ], creatures : [ config/creatures.json ], artifacts : [ config/artifacts.json ], objects : [ config/objects.json ], spells : [ config/spells.json ], terrains : [ config/terrains.json ], roads : [ config/roads.json ], rivers : [ config/rivers.json ], battlefields: [ config/battlefields.json ], obstacles : [ config/obstacles.json ], mapLayers : [ config/mapLayers.json ], templates : [ config/templates.json ], translations: [ config/englishStrings.json ], polish : { name : Mój mod testowy, description : Mój mod testowy, który dodaje mnóstwo bezużytecznych rzeczy do gry, author : Anonim, translations : [ config/polish.json ] } }7.3 校验与排错Schema 校验VCMI 内置了 mod.json 的 JSON Schemaconfig/schemas/mod.json。模组加载时会先经过JsonUtils::validate(mod.getLocalConfig(), vcmi:mod, mod.getID())校验见 lib/modding/ContentTypeHandler.cpp非法字段或缺失必填字段会导致校验失败。由于 Schema 设置了additionalProperties : false拼写错误的字段名也会被直接拒绝这是最常见的新手错误。加载日志引擎在读取 mod.json 时若发现modType缺失会输出错误日志Can not load mod %s - invalid mod config file!并跳过该模组见 lib/modding/ModManager.cpp。依赖与启用状态模组启用状态由ModsPresetState持久化在用户配置目录的 settings 文件中并以 preset 形式管理见 lib/modding/ModManager.h。依赖解析失败含翻译语言不匹配、版本不兼容、冲突模组共存的模组会进入 broken 列表不会参与游戏加载。八、总结mod.json是 VCMI 模组的唯一入口一份合格的 mod.json 需要同时承担三重职责元信息通过name、description、author、licenseName、version、modType、language、contact等字段向 Launcher 描述模组身份依赖与兼容管理通过depends、softDepends、conflicts、compatibility、keepDisabled声明模组的加载关系与适用范围内容目录通过factions、creatures、heroes、spells、objects、artifacts、terrains、battlefields、templates等字段把Content/目录下的配置文件组织起来并可选地通过settings修改游戏全局设置、通过语言区块与translations提供多语言支持。对模组制作者而言最佳实践是内容尽量拆分为一个对象一个文件改动现有对象时只声明被修改的属性小型改动可内嵌对象形式翻译模组与兼容性模组务必正确设置modType以利用自动激活机制发布前对照 config/schemas/mod.json 逐项自检避免字段拼写错误导致的加载失败。赞分享游戏开发【免费下载链接】vcmiOpen-source engine for Heroes of Might and Magic III项目地址https://gitcode.com/gh_mirrors/vc/vcmi点击查看免费下载相关推荐VCMI Lua 脚本类型详解声明格式、公共字段、参数 Schema 与三大脚本接口的完整指南VCMI Lua 脚本类型详解声明格式、公共字段、参数 Schema 与三大脚本接口的完整指南 VCMI 的 Mod 系统通过 Lua 脚本扩展法术效果、战斗游戏开发Sapling/Mercurial Requires 文件机制详解仓库格式能力声明与兼容性控制Sapling/Mercurial Requires 文件机制详解仓库格式能力声明与兼容性控制 导读 requires 文件是存储在仓库内部的元数据文件用于开发工具CLI后端ComfyUI-Manager组件JSON格式详解结构与字段说明ComfyUI Manager组件JSON格式详解结构与字段说明 在使用ComfyUI Manager进行组件共享时正确理解和使用JSON格式是关键。本文将人工智能AI 应用插件系统上一篇tldr 仓库实战解析GNU tail 命令从文件尾部查看到实时日志跟踪的完整指南下一篇零基础快速上手qStudio免费SQL数据分析工具完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考