Рубрики
Без рубрики

Создание мода Minecraft с использованием Java и Fabric

Несколько недель назад YouTube порекомендовал мне видео Minecraft с канала Dream, в котором он пытался… С тегами учебник, новички, java, minecraft.

Несколько недель назад YouTube порекомендовал мне видео Minecraft с канала Dream , в котором он пытался победить в игре, в то время как его друг Джордж пытался остановить его. Это видео было действительно забавным и заставило меня изучить больше их контента.

Прямо сейчас есть куча людей, которые записывают и загружают видео Minecraft на YouTube, но эти двое нашли способ сделать свой контент другим. В принципе, они создают свои собственные плагины для изменения правил игры а затем они записывают себя, пытаясь победить в измененной игре. Все, что я могу сказать, это то, что мне нравится их контент, и это потрясающе – видеть, чего вы можете достичь с помощью кода.

Несколько дней спустя у меня появилась идея разработать мод для Майнкрафта и я подумал Почему нет? Это будет весело!

Выбор инструментов

Как и в Minecraft, нам нужны некоторые инструменты, но в этом случае они помогут нам в процессе создания нашего первого мода.

Несколько инструментов помогут вам создавать моды Minecraft, и я выбрал Fabric , потому что один из модов, с которыми я обычно играю, был создан с его помощью.

Minecraft использует Java, как и Fabric, что означает, что нам также необходимо установить набор для разработки Java или JDK. Чтобы быть более конкретным, нам нужен JDK 8, чтобы иметь возможность скомпилировать наш мод. Вы можете скачать его на этой странице .

И последнее, но не менее важное: нам нужно выбрать редактор кода, в данном случае я выбрал Код Visual Studio , потому что это мой любимый редактор. Тем не менее, вы можете использовать для этого руководства любой редактор, который вам нравится, так как большинство шагов будет выполнено в командной строке.

Настройка проекта

В этом руководстве мы будем использовать стартер, чтобы быстро перейти к созданию нашего первого мода. Давайте пройдем через следующие шаги:

1. Клонирование/Загрузка репозитория

Если вы используете Git, просто клонируйте репозиторий:

$ git clone https://github.com/HorusGoul/fabric-mod-starter.git

В противном случае нажмите на эту ссылку, чтобы загрузить его .

Хорусгул/ткань-мод-стартер

2. Откройте папку проекта с помощью редактора кода

Использование кода Visual Studio:

$ code fabric-mod-starter

3. Откройте терминал внутри папки проекта и запустите клиент

$ cd fabric-mod-starter
$ ./gradlew runClient

записка: В Windows вам нужно будет запустить .\gradlew.летучая мышь вместо этого запустите Клиент .

4. Проверьте, все ли работает

Экземпляр Minecraft должен быть запущен сейчас на вашем компьютере, и консоль должна была напечатать эти две строки рядом с другими:

...

[main/INFO]: [STDOUT]: Hello Fabric world!

...

[main/INFO]: [STDOUT]: This line is printed by an example mod mixin!

...

Если это не так для вас, перепроверьте все, и если ничего не работает, оставьте комментарий или отправьте мне сообщение в личку, и я постараюсь вам помочь.

Знакомство с проектом

На данный момент мы уже можем испачкать руки, начав кодировать, но давайте ознакомимся с некоторыми файлами.

На данный момент мы уже можем испачкать руки, начав кодировать, но давайте ознакомимся с некоторыми файлами.

В этом файле мы можем настроить некоторые значения, которые будут использоваться при создании нашего мода. Например, мы можем изменить версию Minecraft, версию загрузчика ткани, версию мода и другие свойства, которые нам может потребоваться изменить, если мы хотим использовать новые функции Fabric или Minecraft.

# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G

# Fabric Properties
    # check these on https://fabricmc.net/use
    minecraft_version=1.15.1
    yarn_mappings=1.15.1+build.1
    loader_version=0.7.3+build.176

