Как мне проверить, выполнил ли игрок достижение?

13

Я делаю MMO-игру, и я только что дошел до того, что мне нужно реализовать достижения ... Как мне это сделать? Самое простое, что можно сделать, - это запускать его каждые 100 мс:

for a in achievements
    for p in players
        if a.meetsRequirements(p) then p.completeAchievement(a)

Но это только вызывает еще больше осложнений. Например, как я могу проверить, действительно ли достижение было завершено? Есть ли у игроков собственные свойства только для определенного достижения? Я делал подобные вещи с квестами, потому что они в основном "собирают 100 дров", так что активные квесты игрока проверяют это. Кроме того, должно быть лучшее время, чтобы проверить это, я думаю, это будет периодически замедлять работу моего сервера.

jcora
источник
7
Почему бы просто не выполнить соответствующие проверки по мере выполнения действий? Т.е., если пользователь собирает древесину, посмотрите, соответствуют ли они спецификации «собрать 100 древесин».
Майк Клак
1
Это выглядит слишком грязно ... Повсюду будут тонны чеков. Я думаю, что я буду придерживаться вышеупомянутого алгоритма из-за его простоты ...
Jcora
10
Есть способы сделать его менее беспорядочным: например, иметь обработчик события «OnChange», затем прикреплять к ним «объекты» достижений и обрабатывать там логику. Также поймите, что с вашей текущей настройкой у вас есть уровень сложности O (n ^ 2), что означает, что ваша игра становится намного медленнее, с большим количеством персонажей. Вид проблемы для MMO
Майк Клак,
Связанный: gamedev.stackexchange.com/questions/908/...
Тетрадь

Ответы:

23

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

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

У вас будут сообщения о типичных событиях, которые вы, возможно, захотите услышать о достижениях. Такие вещи, как «игрок приобрел предмет X» или «сущность Y убила сущность Z». Таким образом, вы можете отслеживать такие вещи, как количество Z, убитых игроком.

Это, вероятно, лучшее, что вы можете сделать для системы достижений. Он максимально централизует код и возлагает бремя на слушателей для фактического обнаружения достижения.

Кроме того, следует отметить, что для централизованных систем достижений (X-Box Live, достижения Steam) прогресс в достижении обычно хранится на сервере. Таким образом, для накопления достижений («выполнить задачу XY раз»), сценарий достижений просто определяет, когда X был выполнен, и увеличивает счет сервера. Для других видов достижений («выполнить задачу X») серверное достижение является двоичным: либо вы сделали это, либо нет.

Николь Болас
источник
+1 Это отличная информация. Даже полезно без меня, чтобы реализовать достижения в это время.
Джошуа Хеджес
Благодарность! Не могу дождаться, чтобы реализовать это, я хотел бы иметь эту идею раньше ...
Jcora
3

В зависимости от характера ваших достижений вы также можете ввести некоторые «маркерные достижения».

Например, если у вас есть 3 последовательных достижения:
Древесина 1 - Соберите 100 древесин
Древесина 2 - Соберите 500 древесин
Древесина 3 - Соберите 1к дерева

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

Это, конечно, требует проектирования (или расчета) дерева зависимостей достижений.

PrinceCharles
источник