Рождение идеи


Все мы помним такие легендарные MMORPG нулевых, как Lineage 2, World of Warcraft, Aion, Perfect World. Мы растем, жизненные приоритеты меняются — работа, семья, друзья. И уже не можем уделять столько времени играм. Но желание играть никуда не пропадает! Хочется вечером зайти на своего персонажа, собрать лут, сходить на осаду, почеленджить корейский рандом своим везением и заточить оружие еще на один уровень.


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


image


Вот я и столкнулся с классической ситуацией "во что поиграть?". Год назад я набрел на Warspear Online. Еще на сенсорной Nokia в школе я нашел эту игру. Но то ли не осилил установку, то ли не разобрался как играть — забыл и забил. И вот уже в сознательном возрасте, вернувшись в проект, который и кроссплатформенный, и с чудесной (на мой взгляд) графикой, я погрузился в мир классической MMORPG. Казалось бы, все отлично, но через 1.5 месяца засосала работа, домашние дела и сидеть по 2-3 часа в игре (хоть и на телефоне), стало невозможным.


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


Шли дни и недели поисков новой игры. Пересмотрев и перепробовав кучу Idle и кроссплатформенных MMO проектов, набрел на интересную идею Максима Газизова GazizovMadMax52 Wasteland Wars.


MMORPG в моем любимом мессенджере — Telegram! Это же можно и от работы не сильно отвлекаться, и лишней графики нет. Поиграв недельку и поддержав проект, пришла мысль, а почему бы мне и самому не сделать нечто подобное. Постапокалиптическое это немного не мое, я все же, больше по классике — Орки, Эльфы, осады, совместные данжи и прочее. Да и программировать — моя нереализованная мечта.


Немного про background


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


Последние 3-4 года я время от времени покупаю какой-то урок и прохожу его. Иногда вдохновения хватает пройти полный курс, иногда только половину.


Пробовал разные языки, JavaScript на фронте, Swift 2, Java, Python, C# и получались элементарные приложения для iPhone, скрипты для автоматизации сбора excel табличек на работе, 2D персонаж в Unity с Path finding. Из действительно используемых, остался только Chrome Extension, которым пользуются коллеги для дебага и упрощения работы со страницами в интернете. Вот и весь опыт. К сожалению, далеко на теории не уедешь, и MMORPG в Telegram это первый мой крупный проект.


"MMORPG для начинающего — куда ты лезешь?"


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


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


Начало пути


Идея появилась в конце Декабря 2019. Новогодние каникулы — идеальное время, чтобы начать писать проект. До 31го Декабря я собирал все идеи на листочек бумаги. Первое, что пришло в голову: MMORPG — проект с зависимостями между объектами. Начал я планировать архитектуру базы данных. На тот момент, у меня не было опыта работы с БД, и я не понимал, к чему это приведет.


Спустя 2 дня получилось что-то вроде этого


image


Это архитектура самой последней версии (7?го Января). В процессе она дорабатывалась, так как я начинал познавать по каким канонам необходимо создавать архитектуры БД. Например, добавление ассоциативных таблиц. До этого все данные должны были храниться в 4-5 таблицах.


В качестве базы данных я выбрал PostgreSQL. Почему — не спрашивайте. Слышал, что на работе эта база используется для хранения и редактирования информации и счетах пользователей. Слово "Редактирование" ударило мне в голову, и я выбрал эту базу данных. На этот момент мне рано было гнаться за перфомансом. Да и на старте проекта, не думаю, что именно выбор неправильной базы данных положит мне базу 10-20 людьми.


Пришло время приступать писать код. Первое что нагуглил по запросу "Telegram bot — инструкцию с библиотекой Telebot. В ней дается 2 варианта работы с Telegram API: 1) Long Poll 2) Webhook. Немного покопавшись и поразмыслив, пришел к решению использовать Webhook.


Первый вариант я отмел, так как постоянно дергать Телегу, чтобы получать апдейты — зачем так заморачиваться. Самое большое преимущество, что запросы могут быть сделаны откуда угодно — нам не интересно, так как я изначально планировал запускать на сервере.


Скопировал кусок кода. Заменил ключ API. Регистрирую webhook — ноль реакции. Начинаю копаться. Точно! Телега же заблокирована.


