Snowygems

多版本兼容

SnowyGems 如何在 1.21.4 到 26.x 之间通用:注册表探测原理、版本模块开关、混服配置策略。

多版本兼容

SnowyGems 支持 1.21.4 及以上的全部版本,包括 1.21.5 ~ 1.21.11 与 26.x。同一份配置可以直接发到不同版本的子服,高版本内容在低版本上自动跳过。


实现原理:不猜版本,只问服务端

大多数插件用「如果版本 ≥ X 就支持 Y」的写法,问题是每出一个新版本都要更新插件,而且 Mojang 从 2026 年改用「年份.次版本」命名(26.1、26.2)后,版本号比较很容易出错。

SnowyGems 的做法是启动时读服务端的注册表,把当前实际存在的属性、附魔、药水效果、物品读成一份快照,之后所有查询都基于这份快照。

这带来三个直接好处:

新版本自动支持

服务端加了什么新属性/附魔/效果,插件立刻就能用,不需要等插件更新。

低版本优雅降级

配置里写了当前版本没有的内容,只跳过那一条并记日志,其他宝石照常工作。

数据包内容也认

你用数据包自定义的附魔/属性同样在注册表里,插件一样能识别。

查看当前版本支持什么

/sgem compat        # 简报
/sgem compat all    # 完整清单 + 配置自检明细

输出包含:

  • 服务端实现与版本
  • 注册表规模(属性/附魔/效果/物品各多少项)
  • AttributeModifier 用的是新 API 还是旧 API
  • 逐项能力探测结果(支持 / 当前版本没有 + 需要什么版本)
  • 功能模块启停状态
  • 配置自检结果

启动时也会打印简报,可以在 config.yml 里用 Compat.ReportOnStartup: false 关掉(仍可用命令随时查看)。


各版本新增内容一览

插件已把这些内容纳入探测清单,配置里可以直接写:

物品

内容引入版本配置里怎么写
锤 MACE1.21Require: [MACE]
矛 SPEAR1.21.11Require: [SPEAR]~onHit:SPEAR
铜盔甲 / 铜工具1.21.9Require: [COPPER_*]
狼铠 WOLF_ARMOR1.20.5Require: [WOLF_ARMOR]
刷子 BRUSH1.20Require: [BRUSH]

属性

属性引入版本简写
scale 体型1.20.5scale / size
block_interaction_range 方块交互距离1.20.5block_reach
entity_interaction_range 实体交互距离1.20.5attack_reach / entity_reach
jump_strength 跳跃力1.20.5jump
gravity 重力1.20.5gravity
max_absorption 吸收上限1.20.5absorption
safe_fall_distance 安全落地距离1.20.5safe_fall
fall_damage_multiplier 落地伤害倍率1.20.5fall_damage
submerged_mining_speed 水下挖掘速度1.21.2water_mining
mining_efficiency 挖掘效率1.21.2mining_efficiency
movement_efficiency 移动效率1.21.2movement_efficiency
burning_time 燃烧时长1.21.2burning_time
oxygen_bonus 氧气加成1.21.2oxygen_bonus
sneaking_speed 潜行速度1.21.2sneaking_speed
sweeping_damage_ratio 横扫伤害比1.21sweeping
waypoint_transmit_range 路径点广播26.x同名
waypoint_receive_range 路径点接收26.x同名
camera_distance 视角距离26.x同名

附魔(锤专属)

附魔引入版本
density 密度1.21
breach 穿透1.21
wind_burst 风爆1.21

药水效果(试炼密室)

效果引入版本
oozing 渗浆1.21
infested 寄生1.21
weaving 盘丝1.21
wind_charged 蓄风1.21
trial_omen 试炼预兆1.21
raid_omen 袭击预兆1.21

旧名兼容

1.20.5 起 Mojang 把附魔、药水效果、属性都从静态常量改成了注册表,旧名(DURABILITYDAMAGE_RESISTANCEGENERIC_MAX_HEALTH)在新版本已经不存在。

插件内置了旧名 → 新键的映射表,老配置不用改

你写的实际解析成
DURABILITYunbreaking
DAMAGE_ALLsharpness
LOOT_BONUS_BLOCKSfortune
ARROW_INFINITEinfinity
DAMAGE_RESISTANCEresistance
FAST_DIGGINGhaste
INCREASE_DAMAGEstrength
JUMPjump_boost
GENERIC_MAX_HEALTHmax_health

三种写法都能用:项目简写(health)、现代注册表键(max_healthminecraft:scale)、旧 Bukkit 常量名(GENERIC_MAX_HEALTH)。

