2010-02-26 4 views
33

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

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

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

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

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

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

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

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

+0

Это очень хороший вопрос и быть геймером, о чем я думал об этом с тех пор, как я получил приличное программирование.Я знал, что события определенно связаны с этим, но я все еще удивляюсь об одном: есть старые игры, которые не были построены с достижениями в уме, и я полагаю, что они не излучают эти события. Тем не менее, эти игры иногда получают достижения, когда они переиздаются на таких платформах, как Steam. Означает ли это, что Valve сделал некоторые изменения в ядре? – MarioDS

+1

Я уверен, что вы ищете: [Как создать гибкую структуру для обработки достижений?] (Http://gamedev.stackexchange.com/questions/908/how-can-i-set- до-а-гибкому-каркасный для-разгрузочных-достижений). Эти ребята предлагают очень хорошие решения. –

ответ

21

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

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

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

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

+0

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

+2

@JosephShanak - Нет. Вы записали бы какое-то подмножество событий, затем запустили бы окно через них и старели события, поскольку они стали неуместными. В вашем примере вам никогда не нужно записывать более 6 значений. Когда появится новое значение, сравните начальное и конечное значение и посмотрите, не попадают ли они в течение одной минуты. Если они это сделают, у вас есть достижение. Если они этого не сделают, отбросьте самое старое значение, шунтируйте список вместе и дождитесь появления следующего и повторите. –

+0

@ire_and_curses Что делать, если вам нужны сложные исторические данные, такие как «пользователь играл более двух недель, правильно ответил на не менее 65% вопросов и дал 100% правильные ответы за последние 3 дня»? И вдобавок к этому добавьте, что это веб-игра, в которой статистика хранится в базе данных SQL. SQL-запросы для исторических данных являются дорогостоящими, особенно при агрегировании данных. Вы предложили бы другой подход в этом сценарии? –

1

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

+2

Не могли бы вы рассказать об этом? –

+0

Это грустный ответ. Кажется интересным ... –

3

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

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

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

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

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

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

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

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