На дворе осень и сын все чаще остается дома, уткнувшись в телефон или планшет, слабо реагируя на внешние раздражители. Меня это огорчает. Сам я начал программировать, как мне кажется, с того, что к моему первому компьютеру БК 0010-01 игры то на кассетах в комплекте шли, а вот магнитофон не шел. Пока добывали магнитофон с подходящим линейным выходом, я успел попробовать Бейсик, спасибо отцу за первые уроки. Так что, когда смог со скрипом загрузить первую графическую игру, то смотрел на нее уже не как на то, во что наконец буду играть, а очарованно думал, как бы сделать свою не хуже. Сына же, в его 8 лет, давно поглотил мир видеоигр и ютуба, так что начинать программирование с трели на встроенном динамике, похоже, впечатления не произведет.
Мне давно попадались статьи о программировании с Minecraft на питоне и тут я понял, что пора. Minecraft — одна из самых любимых его игр и я подумал, что лучше будет начать именно с этой, хорошо освоенной территории.
Однако, пробежав по имеющейся в свободном доступе информации, я понял, что все очень не просто. Найденные книги "Программируем с Minecraft. Создай свой мир с помощью Python" 2017 года и "Minecraft. Программируй свой мир на Python" 2018 года начинают с установки серверов Spigot и Bukkit соответственно. Оказалось, что мобильные клиенты, которые на android/iphone, они же pocket edition, они же bedrock edition, с этими серверами не работают. Надо покупать клиент под Windows/Mac, что портит всю затею. Во-первых это будет уже не "родная" среда, привычная сыну. Во-вторых, пересаживаться ради программирования в другую среду продемонстрирует слабость, что ли, подхода, мол игры отдельно, программы отдельно. В-третьих, сыну наверное захочется показать свои эксперименты друзьям, а у друзей популярны именно мобильные версии. Так нельзя, решил я, раз эти мобильные игрушки умеют подключаться к серверам, не все потеряно. И я начал искать.
В первый день мой хром был до отказа забит вкладками, а в голове воцарился хаос.
Первым нашелся сервер Nukkit с открытым исходным кодом, к которому игра на моем андроиде подключилась вполне успешно. Единственный момент тут, что нужна актуальная версия игры (1.12 на сегодня), так что понадобилось обновить ее сначала. У сервера много плагинов, но плагина, пригодного для программирования, вроде, описанных в книгах, не нашлось.
Нашелся, правда, PyPlugins, который вроде запускает Jython — версию питона на java. Но, как я понял, jython остановился на версии языка python 2.7. Отложил этот вариант, как неспортивный.
Пойдем с другой стороны, а как авторы книг подразумевали подключение питона к серверам? Пристально изучив дополнительные материалы к книгам, благо они в свободном доступе, нашел плагин RaspberryJuice, заботливо спрятанный в директории plugins (в книге о нем ни слова), он то и открывает сетевой сокет в ожидании команд. А команды отправляет питоновская библиотека mcpi. Спасибо авторам, все с открытым кодом. Немного напрягало, что последний коммит 2-4 года назад.
Но как подключить RaspberryJuice к Nukkit? И тут отыскивается, не смейтесь, Pokkit — плагин к Nukkit для запуска плагинов под Bukkit. Уж не знаю, почему названия таковы, но мне это добавило лишних часов поиска, так как сначала я их путал. Кажется теперь уже все части пазла на месте, но запуск выявляет ошибку: java.lang.NoSuchFieldError: GOLD_SWORD
. Обидно, ведь в описании Pokkit-а отмечено, что RaspberryJuice есть в списке поддерживаемых. Оформил баг. На удивление быстро пришел ответ — плагин устарел. "У вас все тут ржавое", вспомнилась фраза из любимого фильма. После уточнений, автор любезно разъяснил, где взять современное API для bukkit, ну а дальше "мы уж как-нибудь сами". Форкнул устаревший плагин, довольно шустро заменил все исчезнувшие в текущей версии API методы, найдя им замену. Получилось что-то вроде world.getBlockTypeIdAt(loc)
менялось на world.getBlockAt(loc).getType().getId()
. Однако один момент все же существенный: раньше можно было сделать радугу из одинаковых блоков (как в примере, block.WOOL
), раскрашенных в разные цвета. Теперь же блоки перекрашивать нельзя, надо брать изначально разноцветные блоки (Material.RED_WOOL
, Material.BLUE_CARPET
). Оформил pull request и обнаружил, что таких pull request-ов там еще два, оба свежие. В следующий раз стоит сначала это проверить...
Итак, инструкция, как быстро запустить эту пирамиду из Nukkit-Pokkit-RaspberryJuice-mcpi:
- Берем подходящий сервер, до которого есть доступ с ваших мобильных Minecraft-ов. Например, домашний компьютер с открытым портом 19132 (по умолчанию). Мне проще на linux, но подойдет любая ОС, где есть java runtime environment.
- Сервер Nukkit. Скачиваем рекомендованный JAR по ссылке "Downloads" или собираем свой из исходников (
mvn clean package
). Кладем в отдельную директорию и просто запускаемjava -jar nukkit-1.0-SNAPSHOT.jar
. - Плагин Pokkit. Скачиваем рекомендованный JAR по ссылке "Download and usage" или собираем свой из исходников (
mvn clean package
). Кладем в директориюplugins
, которая образовалась после шага 2. Останавливаем и снова запускаем сервер, как в шаге 2. - Плагин RaspberryJuice с моим патчем. Скачиваем рекомендованный JAR по ссылке или собираем свой из исходников (ветка
pocket-edition
,mvn clean package
). Кладем в директориюplugins/Pokkit/bukkitPlugins/
, которая образовалась после шага 3. Останавливаем и снова запускаем сервер. - Подключаем мобильный minecraft к серверу: Играть — Серверы — Другие серверы — добавить новый или отредактировать имеющийся: "имя сервера" — на ваш вкус, "адрес сервера" — IP адрес сервера из шага 1, "порт" 19132, если не меняли в конфиге. Сохранить и подключиться.
- Устанавливаем python 3 и библиотеку mcpi:
pip3 install --user py3minepi
. После этого можно запускать примеры из книги 1 и 2, просто введяpython3 Adventure3/dice.py
.
UPD: в пункте 6 устанавливать библиотеку mcpi нужно так: git clone https://github.com/py3minepi/py3minepi.git && cd py3minepi && pip3 install --user .
(в конце точка нужна). Это из-за того, что у автора плагина прописана последняя версия питона 3.4.
Можно попробовать и без питона (шага 6), подключившись к плагину обычным netcat-ом: nc localhost 19132
и вводить команды вручную:
player.getTile()
— в ответ придут координаты игрока в формате x,y,z, где ось y направлена в небо, а плоскость xz параллельна земле. У меня вышло75,-5,-5
,world.setBlock(75,-6,-5,3)
— установить блок грязи под игроком,world.spawnEntity(75,-4,-5,93)
— породить курицу над игроком.
Мои эксперименты можно видеть на начальной картинке этого поста.
Если пошел дождь или настала ночь и плохо видно, введите в консоли сервера команды time set 0
и weather clear
.
Вот и все. Здорово, что есть open source и теперь можно вот так просто, поискав в открытом доступе, за несколько вечеров соорудить такую пирамиду работающих программ. Особенно хочется отметить дружелюбность и почти мгновенные ответы в чатах многих проектов.
Еще нашел это замечательное видео о визуализации docker контейнеров сервера в мире Minecraft:
Контейнеры сына заинтересуют навряд-ли, а вот помигать светодиодами в ответ на переключение мультяшных рубильников — самое оно. Буду рад советам, что бы такого необычного еще придумать для обучения программированию.