Create Collision Crashfix
Исправляет краш сервера Create 6.0.10, когда движущиеся конструкции (карьеры на блоках/дрелях) выбрасывают NullPointerException "mf.axis" is null
- Загрузчики
- NeoForge
- Скачиваний на Modrinth
- 25,8 тыс.
- Подписчиков на Modrinth
- 9
- версия
- 1
- Обновлён
- 28 июня 202628 июн.
- Опубликован
- в 2026
Коротко о моде
Нужен и в игре, и на сервере
Create Collision Crashfix
Крошечный хотфикс на одном миксине для фатального для сервера краша в Create 6.0.10 на Minecraft 1.21.1 (NeoForge).
Проблема
Движущийся контрапшн Create может намертво уронить тик-луп сервера:
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После этого мир обычно уходит в краш-луп при загрузке, потому что проблемный контрапшн вызывает тот же краш каждый тик.
Когда срабатывает: проверка коллизий движущегося контрапшна попадает в вырожденный случай с нулевым расстоянием — центр хитбокса сущности оказывается ровно в центре блока контрапшна по всем осям. Чаще всего в реальности это rope pulley + drill quarry (например, массив буров с шкивом в центральном столбце), но вращающиеся подшипники, фермы деревьев с пилой и похожие конструкции тоже могут это словить.
Это баг самого Create, присутствует только в 6.0.10 (6.0.9 не затронут). Официальный фикс — Create PR #10301, намеченный на 6.0.11, который ещё не вышел. Откатиться до 6.0.9 для большинства сборок не вариант, потому что многие аддоны Create требуют create >= 6.0.10.
Связанные баг-репорты
- Issue #10218 (tracking) — https://github.com/Creators-of-Create/Create/issues/10218
- Issue #10278 —
mf.axisis 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
Фикс — что изменилось и почему это работает
Внутри Create в ContinuousSeparationManifold#separate ось разделения axis (и normalAxis) записывается только когда проверяемое расстояние не равно нулю:
if (distance != 0.0 && -diff <= Math.abs(this.separation)) {
this.axis = axis; // never runs in the degenerate, coincident-center case
this.separation = separation;
}При идеально совпадающем перекрытии каждая проверка разделения выполняется с distance == 0, поэтому axis/normalAxis остаются null. Затем collideMany разыменовывает их (mf.axis.x), и сервер падает.
Этот мод оборачивает два чтения полей в collideMany нулевой проверкой (MixinExtras @WrapOperation). Когда записанная ось равна null, возвращается Vec3.ZERO, так что вырожденная коллизия даёт нулевой толчок за этот тик вместо краша. На следующем тике сущность сдвигается на субвоксель, появляется валидная ось разделения, и коллизия разрешается нормально — без застрявших сущностей и без клиппинга.
@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
}
**Почему именно `Vec3.ZERO` и почему это безопасно:**
- Когда `axis` равен null, парный скаляр `separation` равен `Double.MAX_VALUE`. Ненулевая запасная ось вычислила бы `axis * MAX_VALUE` и отбросила сущность в бесконечность. `0 * MAX_VALUE == 0` чисто это нейтрализует — ни NaN, ни телепорта.
- `axis` и `normalAxis` — *единственные* nullable-чтения `Vec3` в `collideMany` (`stepSeparationAxis` — `final` и не null; поля `collision*` — примитивные `double`), так что это покрывает все места разыменования null в методе.
- Защита срабатывает **только** на пути null/вырожденного случая. Каждое нормальное столкновение остаётся байт-в-байт неизменным.
Фикс повторяет замысел апстрим-PR #10301; он намеренно точечный, чтобы не влиять на невырожденную физику.
## Совместимость
- **Minecraft 1.21.1 · NeoForge 21.1.x**
- **Только Create 6.0.10.** Мод жёстко привязан к `create [6.0.10]`. На любой другой версии Create он отказывается загружаться с понятным сообщением `requires create [6.0.10]` — это напоминание **удалить его, когда выйдет Create 6.0.11 (с официальным фиксом)**.
- Устанавливать **и на клиент, и на сервер** (версии должны совпадать).
- Никаких миксинов в классы аддонов — он лишь защищает два чтения полей внутри ядра Create, поэтому уживается с аддонами, которые миксуют `ContraptionCollider` (Create Big Cannons, Aeronautics, Sable и т. д.).
## Лицензия
MIT. Не содержит кода Create — только миксин и метаданные.Частые вопросы
Как установить Create Collision Crashfix?
Установите NeoForge под свою версию Minecraft, скачайте Create Collision Crashfix под ту же версию и загрузчик, положите файл в папку mods и запустите игру с профилем загрузчика.
Для каких версий Minecraft есть Create Collision Crashfix?
У Create Collision Crashfix есть сборки для Minecraft 1.21.1.
Нужен ли Create Collision Crashfix на сервере?
Нужен и в игре, и на сервере