# Mod Properties
    mod_version = 1.0.0
    maven_group = starter
    archives_base_name = starter

# Dependencies
    # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
    fabric_version=0.4.25+build.282-1.15

src/главный

Внутри папки src мы сможем найти другую папку с именем main . Именно там находятся код и ресурсы нашего мода.

src/основной/java

Весь код Java находится внутри этой папки. Там мы можем найти пакет под названием starter , который содержит два элемента: StarterMod.java файл и смешивание пакет.

Мы можем найти файл Мы можем найти файл |/внутри смешивания

совет: Если вы используете код Visual Studio, я рекомендую вам установить Пакет расширений Java . Это позволит вашему редактору использовать множество утилит, чтобы упростить разработку Java.

Это позволит вашему редактору использовать множество утилит, чтобы упростить разработку Java.

Это основная точка входа в наш мод, как мы видим, он относится к пакету starter и реализует метод OnInitialize() , который просто печатает Привет, мир ткани! к консоли.

package starter;

import net.fabricmc.api.ModInitializer;

public class StarterMod implements ModInitializer {
  @Override
  public void onInitialize() {
    // This code runs as soon as Minecraft is in a mod-load-ready state.
    // However, some things (like resources) may still be uninitialized.
    // Proceed with mild caution.

    System.out.println("Hello Fabric world!");
  }
}

|| к консоли.

Этот класс относится к пакету starter.mixing . Наш мод будет действительно маленьким поэтому нам не стоит сильно беспокоиться о файловой структуре нашего проекта. Давайте просто предположим, что все миксины будут расположены внутри пакета starter.mixing .

А что такое смешивание?

Миксины отвечают за внедрение кода в существующие классы игры. Например, в StarterMixin.java , мы вводим метод в начале (НАЧАЛО) метода init() , который реализован в классе TitleScreen из Minecraft.

Теперь, если мы загрузим это смешивание, как только Minecraft вызовет init() метод |/TitleScreen , наш метод, который включает в себя System.out.println (“Эта строка напечатана с помощью примера модного миксина!”); также будет вызван!

Это часть магии миксинов, и это только верхушка айсберга, на данный момент это все, что нам нужно для создания нашего мода. Если вам нужны более глубокие знания, вам следует проверить Документы по смешиванию .

package starter.mixin;

import net.minecraft.client.gui.screen.TitleScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(TitleScreen.class)
public class StarterMixin {
  @Inject(at = @At("HEAD"), method = "init()V")
  private void init(CallbackInfo info) {
    System.out.println("This line is printed by an example mod mixin!");
  }
}

src/основные/ресурсы

Внутри папки ресурсы мы можем найти папку активы , в которой сейчас находится только значок нашего мода. Помимо этой папки, есть два файла JSON:

Помимо этой папки, есть два файла JSON:

Для этого файла я рекомендую вам перейти в Документы Fabric о fabric.mod.json и прочитайте о каждом поле, определенном в файле нашего проекта.

Если вы предпочитаете прочитать документы позже, просто взгляните на свойства точки входа и миксины .

Держу пари, вы уже видите здесь связь. В точках входа мы указываем Fabric, какой из наших классов Java должен выступать в качестве основной точки входа нашего мода.

И затем, есть свойство mixins , где мы просто сообщаем Fabric местоположение любого файла конфигурации микширования, который мы хотим включить в наш мод. В этом случае у нас есть только один, starter.mixins.json .

{
  "schemaVersion": 1,
  "id": "starter",
  "version": "${version}",

  "name": "Starter Mod",
  "description": "Describe your mod!",
  "authors": ["Your Name"],
  "contact": {
    "homepage": "https://horuslugo.com",
    "sources": "https://github.com/HorusGoul/fabric-mod-starter"
  },
  "license": "MIT",
  "icon": "assets/starter/icon.png",

  "environment": "*",

  "entrypoints": {
    "main": ["starter.StarterMod"]
  },

  "mixins": ["starter.mixins.json"],

  "depends": {
    "fabricloader": ">=0.7.3",
    "minecraft": "1.15.x"
  },

  "suggests": {
    "flamingo": "*"
  }
}

