Пиратские проблемы

Обсуждение работы движка сервера. Ваши предложения по улучшению игры. Вопросы по интерфейсу и механике игры

Модератор: Gorlum

Ответить
Gorlum
Император Вселенной
Сообщения: 7299
Зарегистрирован: 13 июн 2009, 15:06
Контактная информация:

Пиратские проблемы

Сообщение Gorlum » 28 апр 2018, 14:07

"Простые" Пираты - почему нельзя просто взять и добавить пиратов в игру

Уже некоторое время на форуме висит запрос на добавление Пиратов в игру: viewtopic.php?f=4&t=3248 . Даже обещали дать денег. Целых 50 баксов! В натуре - люди неделю работают за такие деньги - а тут за простую фишку сразу полтос. Зажрался, Горлум, зажрался...

Окей, давайте в предельно крупном увеличении рассмотрим фишку "пираты". Для начала - давайте посмотрим на проблемы в хотелке, которые очевидны для меня, но, видимо, неочевидны игрокам. Пойдём по пунктам:
Katerina писал(а):
17 фев 2018, 10:32
1. В галактиках рандомно появляются и исчезают планеты. Время остановки на одном месте 12-24-36-48 часов.
В общем - никаких особых проблем нет. Но есть один нюанс. Даже 48 часов - это очень мало. Практически никто из игроков не сканирует Вселенную каждые двое суток. А не-топы - так вообще если и сканируют, то раз в неделю-две. Если планета не появится в системе с активным игроком - её, скорее всего, не заметят. Мелкие и средние игроки, скорее всего просто не обратят на неё внимание. Системы же крупных игроков забиты во избежание появления "поплавков". Я уже не говорю о том, что по теории вероятности большая часть этих планет будут появлятся в пустых зонах Вселенной - там, где их никто не увидит и про них не узнает.
Выходит, что подавляющая часть таких планет просто будет зря тратить ресурсы сервера: их никто не увидит, на них никто не полетит. Либо так - либо добавлять в игру отдельную подсистему, которая будет определять место появления планеты, что бы был хоть какой-то шанс, что её заметят.
Так и запишем в ТЗ: "Добавить в игру алгоритм для определения точки появления планеты"
Katerina писал(а):
17 фев 2018, 10:32
2. На планетах имеются врата (ну или пусть на лунах этих планет) через которые, так же хаотично туда прибывают или убывают пиратские корабли (кол-во и качество караблей зависит от уровня, и при этом так же рандомно).
Тут видна уже определенная работа мысли. Очевидно, что "количество кораблей" будет как-то зависеть от уровня планеты, который будет зависить от уровня пирата.
Остаётся вопрос - а от чего будет зависить уровень пирата? Давайте пока остановимся на самом простом варианте - пусть он будет случаен. Хотя... Не подходит - распределение игроков по рангам (и соответствующим брэкетам) - величина совершенно не случайная. В общем случае - это хвост от "колокола" нормального распределения. В случае, скажем, Альфы, распределение отличается от нормального - из-за того, что сервер старый. Но, в целом, алгоритмы уже есть и можно создавать ботов, которые по частоте появления будут распределены так же, как и активные игроки на сервере - скажем "спасибо" ивентам ЧЛ и ОвК. Именно под них писались и переписывались эти алгоритмы, а так же модифицировался подлежащий код. Например, изначально нельзя было создать игрока с указанным количеством очков. Или сделать игрока, которого бы не трогала статистика - с тем, что бы количество очков не пересчитывалось.
Пока же запишем в ТЗ: "Модифицировать алгоритм выше так, что бы уровень планеты/бота зависел от распределения игроков по званиям/брэкетам на сервере"
Но и это не всё. "Хаотично прибывают или убывают пиратские корабли" - это очень красочное описание. Но, к сожалению, сложно алгоритмизируемое. Например - что, если в результате "хаотичных" действий флот пирата во много раз превысит флот игрока рядом? Или в принципе - совокупность всех флотов всех игроков данного уровня? Или даже - вообще всех игроков ниже уровнем? А так вполне может быть, если не наложить никаких ограничений на флот сверху!
Аналогичная засада есть и с количеством флота "снизу". Понятно, что если пиратский флот будет на порядок меньше, чем флот игрока - то пират попросту превратиться в кормушку-ишку. Не, такой хоккей нам не нужен!
Вывод? Нужен определенный алгоритм, который будет определять состав флота и удерживать его в определенных пределах - которые перед этим надо будет разработать и протестить по матмодели.
Так и запишем в ТЗ: "Добавить алгоритм расчёта минимального и максимального состава флота на планете против игроков в определенном брэкете/звании"
Katerina писал(а):
17 фев 2018, 10:32
3. Пиратов можно атаковать или поставить уд и сражаться вместе с ними.
Тут, вроде, всё понятно и просто. "Удержание" есть в игре - поставить флот на планету... А, стоп! Просто так - нельзя! Надо иметь на орбите "Базу Альянса"! Так и запишем в ТЗ: "Снабдить пиратские планеты Базами Альянса"
Katerina писал(а):
17 фев 2018, 10:32
1. Если планета игрока находится в той же системе и на расстояние в одно поле от планеты пиратов, происходит автоматический вылет пиратов на игрока. (естественно в зависимости от уровня)
О!!! Тут - целый ворох технологических проблем и балансных нюансов!

Начнём с технологий. Сейчас в игре НЕТ системы, которая позволяет игре отправить флот с одной планеты на другую без прямого участия игрока. Нет даже зачатков такой подсистемы! В ЧЛ и ОвК реализованы собственные обработчики "тиков", которые серъёзно нагружают игру и поэтому сделаны достаточно редкими (это не говоря уже о балансных причинах). Поэтому в ходе апрельского Фестиваля 2018 года была объективная просадка при отдельных обновлениях страниц - в статистике это явно видно. Если игроки не заметили или не обратили внимание - ну, значит плюсик мне. Однако разработать и внедрить такую систему на глобальном уровне - это требует немалых трудозатрат. Пока я вообще очень смутно представляю, как такая система должна выглядеть при сохранении функциональности и относительно малом влиянии на игру.
Плюс надо учитывать, что игра может работать и без кэширования в общей памяти. Да, при помощи глубокого кэширования в xcache можно свести даже сейчас задержки от такой системы к минимуму. Но надо помнить, что игра работает еще на десятках других серверов, не каждый из которых может похвастаться мощностью сервера под СН и не каждый из которых имеет установленный xcache.

Тут прийдётся сделать отступление для разъяснения, как работают веб-сайты вообще и СН - в частности. В своём самом рафинированном понимании, веб-сайт является state-less системой - т.е. веб-сайт "не помнит" своего прошлого состояния и каждый заход пользователя на сайт - как в первый раз. Так было на заре веба - открыл УРЛ и тебе выдало содержимое конкретного УРЛа.
Однако позже стало понятно, что это - не очень хороший вариант. Например, если нужен контроль доступа к разным частям сайта, то необходимо как-то идентифицировать пользователя. Поэтому поверх обычного веба начали наворачивать разные прибабахи - куки, сессии, локальные хранилища итд итп.
Потом возникла проблема с "динамическими" страницами - когда в зависимости от многих условий (УРЛ, настройки сервера, настройки веб-сайта, какой пользователь запрашивает страницу) стало необходимым динамически генерировать страницы. Это тоже решили при помощи подключаемых генераторов страниц, написанных на разных языках. Например - на ПХП, как это сделано в СН.
Но при этом всплыло несколько других проблем.
Во-первых - генерация контента начала занимать неприлично много времени. В части сайтов это решили глубоким кэшированием как сгенерированных страниц (и даже их кусков), так и данных.
Во-вторых - сама по себе технологическая основа ВЕБ-а не изменилась и сайт по сути оставался state-less, но уже с накрученными поверх костылями, свистелками и перделками. Фактически, сейчас динамический сайт из внешних условий (вида УРЛа, кукесов, сессии, состояния локального хоронилища итд) определяет своё состояние для каждого запроса, затем переводит себя в него и уже потом генерирует нужную страницу. Т.е. "Если чайник пустой - налить воды, поставить на огонь. Если чайник полный - вылить воду и вернуться на предыдущий шаг".
В-третьих - операция восстановления состояния может быть очень "дорогой" в разрезе ресурсов сервера (дисковые операции, память, процессорная загрузка итд)
В-четвертых - если происходят какие-то фоновые процессы, которые не привязаны к запросу пользователя, то их как-то надо обрабатывать. А поскольку любыие изменения состояний осуществляются ИСКЛЮЧИТЕЛЬНО при запросе пользователя, то всё время обработки этих изменений (т.е. изменения внутреннего состояния сервера) будут включаться во время обработки запроса пользователем. Конечно, можно попробовать применить внешние инструменты для изменения состояния сайта. Но это во-первых - само по себе нетривиально, а во-вторых - влечет определенные проблемы с синхронизацией процессов этих внешних инструментов и процессов на сайте, который может захотеть поменять данные по запросу пользователя.
Вот с этими проблемами и ограничениями приходится сталкиваться и держать их в уме при написании кода сайта.

