What happened
My client crashed while playing on a multiplayer server in the Overworld with Wilder Wild's wind-driven clouds enabled. It had been connected for about 21 minutes, with no reconnect or dimension change near the crash.
The error was:
IllegalStateException: WWWindManagerExtension was not registered for level ClientLevel
This looks related to #80, but it happened with FrozenLib 2.5.3-mc26.2, and the exception is different. I inspected the released JARs; I have not checked whether the current development branch already fixes this.
Likely cause
When a wind update arrives from the server, FrozenLib replaces the wind extension that Wilder Wild uses to position clouds. It removes the old extension, then adds the replacement.
That replacement happens on the network decoding thread while the render thread can still read the same list. If rendering reads it between the removal and the addition, Wilder Wild cannot find its extension and throws the error above.
The released code and a local test confirm that decoding changes the shared wind manager before the update reaches the client thread. I have not captured the exact timing of the crashing frame, so this is the likely explanation for the crash rather than a confirmed reproduction of that frame.
Reproduction and environment
I do not have reliable steps to trigger the crash on demand. It occurred during normal multiplayer play with wind-driven clouds enabled, in a larger modpack.
- Minecraft: 26.2
- FrozenLib: 2.5.3-mc26.2 (Modrinth version
Ak4sHFuc)
- Wilder Wild: 4.2.11-mc26.2 (Modrinth version
TVkz6cZh)
- Fabric Loader: 0.19.5
- Fabric API: 0.160.0+26.2
- Windows 11, Azul Java 25.0.4
Suggested fix and local testing
A local compatibility patch reads incoming wind data into a separate object, then updates the shared wind manager when Fabric applies the attachment on the client thread, after checking its target. This keeps the existing merge behavior and packet order while avoiding changes to live wind state during network decoding.
A small test harness called the real wind decoding and attachment methods using the same FrozenLib, Wilder Wild and Fabric API JARs, with Fabric Loader 0.19.3:
- Without the patch: decoding on a worker thread returned the shared wind manager and changed its state immediately.
- With the patch: decoding left the shared manager unchanged; applying the attachment on the client thread updated it and preserved its identity.
- The patched run also checked packet order, reapplying the shared manager, and attachment deletion. Both test runs exited successfully.
The harness used a minimal synthetic level object, not a playable world. The patch has not been tested in full-pack gameplay or deployed. Its source is in a private repository, so the relevant findings are included here directly.
Technical details and a separate reset problem
Wind update path
WindManager.applyFromStreamCodec writes directly to static WindManager.INSTANCE. For an extension whose supportsApplicationFromSync() returns false, it removes the existing entry before adding the replacement. Wilder Wild inherits the interface's default false implementation.
Minecraft's Netty PacketDecoder invokes this codec before Fabric hands attachment application to the client packet-processing thread. During a periodic wind update, the seed remains present, allowing Wilder Wild's cloud getter to run while its extension is temporarily absent.
The local patch defers the original merge until the attachment write in AttachmentChange.tryApply, after the target resolves. The inspected Fabric attachment module is 2.2.19+515ac5339e.
Separate reset problem
WindManager.reset() clears extensions but leaves loadedExtensions=true. The next tryCreateAndSortExtensions(Level) therefore returns early instead of rebuilding the list. Client level-change and disconnect callbacks both call reset.
The local patch also clears this flag. The unpatched test confirmed the stale flag; the patched test confirmed that one Wilder Wild extension was recreated afterward. Reconstruction itself was not exercised in the unpatched run.
Reset also clears the wind seed, which temporarily disables wind-driven clouds. A later full sync can restore the extension before restoring the seed, so this reset problem alone does not explain the mid-session crash.
Test limits
The synthetic level contained only the client-side, dimension and registry fields required for the calls. It was never installed in Minecraft, ticked or rendered. Handling of an unresolved attachment target was inspected in bytecode but not tested in a connected world. The harness separately shut down a cape-loading executor after its assertions so the test client could exit normally.
Relevant crash stack and JAR checksums
java.lang.IllegalStateException: WWWindManagerExtension was not registered for level ClientLevel
at net.frozenblock.wilderwild.wind.WWWindManagerExtension.lambda$get$0(WWWindManagerExtension.java:75)
at java.util.Optional.orElseThrow(Optional.java:403)
at net.frozenblock.wilderwild.wind.WWWindManagerExtension.get(WWWindManagerExtension.java:75)
at net.frozenblock.wilderwild.wind.WWWindManagerExtension.getCloudX(WWWindManagerExtension.java:79)
at net.minecraft.client.renderer.LevelRenderer.wrapOperation$kde000$wilderwild$wilderWild$changeCloudPosition(LevelRenderer.java:11556)
SHA-256:
FrozenLib-2.5.3-mc26.2.jar
510bce30b1d7fdc869eccab3cd2ffd49609ec81c29b40f30da5d9d984f73338e
WilderWild-4.2.11-mc26.2.jar
dd1111aa5f9eecf95cef3e42c099df0726ef3089cb48064723e286612bd62957
What happened
My client crashed while playing on a multiplayer server in the Overworld with Wilder Wild's wind-driven clouds enabled. It had been connected for about 21 minutes, with no reconnect or dimension change near the crash.
The error was:
This looks related to #80, but it happened with FrozenLib 2.5.3-mc26.2, and the exception is different. I inspected the released JARs; I have not checked whether the current development branch already fixes this.
Likely cause
When a wind update arrives from the server, FrozenLib replaces the wind extension that Wilder Wild uses to position clouds. It removes the old extension, then adds the replacement.
That replacement happens on the network decoding thread while the render thread can still read the same list. If rendering reads it between the removal and the addition, Wilder Wild cannot find its extension and throws the error above.
The released code and a local test confirm that decoding changes the shared wind manager before the update reaches the client thread. I have not captured the exact timing of the crashing frame, so this is the likely explanation for the crash rather than a confirmed reproduction of that frame.
Reproduction and environment
I do not have reliable steps to trigger the crash on demand. It occurred during normal multiplayer play with wind-driven clouds enabled, in a larger modpack.
Ak4sHFuc)TVkz6cZh)Suggested fix and local testing
A local compatibility patch reads incoming wind data into a separate object, then updates the shared wind manager when Fabric applies the attachment on the client thread, after checking its target. This keeps the existing merge behavior and packet order while avoiding changes to live wind state during network decoding.
A small test harness called the real wind decoding and attachment methods using the same FrozenLib, Wilder Wild and Fabric API JARs, with Fabric Loader 0.19.3:
The harness used a minimal synthetic level object, not a playable world. The patch has not been tested in full-pack gameplay or deployed. Its source is in a private repository, so the relevant findings are included here directly.
Technical details and a separate reset problem
Wind update path
WindManager.applyFromStreamCodecwrites directly to staticWindManager.INSTANCE. For an extension whosesupportsApplicationFromSync()returns false, it removes the existing entry before adding the replacement. Wilder Wild inherits the interface's default false implementation.Minecraft's Netty
PacketDecoderinvokes this codec before Fabric hands attachment application to the client packet-processing thread. During a periodic wind update, the seed remains present, allowing Wilder Wild's cloud getter to run while its extension is temporarily absent.The local patch defers the original merge until the attachment write in
AttachmentChange.tryApply, after the target resolves. The inspected Fabric attachment module is2.2.19+515ac5339e.Separate reset problem
WindManager.reset()clearsextensionsbut leavesloadedExtensions=true. The nexttryCreateAndSortExtensions(Level)therefore returns early instead of rebuilding the list. Client level-change and disconnect callbacks both call reset.The local patch also clears this flag. The unpatched test confirmed the stale flag; the patched test confirmed that one Wilder Wild extension was recreated afterward. Reconstruction itself was not exercised in the unpatched run.
Reset also clears the wind seed, which temporarily disables wind-driven clouds. A later full sync can restore the extension before restoring the seed, so this reset problem alone does not explain the mid-session crash.
Test limits
The synthetic level contained only the client-side, dimension and registry fields required for the calls. It was never installed in Minecraft, ticked or rendered. Handling of an unresolved attachment target was inspected in bytecode but not tested in a connected world. The harness separately shut down a cape-loading executor after its assertions so the test client could exit normally.
Relevant crash stack and JAR checksums
SHA-256: