熙源 Theo
DMFD Witch Mod
游戏系统设计&开发 — 2026

DMFD Witch Mod

把动作游戏的咏唱系统迁移到卡牌 Roguelike,并建立一套可验证的 AI 辅助 Mod 开发工作流

我把《Dragon Marked for Death》中的 Witch 搬进了玩法完全不同的《Slay the Spire 2》。项目聚焦于两个核心问题:

  1. 如何识别一个动作游戏角色真正不可替代的部分,并把它转译成卡牌 Roguelike 的决策?
  2. 如何让 AI 在资料零散、接口变化快、视觉与本地化工作量都很大的 Mod 项目中稳定协作?

前一个问题决定角色是否仍然是 Witch,后一个问题决定这个角色能否被完整做出来、验证并持续发布。

项目维度内容
职责系统转译、游戏设计、AI 开发工作流、C# / Godot 实现、测试与发布
技术栈C# / .NET 9、Godot 4.5、Harmony、BaseLib、Python、PowerShell
交付状态已发布至 Steam 创意工坊
实现规模201 个 C# 文件、约 14,340 行 C#、106 个卡牌类

说明: DMFD Witch Mod 是非官方同人模组,与《Slay the Spire 2》《Dragon Marked for Death》的开发商及发行商不存在隶属或合作关系。相关原作名称与角色归其权利方所有。

系统转译:从实时咏唱到回合决策

先理解原作:Witch 的核心在于咏唱决策

《Dragon Marked for Death》是一款横版动作 RPG。原作 Witch 的主要输出始于咏唱状态:玩家输入不同按键序列,将元素、强化、追踪或凝聚等咒文暂存起来,最后释放组合后的法术。

原作 Witch 进入咏唱状态并组合咒文的动图
原作 Witch 的咏唱机制:输入不同咒文逐步组合效果,再选择时机释放。

这套系统有几个关键特征:

  • 施法需要准备。 咏唱期间无法自由移动,输入和释放时机本身就是风险;
  • 法术可以组合。 元素决定基本类型,强化(Power-Up)提升等级,追踪(Homing)改变索敌方式,凝聚(Condense)牺牲范围换取集中与多段效果;
  • 暂存会形成压力。 已完成的魔法需要在时限内释放,但继续输入新的咒文又能延长并改造它;
  • 元素可以替换,修饰可以保留。 玩家可以根据敌人属性改变元素,而不用丢掉已经准备好的强化或特性;
  • 使魔与龙契约参与构筑。 契约会影响特定元素、法术暂存和使魔攻击方式,使角色身份不只存在于咏唱本身。

因此,Witch 最具辨识度的是施法过程:

先准备法术,再组合属性,在风险与收益之间决定何时释放。

这也是我选择迁移的核心。原作机制参考了 Dragon Marked for Death 官方介绍 与 Witch Wiki。

将实时输入转化为回合内的决策单位

动作游戏和卡牌 Roguelike 的时间结构完全不同。直接把按键指令照搬成卡牌,只会得到一组需要按顺序打出的“密码牌”,保留了表面形式,却丢失了原作的决策张力。

我把原作机制拆成四个可迁移的设计单位:

原作中的体验卡牌系统中的转译
咏唱需要停下动作并承担风险打出咒文消耗卡牌、能量与本回合行动机会
咒文暂存在角色身上法印跨卡牌、跨回合保留,等待释放
元素与修饰咒文可以叠加基础、特性、强化三类法印构成组合语法
在时限内选择继续准备或立即施法判断继续叠加价值,还是现在释放并清空法印

迁移后保留了“准备—组合—释放”的节奏,并将实时按键转化为回合内的决策。玩家仍然需要为一次更强的法术提前投入,也仍然可能因为过度准备而失去当下的出牌机会。

法印系统:把组合规则变成可读状态

我将原作咒文拆成三种法印:

  • 基础法印决定元素或回复属性:火、冰、雷、风、治疗、再生;
  • 特性法印改变生成牌的行为:追踪生成多张可选目标牌,凝聚将效果集中为一张高强度牌;
  • 强化法印负责数值放大,并允许逐层积累。

同类法印会替换,不同类型可以同时存在。玩家不用记住长指令,只需要读懂当前三个槽位,就能预测下一次“法术释放”会生成什么。

同一套法印规则同时驱动两个反馈层级:UI 层负责辅助决策,视觉特效(VFX)层负责还原施法表现。

在 UI 决策层,法印指示器直接展示当前三个槽位的图标、强化层数与组合状态,并实时预览下一次释放将生成的卡牌。UI 预览与真实结算共用同一套计算管线,会实时计入智力、强化层数与古龙契约修正,确保玩家看到的预览数值就是打出去的真实效果。

