Modding:Moddable Mod/ru: Difference between revisions

From Vintage Story Wiki
(Created page with "Два мода, которые мы будем создавать, называются «TipMod» и «SpawnMod». * «TipMod» будет хранить полезные п...")
(Created page with "Вот официальные версии: * для VS v1.13.2: [https://wiki.vintagestory.at/index.php?title=File:TipMod_vs1.13.2_v1.0.0.zip TipMod_vs1.13.2_v1.0.0.zip] и [...")
 
(20 intermediate revisions by the same user not shown)
Line 29: Line 29:
* "SpawnMod" зарегистрирует команду, которая телепортирует игрока в заданную или заданную по умолчанию точку возрождения. Он также получит доступ к «TipMod» и добавит свои собственные советы по команде.
* "SpawnMod" зарегистрирует команду, которая телепортирует игрока в заданную или заданную по умолчанию точку возрождения. Он также получит доступ к «TipMod» и добавит свои собственные советы по команде.


== Preparation ==
== Подготовка ==
We start by setting up two empty mods, "TipMod" and "SpawnMod".
Начнем с установки двух пустых модов, «TipMod» и «SpawnMod».
In each mod, we add a new *.cs source file - we will be naming these files <code>TipMod.cs</code> and <code>SpawnMod.cs</code> respectively.
В каждый мод мы добавляем новый исходный файл *.cs — мы будем называть эти файлы <code>TipMod.cs</code> и <code>SpawnMod.cs</code> соответственно.
In our .cs files, we do the following:
В наших файлах .cs мы делаем следующее:
* Add the necessary <code>using</code> directives.
* Добавьте необходимые директивы <code>using</code>.
* Create a class named after the mod it's contained in - <code>TipMod</code> and <code>SpawnMod</code>.
* Создайте класс с именем мода, в котором он содержится — <code>TipMod</code> и <code>SpawnMod</code>.
* Have our classes inherit <code>ModSystem</code> - the base for any VintageStory code mod.
* Наши классы должны наследовать <code>ModSystem</code> — основу для любого мода кода VintageStory.
* Override the <code>StartServerSide</code> method to access [http://apidocs.vintagestory.at/api/Vintagestory.API.Common.ICoreServerAPI.html <code>ICoreServerAPI</code>].
* Переопределите метод <code>StartServerSide</code> для доступа к [http://apidocs.vintagestory.at/api/Vintagestory.API.Common.ICoreServerAPI.html <code>ICoreServerAPI</code>].
* Make the <code>TipMod</code> class <code>public</code> so that it's accessible by other mods.
* Сделайте класс <code>TipMod</code> <code>public</code>, чтобы он был доступен другим модам.


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
Line 82: Line 82:
}
}
</syntaxhighlight>
</syntaxhighlight>
This concludes setting up the basis of our mods. Lastly, in "TipMod", we create an additional file called <code>Tip.cs</code>,  
На этом мы завершаем настройку основы наших модов. Наконец, в «TipMod» мы создаем дополнительный файл с именем <code>Tip.cs</code>,
where we will define the data structure for tips, called <code>Tip</code>.
где мы определим структуру данных для подсказок, называемую <code>Tip</code>.


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
Line 114: Line 114:
}
}
</syntaxhighlight>
</syntaxhighlight>
Our resulting folder structure looks like this.
Наша результирующая структура папок выглядит так.
[[File:ModdableModFolderStructure.png|none]]
[[File:ModdableModFolderStructure.png|none]]
We are now ready to extend our mods, starting with "TipMod" - our moddable mod.
Теперь мы готовы расширить наши моды, начиная с «TipMod» — нашего модифицируемого мода.


