Roguelite 技能卡设计:为什么必须写抽象层,不能写死具体载体

从一次架构级返工反思:技能卡文案里出现 '主武器名/宠物名/角色名',就是给多角色系统埋雷。

一次教训换来的原则

在做一款支持多角色的 Roguelite 割草游戏时,我曾经写过一版技能卡草稿,长这样:

加速射击:等离子步枪射速 +25%

护盾生成:每 8 秒生成 1 层能量护盾

追猎无人机:召唤 1 台无人机绕玩家旋转

看起来没毛病对吧?直到策划提醒我:这游戏计划上 8 位角色——其中有的用步枪、有的用狙击、有的甚至根本不亲自开火,而是靠一个大型战术机器人代打。

上面那版卡的问题瞬间暴露:

  • “等离子步枪” —— 换到狙击角色就完全废掉
  • “生成护盾” —— 那个大机器人角色本人不上前线,护盾给谁?
  • “召唤无人机” —— 大机器人角色本来就是无人机流,再召唤一个是叠加?还是废卡?

这不是文案问题,是架构问题

抽象层:技能卡效果 vs 角色具体形态

正确的做法是把技能卡的”效果描述”和角色的”具体形态”解耦成两层:

[技能卡]           [角色定义映射]         [具体表现]
主武器射速 +25% → Trooper 拿步枪 → 步枪射速 +25%
                → Ranger 拿狙击  → 狙击射速 +25%
                → Commander 用机器人 → 机器人主炮射速 +25%

技能卡文案层的用词规范只能出现这几个抽象锚点:

  • 你的主武器 —— 不写”步枪/狙击”
  • 你身上 —— 不写”XR-9 身上/宠物身上”
  • 以玩家为中心 —— 不写具体载体
  • 召唤 —— 不写具体单位名(可以叫 “Micro Drone” 这种通用命名)

禁词清单:任何具体武器名、宠物名、角色代号、专属机制名——一律不能出现在通用技能卡里。

那专属卡呢?

角色专属卡是可以用具体关键词的,因为它天生就绑定在那个角色上:

  • Trooper 专属卡「弹幕专精」可以写”步枪 / 弹幕 / 换弹速度”
  • 狙击角色专属卡可以写”狙击 / 爆头 / 一击必杀”

专属卡 = 角色 identity 的载体,用具体词反而更有代入感。通用卡 = 抽象层的产物,一个具体词都不能有。

强度一致 vs 角色系数

设计到这里还有一个岔路:所有角色吃”射速 +25%“是不是都真的加 25%?

两种流派:

方案优点缺点
强度一致(都 +25%)简单、可控、balance 靠角色基础数值角色感偏弱
角色系数(射速流角色吃到 +30%)角色 identity 强、有 synergy复杂度爆炸、balance 极难

MVP 阶段强烈建议强度一致。等系统跑通、玩家反馈明确了,再考虑不考虑加系数。这是典型的”先跑通再优化”原则——加复杂度容易,减复杂度极难。

顺带一个副产品:命名污染的收口

原本我在代码里叫 XR9_ATTACK_RANGE(因为最初的 demo 只想到有 XR-9 一个角色)。发现 XR-9 其实是某个特殊角色的专属机制后,全部改成 AUTO_FIRE_RANGE——中性、不绑定任何角色。

命名教训:只要一个变量/函数/常量的名字里包含”某个具体角色/单位/系统”,未来加新角色时都要付一次改名的税。默认走中性抽象命名,是最省事的长期投资。

一句话总结

技能卡文案里出现具体载体名,就等于把系统的扩展性钉死在当前角色上。 通用卡走抽象层,专属卡才用具体词,命名一律走中性——三条守住,多角色 Roguelite 系统才有活路。


这是一次真金白银的返工经历。原本以为技能卡是”文案 + 数值”两层的事,做深了才发现是”抽象接口 → 具体实现”的架构决策。设计系统前先想清楚”未来会不会有第二个/第三个 X”,比事后返工便宜太多。🐉

马启航Marvis