Как сделать сервер для игры
Как создать свой игровой сервер?
Наверняка вы когда-то хотели, чтобы не вы играли на сервере, а у вас играли, играли на вашем сервере. Популярность игровых серверов всегда на высшем уровне, каждый раз выходят новые игры, моды, которые с нетерпением хочется опробовать. Помимо новых игр, есть игры и проекты, которые мы знаем еще с далеких 2000 годов, вспомните к примеру игру Counter-Strike 1.6, сколько же много было создано игровых серверов и как часто мы на них играли.
На данный момент снова замечен рост создания серверов, которые собирают множество игроков по всему миру.
Если вы действительно хотели бы создать свой игровой сервер, первое что Вам нужно сделать, это определиться с выбором сервера, где вы будете размещать файлы игрового сервера. Для этого обратим внимание на ADMINVPS — это российская компания предоставляющая услуги по аренде сервера, хостинга, VPS/VDS и т.д.
Для начала, давайте зайдем на сайт и выберем услугу VPS/VDS. После этого авторизуйтесь и пройдите процедуру регистрации VPS/VDS. На данном сайте процедура регистрации и оформления очень проста и займет у вас не более 10 минут. После оформления вы получите бесплатное администрирование, бесплатное бэкап место, круглосуточную поддержку, которая может Вам в решении ваших проблем.
Сайт предоставляет множество услуг, не только сервера, но и хостинг для ваших сайтов.
К примеру, когда вы закончите с установкой и настройкой вашего сервера, то следующем шагом следует сделать (по желанию) это создать сайт, посвященный вашему серверу, на сайте вы можете выкладывать обновления, изменения на вашем сервере, так же, можете создать форум, где игроки смогут общаться на разные темы по игре. Тем самым вы сделаете свой проект более живым.
Поэтому с хостингом Вам также может помочь ADMINVPS.
Почему именно VPS/VDS сервера?
Дело в том, что гораздо дешевле создать сервер именно в ручную, без использования сервисов, которые предоставляют игровые сервера. Готовые игровые сервера, это удобный сервис, но не дешевый, зачастую вы вряд ли сможете отбить затраты по обслуживанию вашего сервера, если даже будете продавать админки по 300р. Средняя цена игрового сервера это 850р в месяц, думаем, что на первых этапах это будет серьезно бить по карману и вы захотите закрыть Ваш сервер.
Но, если вы разместите свою или скаченную сборку, которая будет грамотно настроена, то вы сможете с экономить свои средства. Найти хорошую сборку не так и сложно, просто более тщательно осуществляйте поиск, и вы обязательно найдете подходящую сборку для Вас.
Также вы можете найти человека, который сможет Вам помочь в этом и создаст сборку под ваши запросы.
Но это также затраты, зато один раз и навсегда, после, если Вам нужно будет что-то доработать на сервере, вы сможете скачивать разные плагины и устанавливать их просто и быстро.
О том, как работать с плагинами, мы поговорим в другой статье.
После выбора сборки, скачайте и распакуйте свою сборку на Ваш сервер от ADMINVPS. Если у Вас возникнут трудности, вы сможете обратить в техническую поддержку вашего сервера, и Вам с радостью в этом помогут специалисты.
Переходите по ссылки и приобретайте свой хостинг – ADMINVPS
Разработка сервера под игру, с чего начать?
Привет.
Такой вопрос, как создаются сервера для игр? Есть к примеру игра GTA SA я так понимаю сторонние разработчики сделали клиент, который как-то взаимодействует с игрой передает данные и тд, вроде понимаю, но как клиет все таки влияет на игру? Я ОЧЕНЬ загорелся идеей сделать сервер для игры GTA 5 сделать моды к нему и тд, но не могу понять с чего начать. Как мне управлять игрой клиентом? Серверную часть я вроде как представляю, вопрос-ответ.
К примеру сделать сервер майнкрафт не состовляет проблем. Скачал, настроил, запустил, тут такого не нашел 🙁 Но по сути такое мне и не нужно, я хочу сделать свой сервер с 0 и свои моды, воплотить свои идеи в жизнь!
Кто имеет опыт расскажите!
Средний 1 комментарий
Есть к примеру игра GTA SA я так понимаю сторонние разработчики сделали клиент
То, что может сторонний разработчик, это сделать моды для готового сервера, используя те инструменты, которые разработчик предложил, либо пытаясь «грабить» протокол взаимодействия. Моды бывают серверными и клиентскими, и возможны только в том случае, если у вас есть доступ к компьютеру, на котором запущен сервер и клиент (клиент у вас всегда есть, так и делают большинство модов).
К примеру сделать сервер майнкрафт не состовляет проблем.
Майнкрафт заметно проще, чем GTA. Хотя бы потому, что майнкрафт сделал один человек, а GTA сделали десятки программистов. И вот для майнкрафта можно сделать свой сервер,а не мод (хотя и моды к нему тоже есть). Как пример, отличная статья.
Разработка сервера для многопользовательской игры с помощью nodejs и magx
Многие разработчики начинают разработку многопользовательского онлайн сервера на основе библиотеки socket.io. Эта библиотека позволяет очень просто реализовать обмен данными между клиентом и сервером в реальном времени, но продумать и реализовать всю логику и интерфейс взаимодействия сервера с клиентами, а также архитектуру масштабирования и оптимизацию трафика все равно придется.
Я хочу рассказать про библиотеку magx, используя которую можно не задумываться о сетевой составляющей (коммуникации сервера и клиентов), a сразу сконцентрироваться на разработке логики игры и клиентского UI.
При разработке архитектуры многопользовательсой игры обычно рассматриваются 2 подхода: с авторитарным сервером и не-авторитарным (авторитарным клиентом). Оба эти подхода поддерживаются библиотекой magx. Начнем с более простого подхода — не-авторитарного.
Не-авторитарный сервер
Суть его в том, что сервер не контролирует результаты ввода каждого игрока. Клиенты самостоятельно отслеживают введенные игроком действия и игровую логику локально, после чего высылают результат определенного действия на сервер. После этого сервер синхронизирует все совершенные действия с игровым состоянием других клиентов.
Это легче реализовать с точки зрения архитектуры, так как сервер отвечает только лишь за коммуникацию между клиентами, не делая никаких дополнительных вычислений, которые делают клиенты.
С помощью библиотеки magx такой сервер можно реализовать всего в несколько строк кода:
Теперь, чтобы подключить клиентов к этому серверу и начать их взаимодействие, достаточно установить js библиотеку:
и подключить ее к проекту:
Также можно воспользоваться прямой ссылкой для использования в HTML:
После подключения, всего несколько строк позволят настроить соединение и взаимодействие с сервером:
Детальный пример как построить взаимодействие между клиентами и не-авторитарным сервером описано в соответствующем примере в проекте magx-examples.
Авторитарный сервер
В авторитарном сервере обработка и выполнение всех действий, затрагивающих игровой процесс, применение правил игры и обработки ввода от игроков-клиентов осуществляется на стороне сервера.
Клиент не может самостоятельно вносить какие-либо изменения в состояние игры. Вместо этого, он отправляет серверу, что конкретно он хочет сделать, сервер обрабатывает этот запрос, вносит изменения в состояние игры и отправляет обновленное состояние клиентам.
При таком подходе логика на клиенте сводится к минимуму, клиент начинает отвечать только за отрисовку состояния игры и обработку действий игрока. Преимущество такого подхода в том, что он значительно усложняет клиентам возможность использования нечестных приёмов (cheating).
Разработка авторитарного сервера требует описания состояния игры и правил взаимодействия игрока с этим состоянием на стороне сервера. В архитектуре сервере magx предполагается, что вся логика реализуется комнате (worker). Каждая комната фактически является отдельным сервером, к которому подключаются клиенты.
Данные/состояние каждой комнаты изолировано и синхронизируется только с клиентам комнаты. Одним из важнейших элементов авторитарного сервера — это система управления состоянием. Mosx — рекомендованная система управления состоянием, но архитектуре magx нет зависимости на какую-либо систему, поэтому выбор всегда остается за вами.
Описание игрового состояния
Так как вся логика игры должна строиться на основе состояния, то первым делом необходимо его описать. С помощью mosx это сделать достаточно просто — необходимо создать классы для каждого типа объектов состояния и обернуть его декоратором @mx.Object, а перед каждым свойством, по которому необходимо отслеживать изменение состояния для синхронизации с клиентами необходимо поставить декоратор @mx. Давайте рассмотрим пример состояния с коллекцией игроков:
Единственное ограничение, которое необходимо учесть при проектировании состояния — необходимость использования Map() вместо вложенных объектов. Массивы (Array) и все примитивные типы (number, string, boolean) могут быть использованы без ограничений.
Описание игровой комнаты
После описания состояния и логики его изменения необходимо описать логику взаимодействия с клиентами. Для этого необходимо создать класс комнаты и описать необходимые обработчики событий:
Регистрация комнаты на сервере
Последний шаг — зарегистрировать комнату и сервер готов.
Полный исходный код рассмотренного примера доступен в репозитарии magx-examples.
Почему стоит обратить внимание на этот проект?
В заключение хотел бы упомянуть о преимуществах используемых библиотек:
Данный проект достаточно молодой и надеюсь внимание комьюнити поможет ему развиваться на много быстрее.
Мультиплеер в быстрых играх (части I, II)
Разработка игры — само по себе непростое занятие. Но мультиплеерные игры создают совершенно новые проблемы, требующие разрешения. Забавно, что у наших проблем всего две причины: человеческая натура и законы физики. Законы физики привнесут проблемы из области теории относительности, а человеческая натура не даст нам доверять сообщениям с клиента.
Если вы уже знакомы с базовыми идеями, стоящими за многопользовательскими играми — смело пропускайте первую часть и переходите ко второй.
Часть I
Проблема читерства
Вся наша головная боль начинается с читерства.
Если вы разрабатываете одиночную игру, вам наплевать если пользователь решит смухлевать — его действия влияют только на него. Да, возможно игрок не получит тот опыт, который вы хотели ему дать, но в конце концов он купил игру и может пользоваться ей как захочет.
А вот в мультиплеерных играх все совсем иначе. В любой соревновательной игре читер не просто упрощает себе игру, но и ухудшает чужой игровой опыт. Вам, как разработчику, стоит препятствовать этому, так как читеры отгоняют игроков от вашей игры.
Есть много вещей которые можно сделать чтобы предотвратить читерство. Но самый главный принцип(и наверное самый глубокий) очень прост: не доверяй игроку. Всегда ожидайте худшего — что игрок будет пытаться вас обмануть.
Авторитарный сервер и наивный клиент
Этот принцип ведет нас к простому, на первый взгляд, решению — вся игровая логика крутится на главном сервере, под вашим контролем, а клиент лишь демонстрирует текущее состояние сервера и отправляет ему команды (нажатия клавиш и т.д.). Обычно это называют авторитарным сервером, потому что он единственный, кто умеет моделировать мир.
Конечно, сервер может быть взломан, но эта тема выходит за рамки данной серии статей. Тем не менее, использование авторитарного сервера предотвращает широкий спектр читов. Например, вы не можете доверять клиенту уровень жизней игрока. Взломанный клиент может изменить локальную информацию и сообщить что у игрока 100000% жизней, но сервер знает что жизней всего 10% и если игрока атакуют, он умрет вне зависимости от того, что об этом думает клиент.
Так же нельзя верить игроку, когда он сообщает о его позиции в мире. Если вы доверитесь, взломанный клиент может сообщить серверу:
— Я на (10, 10)
А секундой позже:
При этом возможно он «прошел» через стену или двигается быстрее чем ему положено.
А вот правильная парадигма. Сервер знает что игрок находится в позиции (10, 10); клиент говорит: «Я хочу подвинуться на единицу вправо». Сервер обновляет позицию игрока на (11, 10), производя все необходимые проверки, а затем отвечает игроку: «Вы на (11, 10)»:
Подытожим: игровое состояние управляется только сервером. Клиенты отправляют свои действия на сервер, а сервер периодически обновляет свое состояние и отправляет его на клиенты, которые, в свою очередь отображают его пользователям.
Разбираемся с сетями
Наивный клиент отлично подходит для медленных пошаговых игр — стратегий или покера. Так же он неплохо сработает при локальном подключении, где информация передается практически мгновенно. Но он абсолютно непригоден для быстрых игр по интернету.
Давайте поговорим о физике. Предположим что вы находитесь в Сан-Франциско и подключаетесь к серверу в Нью-Йорке. Это примерно 4000 километров. Так как ничто не может передвигаться быстрее скорости света, в лучшем случае сигнал дойдет за 13 миллисекунд. Но весьма маловероятно, что у вас будет такая хорошая связь. В реальном мире информация не идет прямым путем, причем не со скоростью света.
Так что давайте предположим, что это занимает 50 мс. И это практически лучший сценарий. А что если вы подключаетесь к серверу в Токио? А что если линия связи перегружена? В таких случаях задержки доходят до половины секунды.
Вернемся к нашему примеру. Пусть клиент отправляет сообщение:
— Я нажал на стрелку вправо.
Сервер получает запрос через 50 мс и сразу отправляет обратно обновленное состояние.
Это сообщение дойдет до пользователя еще через 50 мс.
С точки зрения игрока, он нажал на стрелку, потом 0.1 секунды ничего не происходило, а затем персонаж наконец подвинулся на единицу вправо. Этот лаг между командой и её результатом может показаться незначительным, но он заметен. И уж конечно лаг в полсекунды был бы не просто заметным, а сделал бы игру абсолютно неиграбельной.
Резюмируя
Игры по сети невероятно веселы, но привносят совершенно новый класс проблем и препятствий. Авторитарная архитектура хороша против читеров, но наивная реализация сделает игру неотзывчивой для пользователей.
В дальнейшем мы исследуем возможность создания системы, базирующейся на авторитарном сервере, но с минимальными задержками для игроков, делая их неотличимыми от одиночных игр.
Часть II
Введение
В первой части мы рассмотрели клиент-серверную модель с авторитарным сервером и наивным клиентом, который отправляет команды на сервер и отображает обновленное состояние пришедшее в ответе.
Наивная реализация этой концепции приводит к ощутимой задержке между командой и реакцией. Например, если игрок нажимает стрелку влево, персонаж начнет двигаться через полсекунды. Это происходит потому что команда должна дойти до сервера, а результат команды после этого должен дойти до клиента.
В интернете, где задержки могут составлять десятые доли секунды, геймплей в лучшем случае будет неотзывчивым, а в худшем — неиграбельным. В этой части мы найдем способы уменьшить эту проблему или избавиться от неё вовсе.
Предсказание на стороне клиента
Несмотря на то что некоторые игроки пытаются читерить, большую часть времени сервер получает корректные запросы. Это означает, что полученный ввод будет корректным и игра обновится так, как ожидается. То есть если персонаж находится на (10, 10) и отправляет команду на движение вправо, он окажется на (11, 10).
Мы можем использовать это если игра достаточно детермениртована (то есть результат определен командами и предыдущим состоянием).
Предположим что у нас лаг 100 мс и время перемещения персонажа составляет 100 мс. При использовании наивной реализации, время действия составит 200 мс.
Предполагая что команды будут исполнены, клиент может предсказывать состояние игрового мира и часто предсказание будет правильным, так как игровой мир детерминированный.
Так что вместо того чтобы отправлять команду и ждать пока придет новое игровое состояние чтобы отрендерить его, мы можем отправить команду и начать рендерить результат как если бы команда уже была выполнена. И, разумеется, надо ждать от сервера результата — «настоящего» состояния игры, которое по большей части будет совпадать с локальным состоянием.
Теперь у нас нет абсолютно никакой задержки между действием игрока и результатом на экране, а сервер все еще авторитарный (если взломаный клиент начнет отправлять некорректные команды, он может рендерить что угодно на экране, но это никак не повлияет на состояние игры на сервере, которое видят другие игроки).
Проблемы синхронизации
В предыдущем примере я аккуратно подобрал числа чтобы все отлично работало. Давайте немного изменим сценарий. Лаг будет составлять 250 мс, а анимация передвижения на одну единицу будет длиться 100 мс. А еще давайте игрок дважды быстро нажмет на стрелку вправо.
При использовании текущего подхода вот что произойдет:
Мы столкнулись с интересной проблемой на t = 250 мс, когда нам пришло новое состояние. Клиент предсказал x = 12, но сервер говорит что x = 11. Так как сервер авторитарный, клиент должен передвинуть персонажа обратно на x = 11. Но позже, на t = 350, сервер говорит что x = 12, так что персонаж опять прыгает, но на этот раз вперед.
С точки зрения игрока, он нажал на стрелку вправо дважды, так что персонаж переместился на две единицы вправо, постоял там 50 мс, прыгнул на единицу влево, постоял там 100 мс и прыгнул на единицу вправо. Конечно, это совершенно неприемлимо.
Согласование с сервером
Ключ к решению этой проблемы лежит в понимании того, что клиент видит игровой мир в настоящем времени, но из-за лага обновления с сервера приходят о состоянии мира в прошлом. К тому моменту, когда сервер отправил нам обновления, он еще не получил некоторые наши команды.
Но обойти эту проблему не так уж сложно. Давайте будем добавлять к каждому запросу от клиента его номер. А сервер при ответе будет добавлять номер последнего обработанного запроса. И давайте хранить на клиенте копию всех команд, отправляемых на сервер.
Итак, на t = 250 клиенту приходит «x = 11, последняя команда #1». Клиент удаляет все команды до #1 включительно, но оставляет копию #2, о которой еще не знает сервер. Он применяет полученное от сервера состояние (x = 11), а затем применяет ввод, который еще не виден серверу. В данном случае #2 «вправо на 1 единицу». Конечный результат x = 12, что соответствует истине.
Далее, на t=350, от сервера приходит новое состояние: «x = 12, последняя команда #2». Клиент удаляет все копии команд до #2 включительно, а затем применяет состояние x=12(ничего не изменилось). Так как более нет необработанных команд, на этом все заканчивается, с корректным результатом.
Итоги
Мы разобрали пример с движением, но этот же принцип применим почти ко всему. Например, при атаке вражеского персонажа, вы можете сразу показать кровь и число, отражающее нанесенный урон.
Но не стоит на самом деле обновлять жизни персонажа, пока сервер не пришлет обновленное состояние.
Из-за сложностей игрового состояния, которое не всегда легко откатить, возможно не стоит убивать персонажа даже если уровень его жизни упал ниже нуля. Что если что другой игрок вылечился прямо перед вашей атакой, но сервер еще об этом не сообщил?
Прим. перев. Я бы убивал персонажа сразу, но обеспечил персистентность(возможность откатывания состояний). Так будет проще писать переносимый код, выполняющийся и на сервере и на клиенте. В любом случае, как вы убедитесь в этом позже, это придется делать.
Это все нас приводит к интересному заключению — даже если мир абсолютно детерминированный и нет читерящих игроков, все равно есть вероятность того, что состояние предсказанное клиентом и состояние отправленное с сервера не совпадают. Хоть для одного игрока это невозможно, очень легко воспроизвести такую проблему при нескольких одновременно играющих игроках. Это будет темой следующей статьи.
Поднимаем свой полноценный игровой Minecraft сервер с мини-играми. Часть 2. Устанавливаем карту для лобби сервера
Посмотреть, что в итоге получилось у меня: mc.piratebayserver.net
По любым вопросам пишите в Discord.
После публикации первой части статьи по установке своего Minecraft сервера, ко мне обратился один читатель Хабра. В письме он написал, что по неосторожности показал мою статью своим детям и ему пришлось пообещать сделать все, как написано. Теперь я, как отец двух детей, просто не имею морального права не закончить серию этих статей. Поэтому поехали.
В первой части мы создали виртуальный сервер, скачали и запустили наш первый Minecraft сервер на Paper. Кто проделал все шаги сразу после публикации статьи, прошу обратить внимание на некоторые исправления, которые последовали после. Так, по советам в комментариях, я создал отдельного пользователя на виртуальном сервере. Поэтому все дальнейшие действия после создания пользователя будут выполнятся из под него. Запуск приложений из под root пользователя является плохой практикой и это просто не безопасно, так как предоставляет запускаемым приложениям неограниченный доступ к серверу.
Теперь, когда у нас есть запущенный Minecraft сервер, не плохо было бы заменить сгенерированную карту мира на что-то более подходящее для лобби сервера. Лобби — это наш главный сервер, визитная карточка, он служит точкой входа для игроков. Именно отсюда игроки будут перенаправляться на другие наши сервера, такие, как сервера мини-игр или выживания.
Есть несколько способов импортирования карт на ваш сервер.
Самый простой — копирование папки с миром с вашего ПК в папку вашего сервера. Такой способ подходит, если вы создали карту самостоятельно в одиночной игре либо скачали из интернета в формате, готовом для использования. Как найти файлы карт, сохраненные игрой на вашем компьютере, можно посмотреть здесь.
Второй способ — импорт карт с расширением schematic. Это формат, разработаный сообществом для хранения частей карт и использования их в сторонних программах, таких как MCEdit, WorldEdit, FastAsyncWorldEdit и др.
Я буду использовать для импорта карт второй метод, так как он более трудоёмкий и знание этого процесса может пригодиться вам в будущем. Если вы планируете использовать готовые архивы миров, можете пропустить этот пункт и просто скопировать папку с миром в папку сервера
Так, например, все карты, которые я покупал для своего сервера, шли в формате shematic. Так же, этот метод позволяет редактировать импортированые карты, например вырезать или копировать отдельные части. Мне это понадобилось, когда в купленом файле шли 4 набора островов для BedWars и нужно было разбить их на части по одному набору на сервер.
При использовании файлов в формате schematic для создания карт сервера вам понадобится пустой мир, в который вы будете импортировать карту. Обычно я использую два вида пустых миров: первый — это мир с одним блоком, второй — это океан. Первая карта подходит для создания миров для игр с воздушными островами, такими как SkyBlock, BedWars, SkyWars и тд. Океан же подходит для создания карт с островами в воде.
В интернете вы можете найти туториалы, как создать пустой мир или океан. Я же, ради сокращения размера статьи, просто прикреплю созданные мной карты:
Для удобства дальнейшей установки и редактирования плагинов, а с моей строны для сокращения количества комманд в статье, устанавливаем FTP клиент для подключения к нашему серверу. Я установил FileZilla.
После установки FTP клиента, подключаемся к серверу и переходим в папку с плагинами. У меня это /home/dinikin/PirateBay/plugins. Для краткости и универсальности буду писать
Скачиваем jar файл плагина FastAsyncWorldEdit и копируем в папку plugins на сервере. Так же скачиваем мой архив пустой карты Void.zip, распаковываем и подкладываем папку Void в папку Minecraft сервера
Если вы запускали Minecraft сервер напрямую из терминала, то после закрытия сесии процесс автоматически завершится и сервер остановится. Что бы этого не происходило в дальнейшем, для запуска сервера мы будем использовать программу screen.
Заходим на сервер по ssh:
и проверяем, установлена ли программа:
если возвращается версия программы, значит она установлена, иначе устанавливаем:
и создаем файл start.sh для запуска Minecraft сервера:
со следующим содержимым:
Даем файлу права на выполнение:
Если сервер в вашей терминальной сессии на данном этапе был уже запущен, останавливаем его командой stop.
Перед повторным запуском нам нужно перенастроить наш сервер на новую карту. Открываем через FTP клиент файл
/PirateBay/server.properties и устанавливаем следующие значения параметров:
Если вы использовали карту из одиночной игры со своего ПК, либо скачали архив из интернета, тогда вместо Void укажите имя папки с файлами мира, предварительно скопировав их в папку
Дальше удаляем на сервере папки с ранее сгенерированными мирами:
world
world_nether
world_the_end
Их можно оставить, но я предпочитаю удалять, что бы они в будущем случайно не использовались сервером, если я не изменил в каком то плагине или файле конфигурации название мира по умолчанию.
И так, запускаем сервер через sh скрипт:
теперь, если ваша терминальная сессия оборвется, вы можете посмотреть список запущеных серверов командой:
а подключиться командой:
На самом деле, вместо PirateBay вы можете указать такое название процесса, по которому вам будет однозначно понятно, какой сервер запущен.
И так, мы устаноновили плагин для редактирования карт и перезапустили сервер. Подключаемся к нему из лаунчера игры.
Пустой мир загрузился и мы готовы импортировать какую нибудь карту для лобби. Я выбрал вот такую:
Давайте скачаем ее здесь и скопируем файл WaithSpawn.schematic в папку
Теперь в запущеном игровом клиенте нажимаем / для открытия командной строки и пишем команду schematic. Как видим по сообщению, у нас нет прав на выполнение этой команды.
По умолчанию, большинство устанавливаемых плагинов ограничивают доступ к своим командам, открывая его только для оператора, т.е. администратора сервера. Переключаеся на терминальную сессию нашего сервера и пишем комманду /op Dinikin (в вашем случае это будет ваш никнейм):
Мы предоставили права администратора нашему пользователю и тепрерь можем повторно выполнить команду /schematic в игре:
Как видите, права появились. Но нас больше интересует команда /schematic list
Теперь в списке появилась наша загруженная карта. Нажимаем на нее мышкой и выполняем предложенную команду:
Когда команда выполнилась, выполняем команду //paste. Как результат, карта импортировалась в наш мир:
Поздравляю, мы добавили нашу первую карту на сервер.
Что мы будем делать в следующей части: