字段语义
Max Hand Size 如何处理多余抽牌、Starting Energy 何时覆盖 Base Energy、引擎识别哪些 keyword,以及其他需要明确的字段语义。
准备进入 Play Mode 只为确认字段含义时,先看这页。有些字段一看就懂,这页讲剩下的那些:两种读法都说得通、但只有一种和运行时一致的字段。这里的每条结论都对照过战斗代码,你可以照着创作,不必逐个试错
数值属于承载它的单位:Base HP 和 Base Energy 在 GamePlayerUnit 上,HP Min / HP Max 和 Tier 在 GameEnemyUnit 上。影响整场战斗的一切(Starting Hand Size、Draw Per Turn、Max Hand Size、Starting Energy、Card Reward Count、Animation Gap,以及那几个规则下拉框)都在遭遇战上,位于 Workbench Encounter 模式的 Battle Rules 折叠区。在玩家单位上找手牌或能量设置是找不到的,它们在遭遇战上
名称与描述
| Field | 含义 |
|---|---|
| Name | 编辑器列表和战斗 UI 里显示的名字。Name 非空时 Workbench 还会同步重命名底层的 Unity asset |
| Display Name | 状态专属的显示名,是玩家看到的状态名 |
| Description | 面向玩家的规则或风味文本,应与实际行为一致 |
Description 不是写给未来程序员的备注,它是玩家理解规则的一部分。描述 token 可以让它和图自动保持同步。demo 的 Fire Bolt 写着 “Deal 7 damage. Apply 2 Burn.”,它的图做的就是这两件事,顺序也一样
Type、Tier、Rarity、Tags、Keywords
| Field | 含义 |
|---|---|
| Type | 卡牌类别,用于颜色、过滤和玩家的心智模型。从已注册类型里选,不是手填字符串 |
| Tier | 敌人难度分组,例如 Normal、Elite、Boss |
| Rarity | 卡牌奖励与分组标签,例如 Common、Rare |
| Tags | 项目自由标签。除非节点或你的代码去读它,否则没有内置行为 |
| Keywords | 引擎自己识别并强制执行的卡牌规则 |

Tags 和 Keywords 长得像,行为完全不同。一个 tag 可以写 Fire 然后什么都不做;keyword 会改变战斗对这张卡的处理方式:
| Keyword | 引擎行为 |
|---|---|
Exhaust | 打出后进入消耗(exhaust)堆,而不是弃牌堆 |
Innate | 战斗开始时优先进入起始手牌 |
Retain | 回合结束时留在手牌,不被弃掉 |
Ethereal | 回合结束时若仍在手牌,直接被消耗。即使遭遇战用 Persist 保留手牌,这条规则仍会执行 |
Unplayable | 永远打不出去,只能持有、移动或被引用 |
列表之外的词一律按普通标签处理,没有内置效果
层数与持续时间
| Field | 含义 |
|---|---|
| Stack Rule | 状态被再次施加时如何与已有层数合并:相加、取最大、或替换 |
| Max Stacks | 层数上限。只有正数才生效。-1(默认值)表示不设上限。0 在运行时也表示不设上限,但 Workbench 会把它标记为可能的失误,因此想明确表达“无限”就用 -1 |
| Decay Rule | PerTurn 在持有者回合结束时减一层。挂在敌人身上的状态在敌人的回合衰减,不在玩家的回合。Never 不动层数 |
| Show Stack Count | 状态图标上是否显示数字徽标 |

