Skip to content

现在应该用 debug 还是 log.level

当前版本更推荐:

yml
log:
  level: INFO

可选值:

  • OFF
  • INFO
  • DEBUG
  • TRACE

旧写法仍兼容:

yml
debug: true

兼容关系是:

  • debug: trueDEBUG
  • debug: falseINFO

如果你只是普通上线,建议先保持 INFO;只有查深度链路时才临时开到 TRACE

修改配置后为什么没生效?

先分清你改的是哪一类文件:

只改了脚本配置或脚本文件

例如:

  • GroovyConfig/*.yml
  • GroovyScripts/*.groovy

通常执行:

text
/hncore reload scripts

改了核心配置或共享存储配置

例如:

  • config.yml
  • storage.yml
  • entity-names.yml
  • toolbox-search-aliases.yml

通常执行:

text
/hncore reload

很多“我明明改了配置怎么没变化”的问题,本质上都是 重载命令用错了

为什么脚本出现在 list 里,但没有真正生效?

因为“已加载”和“已启用”是两个概念。

  • 只要脚本文件存在,它就可能出现在 list
  • 只有对应 yml 的 enabled: true 时,它才会真正注册并生效

排查顺序建议:

  1. 先看 /hncore scripts list
  2. 再看 /hncore scripts enabled
  3. 最后核对对应脚本配置里的 enabled

删除脚本文件和 enabled: false 有什么区别?

enabled: false

  • 脚本仍保留在目录中
  • 更适合日常管理
  • 方便后续再次开启

删除脚本文件

  • 服务端不会再加载该脚本
  • reload scripts 后会停止对应脚本
  • 适合你明确不再需要这个脚本时

如果你只是“暂时不用”,通常更推荐改 enabled: false

为什么我改了脚本目录,文档里的 GroovyConfig/GroovyScripts/ 路径不对?

因为当前版本里,脚本目录名本身就是可配置的:

yml
feature-scripts:
  config-directory: GroovyConfig
  script-directory: GroovyScripts

文档里写的是默认目录名

如果你改过这两项:

  • 以后所有脚本配置路径
  • 脚本文件路径
  • 排查时使用的目录

都要以你自己的 config.yml 为准。

为什么我把 security-level 改成 SANDBOXED,脚本还是按 UNSAFE 跑?

因为当前模块化脚本系统为了兼容完整 Groovy 能力,会在发现:

yml
feature-scripts.groovy.security-level: SANDBOXED

时给出警告,并仍按 UNSAFE 模式加载。

也就是说,对 GroovyScripts 来说,当前推荐值就是 UNSAFE

注意:这里说的是 脚本系统formula.groovy 那套数值公式策略是另一条配置链,不要混在一起看。

为什么脚本系统明明 enabled=true,但脚本还是没有注册?

优先检查:

yml
feature-scripts:
  enabled: true
  groovy:
    enabled: true

当前实现里:

  • feature-scripts.enabled = false:整套脚本系统关闭
  • feature-scripts.enabled = truefeature-scripts.groovy.enabled = false:目录和配置可能还在,但脚本不会真正注册

这也是“文件都在,但功能没工作”的高频原因之一。

为什么数据库配置改了,但 HNCore 看起来还是没用新配置?

先确认你改的是不是 storage.yml

数据库与共享存储现在分别看这里:

  • 共享数据库配置入口:storage.yml -> database
  • 共享存储配置入口:storage.yml -> storage.mysql / storage.redis

如果你改完后没同步,执行:

text
/hncore reload

为什么 /hncore reload 之后共享数据库还是不可用?

优先按这个顺序排查:

  1. storage.yml -> database.enabled 是否为 true
  2. type 是否写对
  3. 对应 sqlite / mysql 配置是否完整
  4. 控制台是否有初始化失败日志

另外,/hncore reload 会明确告诉你:

  • 共享数据库是否启用
  • 当前数据库类型
  • 是否初始化成功

所以遇到这类问题,最先看 reload 输出 和控制台日志。

为什么共享键值存储不可用?

当前实现中,共享键值存储的优先级是:

  1. Redis
  2. MySQL
  3. 都没有就不可用

也就是说,如果你看到“共享键值存储不可用”,通常意味着:

  • storage.redis.enabled = false
  • storage.mysql.enabled = false
  • 或者两者虽然开启,但初始化失败

简单理解:

  • 想要键值存储,至少要成功启用 Redis 或共享 MySQL
  • 两边都没起来,就一定不可用

为什么共享消息总线(Pub/Sub)不可用?

因为 Pub/Sub 只在 Redis 可用时才会启用

所以即使:

  • 共享数据库正常
  • MySQL 正常
  • 共享键值存储已经回退到 MySQL

只要 Redis 没启用或初始化失败,Pub/Sub 仍然不可用。

启动日志里的“集群控制面已启用”是什么意思?

它不是 GUI 面板,也不是网页后台。

这里的“集群控制面”指的是 HNCore 新增的 ClusterBus / 集群通信基础层,主要给下游插件做统一跨服广播用,例如 HNAttribute 的:

  • reload cluster
  • refresh cluster
  • debug cluster
  • perf reset cluster

最直接的查看入口是:

text
/hncore cluster status

如果你只在启动日志里看到:

text
transport=loopback

说明当前 ClusterBus 已建立,但只是本服本进程自测模式,还没有真正接到跨服 Redis transport。

为什么日志里提示 cluster.node-id 未配置?

因为当前 storage.yml -> cluster.node-id 留空了。

这时 HNCore 会自动回退为:

text
服务器名@端口

例如:

text
paper@25565

单服测试这样没问题,但多服正式环境建议为每台服显式配置唯一 node-id

为什么 ClusterBus 是 loopback,不是 redis?

最常见原因是:

  • storage.redis.enabled = false
  • 或 Redis 虽然开启,但初始化失败

cluster.transport=auto 时,HNCore 会:

  • Redis 可用 → transport=redis
  • Redis 不可用 → transport=loopback

所以 loopback 不代表系统没启动,而是代表 当前只能本地回环,不跨服

为什么 HNAttribute 的 cluster 广播没有跨服?

现在应该优先排查 HNCore,而不是先排查 HNAttribute 自己。

建议顺序:

text
/hncore status
/hncore cluster status
/hncore cluster ping

重点看:

  • Redis 是否真的 active
  • 当前 transport 是不是 redis
  • cluster.node-id 是否为唯一值
  • cluster.channelstorage.redis.channel-prefix 是否兼容

为什么 /hncore tools 在控制台里不能用?

因为工具箱是 GUI,当前实现 仅限玩家执行

如果你在控制台执行,会被直接拒绝。

为什么我改了 toolbox-search-aliases.yml,但搜索结果没变化?

因为工具箱搜索别名字典是在插件启用时加载的。

改完这个文件后,最稳妥的做法是:

text
/hncore reload

或者直接重启服务器。

只执行:

text
/hncore reload scripts

通常不会重新加载工具箱别名字典。

为什么工具箱能搜英文,搜中文却不太准?

优先检查:

text
plugins/HNCore/toolbox-search-aliases.yml

当前工具箱会基于这个文件做:

  • 中文 ↔ 英文
  • 单复数
  • 常见近义词
  • 常见实体 / 材质 / 音效 / 粒子词

如果这个文件为空,HNCore 会回退到内置默认别名组,但你自己的自定义词就不会生效。

为什么大厅里玩家连箱子、按钮都不能用?

优先检查 WorldProtect 中的:

yml
prevent-interact: true

这项会阻止玩家与很多可交互方块互动。如果你的目标只是防拆防放,而不是彻底禁止交互,就需要重新评估这里的配置。

另外,当前实现只会拦截:

  • 主手触发
  • 右键方块
  • 且方块本身可交互

为什么我有权限还是被 WorldProtect 拦住?

优先核对:

yml
bypass-permission: hncore.scripts.worldprotect.bypass

当前实现要求:

  • 这个权限节点非空
  • 并且玩家拥有该权限,或玩家本身是 OP

如果你把它留空,就不会再按这个权限节点绕过。

为什么爆炸还有声音和特效,但建筑没有被炸坏?

这通常正是 ExplosionProtect 的预期效果。

它会清空爆炸要破坏的方块列表,而不是取消爆炸事件本身。

为什么玩家能自动复活,但物品还是掉了?

因为 AutoRespawn 只负责自动复活,不负责保留背包或清空掉落。

如果你希望“死后秒复活且不掉物”,通常还需要同时启用 KeepInventory

为什么玩家的饥饿值一直不变化?

优先检查是否启用了 NoHunger

如果该脚本开启,当前实现会在这些时机把玩家状态同步回配置值:

  • 饥饿变化时
  • 登录时
  • 重生时
  • 切换世界时

而且当前版本里,reload scripts 后还会立即同步当前在线玩家,所以你改完配置后通常会马上看到效果。

为什么装备和工具几乎不掉耐久?

优先检查是否启用了 DurabilityProtect

这个脚本会监听 PlayerItemDamageEvent,命中配置后直接取消耐久损耗。

如果你只想保护某一类物品,重点检查:

yml
protect-armor: true
protect-tools: true
protect-weapons: true
protect-shield: true
protect-elytra: true

为什么玩家掉进虚空后没有死,而是被传送回来了?

优先检查是否启用了 VoidProtect

当前实现会在玩家受到 VOID 伤害时:

  • 取消这次伤害
  • 优先传送到玩家重生点
  • 若没有重生点,则回到当前世界出生点
  • 按配置决定是否回血、补满饥饿、清火

为什么大厅里玩家互相打不到?

优先检查是否启用了 PvpControl

当前实现不只拦截近战,也会按玩家来源拦截:

  • 投射物
  • 驯服生物
  • 可识别到来源的 TNT

如果你希望管理员或特定职业绕过,检查:

yml
bypass-permission: hncore.scripts.pvpcontrol.bypass

为什么某个世界里的敌对怪突然刷不出来了?

优先检查是否启用了 MobSpawnControl

当前实现会监听 CreatureSpawnEvent,只要满足:

  • 当前世界命中 worlds
  • 当前实体命中了 block-hostile-mobs / block-friendly-mobs 对应的拦截类型
  • 当前生成原因没有被 allowed-spawn-reasons 放行

就会直接取消生成。

重点检查:

yml
block-hostile-mobs: true
block-friendly-mobs: false
worlds: []
allowed-spawn-reasons:
  - COMMAND
  - SPAWNER_EGG
  - CUSTOM

这组默认语义代表:

  • block-hostile-mobs: true:默认拦截敌对生物
  • block-friendly-mobs: false:默认保留友好生物
  • worlds: []:所有世界生效
  • allowed-spawn-reasons:默认保留命令、玩家怪物蛋与插件自定义生成

如果你想保留刷怪笼、发射器怪物蛋、命令或其他插件召唤,记得把对应生成原因加入:

yml
allowed-spawn-reasons:
  - SPAWNER
  - DISPENSE_EGG
  - COMMAND
  - SPAWNER_EGG
  - CUSTOM

我应该先读哪几页?

如果你时间有限,推荐顺序如下:

  1. 快速开始
  2. 安装与首次启动
  3. config.yml 配置说明
  4. 命令说明
  5. GroovyScripts 总览

HN 系列插件文档