Я делаю MMO-игру, и я только что дошел до того, что мне нужно реализовать достижения ... Как мне это сделать? Самое простое, что можно сделать, - это запускать его каждые 100 мс:
for a in achievements
for p in players
if a.meetsRequirements(p) then p.completeAchievement(a)
Но это только вызывает еще больше осложнений. Например, как я могу проверить, действительно ли достижение было завершено? Есть ли у игроков собственные свойства только для определенного достижения? Я делал подобные вещи с квестами, потому что они в основном "собирают 100 дров", так что активные квесты игрока проверяют это. Кроме того, должно быть лучшее время, чтобы проверить это, я думаю, это будет периодически замедлять работу моего сервера.
Ответы:
То, что вы делаете, зависит от характера достижения. Если все ваши достижения не соответствуют простому шаблону (соберите X число Y), вам придется до некоторой степени использовать их в специальном случае.
Используя систему обмена сообщениями на основе сообщений, вы можете предоставить ловушки, которые делают локализацию кода особого случая. Вы можете иметь определенные действия, чтобы запускать сообщения для слушателей, которые регистрируют себя. Тогда ваш код / сценарий достижения может просто зарегистрироваться у соответствующих слушателей и выполнить любое необходимое тестирование, чтобы запустить достижение.
У вас будут сообщения о типичных событиях, которые вы, возможно, захотите услышать о достижениях. Такие вещи, как «игрок приобрел предмет X» или «сущность Y убила сущность Z». Таким образом, вы можете отслеживать такие вещи, как количество Z, убитых игроком.
Это, вероятно, лучшее, что вы можете сделать для системы достижений. Он максимально централизует код и возлагает бремя на слушателей для фактического обнаружения достижения.
Кроме того, следует отметить, что для централизованных систем достижений (X-Box Live, достижения Steam) прогресс в достижении обычно хранится на сервере. Таким образом, для накопления достижений («выполнить задачу XY раз»), сценарий достижений просто определяет, когда X был выполнен, и увеличивает счет сервера. Для других видов достижений («выполнить задачу X») серверное достижение является двоичным: либо вы сделали это, либо нет.
источник
В зависимости от характера ваших достижений вы также можете ввести некоторые «маркерные достижения».
Например, если у вас есть 3 последовательных достижения:
Древесина 1 - Соберите 100 древесин
Древесина 2 - Соберите 500 древесин
Древесина 3 - Соберите 1к дерева
Тогда имеет смысл просто зарегистрировать событие OnChange для первого достижения, пока игрок не завершит его. По завершении вы можете зарегистрировать следующий объект достижения.
Это, конечно, требует проектирования (или расчета) дерева зависимостей достижений.
источник