跳到主要内容

PRD-029 Buff/Debuff 状态系统

文档编号:PRD-029
版本:v1.0
状态:已通过
适用端:服务端 / 客户端
关联模块:SkillStatusManager、tbl/Status.xml、ScenesServer

1. 背景与目标​

Buff/Debuff 是技能、装备、任务、活动共用的状态载体。当前同类状态存在覆盖规则不一致、图标层数显示错误、死亡后未清理等问题。本 PRD 统一状态的添加、叠加、刷新、驱散、免疫与同步。

目标

  • 同一状态 ID 的叠加/刷新规则可配置。
  • 控制、持续伤害、属性增益有明确优先级。
  • 客户端图标、层数、倒计时与服务端一致。

不做

  • 不改变具体技能数值。
  • 不在本期做状态快照回放。

2. 核心规则​

2.1 状态分类​

类型示例是否可驱散死亡清除
增益攻击提升、护盾可是
减益中毒、破甲可是
控制眩晕、沉默、定身按配置是
光环队伍增伤不可是
场景状态温泉经验加成不可离开场景清除
信仰/活动国战增益不可活动结束清除

2.2 叠加规则​

规则说明
REFRESH重复施加只刷新持续时间,不叠层
STACK叠层,每层独立计算,超过上限刷新最旧一层
INDEPENDENT同 ID 但不同来源可共存,分别计时
REPLACE新状态替换旧状态,按强度/等级比较

2.3 覆盖与优先级​

  • 同类控制按优先级覆盖:眩晕 > 冰冻 > 定身 > 减速。
  • 低优先级控制不能覆盖高优先级,但可并存计时。
  • 免疫状态只阻止新状态添加,不移除已有状态。
  • 驱散按“可驱散 > 减益优先 > 剩余时间短优先”的顺序移除。

2.4 持续效果​

  • 持续伤害/治疗每 tick_interval 结算一次,首跳可配置为立即或延迟。
  • 持续伤害不触发暴击,受目标减伤影响。
  • 状态到期/被驱散时触发 on_remove 效果(如爆炸、回复)。

3. 服务端设计​

3.1 模块职责​

模块职责
SkillStatusManager状态添加、叠加、移除、tick
AttributeManager汇总状态对属性的修正
CombatManager持续伤害/治疗结算
ScenesServer场景切换、死亡、离开地图时清理

3.2 数据结构​

struct StatusInstance {
uint64_t instance_id; // 唯一实例
uint32_t status_id;
uint32_t source_id; // 施法者
uint32_t level;
int32_t stacks;
uint64_t expire_ms;
uint32_t next_tick_ms;
uint32_t flags; // 可驱散/免疫/死亡清除
};

struct StatusSet {
std::unordered_map<uint32_t, std::vector<StatusInstance>> by_status;
};

3.3 协议​

方向协议说明
S→CSC_StatusAdd新增状态,含实例 ID、层数、到期时间
S→CSC_StatusUpdate层数/时间变化
S→CSC_StatusRemove移除状态及原因
S→CSC_StatusList登录/重连全量同步
C→SCS_StatusCancel主动取消可取消状态(如变身)

3.4 添加流程​

添加请求
→ 校验免疫/互斥/目标存活
→ 查找同 status_id 实例
→ 按叠加规则 REFRESH/STACK/INDEPENDENT/REPLACE
→ 重新计算属性
→ 广播 SC_StatusAdd / SC_StatusUpdate
→ 注册 tick 定时器

3.5 定时与清理​

  • tick 使用时间轮,避免每个状态一个定时器。
  • 状态到期先执行 on_remove,再移除并重算属性。
  • 玩家死亡清除 death_clear=1 的状态;复活不自动恢复。
  • 跨地图时清除 map_clear=1 的状态,光环类重新施加。
  • 下线时状态不持久化,登录后由装备/被动/活动重新计算。

4. 客户端设计​

4.1 UI 表现​

  • 状态栏按优先级排序:控制 > 减益 > 增益 > 光环。
  • 图标右下角显示层数,鼠标悬停显示来源、效果、剩余时间。
  • 剩余时间小于 5 秒时图标闪烁。
  • 控制状态在角色头顶显示对应特效/文字。

4.2 协议处理​

  • SC_StatusList 全量替换本地状态,避免重连后残留。
  • SC_StatusAdd 按 instance_id 去重;同 ID 不同实例分别显示。
  • 本地倒计时只做展示,到期后等待服务端移除,不自行删除。
  • 收到 SC_StatusRemove 后播放结束表现(如护盾破碎)。

4.3 战斗提示​

  • 被控制时技能栏置灰,显示“无法行动”。
  • 免疫/抵抗时飘出“免疫”文字。
  • 驱散成功时目标头顶显示驱散图标。

5. 配置与数值​

tbl/Status.xml 字段:

字段说明
id状态 ID
type增益/减益/控制/光环
stack_ruleREFRESH/STACK/INDEPENDENT/REPLACE
max_stack最大层数
duration持续时间(ms)
tick_interval持续伤害/治疗间隔
dispel是否可驱散
death_clear死亡是否清除
map_clear跨地图是否清除
priority控制覆盖优先级
attr_mod属性修正列表
on_add / on_tick / on_remove触发效果

6. 边界与异常​

场景处理
同一状态重复添加按叠加规则处理,不产生重复图标
层数超过上限刷新最旧层,不新增实例
免疫时添加返回抵抗,不创建实例
驱散时状态已过期幂等移除,不报错
状态来源下线状态保留至到期;光环类立即移除
跨地图清除 map_clear 状态并重算属性
客户端断线重连全量 SC_StatusList 覆盖

7. 埋点与运营​

  • status_add/remove:状态 ID、来源、层数、持续时间、地图。
  • status_resist:免疫/抵抗次数。
  • status_dispel:驱散者、被驱散状态、剩余时间。
  • 后台可查询某状态的平均覆盖率与死亡率关联。

8. 验收标准​

  • 四种叠加规则均按配置生效,层数与剩余时间正确。
  • 控制优先级覆盖正确,低优先级不会顶掉高优先级。
  • 免疫只阻止添加,不清除已有状态。
  • 死亡、跨地图、下线按配置清理状态。
  • 客户端图标数量、层数、倒计时与服务端一致。
  • 500 个状态同时 tick 时无明显卡顿。