为什么要把数据从代码里拆出来
个人游戏早期直接在代码里写伤害、价格、冷却、敌人血量很快。但 Steam Demo 前后,数值会频繁调整:玩家觉得第一章太难,某个武器太强,商店价格不合理,Boss 血量拖节奏。如果每次调参都要改代码、重新编译、担心误改逻辑,迭代会非常慢。
数据驱动的目的不是追求大型项目那种复杂表格系统,而是让“可调整内容”和“程序逻辑”分开。道具属性、敌人参数、关卡奖励、商店价格、掉落权重、技能冷却,这些都应该能在配置表里清楚看到,并能被校验。
先确定哪些数据外置
不是所有东西都适合放表。可以按变化频率判断:
| 数据 | 是否外置 | 原因 |
|---|---|---|
| 武器伤害 | 是 | 经常调平衡 |
| 敌人血量 | 是 | 难度测试会改 |
| 技能冷却 | 是 | 影响手感 |
| UI 坐标 | 看情况 | 与界面布局相关 |
| 核心算法 | 否 | 需要代码审查 |
| 关卡触发逻辑 | 看情况 | 复杂逻辑仍适合代码或可视化工具 |
| 文案 | 是 | 需要本地化 |
个人项目可以从最容易变的数值开始,不要一开始就把所有系统都配置化。过度配置会让表格难以理解。
表结构要稳定
一个武器表可以这样设计:
| id | name_key | damage | cooldown | range | cost | unlock_stage |
|---|---|---|---|---|---|---|
wpn_knife | weapon.knife | 12 | 0.35 | 1.2 | 0 | 0 |
wpn_hammer | weapon.hammer | 35 | 0.90 | 1.4 | 120 | 2 |
ID 要稳定,不要用显示名称当 ID。显示名称会本地化,ID 用于存档、掉落、成就和日志。如果上线后改 ID,旧存档可能找不到道具。需要改显示名时,只改 name_key 对应文本。
配置校验
每次加载表格时都要校验,不要等玩家遇到 bug:
- ID 是否重复。
- 必填字段是否为空。
- 数值是否在合理范围。
- 引用的文本 Key 是否存在。
- 引用的资源是否存在。
- 解锁阶段是否有效。
- 掉落权重是否为非负数。
校验失败时,开发环境可以直接报错;发行环境要给出日志并尽量降级处理。比如某个可选图标缺失可以使用默认图标,但武器 ID 重复应该阻止构建进入候选。
数值修改要有记录
平衡调整不能只靠感觉。建立 docs/balance-log.md:
| 日期 | 改动 | 原因 | 验证 |
|---|---|---|---|
| 2021-04-17 | wpn_hammer 伤害 42 改 35 | Demo 玩家一击秒精英怪 | 第二章战斗平均时长回到 90 秒 |
| 2021-04-18 | 第一章敌人血量降低 15% | 新玩家死亡率过高 | 10 人测试通过率提升 |
记录原因比记录数值更重要。一个月后你会忘记为什么改某个参数,后来再调可能把问题改回来。
调参要看指标
不要只问玩家“难不难”。可以记录:
| 指标 | 用途 |
|---|---|
| 首次死亡点 | 判断教学和难度尖刺 |
| 关卡完成时间 | 判断节奏 |
| 武器使用率 | 判断选择是否有意义 |
| 资源剩余量 | 判断经济压力 |
| Boss 尝试次数 | 判断挑战强度 |
个人项目不一定接入复杂遥测,也可以通过测试表手动记录。关键是让调参围绕现象,而不是开发者个人感受。
表格和存档兼容
配置数据会影响存档。比如旧存档里有 wpn_hammer,新版本删除了这个武器,读档就会出问题。处理方式:
- 上线后不要随意删除 ID。
- 如果必须删除,写迁移规则。
- 配置表保留弃用字段或映射。
- 存档里尽量保存 ID,不保存整份配置。
- 加载失败时记录清楚日志。
Demo 到正式版也要注意。Demo 中出现的道具 ID,如果正式版改名或删除,要考虑玩家存档和反馈截图。
难度档位的数据组织
难度不一定要复制整张表。可以使用倍率或覆盖表:
| 参数 | 简单 | 普通 | 困难 |
|---|---|---|---|
| 敌人伤害倍率 | 0.75 | 1.0 | 1.25 |
| 资源掉落倍率 | 1.2 | 1.0 | 0.8 |
| Boss 血量倍率 | 0.85 | 1.0 | 1.15 |
但某些关键敌人可能需要单独覆盖。不要只用全局倍率解决所有难度,否则会出现小怪过强、Boss 过肉、经济系统失衡的问题。
给非程序调参留入口
如果有美术、策划或外部测试者帮忙,表格要可读。字段命名要清楚,单位要明确,范围要写备注。比如 cooldown_seconds 比 cd 更清楚,move_speed_tiles_per_second 比 speed 更不容易误解。
可以在表格旁边放说明:
| 字段 | 单位 | 建议范围 |
|---|---|---|
damage | 点数 | 1 到 999 |
cooldown_seconds | 秒 | 0.1 到 10 |
drop_weight | 权重 | 0 以上 |
这会减少沟通成本。
Steam Demo 前的冻结
Demo 发布前一周,数值也要冻结。冻结不代表不能修,而是不能随意大改系统。只处理明显阻断体验的问题,比如新手关过难、某武器导致崩溃、经济系统无法继续。小幅平衡可以进入后续补丁。
每次 Demo 期间改数值,都要重新跑关键路径测试。数值改动同样可能破坏任务、成就、掉落和存档。
最终检查清单
- 高频变化数据从代码中拆出。
- 配置 ID 稳定,不使用显示名。
- 表格加载有校验。
- 平衡调整记录原因和验证结果。
- 调参参考死亡点、时长、使用率等指标。
- 配置变更考虑存档兼容。
- 难度档位不是粗暴复制表。
- Demo 前数值进入冻结流程。
数据驱动让个人游戏更容易迭代,但前提是表格本身可靠。把数据、校验和记录做好,Steam Demo 收到反馈时,调参才是可控工作,而不是在代码里冒险修改。
表格来源不要混乱
配置表最怕出现多个来源:程序改了一份 JSON,策划改了一份表格,发行包里又带着旧导出。个人项目也要规定唯一来源。例如以 data_source/balance.xlsx 为源,构建前导出到 game/data/balance.json;或者直接以版本库中的 JSON 为源,不再维护额外表格。
无论哪种方式,都要在 README 写清楚:
| 项目 | 说明 |
|---|---|
| 源文件 | 谁可以修改 |
| 导出文件 | 是否自动生成 |
| 校验命令 | 构建前如何检查 |
| 发行文件 | 哪些会进入包 |
| 回滚方式 | 出错后怎么恢复 |
这样可以避免上线前出现“我明明改过数值,为什么玩家下载还是旧版本”的问题。
随机和权重要可解释
如果游戏有掉落、随机事件或 Roguelite 奖励,权重表要能解释结果。不要只写一堆数字,让自己两周后也看不懂。可以在表里加类别、解锁条件和设计备注:
| id | weight | unlock | note |
|---|---|---|---|
reward_heal_small | 20 | chapter1 | 新手保底恢复 |
reward_fire_mod | 8 | chapter2 | 火焰构筑核心 |
reward_gold_big | 4 | shop_unlocked | 经济补偿 |
测试随机系统时,不只看单次结果,要跑多轮统计。个人项目可以写一个小的内部模拟按钮,生成 100 次奖励分布,检查是否和预期接近。否则玩家可能连续拿到不合理组合,影响 Demo 第一印象。
调参和难度文案同步
数值改动会影响玩家对难度的理解。比如降低简单难度敌人伤害后,设置页的描述也要同步;增加某武器价格后,商店说明和新手引导可能要调整。数据表不是孤立系统,它会影响文案、教程、成就和商店页承诺。
每次较大调参后,检查相关文本:难度说明、道具描述、技能描述、补丁公告、Demo 结束页。如果玩家看到的文字和实际数值差距很大,会认为游戏不严谨。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。