UI 层显示火焰、凝聚和强化法印状态的界面
UI 层的法印指示器:玩家可以直接读到当前元素、特性与强化层数。
UI 层预览法印组合将生成的凝聚火焰卡牌
UI 层的卡牌预览:直接显示下一次释放将生成的卡牌、最终伤害与强化效果。

在 VFX 表现层,法阵会在咏唱准备与法印维持期间持续存在于角色脚下,通过颜色表达基础法印、中心符号表达特性法印,并在释放瞬间配合攻击动画完成视觉反馈,在卡牌战斗中还原原作蓄力施法的演出感。

视觉特效层展示元素、治疗、再生基础法印与追踪、凝聚特性的组合矩阵
视觉特效层的组合总览:颜色映射基础法印,中心符号映射特性法印,不同组合对应独立的法阵结构。
战斗中持续显示法阵的视觉特效层预览
视觉特效层的战斗表现:法阵在咏唱准备与法印维持期间持续存在,并在释放时配合攻击完成反馈。

取舍:哪些机制被保留,哪些被重构

  • 独立的智力与魔法攻击:原作 Witch 的法术成长依赖 INT 与魔法属性。在《Slay the Spire 2》中,如果直接复用力量、虚弱和易伤,魔法构筑很快会退化成普通攻击牌的换皮。因此我建立了独立的智力与魔法攻击规则——智力先加入生成牌的基础值,再参与凝聚和强化倍率;魔法攻击不受力量、虚弱或易伤修正。这样既立住了法术成长的独特身份,也让预览与结算具备清晰的先后顺序。
  • 可构筑的使魔与龙契约:使魔没有被降级成纯背景动画,而是拥有独立卡牌、休息处成长和战斗状态;古龙契约则把使魔攻击、元素释放与不同减益连接起来,让玩家可以围绕法印、使魔或两者的交叉收益进行构筑。
  • 主动舍弃的实时操作负担:原作中的实时按键、移动限制、暂存倒计时以及魔导书 / 魔导具的完整武器差异都没有被照搬。它们在原作中服务于动作博弈,但在回合制里只会制造额外的记忆负担——卡牌、能量、抽牌顺序和出牌机会已经提供了充足的回合制压力,迁移重点应当留在组合结构与释放判断上。

AI 工程工作流:为模型构建可靠的上下文与验证闭环

《Slay the Spire 2》的 Mod 生态仍在快速变化。游戏本体、BaseLib 与 RitsuLib 的接口版本可能不同,反编译源码、运行时行为、Godot 资源和本地化文本又分散在不同位置。通用模型很容易引用旧版本 API,或写出能够编译但无法被游戏发现的实现。

AI 并不缺写代码的能力,缺的是可靠的上下文与及时的反馈闭环。为此,我逐步建立了一套项目级工作流:

设计文档定义行为
        ↓
只读 MCP 查询精确版本源码
        ↓
仓库 Skill 提供领域规则与检查清单
        ↓
C# / Godot / 本地化并行实现
        ↓
占位图与离线 VFX 先验证完整性
        ↓
自动校验、游戏内测试、打包与显式发布

改造 MCP:从“万能工具箱”收敛为只读证据层

我基于社区的 STS2 Modding MCP 做了定制,将原本同时覆盖代码生成、部署、游戏控制和资源处理的工具,收敛为一个只读源码研究服务。

它只回答三类问题:

  • 当前游戏版本中的类型、方法和继承关系是什么;
  • BaseLib / RitsuLib 当前项目实际依赖版本提供了什么 API;
  • 某个 Hook、符号或调用关系的源码证据在哪里。

服务索引反编译后的游戏 C# 源码,并为 BaseLib、RitsuLib 记录包版本、目标游戏 API、提交与缓存时间。MCP 对外只保留 11 个查询工具,构建、安装、PCK 打包、进程控制和素材生成全部移出 MCP,交回项目脚本与官方工具链。

这个改造解决了两个问题:一是防止 AI 把不同版本的 API 混在一起;二是建立清晰权限边界——源码研究可以自动进行,发布和运行时操作不能被一次查询顺带触发。

编写仓库 Skill:把踩过的坑变成可复用流程

MCP 能提供源码,但不会自动知道项目自己的约束。我把反复出现的经验整理为仓库级 Skill,让 Codex 与 OpenCode 在进入具体任务前加载对应规则:

Skill解决的问题
Modding Pitfalls卡牌注册、SmartFormat、预览变量、程序集命名等容易静默失败的问题
DMFD Witch Localization三语文件、术语表、动态变量与占位符如何同步
Godot PackagingDLL、PCK、安装目录与 Workshop 发布边界
STS2 VFX Style赛璐璐色带、轮廓、命中帧和离线预览规范
KitLib Testing如何在明确授权的测试局中记录操作前后状态并恢复快照

