# 数值策划设计案:魔法工匠 (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` 逐杖 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` 事件后清零。 * **经验值 (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。 --- ## 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-30,E1-③ 归航实装)** —— 原行**保留不改写**,以留存「曾判定其为 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 设计框架)。