主题
这页不主讲大段原理,而是专门回答一个更实际的问题:
我要配一个 DOT、HOT 或周期实例,到底该改哪些字段?
如果你已经知道 HNAttribute 有 direct 和 instance 两种模式,但一到真正落配置时就容易混乱,这页就是给你准备的。
延伸阅读:
一、先记住文件分工
周期系统现在的配置入口是:
text
plugins/HNAttribute/periodic/settings.yml
plugins/HNAttribute/periodic/*.yml可以这样理解:
periodic/settings.yml
负责:
- 周期系统全局设置
- 调试开关
- 战斗状态超时等公共行为
periodic/*.yml
负责:
- 具体效果定义
- direct 周期规则
- instance 周期实例模板
- DOT/HOT 行为本体
如果你在纠结“到底去改哪个文件”,通常按这句判断就够了:
- 改全局行为 →
settings.yml - 改某个具体效果 →
periodic/*.yml
二、先理解三类常见需求
在服主视角里,最常见其实不是“我要配 periodic”,而是下面三类需求:
1. 简单周期回血/掉血
例如:
- 脱战回血
- 安全区回血
- 中毒地形定时掉血
这种通常优先考虑:
direct
2. 真正的 DOT/HOT 状态
例如:
- 中毒
- 灼烧
- 流血
- 持续治疗
这种通常优先考虑:
instance
因为你往往需要:
- 持续时间
- 重施策略
- 叠层
- 运行时实例追踪
- 生命周期钩子
3. 可调试、可 inspect 的运行时状态玩法
例如:
- 一个技能给目标挂 5 秒 DOT
- 再次施放时 refresh / stack / ignore
- 需要
/hnattr periodic list / inspect看实例
这种也优先:
instance
一句话速记:
- 简单规则型周期动作 →
direct - 真正状态型玩法 →
instance
三、全局配置:periodic/settings.yml
默认示例通常会像这样:
yml
combat-timeout: 100
debug:
level: off
key-filter: []1. combat-timeout
表示战斗状态保留时长,单位通常是 tick。
最常见用途:
- 脱战回血什么时候允许开始
- 某些基于
in_combat的周期条件什么时候恢复成立
例如默认回血示例里会用到:
text
in_combat <= 0所以如果你发现“脱战回血迟迟不触发”,要先回来看这里是不是超时时间太长。
2. debug.level
周期实例调试级别。
常见级别:
offbasicdetailtrace
建议:
- 日常服务器用
off - 配置调试时先开
basic - 真要追某个实例为什么没跳,再开
detail或trace
3. debug.key-filter
只调试指定 key。
示例:
yml
debug:
level: detail
key-filter:
- poison-dot适合:
- 不想让整个周期系统刷屏
- 只想盯某个 DOT/HOT 模板
四、一个周期效果最小长什么样
1. direct 最小模板
yml
玩家脱战回血:
enabled: true
selector: players
interval: 20
delay: 20
source-type: internal
tags: [periodic, regen]
condition:
mode: expression
script: "dead <= 0 && in_combat <= 0 && health < max_health && health_regen > 0"
actions:
- type: heal
amount:
mode: expression
script: health_regen它的心智模型是:
- 定时扫描目标
- 条件成立
- 直接执行动作
你可以把它理解成:
定时规则,而不是独立实例。
2. instance 最小模板
yml
玩家中毒实例演示:
enabled: false
mode: instance
selector: players
interval: 40
tags: [periodic, poison]
condition:
mode: expression
script: target_health > 4
instance:
source: nearest-player
interval: 20
delay: 0
duration: 100
reapply-mode: refresh
tick-condition:
mode: expression
script: target_health > 1
fail-policy: cancel
actions:
- type: damage
amount: 1.5它的心智模型是:
- 定时扫描目标
- 条件成立
- 创建一个目标周期实例
- 之后由运行时系统持续驱动它跳动
你可以把它理解成:
真正活着的一条状态实例。
五、顶层字段怎么理解
下面是你在 periodic/*.yml 里最常见的字段。
1. 顶层 key
例如:
yml
玩家中毒实例演示:这是效果定义名,同时通常也会成为你调试时最容易识别的 key。
建议:
- 名字能看出用途
- 别太口语化
- 最好和玩法语义一致
如果后期要大量 debug,命名清晰非常重要。
2. enabled
是否启用。
yml
enabled: true调试新效果时推荐先显式写上,避免你忘了为什么它完全不生效。
3. mode
周期模式。
常见:
- 不写:默认按 direct 理解
instance
如果你的目标是 DOT/HOT,建议显式写:
yml
mode: instance这样自己和后续维护的人都更容易读。
4. selector
扫描目标范围。
常见写法:
players- 其他由系统支持的实体选择方式
如果你只是做玩家相关效果,最常见就是:
yml
selector: players5. interval
扫描间隔,单位一般是 tick。
注意:
- 对 direct 来说,它就是执行周期的频率
- 对 instance 来说,它是“创建实例的扫描频率”,不是实例跳动频率
这点非常容易搞混。
最常见误区
yml
mode: instance
interval: 20很多人会以为这表示实例每秒跳一次。
其实不一定。
真正控制实例跳动频率的通常是:
yml
instance:
interval: 20也就是说:
- 顶层
interval:多久扫描一次、多久尝试挂实例 instance.interval:实例自己多久跳一次
6. delay
仅在某些 direct 模式下常见,用于初始延迟。
例如脱战回血,常见会写:
yml
delay: 20表示不是立即开始,而是有一个初始等待。
7. source-type
周期动作的来源类型。
例如:
yml
source-type: internal
source-type: dot这个字段很重要,因为它会影响:
- 战斗上下文
- 你在管线与调试里如何区分普通攻击、技能、DOT、内部回复
- 后续统计与问题排查时的分类心智
常见建议:
- 脱战回血:
internal - 持续伤害:
dot - 持续治疗:通常也可按你的体系决定是否单独分 source-type
8. damage-type
当动作是伤害时,用于指定它属于哪个伤害类型。
例如:
yml
damage-type: dot或者你也可以让某个 DOT 走元素类型:
yml
damage-type: fire这取决于你想让它:
- 显示为 DOT 分类
- 还是直接显示为火焰/冰霜/毒伤等通道
如果你想让 DOT 也吃某种元素表现,这里就非常关键。
9. tags
给这个周期效果附加标签。
示例:
yml
tags: [periodic, burn]用途通常是:
- 做调试分类
- 给 MythicMobs 或内部逻辑提供语义区分
- 给你自己的玩法体系留出额外标记位
建议:
- 保留一个通用标签,如
periodic - 再加一个玩法标签,如
burn、poison、regen
10. participate-pipeline(新增)
从 2.2.0 版本开始,周期伤害可以通过此参数进入战斗管线。
示例:
yml
actions:
- type: damage
amount: 5
participate-pipeline: true作用:
- 开启后,每跳伤害会作为显式伤害输入进入战斗管线
- 继续走命中、闪避、格挡、增减伤、暴击等阶段
- 系统会自动附加
participate-pipeline、explicit-damage和fixed-damage/percent-damage标签
默认行为(不开启):
- DOT 每跳直接结算,不经过战斗管线
- 保持原有的周期伤害语义
适用场景:
- 想让 DOT 也吃增伤、减伤、暴击等效果
- 需要通过管线配置统一控制所有伤害
- 想让周期伤害和普通伤害使用相同的计算规则
注意事项:
- 只对
type: damage的动作生效 type: heal不会进入战斗管线- 可在管线配置中通过标签控制显式伤害的处理(如排除 DOT 不暴击)
六、条件相关字段
1. condition
表示“这个效果现在有没有资格触发/创建实例”。
示例:
yml
condition:
mode: expression
script: target_health > 4最适合做:
- 玩家未满血才回血
- 目标血量足够时才挂中毒
- 脱战后才触发回复
这个条件是效果入口条件。
可以把它理解成:
这个效果现在要不要开始干活?
2. tick-condition
只在 instance 模式里最常见。
示例:
yml
tick-condition:
mode: expression
script: target_health > 1它不是决定“要不要创建实例”,而是决定:
这个已经创建出来的实例,在每一跳时还能不能继续执行。
所以它更偏运行中条件。
3. fail-policy
tick 条件失败时怎么办。
常见值:
cancel- 其他按系统支持的失败策略
最常见理解:
cancel:条件不满足就直接结束这个实例- 非 cancel:可能只是跳过这一 tick
所以:
- 想让低血时中毒直接停止 →
cancel - 想让某 tick 不满足时只是跳过 → 选跳过型策略
七、instance 节点里的核心字段
如果你在做 DOT/HOT,最关键的通常是 instance: 下面这些字段。
1. source
示例:
yml
instance:
source: nearest-player表示这个实例的来源是谁。
不同来源会影响:
- 调试里看到的 source
- 某些伤害归属
- 某些与来源有效性相关的行为
如果你只是做自作用效果,也可能使用:
self
2. interval
示例:
yml
instance:
interval: 20表示实例每多久跳一次。
这是 DOT/HOT 最关键的节奏字段之一。
3. delay
示例:
yml
instance:
delay: 0表示实例创建后第一次跳前的延迟。
常见理解:
0:马上开始20:延迟 1 秒再开始
4. duration
示例:
yml
instance:
duration: 100表示实例总持续时长。
如果配合 interval: 20,那大致就是持续 5 秒、每秒跳一次。
5. reapply-mode
示例:
yml
instance:
reapply-mode: refresh这是 DOT/HOT 最重要的玩法字段之一。
它决定:
已经存在同类实例时,再次施加要怎么处理。
常见理解:
refresh:刷新持续时间ignore:已有就不重复挂- 其他模式:按系统支持的叠层/重施规则处理
如果你想做:
- “持续时间重置型中毒” →
refresh - “已有灼烧就不重复挂” →
ignore
6. max-stacks
示例:
yml
instance:
max-stacks: 3表示最多可叠多少层。
如果你的玩法需要:
- 流血可叠层
- 中毒最多 3 层
- HOT 最多 2 层
这个字段就很关键。
八、动作:actions
最终真正执行的内容通常在 actions: 里。
例如:
yml
actions:
- type: damage
amount: 1或者:
yml
actions:
- type: heal
amount:
mode: expression
script: health_regen最常见动作类型:
damageheal
amount
可以是:
- 固定数值
- 脚本表达式
例如固定值:
yml
amount: 1.5例如表达式:
yml
amount:
mode: expression
script: health_regen建议:
- 先用固定值验证流程
- 确认效果会跳后,再换表达式
这样排错最省时间。
participate-pipeline(新增)
从 2.2.0 版本开始,可在动作级别配置是否参与战斗管线:
yml
actions:
- type: damage
amount: 5
participate-pipeline: true详见前文"顶层字段"中的 participate-pipeline 说明。
九、生命周期钩子怎么理解
instance 模式最强的地方之一,就是生命周期钩子。
常见有:
on-applyon-skipon-cancelon-expire
例如:
yml
on-apply:
- type: damage
amount: 0.25
on-expire:
- type: heal
amount: 0.3可以这样理解:
on-apply
实例刚挂上时触发一次。
on-skip
某一跳因为条件或策略被跳过时触发。
on-cancel
实例被取消时触发。
on-expire
实例自然到期时触发。
这让你能做很多传统 DOT/HOT 配置做不到的玩法,例如:
- 挂毒时先爆一下
- 中途失败时返一点血
- 到期时触发额外结算
十、最常见的 4 种实际模板思路
1. 脱战回血
优先:
directsource-type: internaltype: heal
2. 简单自伤 DOT 演示
优先:
directsource-type: dotdamage-type: dottype: damage
适合做冒烟测试。
3. 真正中毒/灼烧/流血
优先:
mode: instancereapply-modetick-conditionfail-policymax-stacks
4. 持续治疗状态
优先:
mode: instancetype: heal- 需要时加
refresh或叠层
十一、排查顺序
如果一个 DOT/HOT 没生效,建议按这个顺序查:
1. 先看有没有加载
- 文件有没有放到
periodic/*.yml enabled有没有开/hnattr reload有没有执行
2. 再看入口条件过没过
重点看:
selectorcondition- 顶层
interval
3. 如果是 instance,再看实例有没有创建
命令:
text
/hnattr periodic list
/hnattr periodic inspect <key>如果 list 里没有,问题通常在:
- 创建条件没过
- 模板没启用
- 扫描频率还没到
4. 如果实例创建了,再看运行中逻辑
重点看:
instance.intervaldurationtick-conditionfail-policyactions
5. 最后看显示与伤害上下文
如果你觉得“它没打出来”,还要确认:
- 是不是真的没跳
- 还是跳了但显示不明显
damage-type是否配到了你预期的通道source-type / tags是否被 pipeline 过滤了
十二、最实用的速记版本
如果你不想记太多,就记下面这几句:
- 改全局行为看
settings.yml,改具体效果看periodic/*.yml。 - 简单周期规则用
direct,状态型 DOT/HOT 用instance。 - 顶层
interval是扫描频率,instance.interval才是实例跳动频率。 condition管入口,tick-condition管实例运行中。reapply-mode、max-stacks、生命周期 hooks 决定玩法上限。- 从 2.2.0 开始,可通过
participate-pipeline: true让 DOT 参与战斗管线。
