变体系统

Variable Horizons 的全部功能都建立在一套可开关的「变体」(Variant)枚举上。mod 本身不添加任何方块、物品、实体、维度、附魔或成就——它做的是按开关改写世界生成、配方、维度与难度规则。

注册真源

com.LazyFlesh.variablehorizons.variants.VariantNames 是一个 21 项的枚举,是所有变体的唯一注册真源。配置、GUI、命令、mixin 全部读同一个枚举。

分类 数量 判定方式
组合变体(compositionVariant = true) 4 NORMAL、GARDEN_OF_GRIND、SKYBLOCK、DIMLOCKED
子变体 / 修正项 17 其余全部
其中有 VariantLoader 实现类 12 见下表
仅靠 flag + mixin 生效(无实现类) 9 NO_RECIPE_ADDITIONS、VOID_WORLD、ALTERED_EFFICIENCY、CHEAP_MODE、EXPENSIVE_MODE、SUPERFLAT、MONOBLOCK、NORMAL、SKYBLOCK

组合变体的判定来自构造器重载:VariantNames(id, loaderClass, composedOf[], incompatible[]) 与 VariantNames(id, true, composedOf[], incompatible[]) 都会把 compositionVariant 置为 true。因此 GARDEN_OF_GRIND 与 DIMLOCKED 虽写作「4 参构造」,仍是组合变体而非子变体。

21 个变体

枚举名 对外 id 实现类 分类
NO_RECIPE_ADDITIONS NO_RECIPE_ADDITIONS — 子
VOID_WORLD VOID_WORLD — 子
VOID_ISLAND VOID_ISLAND VoidIsland 子
NO_ROCKET NO_ROCKET NoRocket 子
NO_QUEST_REWARDS NO_QUEST_REWARDS NoQuestRewards 子
NO_POLLUTION NO_POLLUTION NoPollution 子
ALTERED_RECIPE_TIME ⚠️ ALTERED_TIME AlteredRecipeTime 子
ALTERED_EFFICIENCY ALTERED_EFFICIENCY — 子
CHANCED_RECIPES CHANCED_RECIPES ChancedRecipes 子
CHEAP_MODE CHEAP_MODE — 子
EXPENSIVE_MODE EXPENSIVE_MODE — 子
INFINITE_POWER INFINITE_POWER InfinitePower 子
CUSTOM_DIM_START CUSTOM_DIM_START DiffDimStart 子
SUPERFLAT SUPERFLAT — 子
SKYGRID SKYGRID SkyGrid 子
MONOBLOCK MONOBLOCK — 子
CRIMSON_APOCALYPSE CRIMSON_APOCALYPSE CrimsonApocalypse 子
NORMAL NORMAL — 组合(什么都不做)
GARDEN_OF_GRIND GARDEN_OF_GRIND GardenOfGrind 组合
SKYBLOCK SKYBLOCK — 组合
DIMLOCKED DIMLOCKED DimLocked 组合

⚠️ ALTERED_RECIPE_TIME 的枚举名与对外 id ALTERED_TIME 不一致。玩家实际使用的字符串是 ALTERED_TIME(本地化键 variants.ALTERED_TIME.name),见 源码缺陷。

组合与冲突

每个变体持有 3 个集合:composedOf(由哪些子变体组成)、partOf(自己属于哪些组合变体,反向填充)、incompatible(互斥集)。构造时用 addIncompatibility() 双向写入,因此互斥关系是对称的;组合变体还会继承其所有子变体的互斥项。

判定入口:

  • activeContains(String... ids) —— 直接命中 activeVariants 集合,或命中某个子变体的 partOf
  • checkIncompatibility(a, b) —— 除双向 incompatible 外,还会展开双方的 composedOf 做交叉检查

加载时机

CommonProxy.serverStarted 中依次调用 CrimsonApocalypse.applyDifficultyToServer()、AlteredRecipeTime.applyToServer()、ChancedRecipes.applyToServer()。大部分 mixin 是 Phase.EARLY,需要重启游戏才能生效——这也是 mod 名里 “Horizons”(换天)的含义。

相关条目