Pull to refresh
4
0
Владимир Козлов @aienabled

Разработчик игр, C# программист

Send message
Это неприятный аспект, но при грамотном подходе не является проблемой.
Например, в нашем проекте (Github) в 97 случаев используется стандартный BoolToVisibilityConverter (который конвертирует false в Visibility.Collapsed) и в 10 случаях дополнительный BoolToHiddenVisibilityConverter (конвертирует false в Visibility.Hidden).
Я написал им — ответили, что для такого случая стоимость лицензии будет около 1000€ / year / seat. Если кто-то бэкендом только занимается, можно сэкономить. В любом случае, они люди гибкие и договориться о разумной цене очень легко. Ниже xXxVano задавал вопросы по этому продукту и компании в целом — я очень подробно ответил.
Я очень рад поделиться своим опытом!
Coherent, как и прочие решения на HTML5/CSS, набрал популярность благодаря подкупающей доступности и лёгкости разработки. Но, т. к. это по сути своей браузерный движок Chromium, получаем все плюсы и минусы веб-интерфейсов. Главные из которых — слабая оптимизация (те же микрофризы), аппетит на ОЗУ, проблемы со стабильностью, а также зоопарк всевозможных технологий, накопленный за годы развития HTML/CSS.
Также, думаю, сравнивать векторную библиотеку с Chromium (пусть и имеющий поддержку SVG), бессмысленно. Это принципиально разные подходы. Равно как и разница подходов к разработке. У HTML5 были совсем другие цели. WPF изначально разрабатывали достаточно умные люди как решение для разработки сложных анимированных десктопных интерфейсов, сделав очень хороший и логичный фреймворк. В свою очередь, NoesisGUI разрабатывали как высокооптимизированный middleware практически полностью имплементирующий WPF/XAML, при этом с упором на плавную работу, низкое потребление памяти и ресурсов CPU/GPU.

Что касается нативный компонентов интерфейса в UE4 и Unity — они серьёзно ограничены в своих возможностях и удобстве разработки. Во многом это из-за отсутствия поддержки какого-либо markup language. Я разрабатывал игру на Unity на тогда новом Unity UI, сразу после завершения проекта использовавшего NoesisGUI (тоже в составе Unity), и был просто в отчаянии от того, насколько вся эта возня с компонентами/префабами Unity неудобна именно в плане разметки UI и привязки данных, а также в плане удобства взаимодействия с коллегами (попробуйте смержить!). Для меня лично гораздо приятней и быстрее набирать код руками.
XAML + MVVM = очень мощный подход, позволяющий писать сложные интерактивные интерфейсы действительно быстро (посмотрите упомянутый выше код нашего проекта на Гитхабе — всё написано одним программистом, ~0.5 млн строк за несколько лет, очень много UI, а ведь мне ещё нужно всё остальное делать; к тому же игра — сетевая и на своём движке, почти всё приходилось писать с нуля).

Что касается крашей — я просто отметил из своего опыта, что крашей я давно не видел, при этом у нас более 200,000 довольных игроков за последние два года. Дальше будет только лучше, ведь библиотека наконец-то используется в AAA-играх, не считая множество более мелких тайтлов и портов легаси WPF-приложений. В багтрекере вижу только редкие случаи и в основном они касаются Unity Editor или каких-то недавно добавленных платформ. А вот Windows/DirectX/OpenGL — всё уже давно отполировано до блеска и стабильно практически как WPF, я думаю.
Но, если говорить о крашах в принципе, точно такая же проблема наблюдается и с нативным UI в популярных игровых движках, и в любом другом middleware… (к слову, Unity в своё время (2015-2017) меня просто вынудил начать писать свой движок, их CEO даже опубликовал пост в блоге компании из-за вакханалии с багами в каждом билде)
Noesis не менее зрелый, чем тот же Coherent, но построен на гораздо более прочном и предсказуемом фундаменте — команда Noesis очень маленькая и они писали практически весь код с нуля (даже не используя сторонние библиотеки в своём ядре, насколько я помню), покрывая его тестами, и поэтому знают его вдоль и поперёк.

Для меня лично самое важное заключается в том, что NoesisGUI позволяет применять накопленный опыт WPF/XAML, без каких-либо исключений и компромиссов. И это не только игровой middleware, а так же полноценная кроссплатформенная имплементация WPF — можно использовать в десктопных ОС, на консолях, смартфонах, даже в вэб. Недавно появились официальные NuGet пакеты, обновили стандартные контролы, сделав их симпатичными, сделали отличную документацию.

Конечно, жаль, что это не бесплатный опенсорс проект, но понять можно — люди трудились годами, живя на сбережения и инвестиции, поставив всё на этот проект — и теперь пожинают заслуженные плоды. Здоровая конкуренция (та же Avalonia очень радует прогрессом) умерит жадность всех разработчиков таких библиотек!
Этот middleware разработан двумя талантливыми программистами из Испании практически на голом энтузиазме в течение многих лет (мой коллега с ними лично встретился только на GDC 2019, хотя мы одни из их ранних пользователей с 2013 года и наша первая игра была первым серьёзным проектом использующим их библиотеку). И по удачному стечению обстоятельств, у них сейчас просто нет серьёзных конкурентов среди библиотек векторного UI для видеоигр — тем более с устоявшимся workflow (Blend, Visual Studio/Rider для XAML + они активно работают, чтобы добавить новые технологии вроде импорта Lottie (After Effects)).

