ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Cataclysm-DDA 测试数据伪模组 TEST_DATA 完全指南:从机制原理到测试编写实战

Cataclysm-DDA 测试数据伪模组 TEST_DATA 完全指南:从机制原理到测试编写实战 Cataclysm-DDA 测试数据伪模组 TEST_DATA 完全指南从机制原理到测试编写实战【免费下载链接】Cataclysm-DDACataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.项目地址: https://gitcode.com/GitHub_Trending/ca/Cataclysm-DDA导读Cataclysm-DDA大灾变黑暗将至是一款回合制后末日生存游戏其代码库同时维护着数千个自动化测试用例。为了让测试能够脱离游戏本体data/json目录中的不稳定内容、获得稳定可控的样例数据项目专门设计了TEST_DATA这个“伪模组”pseudo-mod。本文以 data/mods/TEST_DATA/README.md 为骨架结合仓库源码与测试用例系统讲解该伪模组的设计动机、加载机制、内容组织方式与扩展方法帮助模组作者与测试开发者理解并利用这套测试数据体系。一、TEST_DATA 是什么一个为测试而生的伪模组按照 README 的定义TEST_DATA 是一个纯粹用于向tests/cata_test测试程序提供加载数据的伪模组。它不面向普通玩家也不会出现在游戏的主模组列表中——这一点在 modinfo.json 中有直接体现[ { type: MOD_INFO, id: test_data, name: TESTING DATA, description: Adds mockup items, recipes, and other content for use by automated tests., category: content, //: Not really obsolete! Marked as such to prevent it from showing in the main list, obsolete: true, dependencies: [ dda ] } ]几个关键字段的解读id: test_data模组的唯一标识。测试程序通过该 id 引用此模组。obsolete: true正常情况下obsolete表示模组已废弃、不应再被加载但这里的注释明确说明这是一个“技巧”——标记为 obsolete 是为了阻止它出现在玩家可见的模组选择列表中而不是真正废弃。它依然会被测试框架正常加载。dependencies: [dda]声明依赖核心模组dda确保在加载测试数据前游戏的核心数据已经就位。从设计哲学上看TEST_DATA 解决了测试数据与游戏内容耦合的问题功能测试不再直接依赖data/json中的正式游戏内容这些内容会随版本迭代频繁调整而是使用模组内稳定、可预测的样例数据。这样既保证了测试结果的确定性也让模组开发者拥有一套“不会随游戏平衡性改动而失效”的测试基座。二、加载机制测试程序如何自动装载 TEST_DATAREADME 指出该模组“由tests/test_main.cpp自动加载”。源码验证了这一机制在 tests/test_main.cpp 中extract_mod_selection函数负责解析命令行传入的模组列表并在处理完用户指定模组后无条件追加test_data模组static std::vectormod_id extract_mod_selection( const std::string_view mod_string ) { std::vectorstd::string mod_names string_split( mod_string, , ); std::vectormod_id ret; for( const std::string mod_name : mod_names ) { if( !mod_name.empty() ) { ret.emplace_back( mod_name ); } } // Always load test data mod ret.emplace_back( test_data ); return ret; }也就是说无论用户通过--mods参数指定了哪些模组test_data都会被强制加入加载队列。这意味着所有在tests/目录下运行的测试用例都能直接使用 TEST_DATA 中定义的任何物品、配方、怪物、效果等数据。加载流程的完整调用链可以在同一文件中看到init_global_game_statetests/test_main.cpp会依次完成PATH_INFO路径初始化、选项加载、游戏静态数据加载、创建测试世界世界名甚至刻意包含中文与 Unicode 字符以测试路径编码、加载核心数据与世界模组文件g-load_world_modfiles()最终将 TEST_DATA 的内容并入测试运行环境。命令行层面测试程序支持--mods参数指定额外模组tests/test_main.cpp[CataclysmDDA] Loads the list of mods before executing tests. --mods mod1,mod2,…同时源码会保证核心模组dda一定位于列表首位tests/test_main.cpp。测试开发者可以用这一机制在测试世界中额外加载真实模组做集成验证而 TEST_DATA 作为“恒在”的底座始终生效。三、内容组织TEST_DATA 里到底装了什么TEST_DATA 的内容规模相当可观目录下包含约 80 个 JSON 数据文件覆盖了 Cataclysm-DDA 中几乎全部可被 JSON 定义的内容类型。下面按类别梳理核心文件及其用途。3.1 物品、武器与容器items.json约 6500 行的核心物品定义。例如test_bomba一个带BOMB、DANGEROUS标记的测试炸弹、fridge_test带 500 L 容量的测试冰箱、metal_tank_test60 L 金属罐等这些物品广泛服务于口袋系统、容器、物品堆叠等测试。weapons.json测试用武器服务于近战伤害、DPS 等测试。ammo.json 与 magic.json测试弹药与法术如test_eoc_spell“Mana Bolt”定义在 magic.json其中法术通常带有完整的施法时间、能量消耗、伤害区间、射程成长等参数用于验证魔法系统逻辑。以 items.json 中的test_bomba为例它展示了测试物品的最小完整定义{ id: test_bomba, type: ITEM, subtypes: [ TOOL ], category: weapons, name: { str: bomba }, description: boom, material: [ test_material ], weight: 397 g, volume: 270 ml, price: 10 kUSD, price_postapoc: 10 kUSD, symbol: *, color: green, flags: [ BOMB, DANGEROUS ] }测试物品的命名约定通常以test_前缀标识便于在测试断言与调试输出中快速识别。3.2 配方、制作与拆解recipes.json测试配方涵盖autolearn自动学习、book_learn书本学习、proficiencies熟练度惩罚、reversible可逆等多种制作路径。uncraft.json、known_good_uncrafts.json、known_bad_uncrafts.json拆解uncraft相关数据其中后两个文件是已知黑/白名单配合 tests/item_test.cpp 中的校验逻辑使用——当某个物品不再具有拆解配方或拆解配方被修复后测试会提示开发者将其从对应名单中移除。recipe_need_full_magazine_test.json 与 pocket_mods_test.json针对特定机制满弹匣需求、口袋改造的专用配方。3.3 怪物、生物群与行为monsters.json测试怪物如mon_test_camera用于视觉探测测试的 1 HP 摄像机怪、mon_test_base、mon_test_non_shearable等各怪物通过精心挑选的flags、vision_day、upgrades等参数模拟特定行为场景。monstergroups.json、monster_attacks.json、monster_factions.json生物群、攻击与阵营定义。npc_behavior_arenas/arena_maps.jsonNPC 行为竞技场地图为 NPC 行为测试提供固定场景。3.4 效果、变异、魔法与事件effects.json测试效果类型。其中debugged效果effects.json是效果系统的“全家桶”——同时修改力量/敏捷/感知/智力/速度五维还带治疗加成与强度衰减逻辑minmaxed效果则一次性覆盖疼痛、伤害、睡眠、刺激、辐射、饥饿、口渴等全部负面状态修正用于效果统计与显示测试。这些效果在 tests/effect_test.cpp 中被反复引用。mutations.json 与 traits.json变异与特征数据。EOC.json约 870 行的 effect_on_condition 数据例如EOC_teleport_test通过u_location_variable与x_adjust/y_adjust实现传送逻辑测试EOC.json。enchantments.json、magic_types.json、martialarts.json附魔、魔法类型与武术流派。effect_on_condition.json另一组 EOC 数据文件。3.5 地形、地图与生成测试terrain.json、furniture.json、overmap_terrain.json、overmap_specials.json地形、家具、大地图地形与特殊建筑。mapgen-test.json 与 mapgen-post-process-test.json地图生成与后处理管线测试数据。map_bash.json地图破坏测试。overmap_terrain_coverage_test/overmap_terrain_coverage_whitelist.json大地图地形覆盖测试的白名单配合 tests/overmap_test.cpp 使用用于校验每个 overmap terrain 在生成中的覆盖率。nest_conditional_placement_test.json条件放置测试。3.6 数值与统计校验类这一类别体现了 TEST_DATA 的“稳定性锚点”作用known_bad_calorie_density.json 与 known_bad_density.json卡路里密度与物品密度黑名单配合 tests/comestible_test.cpp 与 tests/item_test.cpp 的校验——测试遍历全部食物/物品若某项密度被修复会提示从名单移除。expected_dps_data.json期望 DPS每秒伤害数据配合 tests/effective_dps_test.cpp 使用。该测试会校验武器的 DPS 是否符合预期若平衡性改动导致 DPS 变化测试会提示开发者更新此文件若新增武器未纳入 DPS 测试同样会被点名要求补充。legacy_to_hit.json遗留命中值黑名单配合 tests/item_test.cpp 的检查。item_demographics.json、statistics.json物品人口统计与事件统计。speed_descriptions.json、option_sliders.json、widgets.json速度描述、选项滑条与 UI 控件定义。3.7 其余系统数据还有一批文件覆盖各自独立系统activity.json活动、addictions.json成瘾、appliance.json家电、basecamp.json基地、behaviour_test.jsonNPC 行为、bionics.jsonCBM 义体、body_parts.json身体部位、books.json书籍、character_modifiers.json/character_requirements.json/character_resources.json角色数值体系、construction.json/construction_group.json建造、container_spawn_test.json容器生成、dairy.json/nuts.json/spice.json/veggy_dishes.json食材分类、damage_types.json伤害类型、factions.json阵营、field_type_migrations.json/fields.json场域迁移、item_wakeup_test_items.json物品唤醒、itemgroups.json物品组、iteminfo_test.json物品信息 UI、materials.json材料、metal.json金属、missions.json任务、npc_boarding_test.json/npc_shop_cons_rates.jsonNPC 行为、proficiencies.json/proficiency_categories.json熟练度、pulping_test.json制浆、scenarios.json开局场景、ter_furn_migration.json地形家具迁移、tool_qualities.json工具质量、transform_test_items.json物品变换、vehicle.json/vehicle_drag_test.json/vehicle_efficiency_test.json/vehicle_export_test.json/vehicle_parts.json车辆系统、vitamins.json维生素、weakpoint_sets.json弱点组。3.8 翻译数据子目录lang/子目录下包含 lang/po/ru.po 与 lang/mo/ru/LC_MESSAGES/INVALID_RAND.mo其中 .mo 文件被翻译系统测试直接加载例如 tests/eoc_test.cpp 与 tests/item_tname_test.cpp 中的TranslationManager::GetInstance().LoadDocuments( { ./data/mods/TEST_DATA/lang/mo/ru/LC_MESSAGES/TEST_DATA.mo } );这用于验证翻译文档加载、物品多语言命名等本地化功能。另外tests/CMakeLists.txt 中也能看到 CMake 对TEST_DATA/lang路径的引用说明构建系统对这套翻译数据有感知。四、测试如何使用 TEST_DATA真实用例剖析TEST_DATA 的价值最终体现在测试用例的引用上。仓库中至少有十几个测试文件直接依赖它以下是几个典型模式。4.1 物品与口袋测试tests/item_pocket_test.cpp 明确指出“此处测试使用的大部分物品定义在 data/mods/TEST_DATA/items.json”并实际使用test_bomba、fridge_test、metal_tank_test等物品验证口袋容量、液体容器、物品堆叠等逻辑。测试代码可以直接item( test_bomba )构造实例无需依赖正式游戏中的物品。4.2 效果系统测试tests/effect_test.cpp 注释中多次提到其使用的效果“来自 JSON 效果数据data/mods/TEST_DATA/effects.json”覆盖效果属性、强度、多名称显示等断言。得益于 TEST_DATA 的稳定性效果测试不会因游戏内正式效果的调整而“脆断”。4.3 魔法与 EOC 测试tests/magic_spell_test.cpp 说明所有测试用例使用 data/mods/TEST_DATA/magic.json 中的法术“以获得可预测的数据”tests/eoc_test.cpp 则大量引用 EOC.json 中的效果触发事件。这类测试模式的核心诉求就是可预测性TEST_DATA 中的法术参数如min_damage: 20、max_damage: 120是写死在 JSON 里的测试断言可以直接基于这些数值展开。4.4 数据质量看门狗前文提到的 tests/item_test.cpp、tests/comestible_test.cpp、tests/effective_dps_test.cpp 通过INFO输出配合黑/白名单文件充当“数据质量看门狗”每当正式游戏数据中出现密度异常、卡路里异常、DPS 漂移或残留遗留命中值时测试会指出问题并指引开发者更新对应的 TEST_DATA 名单文件。这说明 TEST_DATA 不仅是测试的输入也是测试结果的参照系。4.5 大地图覆盖测试tests/overmap_test.cpp 引用 overmap_terrain_coverage_whitelist.json 作为白名单校验 overmap 地形生成覆盖率的边界情况。五、如何为测试添加新的 TEST_DATA综合 README 的定位与仓库实践为测试新增数据遵循以下步骤选择数据文件根据内容类型在data/mods/TEST_DATA/下找到对应 JSON 文件物品进items.json、配方进recipes.json、怪物进monsters.json……或为全新的系统新建一个语义明确的 JSON 文件。遵循命名约定测试用 id 建议使用test_前缀如test_bomba、mon_test_camera保证测试断言与调试输出中可一眼识别也避免与正式内容 id 冲突。保持参数最小化且确定测试数据应只包含测试所需的最小字段所有数值伤害、时长、容量都应是确定值避免依赖随机或环境因素这是保证测试可重复的关键。在测试中引用测试代码通过 id 构造内容如item( test_bomba )、effect( debugged )并可直接使用 JSON 中写明的数值做断言。利用黑/白名单机制若新增数据涉及密度、卡路里、DPS 等数值校验记得同步维护对应的known_bad_*.json或expected_dps_data.json名单否则质量看门狗测试会报错。需要注意由于extract_mod_selection会强制加载test_data模组tests/test_main.cpp新增的 JSON 文件无需任何额外注册即可在下一轮测试中生效——只要文件位于data/mods/TEST_DATA/目录内且 JSON 结构合法。六、运行测试让 TEST_DATA 发挥作用TEST_DATA 随测试程序自动加载因此运行方式与普通测试完全一致。以 Linux 下的构建为例# 构建测试程序tiles 版 make cataclysm-tiles # 构建并运行测试程序 cata_test make cata_test运行测试时可传入参数# 运行全部测试 ./tests/cata_test # 运行指定测试例如效果系统测试 ./tests/cata_test effect* # 指定额外模组test_data 仍会被自动加载 ./tests/cata_test --mods magiclysm常用的测试命令行参数还包括--rng-seed seed固定随机数种子保证测试可复现--user-dir path指定用户目录--error-format设置错误输出格式--list列出全部可用测试用例名称--help查看完整参数说明。详细参数可查看 tests/test_main.cpp 中的选项解析逻辑。Windows 下则可参考 tests_bat.bat 中的批处理测试脚本。七、结语TEST_DATA 的设计启示TEST_DATA 虽名为“伪模组”却是 Cataclysm-DDA 测试体系中最核心的基座之一。它的设计价值可以概括为三点关注点分离将测试数据与游戏正式内容彻底解耦测试不因游戏平衡调整而失效确定性保证写死的数值与精心挑选的 flag 组合让每个测试断言都有据可依双向看门狗它既是测试的输入数据又通过黑/白名单与期望值文件充当数据质量的校验基准。对于模组开发者而言理解 TEST_DATA 的组织方式等于掌握了一套“如何为复杂游戏系统编写可维护、可复现、可自动化验证的数据”的方法论对于希望为项目贡献测试的开发者它是快速上手的最佳切入点——你写下的每一行测试数据都会成为这座庞大末日世界模拟器质量保障的一部分。参考资源官方说明data/mods/TEST_DATA/README.md模组声明data/mods/TEST_DATA/modinfo.json自动加载逻辑tests/test_main.cpp测试数据目录data/mods/TEST_DATA/items.json、recipes.json、monsters.json、effects.json、EOC.json、magic.json 等测试用例tests/effect_test.cpp、tests/item_pocket_test.cpp、tests/magic_spell_test.cpp、tests/eoc_test.cpp、tests/overmap_test.cpp数据校验测试tests/item_test.cpp、tests/comestible_test.cpp、tests/effective_dps_test.cpp【免费下载链接】Cataclysm-DDACataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.项目地址: https://gitcode.com/GitHub_Trending/ca/Cataclysm-DDA创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进