В этом случае у нас есть только один, ||starter.mixins.json||.

Помнишь наш Стартовый микс в классе? Вот как мы можем сообщить цепочке инструментов миксины, которые мы хотим включить в наш мод. Свойство package – это место, где мы определяем пакет Java, в котором расположены миксины, а внутри массива mixins мы можем разместить все классы миксина, которые мы хотим включить в игру.

Наряду с mixins есть два других свойства, которые позволяют нам указать среду, в которую мы хотим загрузить некоторые миксины. Этими свойствами являются сервер и клиент , но в данном случае мы их не используем.

Этот файл соответствует спецификации, определенной в разделе Файлы конфигурации микширования Документации по микшированию. Точно так же, как и раньше, я рекомендую вам обратиться к документам и узнать больше об этом файле 😄

{
  "required": true,
  "package": "starter.mixin",
  "compatibilityLevel": "JAVA_8",
  "mixins": ["StarterMixin"],
  "injectors": {
    "defaultRequire": 1
  }
}

Давайте создадим наш мод!

Теперь, когда мы знакомы с проектом, давайте испачкаем руки и создадим наш мод!

В этом случае мод просто изменит одну механику игры: получение урона . Мы сделаем так, чтобы всякий раз, когда игрок получает урон, он менял свою позицию и инвентарь с другим игроком на сервере.

Для этого нам понадобится микширование, которое вводит код в сущность игрока класса, чтобы быть более конкретным, непосредственно перед окончанием метода damage() .

Определение того, когда игроки получают урон

Давайте создадим это новое смешивание в starter.mix в пакете с именем SwitchPlayerEntityMixin.java :

package starter.mixin;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;

@Mixin(PlayerEntity.class)
public class SwitchPlayerEntityMixin {

  @Inject(at = @At("RETURN"), method = "damage")
  private void onDamage(DamageSource source, float amount, CallbackInfoReturnable info) {
    System.out.println("The player received damage!");
  }
}

Не забудьте добавить его в файл starter.mixins.json :

{
  "required": true,
  "package": "starter.mixin",
  "compatibilityLevel": "JAVA_8",
  "mixins": ["StarterMixin", "SwitchPlayerEntityMixin"],
  "injectors": {
    "defaultRequire": 1
  }
}

Теперь выполните команду ./gradlew запустите клиент в консоли, запустите мир Minecraft в творческом режиме, возьмите несколько зелий мгновенного урона и попытайтесь получить травму.

Как и в GIF, вы должны видеть, как новая строка появляется в консоли каждый раз, когда игрок получает травму, и это означает, что мы можем продолжить объяснение происходящего.

Взгляните на код микширования, нашей целью было получить метод при повреждении выполняется в конце метода повреждение , вот почему мы используем строку вернуть вместо ГОЛОВЫ . Кроме того, нам понадобится ущерб источник и сумма нанесенного ущерба. Последний параметр, info , требуется для структуры микширования.

Оба источника и сумма – это параметры, которые получает исходный метод ущерб , и именно по этой причине мы можем просто использовать их в нашем методе.

Доступ к текущему игроку

Прямо сейчас мод просто печатает строку каждый раз, когда игрок получает травму, наша следующая цель – доступ к экземпляру игрока.

Сначала мы должны помнить, что метод onDamage находится внутри Сущность игрока экземпляр. Мы можем воспользоваться этим и просто использовать это для доступа к свойствам и методам экземпляра. Проблема возникает, когда компилятор кричит на нас, потому что он думает, что мы являемся экземпляром Переключить Игрока На Миксин Сущности .

У нас нет способа сообщить компилятору, что этот метод выполняется внутри класса другого типа, поэтому мы можем использовать этот трюк:

PlayerEntity self = (PlayerEntity) (Object) this;

При этом мы сообщаем компилятору, что это является объектом а затем мы разыгрываем объект как Сущность игрока . И виллы! У нас есть доступ к игроку, который получает урон, теперь мы можем обновить нашу печатную строку, чтобы отобразить имя игрока.

...

@Mixin(PlayerEntity.class)
public class SwitchPlayerEntityMixin {

  @Inject(at = @At("RETURN"), method = "damage")
  private void onDamage(DamageSource source, float amount, CallbackInfoReturnable info) {
    PlayerEntity self = (PlayerEntity) (Object) this;

    System.out.println("The player " + self.getGameProfile().getName() + " received damage");
  }
}

Переключение позиций с другим игроком

Теперь, когда мы можем получить доступ к свойствам и методам игрока, мы можем использовать один из них для доступа ко всему миру .

Свойство world ссылается на текущий мир Minecraft, в который играют, и одна из вещей, которые мы можем с ним сделать, – это получить список онлайн-игроков.

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

package starter.mixin;

import java.util.List;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;

@Mixin(PlayerEntity.class)
public class SwitchPlayerEntityMixin {

  @Inject(at = @At("RETURN"), method = "damage")
  private void onDamage(DamageSource source, float amount, CallbackInfoReturnable info) {
    PlayerEntity self = (PlayerEntity) (Object) this;

    // Get all the players in the current minecraft world
    List players = (List) self.world.getPlayers();

    // The player we'll switch positions with.
    PlayerEntity otherPlayer;

    // Stop the execution if the player is playing alone.
    if (players.size() <= 1) {
      return;
    }

    // Get a random player from the players list.
    // Repeat this process until we have a player that is
    // not the player who got hurt.
    do {
      int index = (int) Math.floor(Math.random() * players.size());
      otherPlayer = players.get(index);
    } while (otherPlayer == self);

    // Get the block position of both players
    BlockPos selfPos = self.getBlockPos();
    BlockPos otherPlayerPos = otherPlayer.getBlockPos();

    // Teleport damaged player to the other player's coordinates
    // We set the Y to 300 in order to avoid a collision with the other player.
    //
    // We add 0.5 to both X and Z because that's the center point of a block
    // and the players could suffocate under certain circumstances if we didn't
    self.teleport(otherPlayerPos.getX() + 0.5, 300, otherPlayerPos.getZ() + 0.5);

    // Teleport the other player to the position of the damaged player.
    otherPlayer.teleport(selfPos.getX() + 0.5, selfPos.getY(), selfPos.getZ() + 0.5);

    // Finally change the Y to the real value and complete the teleport of both
    // players.
    self.teleport(otherPlayerPos.getX() + 0.5, otherPlayerPos.getY(), otherPlayerPos.getZ() + 0.5);
  }
}

После реализации этого вам понадобятся два клиента Minecraft, чтобы иметь возможность протестировать его. Вы можете сделать это, открыв его с помощью ./gradlew runКлиент а затем используйте официальный клиент Minecraft с вашей учетной записью Mojang. Затем откройте тестовый мир в локальной сети и присоединитесь к нему с другим клиентом.

Обмениваются своими запасами

А теперь мы добавим последнюю функцию мода: замена инвентаря игроков.

Чтобы поменять местами инвентарь двух игроков, мы должны клонировать каждый инвентарь, а после этого мы можем просто заменить и поменять их местами. Доступ к инвентарю игрока можно получить с помощью свойства инвентарь .

Класс Инвентарь игрока имеет два метода, которые мы будем использовать, сериализация и десериализовать . Первый из них позволяет нам клонировать содержимое инвентаря, поместив его внутрь тега List и затем мы можем использовать второй, чтобы заменить содержимое инвентаря содержимым, которое находится внутри тега списка .

