Можно ли создать Игру Мечты, используя SpatialOS?

Теория MMO: DF
— Dwarf Fortress .28~.34

Прочитав комментарий о сомнениях в возможностях SpatialOS, у меня внезапно заболело. Нет, не пониже спины, а в желудке, горле и сердце: за горло ухватилась Жаба, желудок свели давние мысли о прибыли, а сердцу просто стало больно за проекты, лежащие в столе, которые, слава богу, реализовывают другие люди.

Данная заметка — взгляд криворукого практика с ожиданием от существующих технологий. Которые дают надежду на что-то эпичное.

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

Мечта

Теория MMO: "Машина видящая сновидения"
— «Машина видящая грёзы», Сатоши Кон, Хирасава Сусуму(?).

Сама по себе разработка довольно прозаична — ИИ, как это модно сейчас называть, нейросеть, с некоторыми… особенностями реализации. Его задача — работать, балансируя между проблемами. Вернее, наоборот: балансируя между проблемами, он будет функционировать.

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

Но для простого обучения ИИ нужно окружение, а для социального обучения — взаимодействие. С этой целью было задумано создать «игровую площадку» — небольшой мирок, где я буду лишь участником, а не единственным работником (и так сил мало).

К моменту начала воплощения мысль дошла до того, что мне изначально проще писать ММО (пусть и для ботов), чем сингл-игру, и потом к ней прикручивать возможность другим людям потрогать её.

В целом, конструкция выглядела так:

Сервер:
DOS Box0.71, Qb 4.5

Соответственно, ограничения: крайне низкая (как для цели) производительность, 10000 элементов/массив, 32кб/строка + асоциальность.

ИИ:
алгоритм сравнения строк и «удовольствия/боли» от оных.
+ мягкая защита от ловушки Грагарциана (бесконечное повторение «лучшего» действия).
Всё.

Игра:
DIM MAP() — Map — состояние карты
DIM MQ() — MapQuerry — запросы к элементам карты и сигналы обратно.
DIM BOT() — Bots — состояние ботов
DIM BQ() — Bot Querry — запросы к ботам извне и сигналы обратно.

Массивы MQ и BQ являлись необходимым злом, поскольку было ясно, что на одну точку могло быть сразу несколько действий, а значит, и конфликт интересов, который было бы проще решить между ходами, чем разбираться на лету.

Тело:
Тело задумано как некая сущность, которая позволяет боту чувствовать и анализировать. По факту — это просто набор строк, каждая из которых получает свои данные, а затем скармливает их в сторону ИИ (по правилам установленным для тела).

Алгоритмы:
Для упрощения жизни себе все алгоритмы были скинуты в два блока: базовые (для обмена данными и типовых работ) и сложные (могут вызывать базовые, но не равных). Эта сложность была нужна, чтобы не давать себе соблазна сделать циклы, которые будут долго работать «вешая» систему в целом.

В итоге пришлось разрабатывать систему, которая смогла бы обеспечить эту «SMMO» (сингл-ММО) на том, что было:

1. Каждый ход выполняется только один-несколько проходов по состоянию бота. Если бот не успел принять решение — тупит дальше.
2. Оптимизация: все службы сервера (кроме Главного Цикла) становятся такими же ботами. То есть вывод изображения на экран — тоже работа отдельного бота.
3. Клиент — это мини-сервер, который доверяет серверу в плане информации о себе и мире.
4. Любой клиент может принять на себя часть работы сервера и, в целом, наоборот.

Теория MMO: SAO
— SAO — игра, где всё управляется искусственным интеллектом «Кардинал».

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

Как сделать большой мир

Теория MMO: Цитадель
— Stronghold — мир, в котором хочется побыть...

А теперь — к современным проблемам: как же сделать так, чтобы мир смог держать миллионы игроков и не подавиться? А если НПЦ по нагрузке ничуть не ниже?

Когда в 2000-м у меня появился 80486-й мне наконец-то удалось поиграть в WarCraft II. До того я рубился лишь в Civilization, SimСity и жалел, что нет возможности совместить те две игры. Теперь же появился другой вопрос: а почему нельзя поиграть в него как в РПГ?

Затем появился Stronghold и мода на альтернативные рабочие столы. Мысль была проста: а можно ли прогуляться по папкам компьютера, если в каждую положить маленькую сохранёнку? Ведь это же столько новых, разнообразных карт, если создавать их на основе содержимого папки!