层数会影响玩家决策就显示它。只有当状态是明确的开关效果、显示数字反而暗示不存在的行为时,才隐藏
HP 与能量
| Field | 位置 | 含义 |
|---|---|---|
| Base HP | 玩家单位 | 玩家单位的起始 HP,同时也是最大 HP,一个值管两件事 |
| HP Min / HP Max | 敌人单位 | 敌人起始 HP 区间,战斗开始时掷定一次。两端都取得到:demo 的 Strawman 设为 14 到 18,就真的可能掷出 18 |
| Base Energy | 玩家单位 | 玩家每回合开始补满到的能量 |
| Starting Energy | 遭遇战规则 | 遭遇战级覆盖。任何正数都会在这场遭遇战里替换 Base Energy;0 表示“使用玩家单位的 Base Energy” |
能量数值异常时,两个地方都要查。遭遇战覆盖职业默认值是有意设计,而 0 的回退规则很容易让人看错哪个值在生效。还有两类规则会改变补满量:局级 Energy 奖励永久 +1,hook 在 OnEnergyPerTurn 上的状态可以每回合改写这个值
手牌与抽牌
这四项全部是遭遇战级的 Battle Rules
| Field | 默认值 | 含义 |
|---|---|---|
| Starting Hand Size | 5 | 战斗开始时抽的张数。带 Innate keyword 的卡会被优先抽进来 |
| Draw Per Turn | 5 | 第一回合之后,每回合开始抽的张数。第一回合只有起始手牌 |
| Max Hand Size | 10 | 手牌上限。正常抽牌到达上限就直接停,没抽到的卡留在抽牌堆;被创造或被移动进满手牌的卡则改进弃牌堆 |
| Hand Discard | DiscardOnTurnEnd | 手牌是回合结束弃掉还是保留 |
三条相关行为值得记住:
- 抽牌途中抽牌堆空了,弃牌堆会自动洗回抽牌堆;两个堆都空时,抽牌提前停止,不报错
- “当前手牌”永远指效果结算那一刻在手牌里的卡,不含之后才会抽到的卡
- 手牌上限不是整场战斗定死的。带 Hand Size Hook 的状态可以实时升降它,每次抽牌都会检查 hook 后的值
目标
目标用词从玩家视角出发:
| Term | 含义 |
|---|---|
| Self | 拥有或打出该效果的单位。对玩家卡牌来说就是玩家单位 |
| Selected target | 本次结算中由玩家点选、或由图的选择逻辑选出的单位 |
| All enemies | 所有存活的敌方单位 |
| All allies | 与来源同一方的所有存活单位 |
| Random enemy | 由图或运行时规则选出的一个存活敌人 |
卡牌的 Target Mode 和图里的目标解析应保持一致。卡牌要求玩家选一个敌人时,图不应作用于全体,除非 description 明确写了
过滤器
过滤器文案要说清过滤后留下什么:
Cards with Tag = Fire
Enemies with Tier = Elite
Statuses where Is Debuff = true
过滤器语义应保持明确。GCS 的过滤器保留匹配项,而不是剔除匹配项
时机
| 时机用语 | 含义 |
|---|---|
| Battle start | 战斗状态已存在,起始手牌已抽 |
| Turn start | 一方回合的开端:护甲衰减和能量补满在这里执行,早于玩家行动 |
| Card played | 出牌已被接受、费用已扣除,卡牌的行为图即将结算 |
| Enemy phase | 敌人意图执行中 |
| Turn end | 行动方结束后的清理:弃手牌、状态衰减、延迟触发 |
| Battle end | 胜负已定 |
两个效果落在同一个边界时,边界内部的先后顺序决定谁能看到什么。玩家回合开始时:
- 护甲衰减(遭遇战用
Persist时跳过) - 能量补满到解析后的上限
- 设为
PlayerTurnStart的延迟触发跳一次 - 回合开始的状态触发和手牌内卡牌触发依次执行
- 抽 Draw Per Turn 张卡(第二回合起)
玩家回合结束时:
- 弃牌阶段触发执行
- 弃掉手牌,
Retain和Ethereal按各自规则例外处理 - 回合结束的状态触发执行
PerTurn状态各减一层- 临时 hook 和卡牌费用修改倒数一格
- 设为
PlayerTurnEnd的延迟触发跳一次
效果依赖精确时机时,把时机写进卡牌或状态描述。“你的回合开始时”和“抽到时”对赶时间的玩家读起来一样,直到其中一个坑掉一局
表现字段
| Field | 含义 |
|---|---|
| Icon | 编辑器列表和战斗 UI 使用的 sprite |
| Template | 表现层为该对象生成的 prefab |
| Animation Gap | 结算步骤之间的秒数,让效果一步步落地而不是同时糊上来。默认 0.28 |
| Enemy Intent Display | 玩家能看到多少意图信息:完整、只有图标、或隐藏 |
| Card Reward Count | 胜利界面提供多少张候选卡,从遭遇战的 Reward Deck 里抽样,同一条目不重复出现;Copies 越多的条目越容易被抽中。小于 1 的值按 1 处理 |
表现字段负责节奏和观感,绝不能用来隐藏玩法。一个设置若会改变玩家的决策,就把它写成规则并写进文档
数据库可达性
“Active”表示场景的 GameCardManager 已注册该数据库。一个 asset 可达,需要四条同时成立:
- 它存在于正确的数据库类型中
- 该数据库已注册到 manager 上
- 在需要引用的地方,有另一个可达 asset 引用了它
- 遭遇战或运行时流程从可达内容启动
内容没有出现在战斗里时,先查可达性。如果引用链没有到达该内容,修改字段无法解决问题