这些 Skill 是带有入口条件、硬规则、脚本路径和验收标准的操作说明。它们采用渐进披露:先读任务所需的短规则,再按问题进入本地化、VFX、打包或运行时测试细节,减少一次性上下文负担。

同时,DESIGN.md 被设为机制与术语的权威来源。代码、测试、本地化和 Workshop 文案都必须回到同一份设计定义,避免 AI 在不同文件中逐渐创造出互相矛盾的规则。

占位图管线:先让系统完整,再逐步替换美术

卡牌系统需要在美术完成前就验证牌池、升级、预览和战斗流程。为此我编写了占位图生成脚本:每张卡使用固定缩写和按类别区分的渐变色,普通卡与 Ancient 卡输出不同尺寸,并自动生成全量 contact sheet。

脚本还维护一份受保护的正式美术清单。批量生成时,如果正式图片意外丢失,流程会直接失败,以防占位图覆盖正式资源。这让占位素材既能加速早期开发,也不会在后期污染已完成的资源。

DMFD Witch Mod 正式卡面与自动生成占位图的全量检查表
占位图与正式美术共同进入检查表;当前图中包含 62 张生成占位图与 27 张正式卡面。

离线 VFX 预览:把视觉迭代变成可重复测试

VFX 同样没有依赖“进游戏看看,不对再重来”的长反馈链。我把 C# 与 Godot 的职责拆开:C# 负责实例化、目标、伤害结算和时序,GDScript 与 Shader 负责形状、粒子、位移与销毁。

仓库中的 VFX Skill 固定了视觉语言:硬轮廓、窄色带、清晰白色核心和短促命中反馈,避免与游戏背景混在一起的柔软发光。伤害帧必须与白闪、形变、星爆和震屏发生在同一时刻。

在此基础上,VFX 采用 AI 辅助的程序化流程:AI 根据统一的视觉规范生成与修改 GDScript、Shader、粒子参数和 Godot 场景;每个自定义场景都可以直接通过脚本在独立的 Godot 预览环境中运行并自动录制循环 GIF,无需启动游戏。我只需通过离线 GIF 逐帧验收轮廓、节奏与命中帧,确认达标后再打包进 PCK 做游戏内检查。

魔力炮击 VFX 的离线循环预览
“魔力炮击”的离线预览:蓄能、光束发射与命中反馈共用明确时间点。
魔女处刑 VFX 的离线循环预览
“魔女处刑”的离线预览:法阵、蓄能、落刃与实际伤害共用明确命中时间点。

本地化校验与发布安全边界

模组维护简体中文、英语和日语三套文本。简体中文目录定义完整文件与键集合,其他语言必须保持相同结构。每次机制或术语变化都需要同时检查 DESIGN.md 术语表、卡牌描述和三语 JSON。

自动校验会在 Godot PCK 导出前自动执行,把本地化变成硬性的构建条件,取代发布前的人肉检查:

  • JSON 解析、重复键和非字符串值;
  • 各语言的文件集合与 key 是否一致;
  • SmartFormat 动态变量(如 {Damage:diff:}、{Amount})与 formatter 签名是否完全匹配。

最终交付链路也被拆成职责单一的脚本,研究、实现、测试与公开发布各自处于不同的权限层级:

  1. 构建 C# Release 程序集;
  2. 校验本地化并通过官方 Godot CLI 导出 PCK;
  3. 安装到独立 Mod 目录进行游戏内验证;
  4. 生成带版本号的 Release 归档;
  5. 暂存 Steam Workshop 内容;
  6. 只有显式提供发布参数与变更说明时,才调用官方上传器。

普通构建不会触碰 Steam,只读源码 MCP 也无法触发构建或安装。这让 AI 可以放手参与高频开发工作,同时绝无可能越过最后的公开发布边界。


结果

DMFD Witch Mod 最终交付的是两套彼此支撑的系统。

第一套是角色系统:把原作的实时咏唱、法术组合与释放压力,转译为基础 / 特性 / 强化法印、卡牌准备成本和释放时机,让 Witch 在卡牌 Roguelike 中仍然保持原有的思考方式。

第二套是开发系统:用精确版本 MCP 提供证据,用仓库 Skill 固化经验,用设计文档统一规则,再通过占位图、离线 VFX、本地化校验、运行时测试和显式发布脚本形成可重复的交付流程。

对我而言,这个项目不只是“用 AI 写了一个 Mod”,而是一次关于如何设计 AI 工程环境的实践:让模型更容易得到正确上下文,也让错误更早、更明确地暴露出来。

返回作品列表 游戏系统设计&开发