Как, например, работает СН?
При каждой загрузке страницы (за некоторым исключением) СН для начала проводит обсчёт флотов - поскольку со времени последнего запроса флоты могли куда-то прибыть, что-то привезти или вообще - затеять бой. При этом, фактически, СН приходится анализировать все летящие флоты! Там, конечно, есть определенные оптимизации - типа, не анализировать флот, который возвращается и при этом время возврата больше текущего - но это уже нюансы и частные оптимизации.
Для каждого флота, для которого есть какое-то действие (выгрузка ресурсов на планету, возвращение, окончание Экспедиции) запускается обсчёт всех задействованных объектов - игроков, планет, очередей, флотов. Потому что (как будет видно ниже) в общем случае состояние отдельно взятого объекта "неактуально" - т.е. неизвестно, кто и когда обсчитывал его в прошлый раз и какое его состояние на сейчас. Т.е. мы опять возвращаемся к тому, что сайт вынужден восстановить по данным из БД и данным текущего запроса текущее состояние объекта и актуализировать его "на сейчас" - т.е. обсчитать очереди, добычу итд итп. Всё это, напомню, весьма "дорогие" операции.
Дальше происходит обсчёт действия флота и результаты вносятся в БД.
То же самое повторяется для всех флотов, чьё состояние МОГЛО изменится (опять же - не так в лоб, есть определенные оптимизации - но это частные случаи, когда они срабатывают, а когда - нет)
После того, как отработал менеджер флотов - наступает пора модулей. Модули Фестиваля (сам модуль Фестиваля, кстати, состоит из кучи подмодулей-ивентов или "хайспотов" в терминологии СН) грузятся всегда. Потому что основной код в принципе по определению не знает о существовании модуля - в этом и есть суть модуля! Основной код только знает, что надо каждый раз запускать вот эту процедуру (которая запускает код модуля), а уж модуль сам решит дальше - что делать. Далее - модуль (в нашем случае - Фестивальный) восстанавливает своё состояние и грузит подмодули - потому что, опять же, в общем случае модуль Фестиваля не знает, какие есть модули и активны ли они. Далее - подмодули восстанавливают своё состояние из БД и решают - должны ли они что-то делать в этот тик или нет. Если должны - они производят нужные действия. Если нет - просто передают управление коду Фестиваля. Опять же - это очень упрощенный вариант, потому что в коде полно всяческих оптимизаций, хуков и "закладок", для того, что бы максимально сократить загрузку сервера и уменьшить время рендеринга страницы.
Далее код проверяет - не является ли данный вызов страницы по данному УРЛу "специальным случаем". Например - может это вызов из чата о том, что игрок запостил сообщение в чат или вообще - просто хочет обновить содержимое чата? Такие случаи являются частными оптимизациями и просто отсекают существенную часть кода от исполнения.
И вот только после этого в дело вступает основная часть кода. Обсчитывается состояние игрока (очередь Исследований, например), определяется текущая планета, проводится актуализация состояния для неё (обсчитывается добыча со времени последнего обращения, просчитываются очереди, какие флоты летят - для данных в ресурсбаре итд). Если страница имеет навбар или список планет (является Империей или Обзором планеты) - такие же обсчёты производятся ДЛЯ ВСЕХ планет с целью актуализировать их состояния.
Затем вносятся изменения, которые могли быть в запросе. Ну, например - меняется тип планеты или добавляется юнит в очередь или отправляется флот.
И лишь затем - обсчитывается и выдаётся результирующая страница.

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

