Внедрение систем достижений в современные сложные игры - PullRequest
39 голосов
/ 26 февраля 2010

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

Хотя есть некоторые проблемы, для которых я не мог найти хорошие решения.

Системы достижений должны постоянно следить за определенными событиями, придумать игру, которая предлагает от 20 до 30 достижений, например, для боя. Сервер должен будет проверить эти события (например: игрок избегал x атак противника в этом сражении или игрок прошел x миль) все время .

  • Как сервер может обрабатывать такое большое количество операций без замедления и, возможно, даже сбоев?

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

  • Как системы достижений взаимодействуют с ядром игры, в котором содержится ненужная информация? (см. примеры выше)

  • Как они отделены от ядра игры?

Мои примеры могут показаться "безвредными", но подумайте о 1000+ достижениях, доступных в настоящее время в World of Warcraft и о многих, многих игроках онлайн одновременно, например.

Ответы [ 4 ]

25 голосов
/ 26 февраля 2010

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

Возьмите пример «игрок прошел х миль». Я бы реализовал пройденное расстояние как поле в объекте плеера, поскольку это простое значение для увеличения и не требует увеличения пространства с течением времени. Достижение, которое вознаграждает игроков, которые проходят 10 миль, становится подписчиком этого поля. Если бы было много игроков, то было бы целесообразно объединить это значение с одним или несколькими промежуточными уровнями брокера. Например, если в игре существует 1 миллион игроков, вы можете объединить значения с 1000 брокерами, каждый из которых отвечает за отслеживание 1000 отдельных игроков. Затем достижение подписывается на этих брокеров, а не на всех игроков напрямую. Конечно, оптимальная иерархия и количество подписчиков зависят от реализации.

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

Обратите внимание, что большинство наград не обязательно должны быть мгновенными. Это дает вам некоторую свободу в управлении вашим трафиком. В предыдущем примере вы не могли бы обновлять опубликованное пройденное расстояние брокера, пока игрок не прошел в общей сложности еще одну милю или не прошел день с момента последнего обновления (до тех пор, пока он не увеличился). Это действительно просто форма кэширования; точные параметры будут зависеть от вашей проблемы.

4 голосов
/ 12 июня 2014

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

3 голосов
/ 04 января 2014

Есть два способа сделать это в обычных играх.

  1. Оффлайн игры: ничего сложнее, чем паб / саб - это огромное излишество. Вместо этого вы просто используете большую карту / словарь и ведете журнал с именем «events». Затем каждые X кадров или Y секунд (или, обычно: «каждый раз, когда что-то умирает, и 1x в конце уровня»), вы перебираете достижения и делаете быструю проверку. Когда дизайнеры хотят, чтобы новое событие было зарегистрировано, для программиста тривиально добавить строку кода для его записи.

Примечание: pub / sub плохо подходит для этого IME, потому что разработчики никогда не хотят "когда player.distance = 50". На самом деле они хотят, чтобы «когда расстояние игрока, воспринимаемое кем-то, смотрящим на экран, казалось, прошло мимо первой деревни, или, по крайней мере, на 4 ширины экрана вправо», то есть гораздо более расплывчато и абстрактно, чем простой счетчик.

На практике это означает, что логика идет в момент, когда происходит изменение (еще до того, как событие было опубликовано), что является плохим способом использования pub / sub. Есть некоторые игровые движки, которые облегчают выполнение «логики в точке получения» (часть «sub»), но они не являются большинством, IME.

  1. Онлайн-игры: почти идентичны, за исключением того, что вы храните «счетчики» (int, который увеличивается), а также обычно: «deltas» (циклические буферы того, что произошло, кадр за кадром) и: «события» (сложные вещи, которые произошло в игре, которая может быть жестко закодирована в один идентификатор плюс массив параметров фиксированного размера). Затем они предоставляются через, например, SNMP другим серверам для сбора при низкой стоимости процессора и асинхронно

т.е. почти так же, как 1 выше, за исключением того, что вы осторожны, чтобы сделать две вещи:

  • Использование памяти фиксированного размера; и если «читающие» серверы на некоторое время отключатся, то достижения, выигранные за это время, необходимо будет повторно завоевать (хотя вы, как правило, можете попросить сотрудника службы поддержки вручную просмотреть основные системные журналы и выяснить, что достижение «вероятно» "был выигран, и вручить его вручную)
  • Очень низкие накладные расходы; SNMP является хорошим стандартом для этого, и большинство знакомых мне команд в итоге используют его
1 голос
/ 15 июля 2010

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

...