Бильярд, Defold и рок-н-ролл +5


Про рок-н-ролл я правда наврал, разве что в процессе разработки его в том числе слушал, но в статье про него больше ничего не будет.

А расскажу я о разработке своей игры на движке Defold. Игра является разновидностью бильярда, но со своими правилами и механикой(или фишкой, заранее извиняюсь у настоящих геймдизайнеров если неправильно употребляю термин «механика» в тексте), которые будут описаны походу, а пока начну с предыстории.

1. Предыстория

Давным-давно, в детстве, я много играл в видео и компьютерные игры, сначала на приставках(Dendy, MegaDrive, на PlayStation у двоюродного брата), затем на ПК(первый был у меня 486 вроде DX66).

А лет в 10-11 на ПК начал делать какие-то первые попытки программирования на QBasic(у меня был такой классный справочник, который дал мне отец). Ну там кружочки, квадратики нарисовать, подвигать их, какие-то реакции на нажатия, проиграть ноты через спикер. В общем в QBasic было всё, чтобы заниматься подобными экспериментами и это приносило море радости от творчества(если те поделки конечно так можно называть).

Чуть позже, лет в 13-14, особенно под влиянием JRPG(в основном FF7-8 и Star Ocean The Second Story) это уже начало оформляться в желание учиться делать игры профессионально. Причём рисовал в мечтах себе картины, что я и сюжеты придумываю, и программирую, и даже рисую(с этим у меня всегда было так себе, так и осталось). Также были мысли и о спортивных симуляторах(я обожал футбол, занимался им немного, просто много играл на улице, но и “фифу” тоже любил).

Но ни одного законченного проекта у меня не получилось и ко времени выпуска из школы пламя уже угасло, уже другие увлечения и развлечения(а позже и вообще хроническая нехватка времени). Да, пошёл в ИТ, и сменил несколько направлений, от эникея в SCADA-системы АСУТП и C#, потом низкоуровневая разработка прошивок и немного симуляторов, но ничего связанного с играми не было.

Cпустя почти 20 лет с первых попыток на QBasic, вновь разгорелось желание что-то сделать в игровой вселенной. Причём первым желанием было сделать фактически не игру, а визуализацию к велостанку(и в идеале на VR), так как у меня есть станок и зимой на балконе крутить его иногда грустновато. Взялся я за курсы по Unity на Coursera, сделал по примерам простенькие 3D-игрушки. Подумал, что вот сейчас начну своё... И во-первых нужно было рисовать 3D-модели, с этим у меня плохо как и со всем рисованием, попробовал найти в Asset-сторе, и даже что-то купил, но всё не то. Во-вторых основной моей машинкой был старенький Макбук со встройкой Интела, в общем так себе инструмент для 3D-разработки. И третье - я прочитал про Zwift, и дело заглохло ещё на пару лет.

Примерно прошлым летом-осенью появилась новая идея.

2. Идея

На этот раз идея оказалось совершенно не сюжетной и/или хардкорной, а казуальной.

Я как-то прочитал о Квантовых Шахматах и затем попробовал, занимательная штука(хотя я не силён в шахматах и квантмехе если что). А мне захотелось сделать какую-то интересную механику в другой моей горячо любимой игре - бильярде. Прикручивать какую-то мощную научную теорию у меня мысли не было, просто добавить хаотичности. Придумал такую механику - в бортах виртуального стола(но не в лузах) при столкновении с ними шаров с некоторой вероятностью будет открываться “портал”, проглатывать шар, и затем где-нибудь на другом борте открываться другой портал и этот шар из него вылетать. В общем получиться было должно очень хаотично. И назвал будущую игру Portal Billiards.

Такова была изначальная идея, но постепенно она эволюционировала в более консервативный вид.

Во второй итерации порталами стали лузы. Шары и порталы двух цветов(красные и синие). Если забиваешь шар соответствующего цвета в соответствующий портал - начисляются очки, если же шар забивается в несовпадающий портал - то должен выскочить из одного из порталов соответствующего цвета. После каждого удара порталы случайным образом меняются в лузах(закрываются и открываются). Хаоса уже поменьше.