Но если можно прогуляться по своим — почему бы не заглянуть по локалке на соседний комп? Эдакое «посольство», где каждый может проявить себя, рассказать о себе — и довольно быстро настраиваемое. Хотя, а можно ли (почему нет? Скорости-то хватает!) заглянуть по диалапу к другу за 10 км?

И тут повис неловкий вопрос: а почему бы тогда не путешествовать по миру, переходя с одного сервера на другой? Каждая точка трассировки — такой маленький сервер, перекрёсток миров.

Но что делать с читерами, разными наборами экипировки (азиатский сервер не захочет иметь европейских вещей, например)? Только разбивать объекты на локальные сеты, миры на доверенные/недоверенные, сравнивать время последнего логина, вводить сервера-таможни (думается, что такие возникнут сами).

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

Решение

Теория MMO: Серверная
— Просто красивая серверная.

Так как же сделать так, чтобы один игровой мир прожевал миллион игроков и не подавился?

Итак, напомню: есть сервер, в котором каждое действие выполняется один раз за такт. Нет, можно выделить больше процессорного времени/тактов (привет, Трон) но сути это сильно не меняет. Есть клиенты (которые те же сервера, только без мира) и боты, которые — суть те же клиенты, но могут жить сразу на сервере.

Самым простым вариантом (на мой взгляд) связать их воедино — это дать возможность серверу на самостоятельность:

  • Если он нагружен — он инициирует запуск ещё одного сервера (при этом, бот ответственный за анализ состояния может заметить, что 95% игроков — в Китае, потому запускать надо именно китайский сервер).

  • При этом сервер не просто «запускает», а назначает иерархию и делегирует полномочия (кто отвечает за апдейт куска карты, игроков на нём и т.д.).

  • Клиенты, которые попадают на этот новый сервер, сначала получают пакет от текущего: «ребята, переходите-ка туда (ip, порт)».

  • Клиенты тоже ребята ушлые: вместо того, чтобы дропать соединение (идёт смена сервера, пожалуйста подождите....) — открывают ещё одно. Для рекомендованного.

  • Старый сервер ждёт от нового сигнала, что клиенты вошли и каждого вошедшего переводит в режим «трансляции» — он перегоняет данные с нового сервера конкретному игроку.

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

  • Также возможна ситуация «сплитера» — когда, например, група игроков идёт через один поток (или нет возможности увеличить мощность сервера) некоторые клиенты могут взять на себя функцию передатчика: они собирают сигнал от игроков, запаковывают к себе в пакет и отправляют одной кучей на сервер. Это, конечно, съест производительность (и не забываем про необходимость шифрования), но если слотов не хватает — это способ.

  • В случае, если игроку нужны данные одновременно с разных серверов — он свободно цепляется к нескольким серверам сразу, или же к «дежурным», которые получают данные с нескольких серверов сразу и перегоняют дальше.

  • «На всякий случай» можно открыть бэкап-соединение через другой сервер или другого игрока.

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

Любопытно, что эта война с руками и железом породила две, как мне кажется, уникальные механики: борьба за память дала мне идею «хранителей карты» (чьё убийство может привести к локальному концу света), а борьба с ДДОСом при перенаселении — механику усталости от крупных скоплений. Но в тему текущей заметки это как-то не влезает, потому если не будет протестов — опубликую в следующий раз.

Злоключение

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

Заключение

Теория MMO: Титаномахия
— EVE Online, битва при B-R5RB «Титаномахия». Стоило около $315,000 USD.

Так что причин, по которым у группы с финансированием и всем необходимым не может получиться что-то подобное — я не вижу абсолютно. Моя система была рассчитана для работы в условиях разве что не 80286 и в теории давала достаточный уровень производительности на 50-100 игроков в условиях 80486-го + внутрисерверные боты, так что от современных технологий и железа я бы ожидал не менее 2000 клиентов на сервер в самом худшем случае.
Читайте также

23 комментария

avatar
На данный момент я не могу заниматься дальнейшей разработкой ввиду… наличия совести на работе.
Позабавило)
  • Eley
  • 0
  • v
avatar
Я чуток недопонял концепцию. Точнее даже так, 80% всего что у меня сформировалось в голове — это не факты из заметки, а скорее домыслы, построенные на тексте.

У нас есть некие сервера по всему миру, которые мы натыкали за счет средств правообладателя игры? В том плане, что это же не рабочие станции каждого игрока?

У нас есть некий алгоритм, позволяющий перегонять динамически данные о персонаже из одного сервера в другой, при высокой нагрузке, так? Но как мы будем устраивать взаимодействие между сотней игроков, находящихся на сотне разных серверов? Как узнать, что игрок №1 на таком-то сервере, а игрок №2 на другом сервере и обмен событиями нужно вести именно с ними?
avatar
В целом всё так. Эта система изначально задумывалась как способ на моём допотопном железе обеспечить достойный процесс.

У нас есть некие сервера по всему миру, которые мы натыкали за счет средств правообладателя игры? В том плане, что это же не рабочие станции каждого игрока?
Не совсем. Это как сервера электронной почты или html странички. У каждого она своя.
Примерно как «LiF:YO», если сравнивать с современными играми.

Как узнать, что игрок №1 на таком-то сервере, а игрок №2 на другом сервере и обмен событиями нужно вести именно с ними?
Идёт восходящий запрос до ответственного сервера, который указывает с кем соединяться. Причём сделан он может быть как игроком (по очереди цепляться к серверам), так и самим сервером (в зависимости от того как прописать возможности к взаимодействию).
Клиент же вынужден быть мини-сервером. У него может не быть базовых механик вроде поддержки БД или чего-то в этом духе, но как минимум уже для поддержки FI-VR (виртуальной реальности полного погружения), да хоть бы даже и просто прямого нейроконтроля без обратки — сама по себе система должна быть вторым подсознанием игрока.
Опять же, возможность поднять сервер на стороне клиента позволяет искать читеров: система просто отрабатывает нажатия на другом клиенте и при расхождении начинает проверять «с пристрастием».

К слову, об извращённых способах борьбы с читерами, явившихся следствием такой механики могу рассказать в отдельной заметке, если интересует.
avatar
Борьба с читерами конечно интересно. Это не редко становится краеугольным камнем проектов, в которых защиты недостаточно и игра превращается в фарс.

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

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

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

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

В результате получаем такой эффект, когда вся нагрузка как на ЦП, так и на сетевые каналы увеличивается многократно. Лаги на стороне клиента и неспособность поддержки качества клиент на максимальных значениях так сказать. Просто помимо отработки нажатия/не нажатия кнопки у рендомного игрока придется обсчитать все сопутствующие действия, произвести измниния окружения, пересчет всех состояний, а это возможно только при доступе к сопутствующим данным. Следовательно если грубо говоря игрок вбежал в толпу из 20 игроков и пыхнул какую-то АОЕшку, то нам нужно передать не просто данные о его мане, наличии скила, текущем статусе «не метрв», шмоте и тд, но и данные о всем, что в эту АОЕшку попало. Мы собираем из базы и шлем инфу по сети, трижды, там ее принимают и просчитывают, возвращая нам текущие значения, после воздействия АОЕ. Мы получаем три копии (ну или хотя бы первые две), сравниваем их от и до и после этого вносим изменения в рабочие данные.
Как-то все очень уж долго получается, как мне думается. Особенно если данные, которые мы пересчитываем лежат на опять таки пользовательском сервере и могут быть исковерканы, либо приходящие пакеты могут ложно помечаться как фейловые и в результате мы получим дополнительные непонятки при игровом процессе, которые найти будет крайне сложно.

Ой, извиняюсь. Получилось много букаф.
avatar
Можно заставлять просчитать свои действия самого клиента, прислать результат на сервер, тот отправит трём рандомным клиентам, те проверят и пришлют ОК/не ОК. Пока они не прислали — верим (т.е. лагов нет). Если прислали и не ОК, то мы нашли читера.

Так каждому клиенту придётся обсчитывать данные для 4 человек (что нынешние компы легко потянут), а выводить на экран и пересчитывать это всё три дэ — только для одного. :)
avatar
В общем — да.

Только для проверки нужно синхронизировать и контекст.

Хотя, как по мне проще изначально снизить возможности таких читов через правильный диалог с сервером: «воздействие №64 на х+1 у-2, сила 8».
Серверу достаточно проверить запас сил и доступность действия.