Пришел к осознанию, что нужно использовать облачный сервер, и не в РФ, разумеется. В интернетах подсказывают, что отличным выбором будет Heroku или Google Cloud Platform, так как Google еще и 300 зеленых дарит, чего хватит на несколько месяцев работы. Так как у меня уже был опыт работы с Google Cloud Vision API, а ассоциативные цепочки, выстроенные с названием Heroku, не предвещают ничего хорошего, выбор был сделан в пользу первого. Поковыряв еще несколько инструкций, удалось запустить облачный сервер с 1 CPU и 2Gb RAM


Передо мной возникло черное окно Linux Terminal и это было ужасно. Неизвестная OS, с абсолютным осознанием, что я не понимаю, как загрузить бота и запустить его, немного навевали мысли, что ничего не получится. Но, благо туториалов в интернете достаточно.
Создал SSH ключ, подключился через свой Mac.


Как же теперь загрузить файл с ботом на сервер? Ну не писать же бота через terminal?! Еще немного покопавшись, обнаруживаем в интерфейсе Google Cloud Platform (GCP) кнопочку "Загрузить файл". Загрузили, поставили Python, pip, Telebot и другие необходимые пакеты. И вуаля, бот начал отвечать мне в режиме "эхо". Радости не было предела.


База


Выдохнув, и определив, что пользователи в Telebot идентифицируются через переменную message.from_user.username, приходит мысль "не добавить ли мне базу данных уже сейчас?". И я добавил ее за несколько минут. Даже подключение к базе не заняло много времени, как изучение SQL запросов. Создав таблицу с пользователями и сохранив туда username, в ответ на команду "/createuser Someuser" я получил в ответ 2 строчки Someuser и свой Telegram никнейм. Ну все, SQL знаю, библиотеку знаю, Python знаю. Теперь и море по колено.


Код


Создаем логику выбора класса персонажа прямо в handler (чо заморачиваться то). Добавляем таблицу локаций, таблицу мобов. Параллельно натыкаемся на определения Foreign Key, Primary Key — анализируем и реализуем. Делаем несколько запросов в таблицы подряд (ибо JOIN для слабаков и несведущих). Реализуем абстрактный класс Unit с методом fight. Наследуем от него два класса Mob и Player, и вуаля — персонаж дерется с мобом. И даже падает лут. Перемещаемся между городами. Затыков с написанием кода почти нет. Пару часов и новая функция появляется в игре.


Даю брату бота — "Брат, смотри!". Брат заходит в первый экран. 10 раз быстро прокликивает на кнопку "Идти" и вот результат:


image


Сервер и/или API не успевают отвечать. Запросы копятся. А потом по 1-2 выполняются и выплевывают ответ. На тот момент было предположение, что все дело в том, что долго происходит соединение с базой, поэтому запросы и копятся. Поисковик подсказывает про pull connections и ORM, которая сама решает такие проблемы. В процессе решения проблемы также столкнулся и с понятием Deadlock, так как 2 пользователя могут изменять одну ячейку в базе.
За окном 7ое января. Последний день я даже и не открывал крышку ноутбука, но проблемы так и не были решены. В следующие 2 месяца работа полностью накрыла с головой и проект был забыт и забит.


Возвращение


Май. Опять накрыло желание писать и создавать. Идея до сих пор кажется интересной.
Первая идея — писать все с нуля, чтобы вспомнить, а что в январе вообще было. Попытки запустить бота на локалке для теста вновь оказались тщетны, как и использование прокси. Через Midnight Commander, как я делал это в январе, перетаскивать файл на сервер по SSH очень неудобно. Также не вышло у меня и сделать синхронизацию локального файла с серверным, чтобы изменять его на лету. Открыв IDE, видим терминал, и приходит идея подключиться через редактор. PyCharm просит деньги, и тогда нас выручает Visual Studio code. Ave VS code! Теперь прямо в IDE изменяем файл, лежащий на сервере.


Осталось решить проблему с пользовательскими запросами. В момент поступления первого запроса, пока он обрабатывается, отсекать последующие запросы от пользователя. Добавляем Redis, чтобы хранить статус пользователя (есть ли в обработке запросы от юзера, али нет). Поисковик подсказывает, как можно обработать запрос до исполнения основного файла — через middlware handler. Однако, в библиотеке следующий handler после middleware исполняется независимо от того, выкидывает ли исключение middleware, возвращается None или любых других факторов. Ну что ж?! Будем пробовать писать свой первый декоратор.


А на этом пока все. Надеюсь, что следующую часть ждать не долго.