Перейти к содержимому
Для публикации в этом разделе необходимо провести 1 боёв.
BattleFrame

[FAQ] Пакеты модификаций *.mkmod, файл meta.xml и работа с ними

В этой теме 2 комментария

Рекомендуемые комментарии

4 833
[GA]
Разработчик, Коллекционер
3 368 публикаций
23 947 боёв

[FAQ] Пакеты модификаций *.mkmod
Начиная с версии 25.10 мы реализовали новый способ подключения модификаций при помощи специальных пакетов "mkmod".

При этом хочется уточнить, что папка res_mods никуда не девается и всё также функциональна.


Пакеты *.mkmod — это способ организации файлов модификаций, при котором весь контент отдельной модификации упакован в один файл.
В классической схеме распространения файлов модификации устанавливаются в каталог ../bin/<номер_версии>/res_mods/.
При этом файлы разных модификаций располагаются в одних и тех же каталогах, и поэтому зачастую трудно определить, какой файл относится к какой именно модификации.

Структура пакета:
Пакеты *.mkmod располагаются в папке ../bin/<номер_версии>/mods/ и представляют собой обыкновенный zip-архив с нулевым сжатием (это обязательное условие, иначе игра не прочитает пакет)
Каждый пакет представляет собой персональную для располагаемого в нём мода папку res_mods. То есть, внутри архива полностью сохраняется иерархия папок, аналогичная каталогу res_mods

image.pngimage.png

Внутри себя пакет содержит:

  • Ресурсы модификации.
  • Служебный файл meta.xml о котором подробнее далее.

 

Немного про принцип работы:

При запуске игра пробегается по всем пакетам mkmod, а также папке res_mods и формирует у себя в памяти единый список файлов. Благодаря этому модификации между разными пакетами, а также между пакетами и папкой res_mods могут беспрепятственно взаимодействовать.

 

Важно! Особые правила загрузки пакетов:

Существует несколько основных правил по которым выполняется загрузка пакетов mkmod, а также их взаимодействие:

  1. Все пакеты загружаются в алфавитном порядке. (принцип, аналогичный загрузке файлов *.unbound)
  2. Все пути внутри пакета должны быть уникальными. Например, не должно быть ситуации, когда в пакете aaa.mkmod и bbb.mkmod лежат одинаковые файлы по одинаковому пути (например gui/unbound2/mimimap.unbound)
    В таком случае пакет aaa.mkmod будет загружен (т.к по алфавиту он идёт раньше), а пакет bbb.mkmod в котором найден дубликат (любого файла) будет полностью проигнорирован и загружен не будет. При этом в python.log будет выведена ошибка.
  3. Все пакеты обязательно должны быть zip-архивами и обязательно с нулевым сжатием. В случае если это не так - вы получите ошибку в python.log и пакет загружен не будет.
  4. Пакеты mkmod не умеют (на данный момент) загружать python-скрипты. Следовательно, если ваш мод помимо ассетов или вёрстки также содержит файл  PnFModsLoader.py и скрипты в папке PnFMods, то они должны располагаться в папке res_mods.
  5. Папка res_mods всегда в приоритете над всеми пакетами mkmod. Если у вас файлы с одинаковым именем находятся по одинаковому пути в папке res_mods и в одном из пакетов mkmod, то игра будет читать файлы из res_mods.
  6. Пакет не должен содержать только файл meta.xml (без объективных на то причин) при том что остальной мод будет находиться в res_mods (просто не нужно так делать :fish_aqua:)

 

Примеры:

Рассмотрим примеры формирования пакета *.mkmod для различных типов модификаций

Для начала где-нибудь создадим рабочий каталог MODS (для удобства) в котором мы будем готовить свои пакеты.
Представим себе что наш каталог MODS это каталог res_mods и начинаем складывать в него файлики различных модов по очереди.

 

Модификации с заменой или добавлением файлов (озвучки, иконки, трассеры):

  1. Например, у меня есть озвучка, например AlterVOX, которую я хочу запаковать в пакет mkmod
  2. В инструкции написано распаковать содержимое архива в папку /bin/[номер_сборки]/res_mods/ 
  3. Я распаковываю содержимое своей модификации в нашу папку MODS и вижу папку banks, которая для работы озвучки должна лежать в папке res_mods
    image.png
  4. Эту папку мне необходимо запаковать в zip-архив с нулевым сжатием и расширением *.mkmod (название архива - название вашего мода)
    image.png
  5. Готово. Мы получили mkmod пакет, который теперь переносим в папку  /bin/[номер_сборки]/mods/ 
    image.png


Аналогичным способом собираются моды для замены текстур, иконок, конфигов, любых других файлов файловой системы.


Не рекомендуется запаковывать в mkmod модификации, ресурсы которых могут содержаться в других модах!
Например:

  • Порты - несколько модов могут использовать одинаковые модели или текстуры. при запаковке таких модов в mkmod игра увидит конфликт при загрузке файлов и проигнорирует загрузку модификации.
  • Скины кораблей - модификации внешнего вида кораблей без использования ContentSDK располагаются в папке content и также могут конфликтовать друг с другом.

 

 

Внимание!

В наименовании пакетов mkmod допускается использование только лат.букв, цифр и символа _ (например, autospy_minimap)

Давайте не будем устраивать в папке модификаций хаос из имён и спецсимволов.

    • Плюс 3
    • Круто 2

    Рассказать о публикации


    Ссылка на публикацию
    4 833
    [GA]
    Разработчик, Коллекционер
    3 368 публикаций
    23 947 боёв

    Файл метаданных meta.xml
    Опциональный файл. Должен находиться в корне пакета mkmod.
    Предназначен для идентификации модификации, а также для управления подключением элементов в UB2 модификациях на замену старому способу с battle_elements.xml


    Содержание файла:

    • <meta> - Обязательный блок метаданных
      • <id> - уникальный технический идентификатор мода (обязательно). Допускаются только лат.буквы, цифры и символ _ (например, autospy_minimap)
      • <name> -  Наименование мода (обязательно)
      • <version> - опциональный номер версии мода для тех кто её ведёт
      • <description> - Описание мода
    • <elements> - опциональный блок для добавления определенных элементов внутрь других элементов со следующий структурой:

     

    Поля <id>, <name> и <version> будут выводиться в python.log при загрузке модификации, а параметр <description> позволит понять что же вообще находится в данном mkmod

     

    Наиболее полезным файл meta.xml будет при разработке интерфейсных модификаций на unbound2 т.к. приходя на замену battle_elements.xml  имеет функционал встраивания и замены элементов вёрстки.

     

    Встраивание и замена элементов UB2:

    meta.xml позволяет создавать условия для замены элементов вёрстки на свои собственные в момент загрузки, либо для встраивания своих элементов в начало или конец других элементов.

     

    Рассмотрим на примере "меты" от мода "Счетовод":

    <meta.xml>
        <meta>
            <!-- Технический ID модификации -->
            <id>score_timer</id>
            <!-- Версия модификации -->
            <version>1.0</version>
            <!-- Наименование модификации -->
            <name>Счетовод</name>
        </meta>
        <elements>
            <element action="add_before" target="MainHud">ScoreTimer2</element>
        </elements>
    </meta.xml>

    Здесь мы видим что это модификация с именем "Счетовод", версии "1.0" и id "score_timer". Описание автор решил не указывать.

    Также мы видим блок <elements></elements> в котором задаются инструкции встраивания блоков. Инструкций может быть несколько.

    В модификации "Счетовод" основным элементом является ScoreTimer2, который раньше прописывался в battle_elements.xml

    Инструкция add_before из примера говорит игре: "Вставь элемент ScoreTimer2 в самый верх элемента MainHud", после чего наш счетовод расположится в виде (element "ScoreTimer2 ") сразу после блока scope в элементе MainHud

     

    Помимо add_before аргумент action может быть также и add_after, выполняющий ровно то же самое, но размещающий наш элемент в самом конце элемента, указанного в аргументе target

    Важно! Элементы вставленные при помощи add_before и add_after не могут принимать никаких аргументов от родителя (таргета в который они были вставлены):

     

    Кроме add_before и add_after также доступен параметр replace, работающий иначе.

    Допустим мы создаём мод миникарты и знаем что главный элемент миникарты называется BattleMinimapUb2:

    (def element BattleMinimapUb2 (_isLoading:bool=false) layout=true
    ...код родного элемента игры
    )

    мы создаём свой элемент и называем его как-то иначе (список аргументов должен быть таким же как и у элемента который вы хотите заменить)

    (def element MySuperMinimap (_isLoading:bool=false) layout=true
    ...код модификации
    )

    После чего составляем meta.xml мы пишем инструкцию replace

    <meta.xml>
        <meta>
            <!-- Технический ID модификации -->
            <id>my_minimap</id>
            <!-- Версия модификации -->
            <version>1.0</version>
            <!-- Наименование модификации -->
            <name>Крутая миникарта</name>
        </meta>
        <elements>
            <element action="replace" target="BattleMinimapUb2">MySuperMinimap</element>
        </elements>
    </meta.xml>

    Инструкция replace говорит игре: "Замени всё содержимое в элементе BattleMinimapUb2 содержимым из элемента MySuperMinimap".

    То есть, игра оставит оригинальное имя BattleMinimapUb2, оставит все принимаемые им аргументы (вы сможете использовать их в своём моде), но заменит весь код оригинального элемента на код из вашего, в результате чего мы получим:

    (def element BattleMinimapUb2 (_isLoading:bool=false) layout=true
    ...код модификации
    )

    Важно! Инструкция replace ВСЕГДА заменяет только содержимое элемента и не трогает его имя!

    Даже если вы решили заменить глобально все кнопочки в игре, заменив содержимое DefaultButton на содержимое NewButton, то в вёрстке вам всё равно будет необходимо вызывать именно DefaultButton!

     

     

    Ну и напоследок разбор небольшой ситуации.
    Допустим в одном пакете mkmod идёт add_after к MainHud, а в другом его replace

    Мод-1 прописывает условие:
    <element action="add_after" target="MainHud">ModOneElementAfter</element>

    Мод-2 прописывает условие:
    <element action="replace" target="MainHud">ModTwoReplace</element>

    В данном случае в каком бы порядке они не были:

    1. Оригинальный MainHud проигнорируется совсем
    2. ModTwoReplace переименуется в MainHud
    3. В конец MainHud (который уже переименованный) добавится ModOneElementAfter.
    • Плюс 4
    • Круто 2

    Рассказать о публикации


    Ссылка на публикацию
    Гость
    Эта тема закрыта для публикации новых ответов.

    ×