Если моё мнение слишком наивно — буду рад это узнать.
avatar
Хотя, как по мне проще изначально снизить возможности таких читов через правильный диалог с серверо
Это зависит от игры очень сильно. Иногда невозможно упростить условия общения, особенно когда взаимодействие происходит между массой игроков одновременно.
Например выстрел через толпу игроков, возможность/невозможность попадания которого нужно просчитать серверу, учитывая то, что игроки присылают пакеты о своих действиях с разными задержками. Это уже не линейная задача где 1+1=2, а целое детективное расследование, которое может затягиваться до времени пинга самого медленного из игроков.
Сперва игрок 1 говорит, что выстрелил в игрока 2.
Потом игрок 3 говорит, что стоял в это время на траектории выстрела.
Потом игрок 4 говорит, что он убил игрока 3 до того, как тот убил игрока 3.
Ну а в конце мы узнаем, что в этот момент рядом был взрыв и их всех откинуло от 0.5 до 3 метров в сторону.
Ну а потом становится ясно, что не откинуло т.к. выстрела не было т.к. игрок 3 убил игрока произведшего взрыв раньше. Но этого не может быть т.к. его убил выстрел игрока 1. Но тогда игрок 1 смещен и не мог убить игрока 3.
Вот такие простые задачки для сервера, вместо того, чтоб просто проверить запас сил.
avatar
Как говорится, «семеро одного не ждут».

Вроде как ещё на Celeron 300Mhz, 128Мб ОЗУ под Win98SE вполне сносно шёл Stronghold, где лучники стреляли по координатам и могли промахнуться, а иногда шёл выбор в какого из врагов попала стрела — и, в целом, всё было очень даже ничего.

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

Да, будет фейл с задержкой в 8 тактов на изменение состояния цели, т.е. до 1,6с. в худшем случае (ИМХО, 0.16 максимум), что в любом случае приемлемо: в первом случае для чего-то в духе RagnarokOnline, во втором — уже почти для всего. Если же нагрузка на сервер будет менее .01с/такт, то и вовсе задержка падает до .08, чем уже можно просто пренебречь.
(В случае, если игроки на разных серверах в одном мире — да, там ещё начнётся диалог между серверами, что даст ещё +8 тактов).

Проблема только в том, что писать придётся:
а) монолит (по крайней мере, в процессе выполнения)
б) не объектный код (т.к. создание объектов вызывает циклы выделения-очистки памяти), а то и вовсе — экономить на спичках и писать всё в едином адресном пространстве, чтобы избежать любых приколов компилятора.
А это сейчас — моветон-с.
avatar
Можно добавить в механику и интерфейс побольше рандома и приблизительных значений, чтобы скрыть рассинхронизацию. Например, когда атака заявлена строго в цель, у одного класса дальность написана строго 28 метров, а у другого — дальность контроля не менее строго 25 метров, то проблема задержек, раздающих по плюс-минус три, а то и пять метров, вызывает много возмущений. То же самое без гарантированного таргета и с шансовым попаданием за определенной дальностью, думаю, будет восприниматься иначе. Против чьего-то постоянного преимущества не поможет, но проблемы «детективных расследований», когда порядок каждый раз разный, предполагаю, решит. Плюс, на все взрывы и значительные эффекты можно увеличить время от запуска до срабатывания (каст, анимация).
avatar
Ох, это надо опробовать на живом проекте, здесь и сейчас я не смогу осмыслить это.
avatar
Да нет, ну тут по моему все резонно и мысль хорошо, но единственно далеко не ко всему применима. Нужно затачивать все действия под эту структуру, по возможности.
Например лук может бить и на 800м, но прицельно стрелять на таком расстоянии нереально. Зато вполне реально попадать со 100м. Если щель отдалилась, то мы не говорим «цель слишком далеко», а просто выкручиваем шанс промаха по процентам во много раз, пропорционально расстоянию.
С другой стороны, если мы например берем лежащий на земле предмет, то получить «промах» будет как-то нелепо))) Не все действия могут быть так рандомезированны. Ну или там я не знаю даже, предмет выпал из рук?)
avatar
С другой стороны, если мы например берем лежащий на земле предмет, то получить «промах» будет как-то нелепо
Это может быть не мгновенный процесс. Секунды, ну двух, хватит. И в случае, если один предмет пытаются взять двое (трое, пятеро), результат для всех, кроме одного, немного предсказуем.
Комментарий отредактирован 2016-07-12 13:13:57 пользователем Agrikk
avatar
Так каждому клиенту придётся обсчитывать данные для 4 человек (что нынешние компы легко потянут)
Ну и увеличивает нагрузку на каналы передачи данных для сервера и каждого из клиентов в 4 раза конечно.
Но в целом идея мне нравится отсутствием лагов у клиента.
Конечно потребуется хранить историю изменения состояний на последние Х секунд и иметь возможность корректно ее откатывать по необходимости.
avatar
Откатывать может и не понадобиться. Если найден читер, то очень рано, напортил он мало. Можно просто забанить и ничего не откатывать.
avatar
1) Если у нас есть твинк-читер, который создал эпический предмет в торговом окне или 100500к золота переслал майну через аукцион за бесполезную мелочь, то толку от бана этого твинка ноль. Сделку нужно откатывать.

