Modding:Расширяемость модов
Эта страница проверялась в последний раз для версии Vintage Story 1.15.
Для этой статьи требуется установка среды разработки. Если у вас его нет, прочитайте учебник
на настройка вашей среды разработки. Для краткости эта статья предполагает некоторое знакомство с моддингом кода VintageStory, в первую очередь как упакованы моды и Setting_up_your_Development_Environment#Project_Setup_.28Compiled_Zip.29 как настроить скомпилированный проект мода.
Если вы хотите создать свой первый мод кода, мы рекомендуем вместо этого начать здесь.
Введение
VintageStory делает все загруженные моды доступными через обширный API, который вы можете изучить в документации по API. Это позволяет модам кода взаимодействовать друг с другом и получать доступ к общедоступным свойствам друг друга. Однако это делает любой мод, включающий другой мод, зависимым от этого мода. Если включаемый мод отсутствует или отключен, включаемый мод не будет работать.
Загрузка и извлечение модов осуществляется через IModLoader
, который мы получаем из [http:/ /apidocs.vintagestory.at/api/Vintagestory.API.Common.ICoreAPI.html ICoreAPI
]. Мы можем получить как полный Mod
, со всеми его полезными данными, так и содержащийся [ http://apidocs.vintagestory.at/api/Vintagestory.API.Common.ModSystem.html ModSystems
].
Это очень полезно в нескольких сценариях, например:
- Разделение большого мода на более мелкие логические части, которые сообщаются друг с другом - модпак.
- Например, расширяемые моды — творческий инструмент с графическим интерфейсом для выращивания деревьев, который позволяет регистрировать новые типы деревьев и легко их тестировать.
В этой статье мы будем создавать два мода. Наш первый мод предоставит метод для взаимодействия с нашим вторым модом.
Мы продемонстрируем использование ModLoader
, а также объясним, как ссылаться на внешний мод и получить эту ссылку.
решить во время игры.
Обратите внимание, что, за исключением использования отражения или использования промежуточной библиотеки, что выходит за рамки этой статьи, только скомпилированные моды могут взаимодействовать друг с другом.
TipMod & SpawnMod
Два мода, которые мы будем создавать, называются «TipMod» и «SpawnMod».
- «TipMod» будет хранить полезные подсказки по геймплею и периодически выводить их в чат. Он также предоставит метод, который другие моды могут использовать для добавления своих собственных советов.
- "SpawnMod" зарегистрирует команду, которая телепортирует игрока в заданную или заданную по умолчанию точку возрождения. Он также получит доступ к «TipMod» и добавит свои собственные советы по команде.
Подготовка
Начнем с установки двух пустых модов, «TipMod» и «SpawnMod».
В каждый мод мы добавляем новый исходный файл *.cs — мы будем называть эти файлы TipMod.cs
и SpawnMod.cs
соответственно.
В наших файлах .cs мы делаем следующее:
- Добавьте необходимые директивы
using
. - Создайте класс с именем мода, в котором он содержится —
TipMod
иSpawnMod
. - Наши классы должны наследовать
ModSystem
— основу для любого мода кода VintageStory. - Переопределите метод
StartServerSide
для доступа кICoreServerAPI
. - Сделайте класс
TipMod
public
, чтобы он был доступен другим модам.
// In TipMod.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API.Common;
using Vintagestory.API.Server;
namespace tipmod.src
{
public class TipMod : ModSystem
{
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
}
}
}
// In SpawnMod.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API.Common;
using Vintagestory.API.Server;
namespace spawnmod.src
{
class SpawnMod : ModSystem
{
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
}
}
}
На этом мы завершаем настройку основы наших модов. Наконец, в «TipMod» мы создаем дополнительный файл с именем Tip.cs
,
где мы определим структуру данных для подсказок, называемую Tip
.
// In Tip.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace tipmod.src
{
public class Tip
{
string author;
string tip;
public Tip(string author, string tip)
{
this.author = author;
this.tip = tip;
}
public override string ToString() {
return "Tip by \"" + author + "\": " + tip;
}
}
}
Наша результирующая структура папок выглядит так.
Теперь мы готовы расширить наши моды, начиная с «TipMod» — нашего модифицируемого мода.
Настройка TipMod
Для «TipMod» делаем следующее:
- Сохраните объект
ICoreServerAPI
как поле, чтобы мы могли получить к нему доступ во всем нашем классе. - Определите
List
, в котором хранятся объектыTip
. - Определите метод, который выбирает случайный
Совет
изСписка
и печатает его в чате для всех игроков, печатая сообщение по умолчанию, еслиСписок
пустой. - Зарегистрируйте этот метод для вызова через заданные интервалы с помощью
Timer
, который доступен вIServerEventAPI
. - Определите метод
public
для добавления новых объектовTip
.
// In TipMod.cs
public class TipMod : ModSystem
{
ICoreServerAPI api;
List<Tip> tips = new List<Tip>();
double tipInterval = 10;
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
this.api = api;
api.Event.Timer(OnInterval, tipInterval);
}
private void OnInterval()
{
int tipCount = tips.Count();
string message = "There aren't any listed tips";
if (tipCount > 0)
{
// Выберите случайное число из диапазона [0-1]
double random = api.World.Rand.NextDouble();
// Сделайте число относительно размера нашего списка советов
int randomTip = (int)Math.Floor(random * tipCount);
Tip tip = tips[randomTip];
message = tip.ToString();
}
api.SendMessageToGroup(GlobalConstants.GeneralChatGroup, message, EnumChatType.AllGroups);
}
public void AddTip(Tip tip)
{
tips.Add(tip);
}
}
В целях тестирования мы установили очень короткий интервал (10 секунд). Не стесняйтесь изменить это соответствующим образом.
Помните, что как классы, так и методы, с которыми будут взаимодействовать другие моды, должны быть объявлены public
.
В C# классы и методы по умолчанию не являются общедоступными. Вы можете прочитать об этом здесь.
Теперь мы можем скомпилировать наш мод, добавить его в папку с модами VintageStory и протестировать его в игре. Если в чате время от времени появляются сообщения «Нет советов в списке», наш мод работает. Мы готовы перейти к следующему шагу — настроить «SpawnMod», а затем заставить его взаимодействовать с «TipMod».
Настройка SpawnMod
Давайте сначала настроим функциональность наших модов. Мы регистрируем команду, которая телепортирует игрока на спавн. Для удобства объект IServerPlayer
хранит свою позицию появления, а также .vintagestory.at/api/Vintagestory.API.Common.IPlayer.html#Vintagestory_API_Common_IPlayer_Entity IPlayerEntity
, который определяет метод телепортации в определенное место.
// In SpawnMod.cs
class SpawnMod : ModSystem
{
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
api.RegisterCommand("spawn", "Teleport to spawn", "", OnCmdSpawn);
}
private void OnCmdSpawn(IServerPlayer player, int groupId, CmdArgs args)
{
player.Entity.TeleportTo(player.SpawnPosition);
}
}
"СпаунМод" готов. Давайте проверим это. Команда /spawn
теперь должна телепортировать нас к месту появления.
Если наши моды работают, мы готовы заставить "SpawnMod" взаимодействовать с "TipMod".
Моды взаимодействуют
Прежде чем мы начнем, мы должны добавить ссылку в «SpawnMod» на «TipMod».
Добавление ссылки на внешний мод
Если вы используете Visual Studio, в обозревателе решений, прямо под вашим проектом, щелкните правой кнопкой мыши "Ссылки" и выберите "Добавить ссылку".
Здесь мы находим либо проект «TipMod», либо скомпилированный файл .dll и добавляем его.
После добавления ссылки убедитесь, что он не копирует файл в выходную папку при компиляции -
наличие нескольких файлов .dll с ModSystems
в них сломает ваш мод.
Доступ к ModLoader
Теперь мы готовы к тому, чтобы "SpawnMod" добавил подсказки. Давайте продолжим и сделаем следующее.
- Добавьте директиву
using
для пространства именtipmod.src
. - Получить
TipMod
черезModLoader
, передав его тип. - Вызовите метод
AddTip
, предоставляемыйTipMod
, и добавьте различные подсказки.
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
api.RegisterCommand("spawn", "Teleport to spawn", "", OnCmdSpawn);
using tipmod.src;
TipMod tipMod = api.ModLoader.GetModSystem<TipMod>();
tipMod.AddTip(new Tip("codemeister32", "To quickly return to spawn, type /spawn"));
tipMod.AddTip(new Tip("codemeister32", "Can't find your way home? Type /spawn"));
tipMod.AddTip(new Tip("codemeister32", "Being chased by wolves? Quick, type /spawn"));
}
Заключение
Следуя шагам, описанным в этой статье, вот как выглядит наш результирующий код, распределенный по двум модам.
// In TipMod.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API.Common;
using Vintagestory.API.Config;
using Vintagestory.API.Server;
namespace tipmod.src
{
public class TipMod : ModSystem
{
ICoreServerAPI api;
List<Tip> tips = new List<Tip>();
double tipInterval = 10;
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
this.api = api;
api.Event.Timer(OnInterval, tipInterval);
}
private void OnInterval()
{
int tipCount = tips.Count();
string message = "There aren't any listed tips";
if (tipCount > 0)
{
// Выберите случайное число из диапазона [0-1]
double random = api.World.Rand.NextDouble();
// Сделайте число относительно размера нашего списка советов
int randomTip = (int)Math.Floor(random * tipCount);
Tip tip = tips[randomTip];
message = tip.ToString();
}
api.SendMessageToGroup(GlobalConstants.GeneralChatGroup, message, EnumChatType.AllGroups);
}
public void AddTip(Tip tip)
{
tips.Add(tip);
}
}
}
// In Tip.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace tipmod.src
{
public class Tip
{
string author;
string tip;
public Tip(string author, string tip)
{
this.author = author;
this.tip = tip;
}
public override string ToString() {
return "Tip by \"" + author + "\": " + tip;
}
}
}
// In SpawnMod.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API.Common;
using Vintagestory.API.Server;
using tipmod.src;
namespace spawnmod.src
{
class SpawnMod : ModSystem
{
public override void StartServerSide(ICoreServerAPI api)
{
base.StartServerSide(api);
api.RegisterCommand("spawn", "Teleport to spawn", "", OnCmdSpawn);
TipMod tipMod = api.ModLoader.GetModSystem<TipMod>();
tipMod.AddTip(new Tip("codemeister32", "To quickly return to spawn, type /spawn"));
tipMod.AddTip(new Tip("codemeister32", "Can't find your way home? Type /spawn"));
tipMod.AddTip(new Tip("codemeister32", "Being chased by wolves? Quick, type /spawn"));
}
private void OnCmdSpawn(IServerPlayer player, int groupId, CmdArgs args)
{
player.Entity.TeleportTo(player.SpawnPosition);
}
}
}
Теперь мы готовы протестировать наши моды, чтобы увидеть, успешно ли они взаимодействуют. После помещения обоих наших скомпилированных модов в папку модов и загрузки в мир мы должны видеть всплывающую случайную подсказку в чате каждые 10 секунд.
Если да, то молодец! Вы успешно следовали статье и создали модифицируемый мод.
Устранение неполадок
Если у вас возникли проблемы с настройкой любого мода, проверьте журналы ошибок, расположенные в VintagestoryData/Logs
в server-main.txt
.
Возможные причины того, что любой из модов не работает:
- Это мод .cs (исходный код), а не мод .dll (скомпилированный). Обратитесь сюда чтобы узнать, как установить скомпилированный мод.
- Отсутствует
modinfo.json
. - Ваша версия VintageStory устарела.
- У вас есть несколько файлов .dll, содержащих
ModSystems
в папке вашего мода. - Упомянутый мод "TipMod" отсутствует в папке мода.
Распространение
Чтобы распространить этот мод, запустите следующую команду в vsmodtools cli pack <your mod id>
, затем скопируйте ZIP-файл в папку модов VintageStory.
Вот официальные версии:
- для VS v1.13.2: TipMod_vs1.13.2_v1.0.0.zip и SpawnMod_vs1.13.2_v1.0.0.zip..
Wondering where some links have gone?
The modding navbox is going through some changes! Check out Navigation Box Updates for more info and help finding specific pages.
Modding | |
---|---|
Modding Introduction | Getting Started • Пакет тем |
Content Modding | Content Mods • Developing a Content Mod • Basic Tutorials • Intermediate Tutorials • Advanced Tutorials • Content Mod Concepts |
Code Modding | Code Mods • Setting up your Development Environment |
Property Overview | Item • Entity • Entity Behaviors • Block • Block Behaviors • Block Classes • Block Entities • Block Entity Behaviors • Collectible Behaviors • World properties |
Workflows & Infrastructure | Modding Efficiency Tips • Mod-engine compatibility • Mod Extensibility • VS Engine |
Additional Resources | Community Resources • Modding API Updates • Programming Languages • List of server commands • List of client commands • Client startup parameters • Server startup parameters Example Mods • API Docs • GitHub Repository |