Вы всё еще читаете? Не заснули? Не потеряли нить? Тогда вернёмся к нашим пиратам и их проблемам.

Проблема первая - вероятность того, что пиратская планета окажется на расстоянии одного поля от игрока равного уровня - стремится к нулю даже с учётом алгоритма генерации пирата в соответствии с распределением игроков по уровню - мы же учитываем уровень при нападении, правда? Более того - от такой системы будут страдать игроки среднего и нижнего уровней - которым и так несладко. Топы и сабтопы же не будут подвергаться нападкам пиратов ВООБЩЕ - из-за того, что их системы плотно упакованы и просто некуда вставить планету.
Проблему можно решить, размещая пиратов в соседних системах и нападая далее 1 поля... Но тогда возникнет следующая проблема - как выбирать цель при прочих равных? Как выбрать между игроками, чьи планеты на одинаковом расстоянии (в пределах одной системы) - кого из них атаковать? А если у выбранного игрока куча планет - куда лететь? Случайным образом?
О! "Случайный образ" - он же "рэндом"! В игре рэндом даёт лишь нормальное распределение на достаточно больших выборках. Но при конкретном применении рэндома к отдельно взятому игроку возникают артефакты типа "Двадцать раз делал луну - и всё неудачно!" или "Слетал 5 раз в экспу - каждый раз терял флот!". При том, что случайное равномерное распределение - случайно и равномерно (т.е. в среднем - луна получается в 30%, а флот теряется в х%), при наложении в рарезе отдельного игрока неизбержны выплески. И тут же начнётся вой в чате - "АААА!!! МЕНЯ ПИРАТЫ АТАКУЮТ СЛИШКОМ ЧАСТО!". С другой стороны, это будет означать, что на кого-то пираты вообще не нападают и... "АААА!!! ПИРАТОВ В ИГРЕ НЕТ!!!" Значит нужна какая-то система отслеживания - на кого и как часто нападают пираты, что бы не допустить таких крайних случаев.
Так и запишем в ТЗ аж три пункта:
"Модифицировать алгоритм появления планет так, что бы планеты появлялись недалеко от игроков указанного уровня"
"Разработать и сбалансировать матмодель по частоте появления пиратов в зависимости от звания/брэкета игрока"
"Модифицировать алгоритм так, что бы пираты не нападали слишком часто/редко на одного и того же игрока"