== Setting up TipMod ==
== Настройка TipMod ==
For "TipMod", we do the following:
Для «TipMod» делаем следующее:
* Store the <code>ICoreServerAPI</code> object as a field so that we can access it throughout our class.
* Сохраните объект <code>ICoreServerAPI</code> как поле, чтобы мы могли получить к нему доступ во всем нашем классе.
* Define a <code>List</code> that stores <code>Tip</code> objects.
* Определите <code>List</code>, в котором хранятся объекты <code>Tip</code>.
* Define a method that selects a random <code>Tip</code> from the <code>List</code> and prints it in chat for all players, printing a default message if the <code>List</code> is empty.
* Определите метод, который выбирает случайный <code>Совет</code> из <code>Списка</code> и печатает его в чате для всех игроков, печатая сообщение по умолчанию, если <code>Список</code> пустой.
* Register that method to be called at set intervals by the [http://apidocs.vintagestory.at/api/Vintagestory.API.Server.IServerEventAPI.html#Vintagestory_API_Server_IServerEventAPI_Timer_Vintagestory_API_Common_Action_System_Double_ <code>Timer</code>], which is available in the [http://apidocs.vintagestory.at/api/Vintagestory.API.Server.IServerEventAPI.html <code>IServerEventAPI</code>].
* Зарегистрируйте этот метод для вызова через заданные интервалы с помощью [http://apidocs.vintagestory.at/api/Vintagestory.API.Server.IServerEventAPI.html#Vintagestory_API_Server_IServerEventAPI_Timer_Vintagestory_API_Common_Action_System_Double_ <code>Timer</code>], который доступен в [http://apidocs.vintagestory.at/api/Vintagestory.API.Server.IServerEventAPI.html <code>IServerEventAPI</code>].
* Define a <code>public</code> method for adding new <code>Tip</code> objects.
* Определите метод <code>public</code> для добавления новых объектов <code>Tip</code>.


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
Line 150: Line 150:
             if (tipCount > 0)
             if (tipCount > 0)
             {
             {
                 // Select a random number in the range of [0-1]
                 // Выберите случайное число из диапазона [0-1]
                 double random = api.World.Rand.NextDouble();
                 double random = api.World.Rand.NextDouble();
                 // Make the number relative to the size of our tips list
                 // Сделайте число относительно размера нашего списка советов
                 int randomTip = (int)Math.Floor(random * tipCount);
                 int randomTip = (int)Math.Floor(random * tipCount);


Line 170: Line 170:
     }
     }
</syntaxhighlight>
</syntaxhighlight>
For testing purposes, we set the interval to be very short (10 seconds). Feel free to change this accordingly.
В целях тестирования мы установили очень короткий интервал (10 секунд). Не стесняйтесь изменить это соответствующим образом.


Remember, both <b>classes and methods which other mods will interact with have to be declared <code>public</code>.</b>
Помните, что как <b>классы, так и методы, с которыми будут взаимодействовать другие моды, должны быть объявлены <code>public</code>.</b>
In C#, classes and methods are not public by default. You can [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers read more about this here.]
В C# классы и методы по умолчанию не являются общедоступными. Вы можете [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers прочитать об этом здесь].


We can now compile our mod, add it to our VintageStory mod folder and test it ingame. If the there are occasional chat messages saying "There aren't any listed tips", our mod is working. We are ready to move on to the next step - setting up "SpawnMod" and then having it interact with "TipMod".
Теперь мы можем скомпилировать наш мод, добавить его в папку с модами VintageStory и протестировать его в игре. Если в чате время от времени появляются сообщения «Нет советов в списке», наш мод работает. Мы готовы перейти к следующему шагу — настроить «SpawnMod», а затем заставить его взаимодействовать с «TipMod».
== Setting up SpawnMod ==
== Настройка SpawnMod ==
Let's first setup our mods functionality. We register a command which teleports the player to spawn. Conveniently, the [http://apidocs.vintagestory.at/api/Vintagestory.API.Server.IServerPlayer.html <code>IServerPlayer</code>] object stores it's spawn position, as well as the [http://apidocs.vintagestory.at/api/Vintagestory.API.Common.IPlayer.html#Vintagestory_API_Common_IPlayer_Entity <code>IPlayerEntity</code>], which defines a method for teleporting itself to a location.  
Давайте сначала настроим функциональность наших модов. Мы регистрируем команду, которая телепортирует игрока на спавн. Для удобства объект [http://apidocs.vintagestory.at/api/Vintagestory.API.Server.IServerPlayer.html <code>IServerPlayer</code>] хранит свою позицию появления, а также [http://apidocs .vintagestory.at/api/Vintagestory.API.Common.IPlayer.html#Vintagestory_API_Common_IPlayer_Entity <code>IPlayerEntity</code>], который определяет метод телепортации в определенное место.
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
     // In SpawnMod.cs
     // In SpawnMod.cs
Line 195: Line 195:
     }
     }
</syntaxhighlight>
</syntaxhighlight>
"SpawnMod" is ready. Let's test it. The command <code>/spawn</code> should now teleport us to spawn.
"СпаунМод" готов. Давайте проверим это. Команда <code>/spawn</code> теперь должна телепортировать нас к месту появления.
If our mods are working, we're ready to make "SpawnMod" interact with "TipMod".
Если наши моды работают, мы готовы заставить "SpawnMod" взаимодействовать с "TipMod".


== Mods interacting ==
== Моды взаимодействуют ==
Before we get started, we have to add a reference in "SpawnMod" to "TipMod".  
Прежде чем мы начнем, мы должны добавить ссылку в «SpawnMod» на «TipMod».
=== Adding a reference to an external mod ===
=== Добавление ссылки на внешний мод ===
If you are using Visual Studio, in your Solution Explorer, directly under your project, right-click "References" and select "Add Reference".
Если вы используете Visual Studio, в обозревателе решений, прямо под вашим проектом, щелкните правой кнопкой мыши "Ссылки" и выберите "Добавить ссылку".
[[File:ADDINGAREFERENCERIGHTCLICK.png|none]]
[[File:ADDINGAREFERENCERIGHTCLICK.png|none]]


Here we locate either the "TipMod" project or the compiled .dll file, and add it.
Здесь мы находим либо проект «TipMod», либо скомпилированный файл .dll и добавляем его.
[[File:FindingReference.png|none]]
[[File:FindingReference.png|none]]


After adding the reference, make sure it is not copying the file to the output folder when compiling -
После добавления ссылки убедитесь, что он не копирует файл в выходную папку при компиляции -
having multiple .dll files with <code>ModSystems</code> in them will break your mod.
наличие нескольких файлов .dll с <code>ModSystems</code> в них сломает ваш мод.
[[File:SettingCopyLocalToFalse.png|none]]
[[File:SettingCopyLocalToFalse.png|none]]


=== Accessing the ModLoader ===
=== Доступ к ModLoader ===
Now we're ready to have "SpawnMod" add tips. Let's go ahead and do the following.
Теперь мы готовы к тому, чтобы "SpawnMod" добавил подсказки. Давайте продолжим и сделаем следующее.
* Add a <code>using</code> directive for the namespace <code>tipmod.src</code>.
* Добавьте директиву <code>using</code> для пространства имен <code>tipmod.src</code>.
* Retrieve <code>TipMod</code> through the <code>ModLoader</code> by passing it's type.
* Получить <code>TipMod</code> через <code>ModLoader</code>, передав его тип.
* Call the <code>AddTip</code> method provided by <code>TipMod</code> and add a variety of tips.
* Вызовите метод <code>AddTip</code>, предоставляемый <code>TipMod</code>, и добавьте различные подсказки.


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
Line 232: Line 232:
</syntaxhighlight>
</syntaxhighlight>


== Conclusion ==
== Заключение ==


Following the steps in this article, this is what our resulting code looks like, spread across two mods.
Следуя шагам, описанным в этой статье, вот как выглядит наш результирующий код, распределенный по двум модам.


<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
Line 271: Line 271:
             if (tipCount > 0)
             if (tipCount > 0)
             {
             {
                 // Select a random number in the range of [0-1]
                 // Выберите случайное число из диапазона [0-1]
                 double random = api.World.Rand.NextDouble();
                 double random = api.World.Rand.NextDouble();
                 // Make the number relative to the size of our tips list
                 // Сделайте число относительно размера нашего списка советов
                 int randomTip = (int)Math.Floor(random * tipCount);
                 int randomTip = (int)Math.Floor(random * tipCount);


Line 357: Line 357:
</syntaxhighlight>
</syntaxhighlight>


We're now ready to test our mods to see if they're interacting successfully. After placing both our compiled mods in the mods folder and booting into a world, we should see a random tip pop up in the chat every 10 seconds.
Теперь мы готовы протестировать наши моды, чтобы увидеть, успешно ли они взаимодействуют. После помещения обоих наших скомпилированных модов в папку модов и загрузки в мир мы должны видеть всплывающую случайную подсказку в чате каждые 10 секунд.
[[File:ModdableModSuccess.png|none]]
[[File:ModdableModSuccess.png|none]]
If so, well done! You've successfully followed the article and have created a moddable mod.
Если да, то молодец! Вы успешно следовали статье и создали модифицируемый мод.


== Troubleshooting ==
==Устранение неполадок==


If you've ran into problems setting up either mod, check the error logs located at <code>VintagestoryData/Logs</code> in <code>server-main.txt</code>.
Если у вас возникли проблемы с настройкой любого мода, проверьте журналы ошибок, расположенные в <code>VintagestoryData/Logs</code> в <code>server-main.txt</code>.
Possible causes for either mod not working:
Возможные причины того, что любой из модов не работает:
* It's a .cs (source) mod and not a .dll (compiled) mod. Refer here [https://wiki.vintagestory.at/index.php?title=Modding:Setting_up_your_Development_Environment#Set_Mod for how to set a compiled mod.]  
* Это мод .cs (исходный код), а не мод .dll (скомпилированный). Обратитесь сюда [https://wiki.vintagestory.at/index.php?title=Modding:Setting_up_your_Development_Environment#Set_Mod, чтобы узнать, как установить скомпилированный мод.]
* It's missing <code>modinfo.json</code>.
* Отсутствует <code>modinfo.json</code>.
* Your version of VintageStory is outdated.
* Ваша версия VintageStory устарела.
* You have multiple .dll files containing <code>ModSystems</code> in your mod folder.
* У вас есть несколько файлов .dll, содержащих <code>ModSystems</code> в папке вашего мода.
* The referenced mod, "TipMod", is not present in the mod folder.
* Упомянутый мод "TipMod" отсутствует в папке мода.


== Distribution ==
== Распространение ==
To distribute this mod, run the following command in the vsmodtools cli <code>pack <your mod id></code>, then copy the .zip file into your VintageStory mods folder.
Чтобы распространить этот мод, запустите следующую команду в vsmodtools cli <code>pack <your mod id></code>, затем скопируйте ZIP-файл в папку модов VintageStory.


Here are the official versions:
Вот официальные версии:
* for VS v1.13.2: [https://wiki.vintagestory.at/index.php?title=File:TipMod_vs1.13.2_v1.0.0.zip TipMod_vs1.13.2_v1.0.0.zip] and [https://wiki.vintagestory.at/index.php?title=File:SpawnMod_vs1.13.2_v1.0.0.zip SpawnMod_vs1.13.2_v1.0.0.zip].
* для VS v1.13.2: [https://wiki.vintagestory.at/index.php?title=File:TipMod_vs1.13.2_v1.0.0.zip TipMod_vs1.13.2_v1.0.0.zip] и [https://wiki.vintagestory.at/index.php?title=File:SpawnMod_vs1.13.2_v1.0.0.zip SpawnMod_vs1.13.2_v1.0.0.zip]..


{{Navbox/modding/ru|Vintage Story}}
{{Navbox/modding/ru|Vintage Story}}

Latest revision as of 10:49, 16 June 2022

Other languages:

Эта страница проверялась в последний раз для версии 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; 
        }
    }
}

Наша результирующая структура папок выглядит так.

ModdableModFolderStructure.png

Теперь мы готовы расширить наши моды, начиная с «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, в обозревателе решений, прямо под вашим проектом, щелкните правой кнопкой мыши "Ссылки" и выберите "Добавить ссылку".

ADDINGAREFERENCERIGHTCLICK.png

Здесь мы находим либо проект «TipMod», либо скомпилированный файл .dll и добавляем его.

FindingReference.png

После добавления ссылки убедитесь, что он не копирует файл в выходную папку при компиляции - наличие нескольких файлов .dll с ModSystems в них сломает ваш мод.

SettingCopyLocalToFalse.png

Доступ к 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 секунд.

ModdableModSuccess.png

Если да, то молодец! Вы успешно следовали статье и создали модифицируемый мод.

Устранение неполадок

Если у вас возникли проблемы с настройкой любого мода, проверьте журналы ошибок, расположенные в VintagestoryData/Logs в server-main.txt. Возможные причины того, что любой из модов не работает:

  • Это мод .cs (исходный код), а не мод .dll (скомпилированный). Обратитесь сюда чтобы узнать, как установить скомпилированный мод.
  • Отсутствует modinfo.json.
  • Ваша версия VintageStory устарела.
  • У вас есть несколько файлов .dll, содержащих ModSystems в папке вашего мода.
  • Упомянутый мод "TipMod" отсутствует в папке мода.

Распространение

Чтобы распространить этот мод, запустите следующую команду в vsmodtools cli pack <your mod id>, затем скопируйте ZIP-файл в папку модов VintageStory.

Вот официальные версии:

Icon Sign.png

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 ItemEntityBlockBlock BehaviorsBlock ClassesBlock EntitiesBlock Entity BehaviorsWorld properties
Workflows & Infrastructure Modding Efficiency TipsMod-engine compatibilityMod ExtensibilityVS Engine
Additional Resources Community Resources Modding API Updates Programming Languages List of server commandsList of client commandsClient startup parametersServer startup parameters
Example ModsAPI DocsGitHub Repository