Learn · frameworks
Что такое Mixin? Объяснение внедрения байт-кода
Mixin — это библиотека для внедрения байт-кода, которая позволяет модам изменять скомпилированные классы Minecraft во время загрузки. Вот как работает внедрение и почему каждому современному моду она необходима.
Что такое Mixin в Minecraft?
Mixin — это библиотека для внедрения байт-кода, которая позволяет моду изменять скомпилированные классы Minecraft во время загрузки, не затрагивая при этом исходный код. Мод пишет небольшой класс, который указывает: «вставить этот код в эту точку в этом игровом методе», и Mixin вплетает этот код в байт-код в тот момент, когда JVM загружает целевой класс. Fabric использует его в качестве основного механизма моддинга.
Коротко говоря: Minecraft распространяется в виде скомпилированного Java. Mixin рассматривает эти скомпилированные классы как поверхность, на которой можно строить, и редактирует их в памяти до того, как игра запустит хотя бы один кадр.
Как работает внедрение байт-кода Mixin?
Mixin работает в промежутке между компиляцией и выполнением. Игровой класс уже скомпилирован, но JVM ещё не загрузила его. Это и есть окно, которое использует Mixin. Мод передает загрузчику класс Mixin, аннотированный для нацеливания на реальный игровой класс, и когда этот игровой класс загружается, Mixin переписывает его байт-код на лету, чтобы включить код мода.
Аннотации — это весь секрет. Они не описывают, как выглядит игровой файл построчно. Они описывают куда вам нужно попасть: на вершину метода, к возврату, к конкретному вызову внутри него, к локальной переменной. Mixin находит это место в байт-коде и вшивает ваши инструкции вокруг него.
Это необходимо, потому что Minecraft никогда не создавался для расширения. Для большинства изменений, которые хотят внести моды, отсутствует официальный API плагинов. Mixin — это ответ на эту проблему: если игра не предоставляет вам точку входа, вы вырезаете её сами в скомпилированном коде.
Почему моды используют Mixin вместо непосредственного редактирования игры?
Два фактора определяют всю аргументацию: совместимость и выживание после обновлений.
Если редактировать исходный код игры напрямую, вам придётся распространять полную модифицированную копию Minecraft. Никто другой не сможет строить на основе вашего форка, и он сломается сразу после обновления игры. Mixin-патчи небольшие и точечные, что позволяет десяткам модов одновременно изменять одну и ту же игру, не распространяя при этом полную копию.
| Подход | Совмещает работу с другими модами | Выживает после обновления игры | Распространяется как |
|---|---|---|---|
| Ручное редактирование скомпилированной игры | Нет, побеждает один форк | Нет, ломается при любом изменении | Полный модифицированный jar |
| Внедрение Mixin | Да, патчи накладываются | Часто, если метод сохранился | Несколько небольших классов |
Вторая колонка — это тихая суперспособность. Поскольку Mixin говорит "внедрить здесь" вместо "файл выглядит именно так", многие Mixin-патчи продолжают работать в разных версиях без каких-либо изменений. Это разница между описанием пункта назначения и запоминанием карты.
Как Mixin вписывается в Fabric?
Ткань построена на Mixin, точка. Загрузчик читает конфигурацию mixin каждого мода, собирает классы mixin, указанные в этой конфигурации, и передает их Mixin для применения во время загрузки классов. Вам не нужно вручную настраивать что-либо из этого; объявление ваших mixin-ов в конфигурации — это вся интеграция.
Типичный мод для Fabric состоит в основном из собственных обычных классов, плюс небольшой набор mixin-ов, которые перехватывают лишь те игровые методы, которые ему действительно нужно изменить. Реальная логика мода содержится в обычном коде. Mixin-ы — это лишь тонкий слой, который захватывает управление в нужные моменты.
Какие наиболее распространенные точки внедрения Mixin?
Тип внедрения, который вы выбираете, определяет, насколько агрессивным будет патч и насколько хорошо он будет взаимодействовать с другими модами. Более мягкие изменения безопаснее и устойчивее к обновлениям. Более тяжелые изменения дают вам больше контроля, но за счет хрупкости.
| Аннотация | Что она делает | Когда стоит использовать |
|---|---|---|
@Inject | Запускает ваш код в выбранной точке внутри целевого метода | По умолчанию; наименее инвазивный, наиболее устойчивый к обновлениям |
@Redirect | Заменяет один конкретный вызов метода внутри целевого | Заменяет один вызов без переписывания метода |
@ModifyArg | Изменяет аргумент, передаваемый в вызов внутри целевого | Немного меняет одно значение, поступающее в вызов |
@ModifyVariable | Переписывает локальную переменную в середине метода | Корректирует состояние, которое метод уже вычислил |
@Overwrite | Заменяет весь метод | Крайняя мера; конфликтует с чем-либо еще, что к нему прикасается |
@Inject — это основной инструмент, потому что он узкий и вежливый. Он вставляется в точное место и оставляет остальную часть метода нетронутой, что и является причиной того, что он, как правило, выживает при обновлениях и редко конфликтует с другими модами. @Overwrite находится на другом конце: он уничтожает весь метод, поэтому любой другой мод, который также хочет этот метод, теряет. Хорошие Mixin намеренно стараются оставить небольшой след.
Чистая точка введения — ещё одна причина, по которой удаление мода происходит мгновенно. Ничего не было записано в ваши файлы, поэтому удаление мода удаляет все изменения вместе с ним.
Почему Mixin важен для серьезного клиента
Это фундамент, на котором построен Terminus. Премиальный утилитарный клиент выживает или погибает в зависимости от того, насколько чисто он интегрируется в игру, и Mixin делает это возможным, не отправляя изуродованную копию Minecraft. Узкие точки внедрения поддерживают совместимость клиента с уже установленными модами и остаются работоспособными при обновлениях игры, не ломаясь после выхода патча. Понимание Mixin – самый быстрый способ увидеть, почему хорошо разработанный клиент ощущается как часть игры, а не как хрупкое дополнение.
Часто задаваемые вопросы
Нет. Mixin — это библиотека, с помощью которой создаются моды, а не то, что скачивается отдельно. Загрузчик, например Fabric, включает Mixin внутрь и применяет миксины, которые каждый мод объявляет, при загрузке игры.
Нет. Вся перепатка происходит в памяти во время загрузки классов. Jar-файл на диске никогда не меняется, поэтому удаление мода полностью удаляет его поведение, не оставляя никаких следов.
Когда два миксина изменяют один и тот же метод таким образом, что изменения конфликтуют, один может перезаписать другой. Чаще всего виновником является @Overwrite. Миксины, использующие узкие точки внедрения, такие как @Inject, гораздо надежнее сосуществуют.
Нет. Mixin — это универсальный фреймворк для Java-байткода. Моддинг Minecraft — это лишь то место, где он используется наиболее интенсивно, а то, что Fabric стандартизировал его, сделало его основным инструментом для этой экосистемы.
Получить Terminus
Built on clean Mixin hooks, not a hacked-up jar.