【订正】wand_fast(0.25s) 的饱和点按公式 (1/60)/0.25 = 0.0667,不是 0.05。
numerical_design:21 的标注与它自己上一句的公式直接矛盾,spec/plan 另有三处同源
错误标注——均派生自一句口头转述,实测表里记的 0.0667 一直是对的。
结论也随之改对,不只是改数字:hard=0.05 使 wand_basic(饱和 0.0333) 与
circuit_fork(0.0278) 无无效区间,但 wand_fast 仍剩 [0.05, 0.0667) 这段买不到东西
(较原 hard:0.01 的 6.7 倍缩至 1.33 倍)。仍取 0.05 的理由:饱和点 = (1/60)/法杖
基准间隔,随杖而异,不存在对所有杖都最优的单一 hard——取 0.0667 让 wand_fast 干净
会使另两把杖够不到自己的饱和点,反而制造新的不可达区间。hard 数值不变。
顺带说明实测表里 wand_fast@0.0667 读到 2 帧的原因:采样点比真实边界 1/15 高 3.3e-5
(T 上高 8.3e-6 s),再叠加整帧倍数多花一帧的浮点余量效应,故实际 1 帧上界略低于
0.0667。数据没错,是标签错了。
【roadmap】E3-① 下的 cast_delay_mod 条目仍记为「待人定」并指向两个选项,而该决定
已在 ba7c885 关闭——roadmap 是查「E3 还剩什么」的索引,留着会把已关闭的决定重新打开。
改为已处理,并注明彻底消除需让 hard 逐杖化(挪进 cores.json),属独立立项。
【roadmap】「实测 200→300 px/s」读起来像发版移速由 200 改成 300,与同批改动里
numerical_design 的订正(发版是 200,300 是从未被读过的纸面值)直接冲突。改写为
「发版基准仍是 200;实测手段是临时挂 +50% 加成使生效值变 300」。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
19 KiB
数值策划设计案:魔法工匠 (Arcane Artificer)
0. 设计理念 (Design Philosophy)
本游戏的数值体系服务于 “高自由度构建” 这一核心目标。 数值设计不应教玩家怎么玩,而应提供足够宽广的边界(Boundary)和明确的权衡(Trade-off)。
核心公式:
构建强度 = (基础数值 * 修正系数) ^ 逻辑复杂度
1. 基础资源模型 (Resource Model)
1.1 玩家属性 (Player Stats)
这些属性是全局的,会修正所有法杖的输出。
| 属性 ID | 名称 | 基准值 | 软上限 | 硬上限 | 说明 |
|---|---|---|---|---|---|
hp_max |
最大生命 | 100 | 2000 | - | |
mana_max |
最大魔力 | 100 | 1000 | - | 全局蓝条上限,法杖也有自己的上限,取 Min 值 |
move_speed |
移动速度 | 200 | 600 | 800 | 像素/秒。⚠️ 2026-07-31 订正:原写 300 从未被任何代码读取过,是纸面孤值;实际实现自 S0 起即为 200(player_manager.gd 的 const MOVE_SPEED,现已改为读 data/attributes.json),20 波内容、Boss 弹幕密度、无敌帧 0.5 s 均按此值调校。此处以既成事实为准 —— 改回 300 等于用未经验证的数字推翻一整轮已调校的内容。理由详见 docs_dev/specs/2026-07-31-player-attributes-design.md §2.2。 |
cast_delay_mod |
施法延迟修正 | 1.0 (100%) | 0.1 | 0.05 | 越低越快,乘算系数。⚠️ 2026-07-31 由 0.01 上调至 0.05:player_manager._handle_auto_cast 用 if 而非 while,每物理帧至多施法一次,故本属性存在饱和点 = (1/60) / 法杖基准间隔 —— wand_basic(0.5 s) ≈ 0.0333、wand_fast(0.25 s) ≈ 0.0667、circuit_fork(0.6 s) ≈ 0.0278。饱和点随杖而异,故不存在对所有杖都最优的单一 hard:要让 wand_fast 无无效区间需 hard ≥ 0.0667,但那会让 wand_basic 够不到自己的 0.0333,反而制造新的不可达区间。取 0.05 是折中 —— wand_basic 与 circuit_fork 无无效区间,wand_fast 仍剩 [0.05, 0.0667) 这一小段买不到东西;相对原 0.01(两把主力杖都深陷饱和区、从 0.0333 一路买到 0.01 射速纹丝不动)是大幅改进。实测数据(可达档位是台阶而非曲线、周期恒为 ceil(T×60))见 docs_dev/specs/2026-07-31-player-attributes-design.md §2.2b。 |
recharge_speed_mod |
充能速度修正 | 1.0 (100%) | 5.0 | - | 越低越快 |
luck |
幸运 | 0 | 100 | - | 影响高阶法术掉率、暴击率 |
cpu_limit |
运算力上限 | 0(玩家侧) | 20 | 50 | SpellEvaluator 实际 MAX_OPS = 生效 cpu_limit × 40,与 implementation_plan.md §2.2 的 MAX_OPS_PER_CPU = 40 常量对应。生效值 = 玩家侧基准 0 + 法杖份额(cores.json 逐杖 3–8,以 source="core" 的加成来源接入)+ 未来的玩家加成;hard(50) 作用于加总后的生效值,故法杖份额也受硬上限约束。玩家侧基准取 0 而非 5 是刻意的:生效值已含法杖的 3–8,取 0 使小木法杖仍为 5 → 200 步(现有平衡零改动),取 5 会让所有法杖的执行预算翻倍;语义上玩家属性是"全局加成",基准 0 正是纯加成语义。 ✅ 2026-07-31 已修复(原 ⚠️「代码硬编码 MAX_OPS = 40×5 = 200,从不读 cpu_limit」现已失效):spell_evaluator.gd 改读 MAX_OPS_PER_CPU * maxi(PlayerStats.cpu_limit, 1),cores.json 逐杖配置的运算力自此生效(高速法杖 3 → 120 步、小木 5 → 200、矩阵板 8 → 320,运行时实测)。设计见 docs_dev/specs/2026-07-31-player-attributes-design.md §2.2。 |
attunement_fire |
火焰精通 | 0 | 50 | 100 | 每点:火焰伤害 +3%(乘算),火焰状态(点燃/爆燃)触发概率 +2%。影响 damage_type=FIRE 的所有投射物。 |
attunement_ice |
冰霜精通 | 0 | 50 | 100 | 每点:冰霜伤害 +3%,冰冻/减速触发概率 +2%。 |
attunement_lightning |
雷电精通 | 0 | 50 | 100 | 每点:雷电伤害 +3%,麻痹/连锁导电触发概率 +2%。 |
attunement_poison |
毒素精通 | 0 | 50 | 100 | 每点:毒素 DoT +3%,中毒叠层上限 +1(上限 20)。 |
1.2 经济系统 (Economy)
-
金币 (Gold) (代号
G)- 来源: 击杀怪物 (1-5G),波次结算 (100G + 10%利息)。
- 消耗: 购买法术 (50-500G),购买法杖 (200-2000G),刷新商店 (20G*)。
- 利息上限: 10% 利息计算时,单次波次奖励上限为 100G(即持有 1000G 以上部分不再产生额外利息)。防止后期经济失控膨胀。
- 膨胀控制: 商店刷新价格每次增加,波次结束后重置。金币不捡 5 秒后消失,逼迫玩家移动拾取。
- 刷新价格公式(F11 补充,P6-N23):
刷新费用 = 20 + (本波已刷新次数 × 10)(单位:G)。 即第 1 次刷新 20G,第 2 次 30G,第 3 次 40G,以此类推;波次结算后重置为 20G。 设计意图:前 1-2 次刷新成本低,鼓励灵活换货;反复刷新代价指数感,抑制"无脑刷新"。 实现:ShopManager维护_refresh_count: int(波次内),WAVE_COMPLETE事件后清零。
- 刷新价格公式(F11 补充,P6-N23):
-
经验值 (XP)
- 升级曲线(权威公式 P6-N16):
XP\_required(level) = \lfloor 10 \times 1.4^{level-1} \rfloor等级 所需 XP 累计 XP 1→2 10 10 5→6 54 234 10→11 289 1397 15→16 1551 7174 20→21 8322 39,343 - 系数
1.4使早期升级快速(前 5 级约 4 波内完成),后期升级需要持续 3-5 波,节奏符合 Roguelite 期望。 ProfileManager在关卡加载时预计算前 50 级的阈值表并缓存,避免运行时浮点指数运算。- ⚠️ F10 可行性验证(P6-N22):Level 21 累计 XP 需求 39,343。20 波 × 60 秒/波 = 1200 秒游戏时长。
设平均每秒击杀 2 只敌人,每只掉 15 XP(Wave 10+ 标准怪),则 1200 × 2 × 15 = 36,000 XP——
略低于 39,343,意味着理论上最高只能达到 Level 20 左右(不满 21 级)。
若期望玩家在通关时达到 20 级,需将
XP_required公式中系数从1.4调整为约1.38, 或将波次奖励 XP 提高(每波结算奖励 200 XP)。当前设计定为 Level 20 通关上限,不强制要求 Level 21; Level 21+ 曲线仅服务于 Endless 模式。敌人 XP 掉落参考值:Wave 1 杂鱼 = 5 XP,Wave 10 精英 = 30 XP,Boss = 500 XP。
- 系数
- 升级曲线(权威公式 P6-N16):
2. 法术系统数值 (Spell System Metrics)
2.1 核心参数定义
每个法术卡片 (Godot Resource / Json) 包含以下关键数值:
- Mana Cost (魔耗): 执行此节点消耗的魔力。
- 原则: 越强力的效果,蓝耗越高,或者有其他负面代价。
- Cast Delay (施法后摇): 执行此节点后,给法杖增加的“冷却时间”。
- 原则: 强大的单发法术通常有高延迟(如核弹 +2.0s)。
- Recharge Time (充能延迟): 这是一个特殊的延迟,只有当完整的一轮(Deck空了)打完正在重置时,才会计算。
- 原则: 只有极强的终极技能才会增加此值。
2.2 基础法术参考表 (Spell Database)
⚠️ 注意:Projectile/Action 类型法术必须在
.tres中显式设置damage_type(DamageType 枚举值)。 未填写时ProjectileDef.reset()默认DamageType.PHYSICAL,但设计意图应在此表中明示, 避免内容制作者遗漏火/雷等元素属性导致构建伤害系统无法正常触发。
Tier 1 (新手/平民)
| ID | 名称 | 类型 | Mana | Delay | 伤害类型 | 效果/修正 | 备注 |
|---|---|---|---|---|---|---|---|
spark_bolt |
魔法飞弹 | Projectile | 5 | +0.05s | PHYSICAL | Dmg: 3, Speed: 600 | 最基础的突突突 |
energy_orb |
能量球 | Projectile | 20 | +0.20s | PHYSICAL | Dmg: 15, Speed: 300 | 慢速高伤 |
double_cast |
双重施法 | Multicast | 2 | +0.00s | — | Draw: 2 | 必备插件 |
spread_mod |
散射修正 | Modifier | 0 | -0.10s | — | Spread: +30°, Speed: +10% | 这一发打不准,但射得快 |
Tier 2 (进阶/功能)
| ID | 名称 | 类型 | Mana | Delay | 伤害类型 | 效果/修正 | 备注 |
|---|---|---|---|---|---|---|---|
shotgun_blast |
霰弹爆破 | Projectile | 25 | +0.40s | PHYSICAL | 发射3枚 4dmg 的弹片 | 自带多重效果 |
damage_plus |
伤害增强 | Modifier | 15 | +0.10s | — | Dmg: +10 | |
speed_up |
加速推进 | Modifier | 5 | -0.05s | — | Speed: +400, Range: +20% | 狙击流必备 |
trigger_hit |
击中触发 | Trigger | 10 | +0.00s | — | Payload Dmg: 0.1x | 子母弹核心 |
Tier 3 (史诗/质变)
| ID | 名称 | 类型 | Mana | Delay | 伤害类型 | 效果/修正 | 备注 |
|---|---|---|---|---|---|---|---|
nuke |
战术核弹 | Projectile | 200 | +3.00s | PHYSICAL | Dmg: 500, Radius: 300 | 屏幕清空,可能会炸死自己 |
homing |
自动追踪 | Modifier | +0.10s | — | |||
heavy_cost |
鲜血献祭 | Modifier | 0 | -0.50s | — | Dmg: +50, Cost: 10 HP | 卖血流 |
chain_bolt |
连锁闪电 | Projectile | 60 | +0.80s | LIGHTNING | 弹射 5 次 | 清怪神器 |
⚠️
homing行注(2026-07-30,E1-③ 归航实装) —— 原行保留不改写,以留存「曾判定其为 Tier 3」这一判断记录。实际发版取代如下:
原表(Tier 3) 实际发版( data/spells.jsonmodifier_homing)强度 Homing Force: 5.0homing: 1.5Mana 40 8 商店价 — 18
Homing Force这一语义已废。 实现的量是最大转向角速度(弧度/秒),不是「转向力」—— 每帧把速度矢量朝锁定目标旋转,单帧转角上限strength × delta,速率不变。5.0与1.5不是同一量纲的数,不可直接比较。- Mana 40 / Tier 3 的定价被同族标准取代:与
modifier_pierce_plus、modifier_bounce同为 8 蓝 / 18 金。代价是把强度降到 1.5 rad/s 使其名副其实 —— 运动学核算表明原设想的 3.0 rad/s 对本工程敌人速度(45~140 px/s)而言接近「稳定命中」,确实配得上原表 Tier 3 的判断;1.5 rad/s 才是「中度制导」(对最快敌人在 93 px 内会跟丢)。- 该表其余行的 Mana 列与
spells.json已实现条目逐一吻合,仅此行曾出现偏离,现予记录消解。权威细节见 spec
docs_dev/specs/2026-07-30-bullet-homing-design.md§2.0(运动学核算)与 §2.8(定价决策)。
3. 敌人与战斗数值 (Combat Metrics)
3.1 伤害计算管线
⚠️ 权威公式(Authoritative Formula):所有文档均应引用此处定义,不得出现矛盾版本。
为了支持复杂的 Buff/Debuff,伤害计算必须分步:
- Base Damage: 法术面板值 (e.g. 10)
- Add Modifiers: 累加修正器 (e.g. +5 +5 -> 20)
- Mult Modifiers: 乘法修正器 (e.g. Critical 2.0x, Element Weakness 1.5x)
- Flat Reduction: 敌人护甲 (Armor -2)
- Percent Reduction: 敌人抗性 (Fire Res 50%)
Damage = ((Base + Add) × Mult) × (1 - Res) - Armor
(最小伤害为 1)
3.2 怪物设计标准
我们设定 “标准单位时间伤害 (DPS)” 为基准。
- 玩家 Lvl 1 预计 DPS: 20
- 玩家 Lvl 20 预计 DPS: 5000+
| 怪物等级 | 怪物类型 | HP | 移动速度 | 攻击力 | 特殊词条 |
|---|---|---|---|---|---|
| Wave 1 | 杂鱼土豆 | 15 | 100 | 5 | - |
| Wave 5 | 冲锋甲虫 | 80 | 250 | 12 | 击退抗性 50% |
| Wave 10 | 坦克巨兽 | 2000 | 50 | 30 | 护甲 5 (免疫机枪) |
| Wave 20 | 虚空领主 | 50000 ⚠️ | 150 | 100 | 弹幕反射盾 |
3.3 波次强度控制 (Pacing)
游戏设计为 20 波 (Wave),每波 60秒。
- W1-3: 爽局。怪物血量 < 玩家单发伤害。
- W4-7: 压力局。怪物密度增加,玩家必须拥有至少一个 AOE 手段(穿透/爆炸)。
- W8: 首领战 (Mini Boss)。考验单体 DPS。
- W9-15: 资源局。怪物掉落增加,但伴随高护甲怪,考验玩家的“破甲/元素”构建。
- W20: 最终 Boss。
4. 元素反应矩阵 (Elemental Matrix)
为了增加构建深度,引入简单的元素克制/反应。
| 攻击 \ 如果目标状态 | 无 | 潮湿 (Wet) | 油腻 (Oily) | 燃烧 (Burning) | 冰冻 (Frozen) |
|---|---|---|---|---|---|
| 火 (Fire) | 点燃 | 蒸发 (AOE) | 爆燃 (x3 Dmg) | - | 融化 (解冻) |
| 冰 (Ice) | 减速 | 冻结 (硬控) | - | 熄灭 | - |
| 雷 (Elec) | 麻痹 | 连锁导电 (AOE) | - | 过载 (爆炸) | 碎冰 (物理Dmg) |
数值策划备注:
- 潮湿:受到雷电伤害 +100%。
- 油腻:受到火焰伤害 +200%,且持续时间翻倍。
- 冻结:无法移动,受到物理撞击伤害 +300% (即碎冰机制)。
5. 平衡性隐患与对策 (Balancing Risks)
A. 无限蓝机枪 (Infinite Mana Gun)
- 问题: 玩家堆积大量
-Delay和Mana Regen,导致射速突破帧率限制,且蓝不掉。 - 对策:
- 最小帧限制: 设定射击间隔至少为 1 帧 (0.016s)。
- 过热机制 (Overheat): 连续射击超过 5秒,法杖进入“过热”状态,强制冷却 2秒 或 增加散布。
- 递增蓝耗: 连续快速射击时,每发子弹蓝耗增加 1%,停止射击后快速衰减。
⚠️ 实现现状 (2026-07-21 → 已实现):递增蓝耗已落地(
PlayerStats.mana_heat,balance.json.mana_heat可调,平衡页签);未做「最小帧限制/过热强制冷却」(用递增蓝耗替代)。
B. 显卡杀手 (GPU Killer)
- 问题: 玩家构建出
无限分裂+无限粒子。 - 对策:
- 最大弹道数 (Max Projectiles): 全局限制 2000 个弹道。超过时,新的子弹不再生成(或顶掉旧的)。
- 双重限制机制:
- MAX_OPS(=
cpu_limit × MAX_OPS_PER_CPU,默认5 × 40 = 200,软上限20 × 40 = 800):SpellEvaluator每帧单次施法最多执行对应条指令(包括 ACTION/MODIFIER/LOGIC 各类节点)。主要防止线性/循环构建死循环。与implementation_plan.md §2.2的MAX_OPS_PER_CPU = 40常量对应。 - 嵌套深度锁 MAX_TRIGGER_DEPTH = 3:
SpellEvaluator.execute_sub调用时传入depth参数,超过 3 层不再触发新的 SubPayload(即 TRIGGER 内嵌套 TRIGGER 最多 3 层)。两者分工:MAX_OPS 管局内指令数量,MAX_TRIGGER_DEPTH 管跨子弹的调用深度。
- MAX_OPS(=
C. 站桩输出 (AFK Build)
- 问题: 比如”自动追踪吸血光环”,玩家站着不动就能通关。
- 对策:
- 反挂机怪: 设计一种怪物,会向玩家当前位置投掷”毒圈”,逼迫玩家移动。
- 资源衰减: 掉落的金币如果不捡,5秒后消失(或变少),逼迫玩家去捡钱。
D. W20 Boss Phase 1 DPS 门槛(P6-N17)
-
问题: Phase 1 的
regen_on_physical_hit = 0.005(每次物理命中恢复 Boss 最大 HP 的 0.5%)。 Boss 最大 HP = 50,000,即每次物理命中回血 250 HP。⚠️ 实现现状 (2026-07-20 审计):代码 Boss 实际 HP = 450(mini)/1800(final)(
balance.json,疑为占位),非 50000;regen_on_physical_hit虚空再生、反射盾、元素抗性均未实现。本节 DPS 门槛测算基于 50000 已失真,需统一血量口径后重算。详见 审计报告。 若玩家攻速 10 发/秒(纯物理构建),Boss 每秒净回血 2,500 HP。 -
DPS 突破阈值(最低要求):物理构建需满足以下条件才能有效磨血:
DPS_{physical} > \frac{250 \times hit\_rate}{1} \Rightarrow DPS > 2500 \text{(10发/秒时)}等价条件:每发伤害 > 250(单发狙击流),或总 DPS > 2500(高频流)。
- 设计意图:并非阻止物理构建,而是要求玩家必须达到中后期构建强度(DPS 5000+)才能高效磨血;低配物理构建可用更长时间磨过,但效率不如元素/共鸣流。
- 数值调整入口:
res://resources/bosses/boss_w20.json中的regen_on_physical_hit字段,平衡迭代时直接修改数据而无需改代码。
E. infinite_spells 与 heavy_cost 叠加交互(P6-N18)
- 问题:
infinite_spells特性(法力耗尽时每发+1 HP 代价)与heavy_cost修正器(每次施法-10 HP)叠加时,HP 代价是否累加? - 规则定义:两者独立计算、顺序执行:
SpellEvaluator先执行heavy_costMODIFIER(扣 10 HP,归类为”构建设计主动代价”)。- 之后,若 mana 不足,
infinite_spells机制额外扣 1 HP(归类为”资源溢出代价”)。 - 两者同帧触发时,单发最大 HP 代价 =
heavy_cost 值 + 1(如 10+1=11 HP/发)。
- UI 提示:法杖编辑界面在检测到
infinite_spells Core+heavy_cost组合时,显示橙色警告”⚠ 双重 HP 消耗”,并提示预估每秒 HP 消耗量。 - 上限保护:单次施法 HP 代价上限 =
player.hp_max × 0.15(15% 上限),防止极端组合一发即死。
6. 波次生成配置格式 (SpawnConfig Schema — E5 权威定义)
波次内容完全由数据驱动,关卡设计师仅需编辑 JSON 无需改代码。文件位于 res://resources/waves/wave_XX.json:
{
"wave": 5,
"duration_sec": 60,
"budget": 200,
"spawn_groups": [
{
"enemy_id": "bug_charger",
"weight": 3,
"count_min": 2,
"count_max": 5,
"spawn_interval": 3.0,
"spawn_radius_from_player": [400, 700]
},
{
"enemy_id": "tank_brute",
"weight": 1,
"count_min": 1,
"count_max": 1,
"spawn_interval": 15.0,
"spawn_radius_from_player": [500, 800]
}
],
"elite_overrides": [
{ "at_sec": 45, "enemy_id": "elite_bug_charger", "count": 1 }
],
"boss": null
}
budget:本波总"刷怪点数",每个怪物有对应的cost;实际刷新量 =floor(budget / cost)。weight:同时存在多个 group 时,按权重随机选组,而非轮流刷新。elite_overrides:精确时间点强制刷出精英怪,不消耗 budget。boss:非 null 时在波末触发 BossSpawn(见 §6 Boss 设计框架)。