SirCapy

SirCapy

На Пикабу
поставил 10 плюсов и 6 минусов
170 рейтинг 1 подписчик 0 подписок 2 поста 1 в горячем

Рубрика "Весёлое багло в мультике и не только"

Это одна из маленьких историй о трех маленьких, но храбрых и независимых разработчиках в жестоком мире гейм дева! Приключения Сира Т, Сира R и Сира I с их славной игрой "First Feudal" начинается здесь и сейчас!

Рубрика "Весёлое багло в мультике и не только" Игры, Gamedev, Gamemaker Studio 2, Инди, Indiedev, Длиннопост

Сегодня окунемся в мир багла! Но не абы какого, а весёлого, непредсказуемого, но в меру адекватного! Поехали!

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

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

В этом же посте хотел рассказать про особый баг, который был и нелеп, и прост, и весел, и раздражающь. Воспроизводился он как в мультике, так и в соло игре. Здесь стоит оговориться, что мы выбрали клиент-серверную архитектуру, что по факту означало реализацию сетевого коннекта в обоих режимах. Т.е. даже в одиночной игре запускается 2 приложения: клиент и сервер. Простейший и чуть ли не единственный способ общаться двум аппам в Windows без лишнего геммороя и кучи сложных багов - соединить их по сети: один создал сокет, второй создал сокет, соединились и болтают по стандартному tcp. Выбирать именно такие архитектурные решения сподвигали определенные обстоятельства и попутные фичи типа стабильного fps на клиенте или необходимости соблюдения последовательности пакетов.

В итоге мы имели обыное tcp соединение, на базовом network функционале GameMaker. Естесн была написана библа, чтобы упростить обращение с базовым нетворкингом, но внутри это были именно  network_send_packet, network_create_server и т.п.

Когда это дело улетело на прод периодически стали прилетать баги с текстом, который можно было расшифровать как "Какого-то фига прилетел кривой пакет, я упаль". Более того, это багло воспроизводилось редко и локально на компахи Сиров, однако делало это очень нестабильно. Иногда 5 раз подряд, а потом само проходило.

Сир I был осведомлен, что tcp лишь гарантирует, что если что-то пойдет не так - он об этом оповестит, но пересылать сам не будет, поэтому были прикручены несколько механизмов повторной посылки пакетов и разруливания ситуации кривых пакетов. Но и они не спасали. Опрос 3-их знакомых сетевиков ни к чему конкретному не привел, хотя совет поставить WireShark и посмотреть, что там в потоке прилетел именно от них. Впрочем логи не помогли ни сетевикам, ни тем более Сирам, с виду все ровно, однако сие черные строчки не давали покоя Сиру I:

Рубрика "Весёлое багло в мультике и не только" Игры, Gamedev, Gamemaker Studio 2, Инди, Indiedev, Длиннопост

Дальше было 100500 расспросов и гуглений в слепую на тему "что за Window Full" и "что на заполненность этого Window влияет"?

Оказалось, что в tcp есть понятие входящего окна, условно это кеш определенного размера "сколько сообщений по tcp готова принимать винда, пока не начнет их отвергать". Стандартно это дело выставлено в 64Кб. И если окно переполняется, тоооо - дальше все зависит от локальных настроек, которые выставляются при помощи:

`netsh interface tcp set global rss=enabled`

`netsh interface tcp set global autotuninglevel=normal`

Если autotuninglevel - выставлен, то в ситуации переполнения окна - он сам расширится (станет 128Кб, 256Кб и т.д.), а если нет, то следующие пакеты будут отвергаться (на клиент прилетит -1, при попытке вызова network_send_packet). Однако все это не объясняет почему прилетают кривые пакеты. Это же tcp, что отослал, то и прилетело, а если не прилетело, то и кривиться нечему. И все было бы так, если бы не GameMaker. Во всяком случае Сир I в итоге обвинил его во всех tcp грехах, и само собой, что такую шляпу не могли обнаружить сетевики.

Прикол тут в том, что поведение GameMaker в ситуации, когда autotuninglevel отключен - абсолютно неочевидно. Он дублирует пакет, который пришел последним, а после этого получает все оставшиеся в tcp окне пакеты (которые набились) разом, слепленные в один. Само собой клиент не ожидает такого поведения и падает. Точнее не ожидал. Эту особенность, про получение дубликата пакета и взяли за индикатор влетания в эту ситуацию. Теперь, когда такое происходит, мы выполняем полную синхронизацию соедининия, по факту, разрывая его и создавая вновь.

