Подтвердить что ты не робот

Внедрение систем достижений в современных сложных играх

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

В обычных играх это делается двумя способами.

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

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

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

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

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

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

Ответ 3

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

Ответ 4

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