性能设置
调整属性更新、定时检查和缓存清理
Symphony 的主要开销来自属性更新、伤害计算、定时回调和物品 Lore 刷新。默认设置适合普通服务器;实体数量较多或回调较复杂时,可以根据本页调整。
可调项目
| 配置 | 默认值 | 用途 |
|---|---|---|
equipment.coalesce-ticks | 以主配置为准 | 合并短时间内连续发生的装备变化 |
performance.timer-bucket-ticks | 20 游戏刻 | 状态、环境和 entity.timer 的检查间隔 |
performance.cache-idle-seconds | 300 秒 | 清理长期未使用实体数据前的等待时间 |
提高检查间隔可以减少主线程工作量,但状态到期、环境变化和定时回调的响应也会稍慢。缩短缓存等待时间只会更早清理已经失效或长期不用的实体,不会移除仍带有有效属性的怪物。
属性更新
装备、状态或外部物品来源发生变化时,Symphony 会重新计算受影响实体的属性。短时间内连续拖动、切换或穿脱装备时,equipment.coalesce-ticks 会把这些操作合并为一次更新。
属性内容没有变化时,不会重复更新。原版属性同步也只修改 Symphony 自己添加的 Bukkit 属性修改器,不会清除药水、原版装备或其它插件提供的数值。
如果服务器中频繁发生装备切换,可以适当提高 equipment.coalesce-ticks。数值不宜过高,否则玩家换装后会明显感觉属性更新延迟。
定时检查
performance.timer-bucket-ticks 同时影响状态、环境和 entity.timer:
- 没有配置
entity.timer回调时,不会为了该回调遍历世界生物; - 状态到期、状态周期效果和环境条件按该间隔检查;
- 已过期的元素附着、技能冷却、回调冷却和脚本执行间隔会在维护时清理。
持续生效的属性应优先写成装备、状态或环境效果,不建议用每游戏刻扫描所有实体的回调实现。
战力读取
战力在界面、PlaceholderAPI 或 API 第一次读取时计算,属性和公式未变化时会直接使用已有结果。没有读取战力的怪物不会提前计算战力。
如果战力公式使用 level 或 experience,第一次读取应发生在 Bukkit 主线程。异步 PlaceholderAPI 请求只能读取已经计算好的结果。
实体数据何时清理
| 情况 | 处理方式 |
|---|---|
| 玩家退出或被踢出 | 关闭界面,并清理该玩家的临时属性、战斗记录、护盾、冷却、状态和元素附着 |
| 普通生物死亡 | 本次伤害处理完成后清理 |
| MythicMobs 死亡或消失 | 移除怪物属性并清理临时数据 |
| 实体失效或长期不再使用 | 达到 cache-idle-seconds 后清理 |
| 插件关闭 | 取消任务、返还界面中的暂存物品并清空临时数据 |
仍然存活且带有有效属性的实体不会仅因长时间无人读取而失去属性。服务器若长期保留大量自定义怪物,内存占用也会随实体数量增加。
每个实体最多保留最近 100 笔伤害记录。已经到期的临时属性修改会被移除,不会继续阻止该实体被清理。
附属插件
附属插件注册的属性、LevelProvider、AttributeProvider 和触发器会在该插件停用时注销。附属插件仍应保存并在停用时关闭自己的 RegistrationHandle,避免重载期间暂时保留旧注册项。
调整建议
出现卡顿时,应先用采样器确认开销来自哪里:
- 装备切换较多:检查 Lore 重建次数,并适当提高
equipment.coalesce-ticks; - 状态或环境较多:适当提高
performance.timer-bucket-ticks; - 常驻怪物较多:检查带有 Symphony 属性的有效实体数量;
- 回调耗时较高:减少高频 Aria 脚本,优先使用现成的条件、动作和状态;
- 伤害频率较高:检查每次攻击包含的通道数和回调数量。
压测时应使用正式服的属性定义、装备数量和脚本。除 TPS 外,还应观察主线程采样、实体数量、堆内存和完整 GC 后仍然保留的对象。
