▶️ ЗАБЕРИ СВОИ 8 ПОДАРКОВ 🎁 ПРИ СОЗДАНИИ СВОЕГО МАЙНКРАФТ СЕРВЕРА
Моды/Create Collision Crashfix
Create Collision Crashfix

Create Collision Crashfix

Fixes the Create 6.0.10 server crash where moving contraptions (pulley/drill quarries) throw NullPointerException "mf.axis" is null

Оцените первым
3.2K
2

Create Collision Crashfix

A tiny, single-mixin hotfix for a server-fatal crash in Create 6.0.10 on Minecraft 1.21.1 (NeoForge).

The problem

A moving Create contraption can hard-crash the server tick loop:

java.lang.NullPointerException: Cannot read field "x" because "mf.axis" is null
    at com.simibubi.create.foundation.collision.ContinuousOBBCollider.collideMany(ContinuousOBBCollider.java:153)
    at com.simibubi.create.content.contraptions.ContraptionCollider.collideEntities(ContraptionCollider.java:166)
    at com.simibubi.create.content.contraptions.ContraptionHandler.tick(ContraptionHandler.java:54)
    Description: Exception in server tick loop

Once it happens the world usually crash-loops on load, because the offending contraption fires the same crash every tick.

When it triggers: a moving contraption's collision check hits a degenerate, zero-distance case — an entity's bounding-box center lands exactly on a contraption block's center on every axis. The most common real-world trigger is a rope pulley + drill quarry (e.g. a drill array with the pulley in the center column), but rotating bearings, tree farms with a saw, and similar setups can also hit it.

This is an upstream Create bug, present only in 6.0.10 (6.0.9 is unaffected). The official fix is Create PR #10301, milestoned for 6.0.11, which is not released yet. Downgrading to 6.0.9 is not an option for most packs because many Create addons require create >= 6.0.10.

Related upstream reports

  • Issue #10218 (tracking) — https://github.com/Creators-of-Create/Create/issues/10218
  • Issue #10278 — mf.axis is null when entity AABB center coincides with contraption block center — https://github.com/Creators-of-Create/Create/issues/10278
  • Issue #10344 — https://github.com/Creators-of-Create/Create/issues/10344
  • Issue #10353 — https://github.com/Creators-of-Create/Create/issues/10353
  • Issue #10378 — contraption collision NPE edge cases — https://github.com/Creators-of-Create/Create/issues/10378
  • Issue #10479 — tree farm crashes server when loaded — https://github.com/Creators-of-Create/Create/issues/10479
  • Upstream fix: PR #10301 — https://github.com/Creators-of-Create/Create/pull/10301

The fix — what changed and why it works

Inside Create's ContinuousSeparationManifold#separate, the separation axis (and normalAxis) are recorded only when the tested distance is non-zero:

if (distance != 0.0 && -diff <= Math.abs(this.separation)) {
    this.axis = axis;          // never runs in the degenerate, coincident-center case
    this.separation = separation;
}

In a perfectly coincident overlap every separation test runs with distance == 0, so axis/normalAxis stay null. collideMany then dereferences them (mf.axis.x) and the server dies.

This mod wraps the two field reads in collideMany with a null guard (MixinExtras @WrapOperation). When the recorded axis is null, it returns Vec3.ZERO, so the degenerate collision contributes zero push for that tick instead of crashing. The next tick the entity has moved sub-voxel, a valid separation axis exists, and collision resolves normally — no stuck entities, no clipping.

@WrapOperation(
    method = "collideMany",
    at = @At(value = "FIELD",
             target = "L.../ContinuousOBBCollider$ContinuousSeparationManifold;axis:Lnet/minecraft/world/phys/Vec3;",
             opcode = Opcodes.GETFIELD),
    remap = false)
private static Vec3 guardAxis(@Coerce Object manifold, Operation<Vec3> original) {
    Vec3 value = original.call(manifold);
    return value == null ? Vec3.ZERO : value;     // same for normalAxis
}

Why Vec3.ZERO specifically, and why it's safe:

  • When axis is null, the paired separation scalar is Double.MAX_VALUE. A non-zero fallback axis would compute axis * MAX_VALUE and fling the entity to infinity. 0 * MAX_VALUE == 0 neutralizes it cleanly — no NaN, no teleport.
  • axis and normalAxis are the only nullable Vec3 reads in collideMany (stepSeparationAxis is final and non-null; the collision* fields are primitive double), so this covers every null-deref site in the method.
  • The guard activates only on the null/degenerate path. Every normal collision is byte-for-byte unchanged.

The fix mirrors the intent of upstream PR #10301; it is deliberately surgical so it cannot affect non-degenerate physics.

Compatibility

  • Minecraft 1.21.1 · NeoForge 21.1.x
  • Create 6.0.10 only. The mod is hard-pinned to create [6.0.10]. On any other Create version it refuses to load with a clear requires create [6.0.10] message — which is your reminder to remove it once Create 6.0.11 (with the official fix) is out.
  • Install on both client and server (versions must match).
  • No mixin into addon classes — it only guards two field reads inside Create core, so it coexists with addons that mixin ContraptionCollider (Create Big Cannons, Aeronautics, Sable, etc.).

License

MIT. Ships no Create code — just a mixin and metadata.

Часто задаваемые вопросы

Совместимость

Minecraft: Java Edition

1.21.x

Платформы

Поддерживаемые окружения

Клиент и сервер

Ссылки

Создатели

Детали

Лицензия:
Опубликован:4 недели назад
Обновлён:4 недели назад
Главная