下载 App
开发者日志03
2026-10-17
某天我们收到两条需求,单独看都合理,放在一起就是灾难。第一条,玩家初始攻击力下调 10 倍。第二条,敌人攻击力上调 20 倍。
问题在于,原来玩家和敌人的攻击力是放在同一个伤害公式里直接对撞的。原来玩家攻击是 10、敌人是 17,还算能打;现在玩家变 1、敌人变 340,公式必然崩掉,要么玩家挠痒痒,要么敌人一刀秒杀。如果硬调系数,又会把"玩家初始很弱"这个设计意图抹掉。我们卡了整整一天。
突破口是想明白一件事:面板上的数字是给玩家看的,伤害公式里的数字是给系统算的,它们不必是同一个数。
于是我们做了两层拆分。第一层是面板攻击力,用来展示、满足需求。玩家的叫战力,等于基础 1 加装备加成,是小数值,靠装备成长;敌人的叫火力,等于原始值乘 20,是大数值,直接乘 20。第二层是实际伤害,战斗结算时用,由系数换算。玩家的实际伤害等于面板乘 4.0,敌人的实际伤害等于面板乘 0.025。
两个系数把不同量纲的面板值拉到了同一个伤害量纲上。于是需求满足了:玩家面板确实从 1 起步,敌人面板确实是乘 20。战斗也可用了:双方实际伤害在同一量级,打起来有来有回。这是整个战斗系统最关键的一步。之前"设计不好"的根源就是没有拆开,既想满足面板需求,又想公式直接可用,两者不可兼得。
伤害公式本身是这样的:面板攻击乘伤害系数,再乘一个 0.85 到 1.15 的随机浮动,避免每场战斗完全一样,然后乘上护甲减免后的余量,最后乘倍率。倍率有两个来源,暴击是 15% 概率、1.8 倍,重击是能量条攒满 100 自动触发、2.2 倍。
拆开之后,护甲模型的问题就暴露出来了。第一版用的是扁平减免,直接扣减护甲乘以 0.6。问题是它是减法。敌人火力从流浪汉 340 到棕熊 1800,成长 5.3 倍;玩家护甲从 7 到 42,看着也成长了 6 倍,但扁平减免扣掉的是固定值,敌人伤害越高,这点固定值占比越小。标定数据很直白:顶级护甲 42 在扁平模型下,只能把棕熊的伤害从 38 压到 25,只减了 34%。高护甲装备迅速贬值,后期全靠武器硬撑。
于是改成乘法减免:减免率等于护甲除以护甲加 45。同样 42 点护甲,减免率是 42 除以 87,约等于 48%,而且与敌人伤害的绝对值无关。护甲成长能稳定跟上敌人火力成长。收益递减但不归零,符合"堆护甲有用,但不能无脑堆"的预期。
护甲对应的减免率是这样的:
护甲 减免率
7(白装) 13%
18(蓝装) 29%
26(紫装) 37%
34(金装) 43%
42(红装) 48%
装备分六档:白、绿、蓝、紫、金、红。每档的定位是刚好吃下对应层级的敌人:
档位 代表装备 战力 对同级敌人胜率
裸装 空手加便服 1 0%,打不过任何人
白 铁管加毛线帽 3 100% 流浪汉
绿 铁锤加防风镜 4 88% 小偷
蓝 工兵铲加钢盔 7 100% 拾荒者
紫 砍刀加防弹背心 13 100% 掠夺者
金 武士刀加复合护甲 18 20% 散兵
红 斩马刀加动力装甲 25 98% 散兵
这里有两个刻意的设计意图。裸装必须全败,这是"初始必须弱"的硬约束,也是逼玩家去装备店消费的动机,把金币经济和战斗成长绑在一起。金装对散兵只有 20%,这不是没调好,是故意的,这是设计上"你还需要再买一件红装"的信号,让玩家有明确的下一个目标。
数值这么绕,手调肯定不行。我们写了一个离线标定脚本,每组配置跑 400 场,输出胜率矩阵。它同时跑胜率矩阵、角色曲线、地图池覆盖率和连续远征。每次改完数值常量,都必须重跑,确认对角线还成立。改数值前先跑模拟器,不要凭感觉调——这条规矩救了我们很多次。比如"蓝武器攻击加成从 9 改成 8"这个提案,模拟器显示会让掠夺者胜率从 63% 腰斩到 32%,而它想解决的问题,也就是蓝装过度覆盖,其实已经被地图梯度解决了,所以我们否决了这个改动。
单场胜率好看还不够。我们额外测了连续远征,6 场一条命,生命跨场累积,血低于 35% 才用药。结果是,蓝装的最高配置在超市、医院、基地的清空率全是 0%,连超市都清不空,平均只存活 2.7 场。这说明地图风险是真的成立了。"能赢一场"和"能清全图"是两回事,远征内的生命和药品消耗必须被珍惜。
下一篇讲装备和经济:金币从哪来,商店为什么不能"有钱就买到最高档",以及五个角色是怎么做出差异化的。




