ZDoom 伤害与 DPS 计算器
计算任何 ZDoom/GZDoom 武器或投射物的精确伤害范围、期望 DPS 与击杀时间。包含 random(1,8) 倍率、STRIFEDAMAGE 旗标,以及给 ACS 脚本用的 tic 与秒互换器。
毁灭战士 MOD 作者的伤害范围、DPS 与 tic 换算器。
计算任何投射物、扫描枪或自定义 DamageFunction 的最小/平均/最大伤害。
伤害公式
使用 Damage × random(1, 8) — ZDoom 标准投射物公式。
选择原版《毁灭战士》投射物即可自动填入 Damage。事后修改 Damage 会把预设切回自定义。
dmg
DECORATE/ZScript 中 Damage 后面写的 N 值(例如:小鬼火球 Damage 3)。
伤害分布
random(1, N) 是均匀分布——每个倍率概率相同。
| 每次命中伤害 | 概率 |
|---|---|
| 3 | 12.5% |
| 6 | 12.5% |
| 9 | 12.5% |
| 12 | 12.5% |
| 15 | 12.5% |
| 18 | 12.5% |
| 21 | 12.5% |
| 24 | 12.5% |
原版投射物速查表
点击任意一行即可载入到上方输入栏。
| 投射物 | Damage | 倍率 | 最小 | 最大 | 平均 | 速度(mu/tic) |
|---|---|---|---|---|---|---|
| 小鬼火球 — DoomImpBall | 3 | × random(1, 8) | 3 | 24 | 13.5 | 10 |
| 巨脑魔等离子弹 — CacodemonBall | 5 | × random(1, 8) | 5 | 40 | 22.5 | 10 |
| Arachnotron 等离子弹 — ArachnotronPlasma | 5 | × random(1, 8) | 5 | 40 | 22.5 | 25 |
| 等离子枪球 — PlasmaBall | 5 | × random(1, 8) | 5 | 40 | 22.5 | 25 |
| 地狱男爵/地狱骑士火球 — BaronBall | 8 | × random(1, 8) | 8 | 64 | 36 | 15 |
| Mancubus 火球 — FatShot | 8 | × random(1, 8) | 8 | 64 | 36 | 20 |
| Revenant 追踪导弹 — RevenantTracer | 10 | × random(1, 8) | 10 | 80 | 45 | 10 |
| 火箭(直击) — Rocket | 20 | × random(1, 8) | 20 | 160 | 90 | 20 |
| BFG 散射(每条光线) | 67 | × 1..8 loop | 15 | 120 | 67.5 | — |
| BFG 球体(直击) — BFGBall | 100 | × random(1, 8) | 100 | 800 | 450 | 25 |
可重现这些数值的 DECORATE/ZScript 片段。
ACTOR CustomProjectile : DoomImpBall{ Damage 3 // Min 3 Max 24 Avg 13.5 (× random(1, 8))}ZDoom 伤害计算器。给毁灭战士 MOD 作者用的伤害范围、DPS 与 tic 速查表。
ZDoom 伤害与 DPS 计算器是什么?
如何计算 ZDoom 的伤害、DPS 与 tic 换算(顺便看看这款计算器在做什么)
伤害、DPS 与 tic 换算 — 引擎里的数学
- = DECORATE 或 ZScript actor 的 Default 区块中声明的 Damage 属性(整数)
- = 随机倍率上下界 — 默认为 1 与 8;挂 +STRIFEDAMAGE 为 1 与 4;手枪/霰弹枪/加特林的每颗弹丸为 1 与 3;拳头/电锯为 1 与 10
- = 每次攻击的 tic 数 — actor 的 States 区块里两次连续开火调用之间 state machine 的时长
- = 目标 HP — 丧尸兵 20、小鬼 60、巨脑魔 400、地狱男爵 1000、蜘蛛魔王 3000、机械巨魔 4000
- = DamageFactor 倍率 — 1.0 正常、0.5 抗性、2.0 弱点、0.0 无敌
- = 以秒为单位的时间 — 乘以 TICRATE = 35 并四舍五入到整数 tic,用作 state 时长或 Delay() 参数
- = 飞行距离(map units)与投射物 Speed(map units/tic);引擎以整数 tic 为步进,故除法向上取整即为飞行 tic 数
完整数字逐步走过的范例
小鬼火球 vs 巨脑魔 — 默认场景
手枪打丧尸兵的 DPS — 「手枪真的废吗」
超级霰弹枪打地狱骑士 — 贴脸开枪的真实数字
BFG 球体直击机械巨魔(不计散射)
ACS Delay 换算 — 「2.5 秒是多少 tic」
ZDoom 伤害与平衡心得 — MOD 作者、地图作者与好奇玩家都用得上
- 读 actor 的 Damage 属性时,要用「期望值」而不是「字面值」去想。Damage 5 的投射物在游戏里平均 22.5(5 × 4.5),不是 5。如果你的自制怪物火球要跟小鬼(期望 13.5)打成同一个级别,Damage 应该写 3,而不是 10。DECORATE 平衡最常见的错误就是把 Damage 10 当作「固定 10 伤害」,结果在游戏里跑出 10 到 80、平均 45 的数字。
- +STRIFEDAMAGE 旗标是最低成本的「收范围」手段。Damage 不变,最大倍率从 8 降到 4,期望值从 4.5× 降到 2.5×。想做一支「固定落在 60 到 240 之间,而不是 60 到 480」的自制火箭时非常好用。旗标取名自 Strife(引擎第一个非 Doom IWAD),但跟底层游戏无关 — 任何 ZDoom MOD 都能用,纯 Doom IWAD 也照样吃。
- 扫描枪完全无视 Damage 属性。手枪、霰弹枪、加特林、超级霰弹枪的 A_FireBullets/A_FirePistol/A_FireShotgun 内部写死了每颗弹丸 $5 \times \text{random}(1, 3)$。想增强扫描枪的伤害,必须改弹丸数、改 A_CustomBulletAttack 的 damage 参数,或者干脆改造成投射物型武器。拳头与电锯是 $2 \times \text{random}(1, 10)$;狂暴只对拳头生效,在随机数之后再乘以 10(每拳 20 到 200,期望 110)。
- 对比 DPS 时,每次攻击的 tic 数比单发伤害更重要。加特林跟手枪的每发公式完全一样(5 到 15,期望 10),但加特林每次攻击大约 4 tic、手枪大约 14 tic — 同样的弹丸公式,DPS 直接差到 3.5 倍。设计武器 MOD 时,先定目标 DPS(原版手枪约 25、霰弹枪约 70、超级霰弹枪约 150、加特林约 88、等离子枪约 263、火箭直击约 150),再反推单发伤害与每次攻击 tic。
- 19 种怪物速查表是设计遭遇战的好工具。丧尸兵(HP 20)、霰弹兵(30)、Wolfenstein SS(50)、小鬼(60)、加特林兵(70)、亡魂/Commander Keen(100)、牛怪/Spectre(150)、Revenant(300)、Pain Elemental/巨脑魔(400)、地狱骑士/Arachnotron(500)、Mancubus(600)、Arch-vile(700)、地狱男爵(1000)、蜘蛛魔王(3000)、机械巨魔(4000)。超级霰弹枪一发(期望 200、最大 300)在最佳运气下一枪就放倒 Revenant(HP 300);Pain Elemental 与巨脑魔(HP 400)至少要两发最佳运气。手枪一发(期望 10)只放得倒丧尸兵。在地图第一个房间放牛怪还是放 Mancubus,是难度 4 倍的差距,而不是 1.5 倍 — HP 曲线是等比上升,不是线性上升。
- GZDoom v3.2.2(2017 年底)起保证 35 tic 等于实时 1.000 秒。再早的版本因为计时器内部整数除法截断,tic 间隔被显示成 28 ms,于是 35 tic 显示成 0.98 秒。如果你的 ACS Delay() 算术需要次秒精度而且要兼容 2017 年前的玩家版本,请预留 2% 的偏移:`Delay(35 * 60)` 在旧版计时器上实际只跑了 58.8 实时秒,比整整一分钟少 1.2 秒。
- BFG 散射是唯一一个不照 $\text{Damage} \times \text{random}(1, 8)$ 跑的投射物。A_BFGSpray 内部把每条光线的伤害定义成 15 次独立 random(1, 8) 的总和,所以单条光线范围 15 到 120、期望 67.5,分布是钟形而不是均匀分布。BFG 球体在前方 90 度锥里最多射 40 条光线,全覆盖击发会在 BFG 球体本体 100 到 800 上面再叠 $40 \times 67.5 = 2700$ 点期望伤害 — 这就是「BFG 一发秒掉机械巨魔」传说的真相,前提是直击与锥形散射同时命中。
- Map unit 的实际尺寸换算有水平、垂直两种,不是一条。水平方向:16 map units = 1 英尺(0.3048 m);垂直方向:因为原版 320×200 分辨率被纵向拉长 20%,10 map units = 1 英尺。投射物沿地图平面飞,所以 Speed 换算用水平比:Speed 10(小鬼火球)≈ 6.67 m/s ≈ 15 mph;Speed 25(等离子、BFG 球体)≈ 16.67 m/s ≈ 60 km/h ≈ 37 mph。毁灭战士本人跑步速度大约 Speed 16,约 24 mph — 这就是为什么在窄走廊里偶尔会被小鬼追上咬到屁股。
- DamageFactor 让你不必改伤害代码就能做抗性与弱点。在怪物身上写 `DamageFactor 'Fire', 0.5` 会把 Fire 类伤害减半,2.0 加倍,0.0 完全免疫。计算器的 DPS 模式用一个标量 DamageFactor 字段呈现,可以不必声明自定义伤害类型就快速建模「对 Fire 0.7 抗性的巨脑魔变种下,原版武器的 TTK 变多少」这种场景。
- 做生存型计算时,最差运气与最佳运气比期望值更实用。「期望击杀 = 30」这个数字藏住了一个极端结果:运气最差时,巨脑魔可以硬吃 134 颗小鬼火球。计算器之所以把最佳/最差跟期望一起列出来,就是为了这种场景 — 做大屠杀地图、需要在严格的弹药预算内把怪物清光时,按最差运气来设计;做休闲地图,按期望来设计。random(1, 8) 投射物两个数字差到 5 到 10 倍并不少见。
- 在中文环境写 MOD 时,actor 名与属性名一律保留引擎里的英文写法(Damage、Speed、Health、+STRIFEDAMAGE、Cacodemon、Cyberdemon 等)。DECORATE 与 ZScript 都不接受被本地化的标识符。B 站、百度贴吧、机核或萌娘百科上看到的「巨脑魔」「机械巨魔」「蜘蛛魔王」只是给玩家看的译名,代码里仍然是 `Cacodemon`、`Cyberdemon`、`SpiderMastermind`。PK3 内坚持英文写法,能让其他 MOD 作者打开 WAD 时省下大把调试时间。
ZDoom 伤害计算器 — 常见问题
为什么我写的 Damage 10 投射物有时候打出 80 点伤害?
ZDoom 每次命中都会把投射物的 Damage 属性乘以 random(1, 8)。Damage 10 会等概率打出 10、20、30、40、50、60、70 或 80,平均 45。加上 +STRIFEDAMAGE 旗标后倍率变成 random(1, 4),落在 10、20、30、40 之间,平均 25。
原版毁灭战士的手枪伤害公式是什么?
手枪每发 $5 \times \text{random}(1, 3)$,也就是 5、10 或 15 等概率落点,期望值 10。加特林与霰弹枪(每颗弹丸)用同一条公式。扫描枪 actor 上的 Damage 属性会被忽略,公式直接写死在 A_FirePistol、A_FireShotgun、A_FireCGun 里。
ZDoom 里 1 秒等于多少 tic?
35 tic。TICRATE 自 1993 年首发以来一直锁在 35。GZDoom v3.2.2 之后保证 35 tic 等于实时 1.000 秒;更早的版本把 tic 间隔截断成 28 ms,所以 35 tic 显示成 0.98 秒 — 这在长串 Delay() 累加时会以约 2% 的速率漂移。
ACS 里要怎么写 X 秒的延迟?
把秒数乘以 35 并四舍五入。0.5 秒 = 18 tic、1 秒 = 35 tic、2 秒 = 70 tic、5 秒 = 175 tic、10 秒 = 350 tic、60 秒 = 2100 tic。在 ACS 里可以直接写 `Delay(35 * seconds)`,乘法会在编译期被解掉。
+STRIFEDAMAGE 旗标到底在做什么?
+STRIFEDAMAGE 把投射物伤害倍率从 random(1, 8) 切成 random(1, 4)。Damage 值不变,范围更窄、平均值更低。旗标取名自 Strife,但跟底层游戏无关 — 任何 ZDoom MOD 都能用,包括纯 Doom/Doom II 套装。想要伤害更稳、波动更小的中威力投射物时,这个旗标最划算。
机械巨魔(Cyberdemon)的 HP 是多少?
4000 HP。机械巨魔对溅射完全免疫 — 火箭与 Mancubus 投射物炸到它脚边都不会吃到溅射伤害,只能靠直击。BFG9000 是惯例武器(连同散射约 2 到 4 个 trigger),其他选项包括贴脸超级霰弹枪约 20 发、火箭直击期望约 45 发(前提是弹药够)。计算器下方的 19 行怪物表完整列出原版每只怪物的 HP。
BFG 的伤害为什么这么怪?「15 次循环」是什么?
BFG 球体本体按标准公式跑(Damage 100 × random(1, 8) = 100 到 800),但散射光线不是。每条光线(最多 40 条)是把 15 次独立 random(1, 8) 加起来,所以单条光线范围 15 到 120、期望 67.5。Doom Wiki 提到 P_Random 的 256-byte 伪随机表确定性会把实机观察到的单条光线范围收窄到 49 到 87 之间,但理论最大值 120 不变。
ZScript actor 也能用这款计算器吗?
可以。ZScript 与 DECORATE 共用同一套 Damage/DamageFunction/Speed/Health/+STRIFEDAMAGE 语义,差别只在语法。Default 区块里写 `Damage 5;` 的 ZScript actor 跟同样写法的 DECORATE actor 掷出完全一样的 $5 \times \text{random}(1, 8)$。本工具的输出对两者皆适用。
Brutal Doom 或 Project Brutality 也能用吗?
对于还在用标准 Damage 属性与原版扫描枪函数的 actor 是可以的。Brutal Doom(Sergeant Mark IV 制作)与 Project Brutality 把大部分武器改写成自定义 DamageFunction 与 A_FireCustomMissile 路径,不再遵守 random(1, 8) 倍率。这类武器只能拿到原版近似值,建议翻一下该 MOD 的 DECORATE/ZScript 自行修正。
PrBoom+、ZDoom、GZDoom、Zandronum 之间,伤害会不一样吗?
对原版《毁灭战士》/《毁灭战士 II》来说不会。PrBoom+、ZDoom、GZDoom、Zandronum 都把 TICRATE 35、random(1, 8) 与 random(1, 3) 公式、原版 HP 数值一字不漏地保留下来。不同 source port 的差异发生在进阶功能(物理、MAPINFO、ZScript、MBF21 怪物脚本),不会发生在伤害基本算式上。同样的随机数序列下,HP 400 的巨脑魔在四套引擎里会用同样的发数倒下。
Revenant 的追踪导弹为什么是 10 到 80 而不是 10 到 40?
`RevenantTracer` actor 虽然写了 Damage 10,但没有挂 +STRIFEDAMAGE 旗标,所以使用默认 random(1, 8) 倍率,范围 10 到 80、期望 45,不是 10 到 40。很多 MOD 作者直觉以为 Revenant 火箭应该走 Strife 风格的数学 — 其实不是。
难度(UV/Nightmare)会让武器伤害变高吗?
不会。Nightmare 把怪物攻击性与弹药拾取数翻倍,但武器伤害在五个难度等级下完全相同。原版里唯一存在的伤害倍率是狂暴(Berserk),它把拳头伤害乘以 10。难度改变的是「谁先开枪、开几枪」,不是「每枪打多重」。
这款计算器跟实机游戏的精度差多少?
在 ZDoom/GZDoom 下跑原版《毁灭战士》/《毁灭战士 II》行为时,引擎级精确。校验范围覆盖每一个投射物预设、每一支扫描枪、每一个怪物 HP,以及 BFG 散射的 15 次循环 — 伤害范围、HP 与投射物 Speed 与原版 actor 定义到单位都对得上。DECORATE/ZScript 替换的 actor、自定义 DamageFunction 表达式、新世代《毁灭战士》(2016、永恒、黑暗时代)用不同算法,不在工具覆盖范围之内。
工具是免费的吗?要不要注册?
完全免费,不必注册,全部运算都在你的浏览器里完成。输入会用 localStorage 在页面刷新之间保留,所选模式也会反映到网址查询字符串(?mode=damage / dps / tics)里,方便书签分享到 B 站专栏、百度贴吧 doom 吧、机核或 ZDoom 论坛。
ZDoom 伤害与时间术语表
Damage 属性
DECORATE 或 ZScript actor 的 Default 区块里的一个整数属性。引擎每次命中都会乘以 random(1, 8)(挂 +STRIFEDAMAGE 为 random(1, 4)),所以 Damage 10 在游戏里会跑出 10 到 80 的范围,不是固定 10。
+STRIFEDAMAGE
把投射物伤害倍率从 random(1, 8) 切成 random(1, 4) 的 actor 旗标。Damage 不变、范围变窄、平均值降低(Damage × 2.5 而非 Damage × 4.5)。跟底层游戏无关,任何 ZDoom MOD 都能使用。
tic
Doom 引擎的最小时间单位。TICRATE = 每秒 35 tic,1 tic ≈ 28.5714 ms。DECORATE/ZScript 的 state 时长与 ACS Delay() 参数都以 tic 为单位。GZDoom v3.2.2 起保证 35 tic = 实时 1.000 秒,更早的版本截断为 28 ms。
扫描枪(Hitscan)武器
不依赖投射物 actor、沿直线即时结算伤害的武器。手枪、霰弹枪、超级霰弹枪、加特林都是扫描枪。公式直接写死在 A_Fire* 动作函数里(每颗弹丸 $5 \times \text{random}(1, 3)$),actor 的 Damage 属性会被忽略。
DamageFactor
针对特定伤害类型的受击倍率。`DamageFactor 'Fire', 0.5` 把 Fire 类伤害减半,2.0 双倍、0.0 完全免疫。计算器 DPS 模式给一个标量 DamageFactor 字段,方便快速建模抗性与弱点场景。
狂暴(Berserk)
在 random(1, 10) 之后再把拳头伤害乘以 10 的能力强化道具,范围 20 到 200、期望 110。电锯、扫描枪、投射物全都吃不到这个 buff,只有拳头吃。
Map unit
Doom 的空间坐标单位。社区公认:水平 16 map units = 1 英尺 = 0.3048 m(毁灭战士本人垂直 56 个单位高 = 5 英尺 7 英寸)。计算器用水平 16 mu/英尺的比例,把投射物 Speed(map units/tic)换成 m/s、km/h、mph。
Speed 属性
投射物 actor 的速度(map units/tic)。小鬼火球 Speed 10;火箭 Speed 20;等离子枪球与 BFG 球体 Speed 25。乘以 35 得到 map units/秒;乘以 0.667 得到 m/s;乘以 1.49 得到 mph。
BFG 散射(BFG spray)
BFG 球体命中时释放的 40 条光线锥形扩散(从 BFG 球体的死亡 state 通过 A_BFGSpray 发射)。每条光线伤害为 15 次独立 random(1, 8) 的总和 — 单条 15 到 120、期望 67.5。BFG 一发秒掉机械巨魔的传说就来自散射,本体球体并不够。
TICRATE
把 Doom 帧率锁在每秒 35 tic 的引擎常数,自 1993 年以来从未变过。在 id Software 的 doomdef.h 里声明,被 ZDoom、GZDoom、Zandronum、PrBoom+、Boom、MBF21 以及所有原版兼容 source port 一字不漏地继承。所有 state 时长、Delay() 参数、投射物飞行时间都以 35 作为换算常数。
DamageFunction
Damage 属性的替代品,让 MOD 作者在命中时通过 ZScript 表达式返回任意整数,绕过 random(1, 8) 倍率。可以返回定值做确定性伤害,也可以根据 inflictor/target/distance 动态计算,做出对场景敏感的行为。
P_Random
Doom 引擎的伪随机数函数,使用一张固定 256 byte、洗牌过的表,索引顺序往前推进,每次调用返回下一个 byte。分布并不均匀(值 1 永远不出现、值 145 出现 5 次),但对战斗算术已经够用。所有伤害掷骰都使用它;M_Random 走另一条索引,给非游戏性效果用,避免破坏多人联机的同步。
由 Smart Calculators 团队审核