新写配置建议直接用现代注册表键(小写下划线,如 unbreakingsharpnessresistance),和游戏内 /enchant/effect 的补全一致,不容易记错。

功能模块开关

config.ymlCompat.Modules 下有 7 个模块,每个可取三种值:

含义
auto由服务端注册表决定:有就启用,没有就停用(默认,推荐
true强制启用。注册表里没有时相关配置会报「跳过」
false强制停用。即使服务端支持也不启用
模块管辖内容
Mace锤及其专属附魔(密度/穿透/风爆)
Spear矛(分类匹配、~onHit:SPEAR 触发)
CopperEquipment铜盔甲与铜工具纳入 ARMOR / TOOL 分类
ModernAttributes1.20.5+ 新属性(scale、交互距离、重力等)
MiningAttributes1.21.2+ 挖掘与移动类属性
TrialEffects1.21+ 试炼密室药水效果
WaypointAttributes26.x 路径点属性

模块停用后,它管辖的属性/附魔/效果/物品在查询时一律返回「不存在」,上层按既有的「跳过并提示」路径处理。

平时不需要动这些开关。 auto 已经能正确处理绝大多数情况。手动改的场景只有一个:混服。

混服策略

如果你有多个不同版本的子服,共用同一份配置:

保持 auto(推荐)

什么都不用改。高版本子服自动启用新内容,低版本子服自动跳过。代价是低版本控制台会有「N 处内容当前版本不支持,已跳过」的提示。

低版本子服手动关掉高版本模块

如果嫌那条提示烦,在低版本子服的 config.yml 里把对应模块设为 false

Compat:
  Modules:
    Spear: false              # 这个子服是 1.21.4,没有矛
    WaypointAttributes: false # 也没有 26.x 的路径点属性

这样 Require: [WEAPON] 在这个子服上就不会把矛算进去,配置自检也不再提示它们。

上线前用 strict 自检

正式服上线前把 OnMissingFeature 改成 strict,重载一次,控制台会用醒目的错误级别列出所有真正写错的条目。确认干净后再改回 skip


配置自检的两类问题

自检会区分两种情况,这个区分很重要:

类型例子处理
版本不支持1.21.4 上写了 Require: [SPEAR]正常状态,只记 Debug 日志 + 一行概要
写错了写了 Enchant{name=sharpnes}(拼错)任何版本都不会生效,明确报出来
不做这个区分的后果是:内置的新版本示例宝石会在 1.21.4 上刷出几十条「错误」,服主看几次就再也不看这个报告了——真正的拼写错误也就被淹没了。

判据是模块归属表:归某个版本模块管的键算「版本不支持」,其余算「写错了」。写错的条目会带上拼写建议(如「你是不是想写: sharpness」)。

OnMissingFeature 三个级别的差异只影响「写错了」这一类的输出方式:

级别行为
skip一行概要 + Debug 明细(默认)
warn用 WARNING 级别逐条输出
strict用 SEVERE 级别逐条输出

三种级别都不会阻止插件启动


AttributeModifier 的 API 差异

这是插件里唯一真正需要按版本分支的地方,插件已经处理好,写在这里供参考:

版本构造函数
1.20.4 及以前AttributeModifier(UUID, String, double, Operation, EquipmentSlot)
1.20.5 起AttributeModifier(NamespacedKey, double, Operation, EquipmentSlotGroup)
1.21.9 前后部分服务端实现开始移除旧构造

插件优先用新 API,用反射探测可用性并缓存结果。清理旧修饰符时同时按 NamespacedKey 和 UUID 两种身份匹配——因为玩家的装备可能是在插件用旧 API 的版本上镶嵌的,服务器升级后如果只按新 key 清理,旧修饰符会永久残留并持续叠加。

/sgem compat 会显示当前用的是哪套 API。

slot 的槽位组语义(anyarmorany_hand)是 1.20.5+ 才有的。在只支持旧 API 的服务端上,这几个值会退化成主手。


常见问题

升级服务端版本后要做什么?

理论上什么都不用做。跑一次 /sgem compat 确认新版本能力被识别到即可。如果之前手动关过模块,记得把它们改回 auto

降级服务端版本后呢?

同样什么都不用做,高版本内容会自动跳过。想让控制台干净些,把对应模块设为 false

为什么我的新属性宝石没效果?

按顺序检查:

  1. /sgem compat all 确认这个属性在你的版本上存在
  2. 确认没有手动把对应模块设成 false
  3. 检查 limitvar 是否同号(这是最常见的原因,见宝石配置
  4. /sgem debug Reward 看这条 Rewards 的实际执行结果
Copyright © 2026