Files
spellforge/docs/design/numerical_design.md
T
joywayerandClaude Opus 5 1aeae19187 docs: 订正 move_speed 300→200 与 cpu_limit「从不读」告警;路线图 E3-① 勾除并订正现状
move_speed 300 从未被任何代码读取,是纸面孤值;200 自 S0 沿用并已围绕它调校
20 波内容与 Boss 弹幕密度,以既成事实为准。cpu_limit 行的「代码硬编码 40×5、
从不读 cpu_limit」告警随本次接线失效,改记生效值构成(玩家基准 0 + 法杖 3–8)
与 hard(50) 作用于加总后的总值;基准值一并由 5 改为 0,否则重蹈 move_speed 的
「纸面值与实现长期脱节」。

路线图 E3 现状原写「player_stats.gd 有 resistance 等占位属性(4/5 stats 未接线)」
与事实不符——权威属性表是 11 个,armor/resistance 根本不在表内,是实现先于设计的
孤儿字段。E3-① 勾除并标注实际范围(只做框架 + 三条死数据),attunement_×4 /
luck / recharge_speed_mod 三项延后各附理由;顺带记 cast_delay_mod 的饱和区待人定。
E1 现状里「玩家侧抗性仍占位」一句同因失效,一并订正。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 12:54:22 +08:00

265 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数值策划设计案:魔法工匠 (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.01 | 越低越快,乘算系数 |
| `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` 逐杖 38,以 `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` 事件后清零。
* **经验值 (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 XPWave 10 精英 = 30 XPBoss = 500 XP。
---
## 2. 法术系统数值 (Spell System Metrics)
### 2.1 核心参数定义
每个法术卡片 (Godot Resource / Json) 包含以下关键数值:
1. **Mana Cost (魔耗)**: 执行此节点消耗的魔力。
* *原则*: 越强力的效果,蓝耗越高,或者有其他负面代价。
2. **Cast Delay (施法后摇)**: 执行此节点后,给法杖增加的“冷却时间”。
* *原则*: 强大的单发法术通常有高延迟(如核弹 +2.0s)。
3. **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 | ~~40~~ | +0.10s | — | ~~Homing Force: 5.0~~ | ~~只有这一个修正就够改变玩法~~ ⚠️ **本行已被取代(2026-07-30**,见下方注 |
| `heavy_cost` | 鲜血献祭 | Modifier | 0 | -0.50s | — | Dmg: +50, Cost: 10 HP | 卖血流 |
| `chain_bolt` | 连锁闪电 | Projectile | 60 | +0.80s | LIGHTNING | 弹射 5 次 | 清怪神器 |
> **⚠️ `homing` 行注(2026-07-30E1-③ 归航实装)** —— 原行**保留不改写**,以留存「曾判定其为 Tier 3」这一判断记录。实际发版取代如下:
>
> | | 原表(Tier 3 | 实际发版(`data/spells.json` `modifier_homing` |
> | :-- | :-- | :-- |
> | 强度 | `Homing Force: 5.0` | `homing: 1.5` |
> | Mana | 40 | 8 |
> | 商店价 | — | 18 |
>
> 1. **`Homing Force` 这一语义已废。** 实现的量是**最大转向角速度(弧度/秒)**,不是「转向力」—— 每帧把速度矢量朝锁定目标旋转,单帧转角上限 `strength × delta`,速率不变。`5.0` 与 `1.5` 不是同一量纲的数,不可直接比较。
> 2. **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 内会跟丢)。
> 3. 该表其余行的 Mana 列与 `spells.json` 已实现条目逐一吻合,**仅此行曾出现偏离**,现予记录消解。
>
> 权威细节见 spec [`docs_dev/specs/2026-07-30-bullet-homing-design.md`](../../docs_dev/specs/2026-07-30-bullet-homing-design.md) §2.0(运动学核算)与 §2.8(定价决策)。
---
## 3. 敌人与战斗数值 (Combat Metrics)
### 3.1 伤害计算管线
> **⚠️ 权威公式(Authoritative Formula**:所有文档均应引用此处定义,不得出现矛盾版本。
为了支持复杂的 Buff/Debuff,伤害计算必须分步:
1. **Base Damage**: 法术面板值 (e.g. 10)
2. **Add Modifiers**: 累加修正器 (e.g. +5 +5 -> 20)
3. **Mult Modifiers**: 乘法修正器 (e.g. Critical 2.0x, Element Weakness 1.5x)
4. **Flat Reduction**: 敌人护甲 (Armor -2)
5. **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 管跨子弹的调用深度。
### 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 已失真,需统一血量口径后重算。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
若玩家攻速 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 代价是否累加?
* **规则定义**:两者**独立计算、顺序执行**
1. `SpellEvaluator` 先执行 `heavy_cost` MODIFIER(扣 10 HP,归类为”构建设计主动代价”)。
2. **之后**,若 mana 不足,`infinite_spells` 机制额外扣 1 HP(归类为”资源溢出代价”)。
3. 两者同帧触发时,单发最大 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`
```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 设计框架)。