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→C | SC_StatusAdd | 新增状态,含实例 ID、层数、到期时间 |
| S→C | SC_StatusUpdate | 层数/时间变化 |
| S→C | SC_StatusRemove | 移除状态及原因 |
| S→C | SC_StatusList | 登录/重连全量同步 |
| C→S | CS_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_rule | REFRESH/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 时无明显卡顿。