2) Далеко не всегда попытка игрока сделать невозможное базируется на читах. Если игрок 1 говорит «я сделал шаг в сторону и теперь стою в точке (х, у)», а спустя 0.5 секунды приходит пакет в котором игрок 2 сообщает, что он там оказался раньше и уже успел поднять предмет лежащий под ногами, переместив его в инвентарь.
Мы заявим, что игрок2 читер? Или просто будем считать, что он лагнул на секунду?
Что делать с предметом? С положением обоих игроков, которые сейчас застряли друг в друге? Или у нас всегда правы те, у кого пинг выше? Тогда получится крайне неприятная ситуация для игроков с дальнего востока например, которые в спорных ситуациях всегда будут в проигрыше, а ситуаций таких будет много при высокой плотности событий.
avatar
1. Все данные оригинальные хранятся на серверах. Если клиент стал доверенным сервером и получил право эмитировать голду, то у меня серьёзные вопросы к жалующейся администрации.

2. Все данные хранятся на серверах. Потому и А, и Б посылают намерение сделать «скилл, сила, направление», потому проблема не возникает изначально.

А вообще я как-то плохо представляю эти пляски вокруг лагов =)
Комментарий отредактирован 2016-07-11 15:52:05 пользователем wano987
avatar
А вообще я как-то плохо представляю эти пляски вокруг лагов =)

Кстати занятная статья по поводу плясок вокруг лагов))
https://habrahabr.ru/post/303006/

Вот из коментов понравилось.
у мультиплееры во всей серии Souls похожи. В целом, там всё тоже самое: если попадается игрок с большим пингом, то часто по тебе проходят удары, которые с твоей точки зрения не должны были до тебя достать, так как ты вышел из зоны действия оружия. Или удар в спину: ты уже стоишь лицом, но тут тебя телепортирюет к позиции врага и срабатывает анимация удара в спину.
avatar
Благодарю, вечером почитаю. Смотрится вкусно.
avatar
Нагрузка-то да, но сколько будет идти данных в одном пакете? Если не делать воксельный мир, где передаваться будет сразу тонна данных, то достаточно передать только данные изменения состояния, т.е. байт 20-30 на пакет максимум. Да игровой чат больше отъест!
Можно было бы соединить клиентов напрямую — но это деанон лютый, так делать не надо бы.

Что же касается «бэкапа» — это вопрос только к объёму ОЗУ, а с другой стороны — если ловить быстро, не давать возможности неправомерных воздействий и т.д. — то в целом это уже паранойя, ИМХО. Не то чтобы в ней было что-то плохое (кроме ресурсоёмкости), но это как проверка «IF 1=1 THEN» — да, это иногда срабатывает, но всё-таки не всегда это нужно.
avatar
Хорошо ответить постараюсь завтра, если буду рядом с компьютером.
А многабукафф это хорошо. Это поиск слабых мест в реализации.

Вот например зашли люди на сервер созданный кем либо, а унего кот наступил на кнопку пилота и комп вырубился. Где в этот момент взять все данные о персонажах и их изменениях?
Так это ещё что! А если он погиб на недоверенном сервере? Или если он погиб, но пришёл на другой сервер? Эх, забыл я про пермасмерть упомянуть заранее.
avatar
В целом с динамическими клиенто-серверами боюсь будет слишком уж много технических сложностей. Не представляю картину, как будет происходить обсчет нетипичных ситуаций.

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

Опять таки кто-то просто из научного интереса или целенаправленно вредя берет и начинает слать фейковые данные промежуточных обсчетов, которые ему доверили. Как это определить и исправить? Придется один пакет обсчитывать минимум трижды, на разных машинах, после определять истинные и ложный?
Во-первых, вопрос «что ему доверять»? Если ему доверять только перегонять шифрованные пакеты, то от MITM-атаки защищает сам процесс входа: Клиент и Сервер договариваются о ключе шифрования, только после этого пакет передаётся Дежурному, уже запароленный.
В случае вскрытия шифрования — меняем шифрование или делаем пул разных методов, из которых выбираем динамически.

