Repository navigation
Developer SpoiledZ Integration
This page documents why and how Globox1997/SpoiledZ was merged directly into WandererZ in v2.3.0, following the same playbook as the JobsAddon, RpgDifficulty, Tiered, and PartyAddon merges.
Every previous merge (JobsAddon, RpgDifficulty, Tiered, PartyAddon) was a LevelZ-specific addon with at
least one compat point importing net.levelz.* classes that needed repointing to net.wandererz.*.
SpoiledZ is different: it's a general-purpose food-spoilage mod by the same author with zero
LevelZ/WandererZ references anywhere in its source tree (confirmed via a full-repo grep for
levelz/LevelZ — zero matches). This made the merge mechanically simpler (no compat-point rewriting
needed at all) but introduced new dependency-management considerations instead.
Both mods also:
- target the same Minecraft version (1.20.1) and Yarn mappings
- use a fully disjoint Java package (
net.spoiledz.*) and resource namespace (assets/spoiledz,data/spoiledz), a clean sibling to the other four merged packages - SpoiledZ additionally ships vanilla resource overrides under
assets/minecraft/*(a cake blockstate- 41 item-model predicate overrides adding "spoiled" variants) — the first merged addon to touch the
minecraftnamespace directly, verified to have zero collision with any prior merge's resources
- 41 item-model predicate overrides adding "spoiled" variants) — the first merged addon to touch the
-
Inventory the tree. Cloned SpoiledZ's
1.20branch (36 Java files: entrypoints, config, mixins, compat). Grepped forlevelz— zero matches, confirming no compat rewrite was needed. -
Map the dependency graph. Three categories, same as Tiered's AutoTag/Reach Entity Attributes
precedent but with a third flavor added:
-
Required, separately-installed: Fabric Seasons — used
unconditionally (no
isModLoadedguard) inSpoiledUtilandServerWorldMixinfor season-based spoilage timing. Declared only infabric.mod.json'sdepends("seasons": "*"), not bundled — matching upstream SpoiledZ's ownmodCompileOnly modRuntimeOnly(notinclude) Gradle declaration. -
Bundled (shaded into the jar): Capsaicin — the
food-eaten/food-properties-modification event library
EventInithooks into. Shipped inside the final jar via Loom'sinclude(), same pattern as Tiered's Reach Entity Attributes. Required adding themaven.siphalor.deMaven repository (Capsaicin's Maven groupde.siphalorisn't on Maven Central or the Fabric/Modrinth maven). -
Optional soft-compat (gated by
FabricLoader.isModLoaded(...)inSpoiledzMixinPlugin): Farmer's Delight (already present in WandererZ's ownbuild.gradleat a matching version — no change needed), Expanded Delight, and Vinery (both newly added asmodCompileOnly).
-
Required, separately-installed: Fabric Seasons — used
unconditionally (no
-
Copy source wholesale, keeping
net.spoiledzas the package name — no renames needed since there was no LevelZ coupling to rewrite. -
Extract the Mod Menu screen. Same single-entrypoint-per-id constraint as every previous merge.
SpoiledZ's standalone
config/ModMenuIntegration.javawas deleted, and WandererZ's combined chooser screen gained a sixth button that opensAutoConfig.getConfigScreen(SpoiledZConfig.class, this). -
Merge the manifest.
fabric.mod.json: appended SpoiledZ'smain/cliententrypoints, registeredspoiledz.mixins.jsonalongside the existing four mixin configs, added"seasons": "*"todepends. Dropped the stray"suggests": {"another-mod": "*"}entry — a leftover from the unmodified fabric-example-mod template upstream SpoiledZ was scaffolded from (itscontact.sourcesfield even still points at the FabricMC example-mod repo) — rather than propagate a meaningless entry. -
Copy resources, verifying no collisions. Checked the main repo had zero pre-existing
assets/minecraft/*content before copying SpoiledZ's cake blockstate + 41 item-model overrides — confirmed safe, since no prior merge had ever touched the vanilla namespace. -
Add Gradle dependencies. Added the
maven.siphalor.derepository, Fabric Seasons asmodCompileOnly modRuntimeOnly(not bundled), Capsaicin as bundledmodImplementation(include(...)), and Expanded Delight + Vinery as optionalmodCompileOnlysoft-compat. -
Validate.
gradlew buildon JDK 17 succeeded, producingwandererz-2.3.0.jar. Verified the jar contains the expectednet/spoiledz/**classes (34), the mergedfabric.mod.json(entrypoints +seasonsdepend entry present), andMETA-INF/jars/capsaicin-1.20-*.jarbundled alongside the pre-existing Reach Entity Attributes bundle. -
Version bump.
mod_versionwent from2.2.0→2.3.0— a MINOR semver bump (additive functionality, no breaking changes).
-
compat/AppleSkinPlugin.javais fully commented-out dead code in upstream SpoiledZ (not wired to any entrypoint) — copied as-is for fidelity with upstream rather than deleted, since it compiles fine and matches the "copy wholesale" pattern used for other merged addons' similarly-inert code. - Farmer's Delight's existing
build.gradledependency — SpoiledZ uses the same version (1.4.3) WandererZ already depended on from the JobsAddon merge, so no version bump was needed. - Non-English SpoiledZ lang files — copied as-is; there was no WandererZ/LevelZ brand string to rebrand since SpoiledZ never referenced LevelZ in the first place.
A later PR added Serene Seasons as an alternative season provider for Food Spoilage, alongside Fabric Seasons. Unlike the rest of this merge, that PR is intentionally kept open for review rather than merged, since it changes a previously hard dependency into an either/or choice and introduces a new reflection-based compat pattern worth scrutinizing before it ships. Key points:
- A
net.spoiledz.compat.season.SeasonProviderinterface abstracts "what season is it / how long is a season" away from any specific mod.SeasonProviderInitpicksFabricSeasonsProviderorSereneSeasonsProviderat startup based onFabricLoader.isModLoaded(...)(Fabric Seasons preferred if both are present), or disables spoilage timing (logging a warning) if neither is installed. -
SereneSeasonsProvidercalls Serene Seasons'SeasonHelper/ISeasonStateAPI entirely via reflection rather than a compile-time dependency: Serene Seasons' Fabric artifact is compiled against Mojang's official mappings (not Yarn intermediary), so its public API types (e.g.Level) don't resolve in this Yarn-mapped project at compile time. Reflection sidesteps that since it resolves against actual runtime classes, which are identical regardless of which mapping set named them at compile time.FabricSeasonsProviderstill calls Fabric Seasons directly, since that mod is a normal Yarn-mapped Fabric artifact. -
fabric.mod.json's"seasons": "*"moved fromdependstosuggests, withsereneseasonsand its requiredglitchcorelibrary added alongside it — none of the three are hard requirements anymore. - Serene Seasons' GlitchCore dependency (Glitchfiend's cross-loader abstraction library) is published on
Modrinth as
maven.modrinth:glitchcore, so it's declared the same way as Serene Seasons itself (modRuntimeOnly, notmodCompileOnly, for the same mapping-mismatch reason above).
| Risk | Resolution |
|---|---|
| Mod Menu only showing one config per button slot | Added a sixth button to the existing combined chooser Screen
|
assets/minecraft/* overrides silently clobbering another mod's vanilla resource customization |
Verified zero pre-existing content at that path across all prior merges before copying |
Capsaicin's Maven group (de.siphalor) not resolving |
Added the maven.siphalor.de repository to build.gradle
|
Fabric Seasons being a hard, unconditional dependency (not isModLoaded-gated) |
Declared as a required dependency in fabric.mod.json's depends, documented in the README's installation section |
Stray template leftover ("another-mod" suggests entry) propagating into the merged manifest |
Dropped during the merge rather than carried forward |
| Hidden package/mixin-target/resource collisions | Verified none exist via full file-tree review before copying — net.spoiledz is fully disjoint from all other merged packages |
Player Guide
- Overview
- Getting Started
- Levels & Skills
- Jobs
- RPG Difficulty
- Tiered
- Party
- Food Spoilage
- Configuration
- Compatibility
- FAQ
Developer Guide