Но и это не все проблемы! Есть принципиальная проблема с нападением бота на игрока. Например, время подлёта флота может быть порядка 60-120 минут. Меньше - уже лютый оверкилл, а больше - нет особого смысла, потому что за 2 часа-то в онлайне можно успеть среагировать и поднять флоты с планеты. Или собрать САБ и превратить пиратов в кормушку... Хотя... А когда это нападение будет? Если ночью - то и 2 часа мало. И 4. И 6... Ой... Значит надо что-то и тут мудрить... Ладно. В принципе, можно трактовать пиратскую планету, как планету другого игрока... И сделать какую-то задержку после появления перед атакой... И не меньше часов эдак 12 - если она ночью появится... И со временем подлёта что-то придумать.... В общем - опять расширяем ТЗ.
Так и запишем в ТЗ: "Модифицировать алгоритм так, что бы у игрока было время обнаружить планету, а так же что бы пираты не летали слишком быстро или слишком медленно"
Хотя это уже не совсем ТЗ - я пока даже не понимаю, какие граничные условия должны быть? И как избежать моментов, когда игрок прошляпил появление пиратов в своей окрестности и его вынесли? Ответ - никак. И тут тоже надо что-то мудрить. Например - что бы пираты не нападали на совсем мелких и реже нападали на середнячков... Я вот сейчас не имею решения - это надо садиться, считать и думать. Много часов.
Ладно, запишем в ТЗ такую абстрактную строчку: "Придумать что-нибудь, что бы пираты не выбивали игроков из игры"
Katerina писал(а):
17 фев 2018, 10:32
2. На пиратских планетах бывают артефакты (для начала нужно разведать). Получить артефакт можно только в результате выигранного боя. Уд на такой планете может нарушить разведку.
Сразу же - КАКИЕ Артефакты? Нужен алгоритм расчёта. Нужно хранить где-то разведанный Артефакт.
Что делать, если Артефакт забрали?
Я уже поплыл, если честно. Просто запишу в ТЗ: "Придумать что-то по генерации Артефакта и вообще"


Теперь сведем список требований к ТЗ в одно место и добавим то, что сразу нужно дописать, что бы его реализовать:
  • Добавить в игру новый тип ботов - боты-пираты
  • Добавить в игру поддержку состояний для ботов
  • Добавить в игру поддержку состояний для планет
  • Добавить в игру алгоритм для определения точки появления планеты
  • Модифицировать алгоритм выше так, что бы уровень планеты/бота зависел от распределения игроков по званиям/брэкетам на сервере
  • "Модифицировать алгоритм появления планет так, что бы планеты появлялись недалеко от игроков указанного уровня"
  • "Разработать и сбалансировать матмодель по частоте появления пиратов в зависимости от звания/брэкета игрока"
  • "Модифицировать алгоритм так, что бы пираты не нападали слишком часто/редко на одного и того же игрока"
  • "Модифицировать алгоритм так, что бы у игрока было время обнаружить планету, а так же что бы пираты не летали слишком быстро или слишком медленно"
  • "Придумать что-нибудь, что бы пираты не выбивали игроков из игры"
  • "Придумать что-то по генерации Артефакта и вообще"
  • Добавить алгоритм расчёта минимального и максимального состава флота на планете против игроков в определенном брэкете/звании
  • Снабдить пиратские планеты Базами Альянса
  • Добавить в игру ИИ для снабжения планет флотами
  • Добавить в игру ИИ для определения возможности полёта
Это только то, что я сейчас упомнил. Скорее всего - потребуется интенсивная модификация исходников для поддержки той или иной фишки. Скорее всего - я что-то просто забыл добавить. Скорее всего - я о чём-то не подумал. Но даже так, по этому списку, по грубой оценке без учёта времени на просчёты матмоделей, ориентировочное время написания фишки составит 100-200 часов. С учётом моего опыта - оценку можно смело умножать на 2 и не очень смело - на 4.

И что же получится в итоге?
Katerina писал(а):
17 фев 2018, 10:32
Даю для начала 50 usd.
Даже если возьмем супероптимистичную оценку по минимуму - 50 USD/100 часов = 0,5 USD/час
Очень щедро! Кто-то хочет сделать фишку и заработать 50 баксов? Стучитесь в личку! Я, само собой, укажу автора - что бы он получил весь вал говна от её добавления в игру! И я уверяю - говна будет предостаточно!
ВНИМАНИЕ! Администрация в личную переписку не вступает, рукописи не возвращает и не рецензирует!
* Если у меня слишком хорошее настроение - я хожу почитать чат *

Ответить

Вернуться в «Движок сервера: жалобы и предложения»