После чего порешали главную причину переполнения окна. Проще всего его переполнить послав ооочень большой пакет, именно такой мы шлем, когда впервые создаем/загружаем игру. Поэтому на архитектурном уровне сети дополнительно пришлось реализовать разбивание и собирание больших пакетов на подпакеты (привет tcp), чтобы винда успевала обработать пакеты без переполнения гораздо реже. Дополнительно в настройки вынесли размер подпакета, на случай если найдется пользователь с базовым размером окна меньше 64к. Т.е. по факту реализовывали часть tcp под tcp.

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

P.S.

Опция rss (как понял Сир I) отвечает за многопоточную обработку пакетов tcp, что увеличивает скорость его работы. Его отключение увеличивает шанс переполнения окна.

Всем добра, господа и дамы. Пойду допиливать новое событие в следующий патч!)

Показать полностью 2

Как мы свет в игру завозили!

Это одна из маленьких историй о трех маленьких, но храбрых и независимых разработчиках в жестоком мире гейм дева! Приключения Сира Т, Сира R и Сира I с их славной игрой "First Feudal" начинается здесь и сейчас!

Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост

Сегодня окунемся в мир игрового света и тьмы на пальцах! Поехали!

Скрин того, что получилось для затравки сразу в студию:

Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост

Сир I, Сир T и Сир R не просто так получили свой титул. Ведь они взялись разрабатывать не на модных Юнитях, а на тру движке - GameMaker. Выбор сий был сделан обдуманно, т.к. для 2д игры все же бОльшая часть наворотов не нужна. Что очень сильно ускорило понимание что делать, создание прототипа и разработку.

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


В частности одним ноябрьским вечером Сир R решил добавить в игру освещение, да не простое, а в динамике (чтобы бежишь ты с факелом, а он меняет освещение от обстановки).

И тут нельзя просто взять сделать модельку освещения, кинуть карту нормалей, накидать источников света, и дальше за вас магию света наколдует движок) Всё это искусство пришлось придумывать и колдовать самим.

Игра про средневековье с крестьянами и феодалами) Вот и движок ему под стать - в определенных моментах - тоже средневековье) Хочешь свет - будь добр рассчитай, отрисуй и обнови сам!

Пол кастрюли геометрии, полкило кастомного кода, щепоть костылей и добротная горсть смекалки - вот и готов прототип)

Ну а потом 300 тонн оптимизаций и переделок) и вот сотворены день и ночь, а крестьяне с феодалами бегают с факелами, освещая путь до ближайшего костра или дома)

Но за всей этой магией лежит просто один кружок, да с десяток трапеций) Но обо всем по порядку)

Сначала вешаем на всю карту тьму) Да будет ночь!

Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост

Потом из этой тьмы вырезаем круги света вокруг источников) Да будет свет!)

Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост

А дальше вырезаем из круга темные трапеции, которые загораживают непрозрачные объекты. Да будет геморрой!

Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост

На последнем пункте остановимся подробно)

Модель у нас сильно упрощена, ведь это 2д и все непрозрачные объекты (стены, горы) - прямоугольные, со стороной кратной одной клетке в игре. Да еще 2д с видом сверху. Это позволяет для всех непрозрачных объектов по внешней стороне построить линии непрозрачности и работать с ними.

Дальше от точки освещения до каждой ближайшей линии непрозрачности строим лучи.

Ну и чтобы не строить их до бесконечности - ограничиваем лучи по длине и отсекаем от трапеции края)

Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост
Как мы свет в игру завозили! Игры, Gamedev, Gamemaker Studio 2, Инди, Видео, Длиннопост

Думал описание получится сложнее) Но как-то словами оно прям просто получается)

А дальше это все обмазывается тонной оптимизаций, ведь расчеты делаются каждый шаг игры!

Для начала статичные светильники - перерассчитываются только когда в зоне их освещения появляется новый объект, ну или они перемещаются)

Затем линии непрозрачности рассчитываются отдельно - в фоне. Ну а для перемещающихся объектов рассчитываются только при смене клетки.

А для красоты, чтобы свет казался живым - слегка меняем диаметр круга света) Круг света - как заклинание звучит)


Вот и сварена похлебка) Кругляши да трапеции.


Напоследок к свету также относится и молния во время дождя.

Достаточно просто на мгновение во время дождя убрать тьму) Видео прилагаемс (качество при заливке пострадало что-то).

Вот так кругляши, трапеции да пресвятой GameMaker смогли привнести в игру свет.

А за ними потянулась целая гряда всяких ништяков - смена дня и ночи, да и вообще течение времени, дождь с грозой, времена года, на которых базируется куча другого геймплея)


Всем добра, господа и дамы. Пойду пилить следующий патч и хотфиксить старый ;)

Показать полностью 7 1
Отличная работа, все прочитано!