NoesisGUI использовать в разработке видеоигр на самом деле удобно — особенно если вам уже знаком WPF/XAML/Blend, т. к. по сути дела это оно и есть. Можно почитать множество отзывов из Unity Asset Store. К слову, для последней игры я разработал свой игровой движок и пишу код UI на XAML как обычное WPF Application (код игры в опенсорсе (включая сотни XAML файлов/C#/шейдеры HLSL/графика/звуки/т. д.), можно посмотреть все ~0.5 млн строк кода и увидеть как всё организовано). Код XAML (равно как и сопутствующий ему C# код) автоматически используется as is и поддерживает горячую перезагрузку (в принципе сам движок заточен на горячую перезагрузку всего и вся, ну и на моддинг — фактически сама игра это мод к движку). В итоге процесс разработки и отладки очень быстрый, так что мне даже не приходится использовать XAML Designer.
Но обычно просто делают два параллельных проекта — один под XAML прототип (с фейковым игровым API), второй — уже сама игра (или её UI часть использующая игровой API), которая просто импортирует XAML и возможно какие-то C# файлы.

Краши — к счастью, их давно искоренили. Но да, за эти годы я репортил десятки тикетов по крашам — всё оперативно устраняли. Включая самые загадочные случаи. Багтрекер у них публичный (некоторые баги репортят приватно).

Исходники полные на C++ они предоставляют при per project лицензии.

Я не думаю, что они забросят вдруг свой продукт или задушат его неразумными расценками на лицензии — он с каждым годом только набирает популярность. Их burnrate достаточно низкий — это небольшой офис в Мадриде да зарплата нескольким сотрудникам… Учитывая, сколько лет они тянули проект с нуля без какого-либо дохода (попробуйте реимплементировать WPF со всеми его неожиданными нюансами — это титаническая работа на несколько лет, прежде чем его можно будет предоставлять публике и тем более брать какие-то деньги) — не могу представить, чтобы они его вдруг забросили. Но самое главное, проект уже дорос до стадии, когда в общем-то это стабильная in-place замена WPF с поддержкой уймы платформ — но при этом отлично (безумно!) оптимизированная, чтобы игры не имели микрофризов и нагрузка на CPU/GPU была минимально возможной, с максимально качественным рендерингом векторной графики и текста, и множеством других фич, которыми сам WPF похвастаться не может (например, PPAA сглаживание, экстеншены для эффектов отрисовки текста, удобный внешний профайлер+инспектор, поддержка горячей перезагрузки, 3D-расширения и т. д.).

Что касается стоимости — кроме бесплатной лицензии для инди, лицензия на средний проект раньше стоила несколько тысяч евро, а для AAA игр (с бюджетом в 10+ млн евро или около того) около десятка тысяч евро. Но многое зависит от числа поддерживаемых платформ. Выше tangro спросил насчёт стоимости лицензии — я написал разработчикам этот вопрос и отпишусь, когда получу ответ.
(Не реклама, просто делюсь проверенным решением для C++ и XAML, которое может подойти по бесплатной лицензии)
С 2013 года пользуемся и активно помогаем развитию NoesisGUI. Это проприетарная кроссплатформенная библиотека векторного UI, на 99.9% совместимая с API WPF и XAML. Написана на C++, отдельно доступен C# SDK. Ориентировано на AAA геймдев (отсюда потрясающая оптимизация и поддержка C++ в самом лучшем виде), но и приложения писать никто не мешает. Разрешают использовать бесплатно, если годовой оборот компании меньше €100K. Можно поиграться в WebAssembly версию (справа сверху выбор сэмпла).
Т. к. у меня был огромный опыт разработки WPF/SL приложений, эта библиотека здорово помогла в создании очень сложного UI для наших проектов-видеоигр, пользуемся все эти годы. Кстати, интерфейс Baldur's Gate 3 разрабатывают именно с помощью этой библиотеки (после смерти Scaleform выбор технологий для векторного UI в видеоиграх очень невелик).
С настройками по умолчанию картинка игры (рендеринг мира, не UI) crop'ится в разумных пределах в случае несовпадения соотношения экрана с 16:9 (сверх разумного — добавляются чёрные полосы). В случае монитора 16:10, картинка лишь чуть-чуть обрежется слева и справа, а вертикальный обзор будет, как если бы монитор был 16:9. Если монитор 16:9 повёрнут боком — будут огромные чёрные полосы сверху и снизу. Но так никто не играет.
Я писал выше, что мы не беспокоимся на этот счёт — большинство игроков не замечает небольшого кропа картинки, а PvP-хардкорщики имеют опцию. При этом согласно статистике Steam порядка 90-95% игроков имеют экраны 16:9 (даже если они играют в оконном режиме развернув на весь экран, картинка лишь чуть-чуть обрежется). Т. к. игра доступна только для PC/Steam, проблемы с этим нет и игроки не жалуются.
А если соотношение сторон другое?

Для хардкорных PvP-игроков есть опция «16:9 (PvP max view)». Добавляются чёрные полосы по сторонам экрана, но гарантирован максимально возможный обзор.
Без этой опции, картинка будет обрезаться сверху и снизу, если у игрока монитор ultrawide 21:9 (если ещё шире — чёрные полосы добавятся слева и справа, т. к. уж слишком сильно обзор резать невозможно). Мы не особо беспокоимся, т. к. согласно статистике Steam, игроков с ultrawide мониторами не больше пары процентов (есть статистика по разрешениям экрана и из неё это очевидно). И динамика такова, что 16:9 сегмент растёт быстрее, чем ultrawide.

При чём проблема не только в самом лаге, но и в том, что неизвестно когда он есть.
Несколько раз игра мне не показывала танк там, где он 100% был(WT).

От багов в имплементации ничто не поможет. Если пинг низкий и код определения видимости написан правильно, проблем не будет и лаг будет едва ощутим.

А ещё с видом от 3-го лица камеру можно переместить практически мгновенно на несколько метров. что тоже изменяет видимость.
Это верно. И если камера действительно полноценно и сразу просчитывается на сервере (а не привязана к самому танку), будет ощущаться лаг равный пингу.

учётом RT видимость не ограничивается прямыми линиями

Да, отражения сильно усложняют всё. Придётся выбирать, игра честная или игра красивая… для новых игр, в которых не принципиален соревновательный PvP, игроки выберут последнее. Графика продаёт игры, увы.

Делать 3D игры (кроме случая, когда вид сверху) с полностью авторитарным сервером — сложнейшая задача, к тому же требующая множество компромиссов. Поэтому и практически все AAA проекты просто не заморачиваются с этим — проще поставить какой-то клиентский античит и банить подозрительных игроков волнами уже пост-фактум. А игроки уже привыкли, что везде есть читеры…

К слову, даже если очень захотеть, маленьким инди-студиям клиентские античит решения для Windows практически недоступны — например, любопытства ради мы связывались с EasyAntiCheat и они перестали отвечать нам, когда узнали наш доход за прошлый год (он весьма приличный для нашей маленькой студии). Не говоря уже про то, что игроки могут просто убить своими отзывами инди-игру в случае, если их банить (хотя недавно в Steam появилась опция раздавать баны игрокам через отдельный API, лишая их доступа к игре полностью, аналогично VAC — но есть сомнения, дадут ли к этому функционалу доступ инди-разработчикам и сохраняется ли возможность написать негативный отзыв в случае такого бана). От отзывов и рейтинга очень сильно зависят продажи, по нашему опыту и опыту нашего издателя.

Мы ориентировались на возможность портирования на другие платформы, полную поддержку моддинга (опенсорс), невозможность (да и нежелание в силу их ненадёжности и инвазивности вплоть до уровня ядра ОС) использования любого популярного клиентского анти-чит решения, отсутствие банов за читинг в принципе. Получилось? Получилось. Но игра разработана с соответствующей философией и соответствующим геймплеем, механиками.
У нас всё гораздо проще т. к. в нашей 2D игре вид сверху и игрок всегда всех видит в рамках поля обзора (30x16 «метров» для всех игроков независимо от разрешения экрана, автоматически скейлится). Стены не являются препятствием к обзору.

В 3D играх всё значительно проблематичней. Сервер в принципе может не присылать то, что игрок не способен видить (объекты за холмами, стенами и другими непрозрачными препятствиями), однако будет ощутимый лаг при входе объектов в поле зрения игрока.
В 3D шутерах есть другие проблемы — например, игроку нужно слышать шаги с 3D-позиционированием для персонажей за стенами.
Замечательная статья и была бы нам очень полезна в своё время! Всё очень знакомо…
В нашем проекте (2D онлайн-выживалка, только PC) мы придерживаемся философии «клиент в руках врага» и поэтому всё изначально было написано с авторитарным сервером и тотальным контролем информации, передаваемой клиенту. Клиент же просто запускает код симуляции, идентичный серверному, для предикции лага, а сервер принимает только команды инпута. Игра при этом легко моддится (код самой игры (не движка) доступен на гитхабе, 0.5 млн строк).
Согласно нашему подходу, делать саму игру следует таким образом, чтобы всевозможные читы были бесполезны. Мы продумывали игровые механики таким образом, чтобы в принципе избежать какой-либо пользы от читов. Худшее, что мы ожидали — аимбот. Хотя игра 2D и прицелиться — дело не хитрое. Но, т. к. со временем была добавлена механика отдачи для автоматического оружия, у игроков появился стимул разработать аимбот (что удалось пофиксить просто добавив для автоматического оружия рандомный разброс на сервере, сделав всякие попытки компенсации бессмысленными; кстати, при высокой скорострельности игроки не замечают, что на самом деле стрельба на сервере симулируется иначе и промахи/попадания не совпадают). Также игроки бот на автоматическое применение оптимальной медицины создали (что пофиксить, конечно, гораздо проще на уровне игровых механик — просто запретили стрелять, пока хилишься — лишать себя такой возможности в пылу боя никто не захочет). Но в итоге PvP-игроки выразили категорическое мнение, что на PvP серверах клиенты должны быть без каких-либо модификаций. Пришлось городить дополнительные слои защиты, шифрования, верификации. Успешно, и не чересчур сложно, благо изначально клиент уже был защищён обфускацией. В итоге у игроков стимула пытаться что-то хакать на стороне клиента не осталось — чересчур много труда (который окажется напрасным стоит нам только собрать новый билд игры несовместимый со старой версией), игровые механики не позволяют получить какого-либо преимущества, а авторитарный сервер просто не принимает от клиента ничего кроме инпута и не присылает ничего такого, что клиенту не следует знать.
Кстати, за всё время мы не забанили ни одного игрока, несмотря на общее число игроков за 200 тысяч человек. Если всплывал факт чита, мы воспринимали это как нашу недоработку.

> 9. Добавили защиту от взлома оперативной памяти.
Было бы интересно узнать, какой подход был использован! В случае .NET приложений, это не так-то просто.

> К новым проектам в разработке тоже стали относиться по-другому и сразу пишем их с защитой, почти как у полноценных ААА-игр.
К сожалению, в последние годы многопользовательские AAA-игры не принято писать с адекватной моделью защиты (хотя бы с подлинно авторитарным сервером). Это сложно, дорого, и не всё возможно сделать хорошо в рамках такой модели (когда клиенту ноль доверия). Обычно просто используют защиту клиента — EasyAntiCheat, BattleEye, которые с переменным успехом позволяют пост-фактум банить читеров, но которые так же не составляет огромного труда обойти (причём не обязательно на уровне клиента, а на уровне сетевого протокола). Существует гигантский чёрный рынок платных читов. Перечислять AAA-проекты за последние 5 лет, кишащими читерами, нет смысла — проще перечислить те, где их нет (по моему, их — нет). Дырявый сервер же пытаются защищать с помощью ИИ (machine learning оценкой поведения игроков на сервере) — что мне видится просто как страшный костыль, не исключающий false-positive срабатываний. Не уверен, что это приведёт к чему-либо хорошему. Вот перенос гейминга в защищённое облачное окружение (с клиентом-терминалом для приёма игрового инпута и отображения транслируемого видеопотока) может гарантировать полное исключение читинга — ценой повышенной латентности. Однако провал Google Stadia показывает, что мы ещё не скоро до этого доберёмся.
(Извиняюсь, немного отредактировал из-за неточного комментария про различии наших графиков)
Посмотрел подробнее ваш график. У меня просто одна ось другая, но смысл очень близкий. По оси Y я отображаю число игроков получивших предмет в данное число попыток (и оно падает с увеличением X, стремясь к 0), а у вас это кумулятивное значение (сколько % игроков получило предмет для заданного числа попыток, соответственно оно растёт с увеличением X, стремясь к 100%).

«Горбик» или «парабола» для стандартного распределения (№1) у вас наблюдается на графике тоже — в виде горизонтальной асимптоты. Просто нужно поставить больше попыток для наглядности — например, 50 — и будет видно, что она и дальше стремится к бесконечности. А для большей наглядности стоит тестировать модель на более низкой вероятности, например, 1/1000.

Но даже на вашем график видно, что на 7-й попытке для стандартного распределения (№1) порядка 67% игроков уже смогли получить предмет. Ещё +12-14% будет достигнуто примерно на 14-й попытке, а 99% будет достигнуто о-о-очень далеко от этого. И это есть главная проблема в геймплее: часть игроков-счастливчиков попадает в самое начало распределения, другая же группа игроков такого же размера практически бесконечно долго гриндит в надежде получить предмет.
Мой алгоритм исправляет данную проблему и мы видим на вашем графике прямую, проходящую до 14 попыток к 100%. 50% должно быть достигнуто на 7-й попытке (и это является как средним, так и медианным значением), и 100% на 14-й попытке. Не уверен, в связи с чем связана некоторая неточность на вашем графике, но тренд очевиден — линия идёт прямо и направляется к 14. Никаких «горбиков». Всё понятно и удобно в использовании. И не нужно объяснить геймдизайнеру и тем более игрокам, почему, затратив более 2000 попыток, они до сих пор не нашли какой-нибудь драгоценный камушек у которого вероятность выпадения 1/1000 — потерпеть максимум вдвое дольше нужного вполне допустимо.

Вклинивая решение с if'ом «в лоб» (подход №2), вы однозначно ставите крест на необходимом среднем числе попыток и на медианном значении. Ваше решение №4 тем более оказывается неудачным, т. к. оно только усиливает «горб» — посчитайте, какое среднее и какая медиана получаются, мне очевидно, что они сильно сдвинуты влево, в сторону меньшего числа попыток. Там уже нет речи про 15% шанс (т. е. «6.667 попыток в среднем», а желательно и по медиане тоже!) — ведь уже с третьей попытки игроки получают предмет в практически 50% случаев. С задачей уложиться в заданное число попыток вы безусловно справились (и если поставлена такая задача, «китайский рынок», это видится мне более уместным решением, чем вариант «в лоб»), но в итоге игроки будут получать гораздо больше предметов, чем задано геймдизайнером.
В моём алгоритме, в сочетании с обычным стандартным распределением функции System.Random, мы получаем идеально ровную прямую (в случае вашего графика однородно/линейно восходящую вверх, т. к. вы строите именно какой % игроков к данному числу попыток получит предмет, это кумулятивное значение включающее игроков получивших предметы за предыдущие попытки). Вот пример моего графика для 50 тысяч игроков:

— все «ведёрки» заполнены одинаково, т. е. игроки равномерно распределены по числу потребовавшихся им попыток для получения предмета. И общее количество попыток не может превысить 1999 для предмета с вероятностью 1/2000. В среднем — 1000, медиана — тоже идеальные 1000. Мы получили равномерное распределение итоговой вероятности получения предмета вместо bell curve или «параболы».
Спасибо за быстрый ответ! Интересный будет диалог, т. к. я давно хотел поговорить об этом с коллегами по индустрии.
Распределение значений System.Random равномерное и с этим никто не спорит (вероятность возврата любого числа одинаковая). Ваш скрипт на JSFiddle показывает это замечательно.
Речь же идёт о другом — сколько игроку нужно сделать попыток, чтобы получить предмет с определённым шансом выпадения. И вот тут как раз получается «парабола» на моём графике. Кому-то везёт очень быстро получить предмет, кому-то не везёт вовсе и они страдают делая невероятное число попыток. Конечно, среднее число попыток, матожидание, достигается, но не тем способом, который бы устраивал разработчиков и игроков (посмотрите на моём графике сколько случаев слева от красной вертикальной линии, и сколько справа, в среднем как раз 1000 выходит, НО, медианное значение около 700!).

Псевдокод простой и соответствует тому как это происходит в игре — возьмите 10 тысяч игроков и прогоните для каждого из них вызов функции ролла предмета с заданной вероятностью в цикле, пока предмет не будет получен. Количество итераций этого цикла как раз показывает число попыток необходимых для получения предмета. Если вы возьмёте и построите на графике для этих 10 тысяч игроков распределение числа сделанных ими попыток для успешного получения предмета, оно будет как раз такой «параболой» — когда половина игроков в среднем действительно уложилась до матожидания, но остальная половина плетётся длиннющим хвостом. Вот JSFiddle (без графика, не забудьте открыть консоль; результат просто в виде разбития по корзинам размером в 200 игроков для выборки в 10000). Как видно в среднем игроку нужно 1000 попыток, а в медиане 700 попыток.

И, соответственно, если вы просто поставите топорный if как предложено в статье, получится вообще странный вариант, когда игроки получат предмет не за ожидаемые 1000 шансов в среднем, а за меньшее число шансов. Вот JSFiddle. Как видно, игроку в среднем нужно 630 попыток, а медиана — 700 попыток (ни то ни другое число не является 1000 как ожидает геймдизайнер!). Как видно по разбивки на bucket'ы, из 10000 игроков порядка 3700 достигают 1000 попыток, когда срабатывает жёсткий лимит и предмет выдаётся насильно. Это мне было очевидно сразу, поэтому я назвал ваш совет из статьи очень плохим.

И теперь посмотрите предложенный мной в корневом комментарии рецепт JSFiddle. Что мы видим? Полностью равномерное распределение числа **попыток** необходимых для получения предмета с нужной вероятностью. В примере для заданной вероятности выпадения предмета в 1/1000 в среднем игроку нужно потратить 1000 попыток, и медиана тоже — 1000 попыток. При этом игроку не придётся осуществлять более 2000 попыток.
Игроки уже успели оценить данное ноу-хау (в других источниках я на такой подход не натыкался и шёл по наитию) и похвалили систему лута за соответствие их ожиданиям. Раньше в игре получить предмет с шансом в 1/1000 хоть и в среднем удавалось за 1000 попыток если рассматривать ВСЕХ игроков, для каждого индивидуального игрока это работало самым непредсказуемым образом — кому-то везло сразу (5% игроков получало предмет за 50 попыток, тогда как другие 5% игроков получало его за более чем 3000 попыток!), кому-то невезло хронически. Теперь же игра гарантированно даст этот предмет за не более чем 2000 попыток, но в среднем и по медиане — 1000 попыток.
Для некоторых игр (тем более одиночных) такой подход даст наилучший результат с точки зрения игрока, да и геймдизайнер тоже доволен предсказуемостью такого псевдослучайного подхода. А вы как думаете?

Что касается вашего графика — конечно, результат будет не тем, т. к. строите вы что-то другое (можно исходник?). Как я это вижу, для шанса в 15% (вероятность 1/6.666(6)) ожидается, что в среднем игрокам за 6.67 попыток достанется предмет. Если округлим до 7, то по моему алгоритму получится, что в среднем игроку придётся затратить 7 попыток, медиана тоже 7, но общее число попыток не более чем 14. Если же вы оставите обычный рандом, с ним получается, что для заданной вероятности (15%, N=6.667) для выборки в 10 тысяч игроков в среднем игроку потребуется 6.6 попыток, медиана 5.0. При этом число игроков, которым потребуется 14+ попыток (вдвое больше ожидаемого среднего!), составляет 12-14%. Просто подставьте значения в мой первый JSFiddle и всё будет очевидно (измените N на 6.667, а размер bucket'а следует сделать равным N для случая с таким малым N).
Подставьте те же цифры в мой последний JSFiddle где используется мой алгоритм, и вы увидите среднее число попыток 6.667, медиану 7, и ровное (прямая линия вместо «параболы») распределение числа попыток во всём диапазоне от 1 до 13 (среднее число попыток не совпадает с медианой только потому что вероятность 15%, что не делится на точное число попыток; можно попробовать N=7 для примера).
Про «Гарантированное выпадение» — очень плохой совет даёте. Постройте график за сколько попыток игрок получает конкретный предмет — например для 1/1000 это обычно выглядит вот так:

Возможно вы очень удивитесь, ведь для шанса выпадения 1/50 при стандартном распределении с помощью обычного псевдо-рандома (System.Random в .NET) получается кривая с сильным перевесом в самом начале и длинным хвостом — хотя в среднем и получится 50 попыток, это далеко не то, что многие игроки ожидают и это особенно неприятно для вещей, у которых очень редкий шанс выпадения вроде 1/1000, ведь в некоторых случаях игроку потребуется более 10 тысяч попыток сделать чтобы получить предмет — такова природа распределения у такой функции рандома.
Так вот, по этой причине, если просто вручную хакать этот метод как вы предложили (поставить if), у вас в среднем получится вовсе не 1/50 шанс выпадения, а гораздо более высокий! Думаю, ближе к 1/25 если не ещё выше. Просто посмотрите на графике выше и поставьте линию отсечения, и оцените сколько попаданий до неё, и сколько после. Всё очевидно!
Я нашёл другой способ. Шанс выпадения должен быть 1/(2*N — M) где N это желаемое число попыток, а M это уже сделанное число попыток. Таким образом при использовании псевдо-рандома получается абсолютно ровное распределение числа попыток с сохранением гарантии выпадения предмета за указанное число попыток N в среднем, но игроку потребуется сделать не более 2*N попыток.
Можете прочитать мою заметку на этот счёт с полезными графиками (на английском) forums.atomictorch.com/index.php?topic=1734 всё объяснено подробно и есть ссылки на Github и онлайн-сэмпл на JS.
У нас в игре была проблема с выпадением редких предметов, и часть игроков жаловалась на это, а другая часть игроков наоборот, говорили, что слишком хорошо выпадают предметы («мне быстро выпало!»). И обе группы в итоге правы, что показывает график опубликованный выше — на одну группу крайних неудачников есть точно такая же по размеру группа крайних счастливчиков. В заметке по ссылке я объяснил, как мы решили эту проблему. Минусов у моего решения найдено не было, а плюсов полно — в виде полностью ровного распределения и гарантии получения предмета за разумное и известное число попыток (не более чем вдвое хуже чем указанная вероятность, т. е. для предмета с шансом 1/50 будет не более 100 попыток, но в среднем 50; но самое прекрасное это то, что вероятность получения предмета за 1 попытку, за 50 попыток, и за 100 попыток — одинаковая, график распределения числа попыток — прямая. Нет сумасшедших счастливчиков и бесконечных неудачников, всё ровно!).
Avalonia стремительно развивается и это не может не радовать! Выбор технологий для разработки кроссплатформенного UI с помощью XAML стал очень широк.

Когда нам в далёком 2013 потребовалось сделать хороший UI для игр и захотелось использовать опыт WPF/XAML, выбор пал на NoesisGUI — проприетарная кроссплатформенная библиотека, имплементирующая WPF API с полной поддержкой всех фич XAML (и даже сверх того за счёт отдельных расширения для 3D эффектов, text stroke и т. п.), с оптимизацией под видеоигры. Спустя много лет и багрепортов (включая сотни моих) проект дорос до достойного уровня и теперь это уже полноценный middleware используемый даже в таких ААА проектах, как Baldur's Gate 3. Ну и наши две инди-игры его успешно используют. Например, (немного устаревшие) скриншоты UI из последней игры twitter.com/noesisengine/status/978583221398114304 при этом исходные коды игры (кроме нашего движка) доступны публично github.com/AtomicTorchStudio/CryoFall Можно посмотреть, как многое устроено (сотни XAML файлов) или даже поиграться в live editing (исходники идут в открытом виде с игрой, во многом благодаря Roslyn это удалось осуществить).
Благодарю! Да, в итоге видео опубликовали в феврале 2019 и я его сразу же посмотрел. К сожалению, далеко не на все вопросы нашлись ответы (очень много граблей, которые просто невозможно разобрать за час). Но стало понятно, что этот подход удобен и эффективен только в определённых сценариях — собственно, о чём я и писал ранее.

Сейчас ECS активно продвигают в том же Unity, так что материалов много и более ясны плюсы-минусы. Но массового применения ECS пока не заметно (именно для игровой логики, а не только физики/рендеринга, для чего аналогичные data-oriented подходы уже много лет применяют в целях оптимизации доступа к памяти). Далеко не многие серьёзные игры можно разобрать на такие системы-конвейеры, способные обрабатывать массивы данных однообразного формата. Из AAA игр с данным подходом мне по-прежнему известен только Overwatch — и есть хороший вопрос, во что он в итоге развился за эти годы и какой процент их архитектуры организован как ECS.
Не всем и не всегда нужен гигантский движок с уймой лишних фич, особенно если есть чёткое понимание какой именно функционал движка будет необходим. Не всегда удобны предоставляемые инструменты и парадигмы разработки (скажем, подход со сценами в Unity, подход в префабами, система ресурсов, и т. д.). Также, многие встроенные функции движков не дотягивают до уровня, который можно получить используя сторонний middleware или просто написав свою имплементацию (например, меня не устраивают UI любых существующих движков поэтому я предпочитаю NoesisGUI (библиотека векторного UI), а для high-level сетевого слоя в последнем проекте понадобилось совершенно кастомное решение с глубокой интеграцией непосредственно в выбранную UDP библиотеку — с большим успехом в итоге, и просто гигантский контраст с тем, что по крайней мере на тот момент предлагали как Unity так и Unreal Engine (Unity HLAPI был годами набит багами, надеюсь они нашли людей доработать это недоразумение; в Unreal просто требовалась уйма сравнительно очень страшного кода на макросах в C++ для их magic репликации).
У меня есть многолетний опыт трудной работы с Unity, который просто доводил нашу студию до отчаяния в эпоху версии Unity 5 — была уйма критических багов, которые не фиксились месяцами (багрепорты часто месяцами игнорировались). А когда фиксились одни, то регрессились другие и долгое время не было доступно действительно полностью стабильной версии для релиза игры (дело дошло даже до постов с извинениями в их блоге и рассказом как они меняют свой подход к QA). Из-за того, что это проприетарный движок, я не мог залезть в его исходники и поправить какую-нибудь критическую мелочь самостоятельно (только на особых «договорных» энтерпрайз лицензиях тогда это было доступно, сейчас стало чуть проще — при условии что у вас много лишних денег). Но нужно понимать, что код движка там C/C++, а не C#, и всё наверняка будет совсем не просто в плане билда.
С тех пор я заработал огромный опыт написания собственного движка и работы с MonoGame.

Если бы я сейчас делал прототип игры, я бы вряд ли воспользовался Unity. Но новичкам в программировании (и тем более людям далёким от программирования) я его рекомендую — он достаточно логичный, зрелый, имеет массу качественных обучающих материалов. Unreal Engine тоже (во многом за счёт визуального скриптинга на Blueprints; рекомендовать новичкам в программировании работать с С++ API я бы не стал). В обоих движках есть удобный редактор сцены и 99% нужных фич по крайней мере для сборки прототипа большинства игр. Asset Store данных движков также может быть очень полезным (там немало бесплатных ассетов и расширений).
В случае наличия чёткого видения проекта и отсутствия потребности в лишних фичах (а так же просто опытным C# программистам) я порекомендую Stride (бывший Xenko) для 3D проектов (и/или когда нужен редактор сцены) и MonoGame для 2D (но там придётся писать свой редактор или ограничиваться сторонним решениями для работы с тайловыми картами, например). Для меня Unreal просто гигантский и медленный, с совершенно другими парадигмами разработки и без ориентации на глубокую интеграцию с C#, что оказалось принципиально важным моментом для выживания нашей студии с 2013 года (речь не только об унификации клиент-серверного кода для игр — на C# пишется вся инфраструктура включая сайты, бэкенд, тулзы, автоматизация облачных серверов и т. д. — всё это здорово ускоряет разработку и обслуживание).

Добавлю, что существует ещё один немаловажный нюанс — ограниченный инструментарий часто заставляет искать другой подход к разработке, который не может не привести к совершенно другому результату, чем если бы использовался полный движок с уймой готовых функций — они не могут быть лучшим выбором во всех случаях и навязывают определённые подходы к разработке. Нередко мы видим действительно уникальные проекты с необычным геймплеем или графикой именно от разработчиков избравших минималистичный путь написания своих движков, что с одной стороны ограничивает, с другой стороны полностью развязывает руки (попробуйте изменить какой-нибудь популярный движок, чтобы он полностью поддерживал live reloading всего и вся в игре, включая C# код — а у меня получилось ещё несколько лет назад на своём движке и это здорово экономило время при дальнейшей разработке — в сравнении с Unity, где приходилось ждать по несколько минут перекомпиляцию прошлого крупного проекта несмотря на его разделение на отдельные библиотеки). До середины 2000-ых это было вполне стандартным подходом, и мы были свидетелями огромного числа действительно уникальных проектов. Сейчас же рынок просто перегружен однообразными играми сделанными на двух наиболее популярных движках… кстати, где-то была статистика по движкам игр в Стиме среди наиболее популярных (worldwide top seller) проектов — и более трети игр имели кастомные движки. Сейчас такой информации не могу найти, но есть статистика по наиболее рейтинговым (исходя из оценки игроков) играм в Steam в 2019 (там в основном инди-игры получились, уж так пошло в Стиме, что они собирают наиболее позитивные отзывы).
Тоже обратил внимание. UO запустилась в 1997 году, а альфа-тестирование (причём платное!) было ещё в 1996.
Когда запустилась EverQuest из UO ушло немало игроков (и долго не приходили) т. к. там не было PvE серверов (в итоге в UO быстро побежали делать Trammel, крупное обновление с PvE). EQ же была первой действительно популярной трёхмерной MMORPG игрой.
Если бы они вышли в одно время как утверждает автор теста, то UO выглядело бы весьма слабо на фоне EQ и вряд ли бы стала такой культовой.
Рекомендую статью от главного геймдизайна UO и ряда других игр www.gamasutra.com/blogs/RaphKoster/20180627/320893/A_brief_history_of_murder_in_Ultima_Online.php это целая глава из книги. Очень интересно!
Благодарю за перевод! Но я не могу не заметить, что текстом информация не воспринимается должным образом в данном случае…
Когда я посмотрел первый раз видео выступления несколько лет назад, у меня был эффект «эврика»! Демонстрации автора очень убедительные, динамика применения изменений поражает любого программиста, который привык ожидать компиляции на каждое изменение. Конечно, всегда были скриптовые языки и байткод (т.к. команды которые интерпритируется на лету), отчасти поддерживающие перезагрузку определённых вещей. Но продемонстрированный подход принципиально более глобальный.
Это было вдохновением, когда я разрабатывал свой игровой движок. В результате игра поставляется вместе с исходным кодом (кроме движка), и движок умеет перезагружать всё на лету — код (C#, XAML (для UI)), шейдеры (HLSL), текстуры, звуки, музыку. Всё это здорово ускорило разработку, и позволило сделать практически безбажную игру (ведь тестировать и отлаживать очень просто и приятно, плюс можно использовать quicksave-quickload для быстрого тестирования определённых случаев после применения изменений), несмотря на традиционно высокую сложность разработки такого рода игр («мини»-ММО).
Движок пока сильно заточен под конкретную игру (и редактор для этой игры), и пока нет возможности его сконвертировать в general purpose game engine для использования в разработке других игр. Надеюсь в будущем появится возможность отрефакторить всё и вывести движок в опенсорс.
Я не разработчик QC, но можно сказать эксперт в этой области, и то что выпишите у меня не вяжется в голове. Исходя из того что вы написали, я вижу это так:

1. «Никаких dedicated серверов» означает не то, что теперь всё крутится в мифическом облаке на акторах, а то, что dedicated сервера не раздаются всем кому попало в виде exe-файла (что само по себе действительно представляет серьёзную уязвимость — их можно реверс инженерить). Т.е. это совершенно другая модель дистрибьюции игры (когда разработчики сами деплоят сервера, продают доступ к игре по подписке или free-to-play), но это не значит, что как-то изменился сам dedicated сервер игры — это тот же executable файл, который деплоится на виртуальную машину (в Azure) и запускается, и к нему игроков пропускает matchmaking сервис.
Сейчас таким образом организовано очень много игр (тот же Fortnite например или Overwatch) — matchmaking собирает игроков и ищет для них рабочий сервер, если такового нет деплоится инстанс на уже доступном железе или арендуется виртуальная машина.
К слову, «Никаких dedicated серверов» всё-таки скорее бизнес-решение (иначе нужно менять модель дистрибьюции игры на классическую — когда игроки покупают клиент и могут сами деплоить сервер где хотят, но сейчас мало кто так делает — увы, рынок изменился). Может быть и разрешат запускать dedicated сервера — но за денежку и в рамках их облачной инфраструктуры.

2. Ещё раз повторюсь, что нет смысла делать игровые сервера на акторах для такой игры. Это подход построения именно backend архитектур, когда производительностью можно (и нужно) пожертвовать в обмен на fail tolerance, load balancing и т.д… Т.е. ожидать, что dedicated сервер игры написан на Orleans это примерно как ожидать, что в игре для всего используется SQL и хранимые процедуры, или какая-нибудь причудливая технология из сферы энтерпрайз. Akka/Orleans традиционно используются в энтерпрайз бэкенде где нужны вышеозвученные фишки. А в рамках fast-paced игры это просто… как бы сказать, «так игры не пишутся». Там и GC pressure будет космический, т.к. всё это на .NET крутится, что в принципе неприемлимо.
А главное, это не имеет смысла, ведь уже есть idTech (огромная выполненная работа), и клиент игры должен прекрасно дружить с сервером за счёт общего стека idTech (общего кода перемещения персонажа и основных игровых систем которые должны симулироваться на клиенте для lag prediction). Всё это реально выбросить и переписывать на чём угодно заново — очень-очень плохое бизнес-решение.
А вот использовать для бэкенда Akka/Orleans + Azure это прекрасное бизнес-решение (как и понятно из этой презентации «мы взяли Orleans и он всё делает за нас»).

3. Aimbot'ы это чисто клиентская вещь и никоим образом не касается серверной архитектуры. Да, это можно пытаться детектить на сервере разными алгоритмами, но всё равно в индустрии это чаще решается средствами по типу V.A.C. и его аналогами (мониторинг на стороне клиента).

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

Опять же, я не разработчик этой игры, но это просто common sense для любого эксперта в индустрии. В эту же пользу говорит и видео-обзор от ютубера о канале которого я писал выше youtu.be/WITA9DpejSg?t=902 игра подключается к конкретному dedicated серверу и обменивается данными именно с ним напрямую в течение всей игровой сессии по протоколу UDP (анализ по Wireshark). Никаких проблем (кроме производительности) автор не заметил, все алгоритмы предикшена и компенсации лага присутствуют как и в остальных шутерах (что не исключает наличия багов о которых вы писали выше). А значит я возвращаюсь к тому же выводу — используется idTech или что-то явно аналогичное, а вот почему всё не хорошо ощущается в самой игре — хороший вопрос. Скорее всего — виноваты баги. Код современных игр очень наворочен в сравнении с тем же оригинальным Q3A, и иногда программисты могут допустить незначительную ошибку в коде приводящую к серьёзным проблемам.
Но погодите, ведь речь в докладе идёт именно о backend инфраструктуре (в значении сервисов — matchmaking, «валюта» игрока, рейтинг игрока, что угодно ещё), а не самой игры (если я ошибаюсь — поправьте меня, времени сейчас посмотреть доклад нет, но прочитал статью довольно внимательно). Да и сложно представить, чтобы на акторах кто-то разрабатывал шутер — это не имеет никакого смысла (load balancing в рамках игрового сервера не нужен, отказоустойчивость тоже; это игровой сессионный сервер и все к нему коннектятся и спокойно играют). Традиционные технологии прекрасно справляются — ещё со времён сетевой модели Quake 3 описанной Кармаком ничего нового не изобрели (всё те же механизмы client lag prediction, lag reconciliation, server state rewind, etc). К тому же, при разработке реальных игровых серверов для такого рода игр (fast-paced FPS/TPS), очень остро стоит вопрос о производительности (==цене) серверов. А оверхэд с акторами будет и ещё какой — нарушается cache locality, невозможно производить многие оптимизации, добавляются всевозможные абстракции…

А вот почему всё не хорошо ощущается в самой игре — хороший вопрос. Неужели действительно не используют сетевую часть idTech, или используют, но породили какие-то баги в ней?

Кстати, с удовольствием иногда смотрю этот канал www.youtube.com/user/xFPxAUTh0r1ty/videos автор только и занимается, что анализирует network performance ПК-игр, в том числе есть пара видео по Quake Champions.
Читы — имею ввиду разнообразные хаки, когда сервер доверяет клиенту часть authority. Как я понимаю, ECS позволяет симулировать независимо все системы и подразумевается что пересылается только инпут. Однако возможно, что сервер принимает и более сложные входные данные и даёт какой-то authority клиенту (чтобы сделать игру приятней с точки зрения клиента т.к. полная authority модель чрезвычайно сложная — в плане необходимости писать lag prediction и lag reconciliation механизмы которые всё равно не будут работать идеально просто потому что сеть не работает идеально). Именно это я и хотел бы уточнить.

В последние годы очень много «hack-fest» инцидентов в многопользовательских играх произошло и происходит, причём даже в случае ААА игр, а не только инди (которые во многом ограничены тем что им предлагает используемая высокоуровненовая сетевая библиотека большинство из которых заточены на P2P сетевую модель). Сервер слишком много доверяет. Примеры типичных хаков — клиент может попытаться поменять позицию и сервер с этим согласится, клиент может выстрелить когда не хватает патронов, клиент может прислать сообщение что по кому-то произвёл выстрел и успешно попал/убил и т.п…
Проблема настолько распространённая и дикая что разработчикам (особенно инди с небольшими бюджетами) игр с authoritative server model приходится отбиваться от заявлений игроков что игра легко ломается и т.д… У нас например один игрок сообщил, что хотел бы да боится хостить свой сервер игры ибо «есть слухи что ваша игра моментально ломается простейшими средствами». И доказательства никакие не требуются, уже верят наслово именно по той причине, что в последние годы ситуация печальная даже для десктопных игр — когда PUBG и Fortnite судятся с читерами и выигрывают, когда многие ААА игры (особенно отметились Ubisoft но там конечно спасибо нужно отдать P2P модели которую они с фейлом несколько лет пытались использовать с целью снижения расходов на серверную инфраструктуру, в итоге одумавшись и занявшись «гибридным подходом») имеют на ютубе удивительные видео с хаками, что ещё могут обычные игроки ожидать, тем более от инди? (если любопытно, вот мой официальный ответ игрокам на эту проблему forums.atomictorch.com/index.php?topic=1147.0 )

ECS это в принципе спорный подход, особенно для шутрера, особенно для мобильного
Тем не менее, на этом подходе успешно построен Overwatch и это не перестаёт меня удивлять (всё-таки там множество уникальных ability персонажей которые так просто не закодить с обычным ECS подходом). Возможно нужно просто уметь грамотно готовить ECS. Увы, когда я разбирался последний раз с этим, видео об ECS в Overwatch с GDC (2017?) было доступно только в GDC Vault за 550 USD/год (и вроде бы ничего с тех пор не изменилось).
1

Information

Rating
Does not participate
Registered
Activity