Просто помимо отработки нажатия/не нажатия кнопки у рандомного игрока придется обсчитать все сопутствующие действия, произвести изменения окружения, пересчет всех состояний, а это возможно только при доступе к сопутствующим данным. Следовательно если грубо говоря игрок вбежал в толпу из 20 игроков и пыхнул какую-то АОЕшку, то нам нужно передать не просто данные о его мане, наличии скила, текущем статусе «не метрв», шмоте и тд, но и данные о всем, что в эту АОЕшку попало. Мы собираем из базы и шлем инфу по сети, трижды, там ее принимают и просчитывают, возвращая нам текущие значения, после воздействия АОЕ. Мы получаем три копии (ну или хотя бы первые две), сравниваем их от и до и после этого вносим изменения в рабочие данные.
В данном примере у нас и так 20 игроков, которым передаётся этот же объём данных.
Ну, ИМХО, семеро одного не ждут, а с другой стороны — зачем обсчитывать всё за один такт?
Примечание: не оптимизированная логика русского языка, в коде это будет несколько иначе!
<code>1. Soket()>>BQ() Принимаем <em>намерение</em> использовать скилл и атрибуты (сила, смещение, проч.)
2. Проверяем валидность.
2а. BQ()>>BOT() Втыкаем строку действий в ИИ.
2б. ИИ пробегается по строке, разгребая входящие: какие в исполнение, какие - в игнор (не свободен кэш).
2в. BOT()>>MQ() ИИ очищает кэш и отправляет проверенные команды.
3. Проводим действия.
3а. MQ()>>BOT() ИИ отвечающий за поддержку карты принимает данные.
3б. ИИ пробегается по строке, разгребая входящие: какие в исполнение, какие - в игнор (не свободен кэш).
3в. BOT()>>MAP() ИИ сохраняет обработанные данные в архив и направляет данные обратно боту (BOT>>MQ)
4. ИИ принимает данные.
4а. MQ()>>BOT() ИИ принимает данные согласно <strong><em>своих ограничений</em></strong>. Т.е. слепое тело проигнорирует изменения графики, глухое - звук и т.д.
4б. BOT()>>BQ() ИИ подготавливает данные "наверх" и заливает в буфер.
5. BQ()>>Soket() Очередь доходит до службы сокетов и она отправляет данные дальше.
</code>
Если на каком-то этапе обработка превышает разумные пределы — она приостанавливается (данные сохраняются для дальнейшего обсчёта) для следующего такта.

Хм, а может и не 8 тактов получается…

Как-то все очень уж долго получается, как мне думается. Особенно если данные, которые мы пересчитываем лежат на опять таки пользовательском сервере и могут быть исковерканы, либо приходящие пакеты могут ложно помечаться как фейловые и в результате мы получим дополнительные непонятки при игровом процессе, которые найти будет крайне сложно.
Вообще-то, «пользовательский сервер» может быть не признаваем официальным. Как «Wurm Online», «Minecraft», например.
Ещё его можно проверять на попытки инъекций — просто сравнивая контрольные суммы всех или некоторых строк данных. CRC, кстати, можно ещё и шифровать.
Этот ИИ можно подгружать, опять же «на лету», не держа на харде клиента.
Но в любом случае сравнение данных (особенно — с рандомным элементом) — это адъ.

Что же до ресурсоёмкости — ещё на 120Мгц 80486 вполне годно шёл WarCraft2 с лимитом юнитов в 128 штук (или 256, не помню) на карту. Не думаю, что их обсчёт был бесплатен, да и АОЕ там вполне себе присутствовало. На Dendy, кстати, были хорошие игры серии «Nekketsu!» (熱血 — горячая кровь, яп.). Рекомендую посмотреть на ю-тюбе футбол (Goal3), хоккей, а так же моногатари спешл средневековом сеттинге (там вообще был открытый мир с бандами в реальном времени, карта с возможностью быстрого перемещения, АОЕ тачкой/другом/врагом по морде). Мощность Dendy сегодня ниже, чем у чипа в самой дешёвой клавиатуре, наверное.
Комментарий отредактирован 2016-07-10 12:16:35 пользователем wano987
avatar
Простите, но ЯННП. О чём игра-то? Ощущение, что эта статья была бы уместнее скорее на Хабре, чем на ММОзге.
avatar
Да, это статья скорее для Хабра (но для Хабра в ней слишком мало кода). Я же предупреждал.

Та игра, была, в целом, ни про что: дождь идёт — трава растёт, вода течёт — трава растёт, зверушка идёт — трава, ой, не растёт, зверюга идёт — зверушка умрёт.
Ну вот собственно и всё.
Это было нужно только для базовой обкатки ИИ.

А тематические игры это потом. В другие заметки.

Оставить комментарий