Вот код:

    // ... teleports ...


    // Only swap inventories if the players are alive
    if (self.getHealth() > 0.0f && otherPlayer.getHealth() > 0.0f) {

      // Get the inventories of both players
      ListTag selfInventory = self.inventory.serialize(new ListTag());
      ListTag otherPlayerInventory = otherPlayer.inventory.serialize(new ListTag());

      // Swap them
      self.inventory.deserialize(otherPlayerInventory);
      otherPlayer.inventory.deserialize(selfInventory);
    }

Как вы, возможно, заметили, мы меняем запасы только в том случае, если оба игрока живы, потому что, если мы не включим эту проверку, один из запасов будет потерян всякий раз, когда игрок умрет.

Окончательный код

Если вы дошли до этого момента, поздравляю! Вы создали свой первый мод для Minecraft, теперь мы должны удалить ненужные файлы, например, StarterMixin.java и StarterMod.java . Не забудьте удалить ссылки на эти файлы внутри fabric.mod.json и стартеры.mixins.json .

Я также рекомендую вам переименовать пакет из starter в то, что вы хотите, просто не забудьте изменить каждое вхождение в проекте.

Вы можете найти последнюю версию кода в ветке окончательный код начального репозитория. Нажмите здесь, чтобы увидеть окончательную версию мода .

Упаковка мода

Если вы знакомы с модами Minecraft, вы, возможно, уже знаете, что моды обычно поставляются упакованными внутри .zip или .jar файлы, которые позже вы поместите в папку mods на сервере или клиенте Minecraft.

Чтобы создать комплект вашего мода, вам нужно всего лишь выполнить следующую команду:

$ ./gradlew build

Если все будет скомпилировано правильно, вы сможете найти файл .jar внутри папки ./build/libs вашего проекта. В большинстве случаев вы захотите выбрать производственную версию без источников, но могут быть случаи, когда также лучше отправить версию разработки вместе с источниками.

Вот и все, теперь вы можете отбросить эту .банку внутри вашей папки mods просто не забудьте сначала установить API Fabric, и для этого вы можете прочитать раздел Установка Fabric в их вики, если хотите узнать, как это сделать.

Учебные ресурсы

Вот некоторые ресурсы, которые могут пригодиться, если вы хотите узнать больше о моддинге Minecraft:

  • Ткань Вики . Об этом уже упоминалось в статье, но серьезно, пойдите и проверьте это, потому что есть много контента, который я не охватил!

  • API-интерфейс Forge . API Forge – это самый известный API Minecraft, вы можете проверить его, потому что с его помощью были созданы некоторые из лучших модов!

  • Сценарное мастерство . Похоже, есть способ создавать моды с использованием JavaScript, поэтому, если у вас есть опыт работы в веб-разработке, вы можете попробовать этот способ.

  • Создатель . Как говорится на их сайте, MCreator – это программное обеспечение, используемое для создания модов и пакетов данных Minecraft с использованием интуитивно понятного простого в освоении интерфейса или встроенного редактора кода. Если вы знаете о ком-то, кто хочет начать заниматься программированием, это может быть хорошим способом познакомить их!

Вывод

Создание моего первого мода для Minecraft было интересно, потому что я узнал немного больше о том, как работает моя любимая игра, и мне даже удалось создать что-то действительно интересное для игры.

Кроме того, я воспользовался этой возможностью для создания этой статьи, потому что я думаю, что моддинг – отличный способ познакомиться с программированием, и есть много игроков в Minecraft, которые могут заинтересоваться и в конечном итоге узнать много нового о разработке программного обеспечения.

Я надеюсь, что вы отлично провели время, читая эту статью. Если вы решите продолжить обучение, я предлагаю вам поделиться своим прогрессом с нами, кто знает, может быть в Minecraft моддинг сообщество может родиться внутри Дев.к 🔥

Оригинал: “https://dev.to/horusgoul/creating-a-minecraft-mod-using-java-and-fabric-3bmo”