В итоге пришёл ещё к более консервативному виду. Порталы стали чем-то вроде “чёрных дыр” красного или синего цветов. Они также меняют случайно свои позиции после ударов, но теперь, если шар не соответствующего цвета попадает в портал, то он нигде не выскакивает, просто очки начисляются сопернику. Это всё равно вносит в игру интересный элемент случайности. Вот вроде бы получилась подстава, шар подкатился к лузе, ан нет – портал поменял свой цвет. Также не получится закатывать шары в одну и ту же лузу при удобном их расположении рядом, и заставит выбирать более сложные дальние удары.

А ещё на этой итерации остановился в том числе потому, что её можно воспроизвести на реальном столе. Хоть порталы и не продаются на Алиэкспресс, можно например размечать лузы случайно жеребьёвкой, или собственно сделать простое приложение, в котором можно нажать “перемешать лузы” и оно покажет куда, и какие шары можно бить.

Я конечно ещё экспериментировал с тем сколько очков начислять/штрафовать в процессе разработки, конечные правила выглядят так:

1) в игре шары и порталы двух цветов - синие и красные;

2) нужно забивать шары соответствующего цвета в соответствующие порталы;

3) после каждого удара порталы случайно меняют позиции в лузах.

4) за правильно забитый шар - бьющему начисляется 3 очка;

5) за неправильно забитый шар - начисляется 3 очка сопернику;

6) в случае если биток не коснулся любого из прицельных шаров, сопернику начисляется одно очко;

7) если биток упал в любой из порталов, он появляется в случайном месте стартовой зоны, удар переходит сопернику;

8) если все прицельные шары забиты - выигрывает игрок, набравший больше очков;

9) в случае ничьей - добавляется один красный шар в начальной позиции для выявления победителя.

3. Разработка

3.1 Выбор движка

Идея выработана, пора приступать к реализации. Так, стоп, а что я умею, на чём делать?

Первое, оценив свои умения, я решил в этот раз делать игру в 2D, чтобы попроще было.

Открыл свои учебные проекты на Unity (но они правда 3D, да), взглянул ещё раз на интерфейс и захотелось чего-то другого, за 2 года всё равно почти всё забыл и осваивать пришлось бы заново.

Поискал, что люди используют для 2D, желательно с поддержкой максимального количества платформ, и как плюс опен-сорс. В итоге отобрал для себя на попробовать Defold и Godot. Godot я немного щупал на предмет 3D ещё тогда же, когда изучал Unity, но в этот раз решил начать попробовать с Defold(по алфавиту, и понравился их форум), а затем думал ещё раз посмотреть Godot. Поизучав Defold на примерах, и чтении форума где-то месяц(вперемешку с фрилансной работой, несвязанной с геймдевом). Мне он показался достаточно простым, вполне фичастым, но не перегруженным. Плюс простой язык Lua вернули мне подобие ощущений тех первых экспериментов на QBasic. Нет конечно это не QBasic, но радость от творчества и экспериментов я определённо поймал.

Да, ассетов для него немного(особенно по-сравнению с Unity), но имеет хороший каркас и дружелюбный форум. Конечно не идеален, есть свои моменты, которые вылезали в процессе разработки(тут конечно может я криворук, например работа со шрифтами для GUI мне показалась не очень удобной). Но для меня плюсов однозначно больше чем минусов, поддержка всех нужных мне платформ в одном небольшом дистрибутиве, сам работает на всех десктопных ОС с приемлемой скоростью, маленький размер бинарника на выходе.

Решил что он мне подходит под эту задачу, а Godot в этот раз не смотрел, может быть в следующий раз.

В итоге остановился на Defold и Lua как языке разработки.

3.2 Графика и GUI

Как я уже говорил ранее - рисование и дизайн не мой конёк, поэтому поначалу в разработке использовал, что нашёл свободного на https://opengameart.org/ и https://pixabay.com/

Ещё за неделю до первого релиза всё выглядело так:

Я показал это двоюродному брату(xbost, https://hue.moe/), который работал над дизайном нашей “умной” колонки Pinder. Он сказал: “графений не годится, попробуем что-нибудь сделать”. И к релизу игра выглядела уже вот так(в качестве фона использовано фото NASA с телескопа Хаббл:

Игровые элементы больше не менялись, но GUI, недавно, в последнем релизе, был обновлён ещё раз:

С точки зрения техники, использованной для построения графики в игре, всё очень просто и ничего особо интересно. Все объекты - спрайты. Стол, шары, порталы, луч для прицеливания. Тень шара - тоже ещё один спрайт, двигающийся вместе с шаром.

3.3 Физика

По физике я полагаюсь на возможности встроенного в Defold движка Box2D(как я понял там не все возможности Box2D поддерживаются, но мне хватило того что есть).

В шарах привязаны 2 физических компонента. Динамический - собственно для обработки физики, прикладывания силы, столкновения с другими шарами и бортами. И компонент триггер - для обработки касания с порталами.

Борта стола - статический компонент для столкновений с динамическим компонентом шаров.

Портал содержит только компонент-триггер, для обработки попадания в него шаров.

Физика бортов не получилась такой же упругой как у настоящих бильярдных столов, и с учётом 2х-мерности физика ближе к хоккейной чем бильярдной, но цели сделать точный симулятор у меня и не было.

3.4 Управление

Казалось бы несложный пункт для такой простой игры, но для меня он стал некоторой головной болью. Целью сразу была поддержка всех возможных платформ, десктопных и мобильных, но при этом не плодить разных версий.

Сначала у меня были отдельный контрол для установки силы удара(а также можно было его задавать колёсиком мышки) и отдельная кнопка “удар”, как в любимом мною опен-сорс симуляторе FooBilliard. Но в общем и целом это не очень современно и удобно, особенно на мобильных платформах. Поэтому я посмотрел как делают в бильярдах для мобильных платформ и скопировал эту механику, чтобы как у всех(ну примерно как у всех).

Слева от стола расположил кий, который нужно потянуть вниз, набирая силу, и затем отпустить. Данная механика не очень удобна на десктопе, так как нужно мышкой вести в левую часть экрана после прицеливания, и опять же мышкой тянуть кий вниз(была также мысль кий расположить справа, но вот мне почему-то показалось удобнее слева). Пробовал также оставить с механикой установки силы колёсиком, но в итоге оставил только один вариант управления как на мобильных, всё таки вполне им можно и десктопе пользоваться. А прицеливание наоборот осталось более удобным для десктопа - мышкой(или тапом на тач-скрине) в сторону удара. Получился такой неидеальный, компромиссный вариант.

3.5 Звук

Это самый простой и маленький раздел. Думал положить на фон какую-нибудь космическо-эмбиентную мелодию, но обычно в такие игры люди играют со своей музыкой на фоне, как мне кажется. Поэтому игра без музыки. Но в будущем не исключаю, что добавлю мелодию.

Почти все звуки(Public Domain и CC BY 3.0, полный список в разделе About игры) нашёл на https://freesound.org/. И ещё один — подтверждение начала онлайн-матча, сам сыграл на синтезаторе в GarageBand. Так как столкновений шаров одновременно много, написал гейтинг как в примере из документации Defold - https://defold.com/manuals/sound/

3.6 Режимы игры

В первом релизе было реализовано два режимы игры: Player VS Computer и Player VS Player(hot-seat). Всего на разработку первого релиза (и изучение возможностей движка попутно) ушло примерно 2 месяца в расслабленном темпе по несколько часов в день.

О хот-сите рассказывать думаю не имеет смысла, самый простой режим. Расскажу немного о том как реализован ИИ в PvC.

Для поиска подходящего прицельного шара применяю алгоритм перебора вариантов с нахождением наименьшего угла резки(я считаю угол между воображаемой линией удара битка в лузу и линией от битка к прицельному шару). В принципе абсолютно стандартный алгоритм, в том же FooBilliard он используется. Но у меня примешивается соответствующие цвета шаров/порталов, которые также оцениваются алгоритмом.

Для нахождения угла резки, использую теорему косинусов:

Совсем недавно, в начале сентября, добавил также Online PvP. Мысль о том, что в игре должен быть режим онлайн-матча была изначально, но вот заставить себя его делать было очень тяжело. В своей карьере, когда писал прошивки для Ethernet-модулей ПЛК на ассемблере, много приходилось отлаживать протоколы сетевого взаимодействия, и что-то эта задача для себя не вызывала у меня такого воодушевления как непосредственно игровые механики. На борьбу с собой ушло почти 3 месяца(лето ещё конечно тоже влияет, да), и наконец в конце августа засел за эту задачу.

Мне очень помогло, что есть такой фреймворк для построения своих игровых серверов Nakama от Heroic Labs – https://heroiclabs.com/nakama-opensource/. И он имеет поддерживаемую клиентскую библиотеку для Defold - https://defold.com/assets/nakama/

Это значительно упростило задачу, не пришлось всё реализовывать самому на сырых сокетах, и за неделю с небольшим работы по вечерам, серверная и клиентская логика были набросаны(по Nakama, разработке и конфигурировании сервера можно вполне написать отдельную статью). При этом здесь немного поленился, и чтобы упростить себе задачу, использовал лёгкий хак-путь – при ударе передаю на сервер(и далее оппоненту) только угол и силу, физика на клиенте уже отрабатывает удар, а не передаю координаты всех шаров постоянно. Поэтому иногда могут быть проблемы рассинхрона, но при тестировании такое у меня практически не случалось.

4. Дистрибуция

Итак, игра сделана, пора покорять Мир. Только откуда развернуть наступление?

В качестве первой платформы для дистрибуции я выбрал Itch(https://itch.io), нишевый магазин, популярный среди инди-разработчиков с минимальным порогом входа.

Изначально я выложил 2 версии игры, для 3х десктопных платформ(Win, Linux, Mac) и Android:

1) Бесплатная демо-версия с поддержкой одного режима Player VS CPU на 6 шаров, на среднем уровне сложности.

2) Полная версия — за 3 бакса(вообще я хотел сделать по 1 баксу за каждую десктоп-платформу и Андройд, за 3 купленные давать 4-ю бесплатно, но не нашёл такой возможности).

А ещё написал о своей игре на форуме Defold в разделе Showcases. Особой активности на страничке Itch не наблюдалось, но зато на форуме один человек из команды Defold(Björn Ritzl) написал мне не собираюсь ли я выложить HTML5 версию игры на Яндекс.Играх(https://yandex.ru/games/ ирония, что мне человеку из России, который пользуется различными сервисами Яндекса, об этой платформе рассказал человек из Швеции) и/или Game Distribution(https://gamedistribution.com/). Для обеих платформ у Defold есть соответствующие модули на Asset-портале.

Я честно говоря думал, что со смертью Flash и популярностью игр для мобильных ОС, платформы для Web-игр тоже умерли(ну или находятся в состоянии зомби). Но как оказалось, ошибался, это вполне живые ресурсы. В итоге сделал версии игры с рекламой для Яндекс Игр и Game Distribution, и грубо говоря денег на пиво они приносят.

Позже ещё сделал версию с рекламой для Google Play(с использованием немного мутного сервиса Enhance), но в ней сейчас не активен онлайн-режим, это не связано с самим Google Play, а вообще не заработало на Андройде, Wireshark’ом не видно никаких соединений, думаю проблема с SSL, возможно позже разберусь, хотя особой популярностью мобильная версия не пользуется(видимо в основном установили мои знакомые, которым дал ссылку).

5. Будущее

Если онлайн будет достаточно популярен — есть мысли добавить лидерборды с различной статистикой, улучшать сетевой протокол, добавить ещё режимов(например чтобы открывалось всего 2 портала разных цветов, чтобы ещё усложнить игру). Но пока посмотрю вообще интересен ли онлайн людям.

И если вдруг(ха-ха) сделаю свой космосим, можно будет туда встроить в качестве мини-игры.

Ещё, как уже писал в разделе об идее игры, хочу как-нибудь сам попробовать перенести это на реальный стол. В принципе подходят любые популярные игры с лузами. Американский пул понятно — полные/полосатые. Снукер — красные/остальные цветные. И в теории даже русский бильярд — чётные/нечётные, хотя наверное с учётом размера луз это будет тяжкое испытание.

Всем спасибо, что прочитали!

Сcылки:

Яндекс.Игры – наиболее свежая версия появляется первой здесь(сейчас 1.2.0.1), если хотите попробовать работающий онлайн, то однозначно сюда. Плюс поддерживается авторизация

Y8(зеркалится с Game Distribution) — здесь сейчас версия 1.2.0.0(1.2.0.1 сейчас на модерации), с глючным онлайном, но остальное также как в Яндекс(только без авторизации)

Десктопные версии на Itch.io

Google Play, как уже писал в статье - не работает онлайн

P.S. Если кто захочет зарубиться со мной, пишите в телеграм-чат, который создал для игры - https://t.me/portal_billiards (есть кнопка в десктопных версиях игры, но не в Web-версиях - площадки запрещают ссылки внутри игры на внешние ресурсы).




К сожалению, не доступен сервер mySQL