Skip to content

fix: move client-only mixins to client array — fixes dedicated server crash (#28)#32

Open
ntman4real wants to merge 6 commits into
Goodbird-git:1.21.1-archfrom
ntman4real:fix/client-mixins-server-crash
Open

fix: move client-only mixins to client array — fixes dedicated server crash (#28)#32
ntman4real wants to merge 6 commits into
Goodbird-git:1.21.1-archfrom
ntman4real:fix/client-mixins-server-crash

Conversation

@ntman4real

Copy link
Copy Markdown

Problem

Dedicated servers crash on startup with:

[main/FATAL] [mixin/]: Mixin apply for mod playerengine failed
playerengine.mixins.json:PlayerCollidesWithEntityMixin from mod playerengine
-> net.minecraft.world.entity.player.Player: InvalidMixinException
ClassMetadataNotFoundException ... net/minecraft/client/player/LocalPlayer

Root Cause

Two client-only mixins are placed in the common "mixins" array in playerengine.mixins.json, causing them to load on dedicated servers where client classes don't exist:

  • ClientBlockBreakMixin — targets MultiPlayerGameMode (client-only class)
  • PlayerCollidesWithEntityMixin — imports net.minecraft.client.player.LocalPlayer (client-only class)

Fix

Moved both mixins from the "mixins" array to the "client" array in playerengine.mixins.json. The Mixin framework will only load entries in the "client" array on the client side.

ClientConnectionAccessor remains in "mixins" — it targets net.minecraft.network.Connection which exists on both client and server.

Testing

  • Verified the mixin JSON is valid
  • The change is a one-file, two-line move (no logic changes)

Fixes #28

Mark Friedman added 6 commits March 19, 2026 18:09
ClientBlockBreakMixin targets MultiPlayerGameMode (client-only class)
and PlayerCollidesWithEntityMixin imports LocalPlayer (client-only class).

Both were incorrectly placed in the common 'mixins' array, causing
dedicated servers to crash with ClassMetadataNotFoundException for
net.minecraft.client.player.LocalPlayer.

Moved both to the 'client' array so they only load on the client side.
ClientConnectionAccessor remains in 'mixins' as it targets Connection
which exists on both client and server.

Fixes Goodbird-git#28
Some mods (e.g. ConstructionStick) access NeoForge config values in
getMaxDamage() which may not be loaded yet during recipe deserialization.
This causes IllegalStateException: Cannot get config value before config
is loaded, crashing the server in a loop.

Fall back to item.hashCode() without damage value when config is
unavailable.
The previous fix only caught IllegalStateException, but Undergarden's
slingshot item triggers loading client-only SoundInstance class during
getDamageValue() -> getMaxDamage() on DEDICATED_SERVER, which throws
RuntimeException from NeoForge's RuntimeDistCleaner.

Widening to catch(Exception) handles both failure modes safely.
…m Silent Gear recursive loop

getMaxDamage -> PartInstance -> ItemStack.copy -> ItemStack.<init> -> recalculateHash -> getDamageValue -> getMaxDamage causes StackOverflowError which extends Error, not Exception.
…loop

The recursive cycle getMaxDamage -> PartInstance -> ItemStack.copy -> ItemStack.<init> -> recalculateHash -> getDamageValue -> getMaxDamage was spinning for 60+ seconds before StackOverflowError, triggering the Server Watchdog to kill the process.

ThreadLocal guard detects re-entry and falls back to item.hashCode() without damage value, breaking the cycle immediately.
Architectury API issue #653: EventFactory$EventImpl uses a plain ArrayList
for its listeners field, which is not thread-safe. When a mod registers a
listener during event dispatch (e.g., during the first server tick), the
ArrayList iterator throws ConcurrentModificationException, crashing the server.

This mixin injects at the end of EventImpl's constructor and replaces the
ArrayList with a SnapshotArrayList subclass whose iterator() returns an
iterator over a snapshot copy. This makes concurrent registration during
iteration safe without changing the field type (which must remain ArrayList).

Fixes deterministic crash loop on server startup with ATM10 modpack.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant