Як часто зберігати стан гравця в стійких онлайн-іграх?


9

В онлайн-іграх люди вважають за краще входити та вимикатись, коли захочуть. Зазвичай їх ігрові досягнення легко зберігаються на сервері. Це не так складно досягти, але мені цікаво, як це можна зробити ефективним способом, який має сенс і масштаб.

Чи має сенс зберігати координати гравця та стан кожного разу, коли вони надсилають його? Мій сервер node.js може це зробити легко, не блокуючи відповідь, і я хочу зайняти базу даних Mongo, але, можливо, це доцільніше робити це раз на секунду та в події на сервері, збираючи все відразу?


Я зберігаю ігровий стан кожні 10 секунд. Я думаю, що цього достатньо, це залишається непоміченим (і я запускаю свій сервер MMORPG на своєму нетбуку, який має 512 Мб оперативної пам’яті).
jcora

Відповіді:


10

Я маю на увазі такий традиційний MMORPG, як World of Warcraft.

Збережіть після кожної команди від кожного гравця та автономної речі (наприклад, NPC)

  • Постійне резервне копіювання. Сервер може спуститися в будь-який момент, і стан гри збережеться до цього моменту (або якнайшвидшого, у будь-якому разі).
  • Вплив на продуктивність сервера; навіть якщо це не блокує (тобто на іншому потоці), навіть якщо база даних знаходиться на іншому сервері, це обробка, яку ви інакше б не робили. Якщо він не блокує, як ви кажете, то інша нитка повинна обробляти його, і це нитка, яка могла б бути зайнята чимось іншим.
  • Збільшено введення / виведення диска, тим самим збільшуючи ризик / швидкість відмови. Це викликає особливе занепокоєння, якщо ви використовуєте SSD для зберігання, враховуючи їх менший термін експлуатації.
  • Якщо ви завантажуєте базу даних на інший сервер, тоді збільшується пропускна здатність; це може викликати занепокоєння, якщо ви платите за пропускну здатність, і якщо це не на окремій мережевій картці, то це забирає ресурси, які можна було б краще використовувати для обробки трафіку плеєра.
  • Що станеться, якщо сервер все далі і далі відстає в збереженні стану цих команд? Тобто, якщо входить більше команд, ніж їх можна зберегти, тож вони збираються в черзі? Чи переповнюється ця чергу і викликає помилку? Ви все зупиняєте, щоб черга могла наздогнати?
  • Мені здається, що цей підхід, хоча це звучить просто, потрібно було б ретельно спланувати. Наприклад, послідовні команди, які покладаються один на одного, потрібно буде зберегти разом; інакше в середині команд може статися збій, і лише одна буде збережена, але не інша. Поміркуйте, якщо два гравці виконують торгівлю і дві команди зберігаються на диску: "додати 1 елемент до одержувача" та "відняти 1 елемент від відправника". Якщо помилка трапляється після першої команди, але перед збереженням другої команди, у вас є дублювання елемента. (якщо замовлення скасовано, ви втратили товар)

Зберігайте все періодично

  • У разі відмови сервер буде дещо застарілим. Сподіваємось, ви використовуєте щось на кшталт підходу з переходом на дорогу, тож останній знімок буде принаймні цілим і послідовним, а всі активні гравці повертаються на стільки ж часу.
  • Незалежно від того, яка система баз даних ви використовуєте, може мати оптимізацію для пакетного оновлення, яка є більш ефективною (менше накладних витрат), ніж оновлення.
  • Якщо замість цього ви вибрали двійкову файлову систему, цей метод просто не вдається. Створіть новий файл, скиньте в нього пам’ять, киньте маркер на кінці, який сигналізує про те, що резервна копія була повністю завершена. Після завершення однієї резервної копії видаліть попередню резервну копію (або ні).
  • Процес резервного копіювання може також потребувати врахування речей, згаданих в останній точці пункту в другому розділі, наприклад, збереження в середині послідовних команд, які не слід розбивати. Ви можете вирішити заблокувати весь набір даних, скинути їх на диск та розблокувати, але залежно від того, скільки часу знадобиться, це може призвести до досить здоровної паузи або уповільнення гри.

Збережіть символ при виході (не зберігайте нічого іншого)

  • Найголовніше для гравця - їх характер, який включає в себе предмети, які вони мають, навички, які вони заробили, список своїх друзів тощо. Якщо вони вб'ють монстра, і награбоване є на землі перед ними, а потім сервер виходить з ладу, вони будуть трохи розбиті, не маючи шансів забрати їхнє бабло, але вони переберуть його. Тож просто збережіть важливі речі, а дрібні речі не спітніть. Наприклад, не зберігайте позиції NPC; якщо сервер опускається, коли він повертається назад, вони будуть нереститися в загальній області, в якій вони повинні знаходитися. Виняток, звичайно, стосується будь-яких "розумних" НПС, які чомусь повинні залишатися на тому місці, де вони були, коли сервер зайшов.
  • Крім того, гравець не повинен входити в систему занадто багато годин одночасно (зауважте, що тут я розглядаю "повернення до лобі" як вихід із системи). Зрештою, їм доведеться зробити перерву у ванній кімнаті або отримати їжу або перешкодити батькові / другові / що завгодно або спати. Таким чином, вони реально не повинні реєструватися без зупинки більше, ніж, скажімо, 8 годин навіть для найжорсткішого геймера. Якщо "гравець" увійшов в систему протягом дуже тривалого періоду часу, є велика ймовірність, що це або кілька людей, або бот, і жоден з них не бажаний або нормальний.
  • Крім того, у процесі виходу вже слід перевіряти такі речі, як вищезазначені послідовні команди. По суті, це вже має бути упаковка персонажа, так що, очевидно, простий час скинути його на диск.

Замикаючі думки

  • Очевидно, що я підтримую останній підхід, але я намагався бути неупередженим щодо всіх трьох.
  • Важко сказати, який із перших двох методів є марнішим. З першим методом, якщо персонаж надсилає кілька команд переміщення, вони будуть збережені на диску та перезаписані, коли чітко їх можна буде упакувати в одну. Але при другому методі, якщо у вас половина населення стоїть навколо, їхні позиції зберігаються на диску, навіть якщо вони абсолютно однакові з часу останньої операції з резервного копіювання. У третьому випадку цілком можливо, що хтось міг би увійти та негайно вийти з системи, але найчастіше багато речей про гравця змінилися, тому марнотратність здається, що це було б мінімальним.
  • Майте на увазі, що це повністю для резервного копіювання у разі відмови, а збій повинен бути зведений до мінімуму. Добре обробляти цей виняток, але врешті-решт, якщо сервер виходить з ладу, деякі дані втрачаються, а деякі гравці будуть засмучені. Тож просто застосуйте будь-який метод, який ви можете, будь-який, на вашу думку, найпростіший чи найкращий, і продовжуйте продовжувати.
  • Не покладайтеся на це як на збереження за замовчуванням; поставити в серверну програму гарну кнопку відключення, яка витончено закриває з'єднання і записує все в базу даних. Використовуйте це на звичайній основі.

Нарешті, не сприймайте цю пораду як абсолютну правду. Я не написав резервну систему для кількох гравців. Я працюю над «грою» в Інтернеті, саме тому я про це подумав і виклав свої думки вище, але я ще не дійшов до етапу реалізації цього. Отже, це написано без фактичного досвіду, але після численного читання та збору знань з даної теми.


4
З того, що я особисто спостерігав, комерційні ММО використовують комбінацію всіх трьох цих. Заощадження виникають після важливих подій та дій, таких як вбивства бойовиків / грабіж / торг, періодично для запобігання пропусканню некритичних дій (а також не покарання тих, хто ввійшов у систему протягом тривалого періоду часу), а також завжди виходив із системи. Одного єдиного методу, як правило, недостатньо. Майже всі ці методи покладаються на базову базу даних у стилі SQL, яка прозоро створюється в резервному копії та відновлюється, якщо є апаратні збої.
NtscCobalt

@NtscCobalt - Я був з вами до "бази даних у стилі SQL". Чи справді SQL є вимогою? А як щодо NoSQL?
beatgammit

@tjameson Ну мій коментар був написаний ще до того, як я торкнувся NoSQL. Я лише намагався сказати, що ви не повинні прокручувати свій власний формат, але все одно рекомендую SQL, оскільки ви повинні знати схему перед рукою (або бути ледачим і використовувати Entity-Key-Value), а послідовність важливіша за можливість розділення цих даних. Дивіться stackoverflow.com/questions/7339374/… для отримання додаткової інформації.
NtscCobalt

1

Я думаю, це залежить від типу гри, кількості трафіку між гравцями та сервером.

У MMORPG не було б сенсу зберігати позицію гравців кожного разу, коли вони надсилають інформацію на сервер. Було б більше сенсу оновлювати, коли поточні дані гравця "несвіжі", так би мовити. Також може бути корисно врятувати стан гравця на великих подіях, таких як перехід на нову територію, перемогу над босом або виїзд з магазину.

У покроковій грі, безумовно, має сенс зберегти стан гравця кожного разу, коли вони закінчують свою чергу, а також після черги суперника (збереження втрати здоров'я, ефектів заклинань тощо).

Знову ж таки, відповідь повністю залежить від масштабу та можливостей вашого сервера. Вся справа в пошуку найкращого балансу та максимальній оптимізації без шкоди для якості.


1

Якщо ви хвилюєтесь лише тоді, коли вони вийдуть із системи, тоді одна проста відповідь - зберегти свою позицію, коли будь-які умови для них більше не існують у ігровому світі (за рахунок виходу з системи або відключення).

Щодо бічної записки, я б трохи насторожився, коли клієнт звітує перед сервером про свою позицію або, принаймні, без якоїсь форми перевірки стану надійності сервера. Якщо у вас вже є таке місце, ви, ймовірно, можете зберегти цю позицію під час виходу з мережі або відключення, оскільки вам не доведеться турбуватися про отримання будь-яких даних від клієнта безпосередньо.


Так, отже, необхідність надсилати регулярні оновлення на сервер за такими значеннями, як позиція та XP. Чим довше ви залишаєте його, тим більш дискусійним стає питання про те, чи гравець насправді зібрав повідомлені дельти чи ні. Якщо ви обмежите ці часові періоди реєстрації, їх набагато простіше контролювати / контролювати.
Інженер

Проблема в тому, коли сказати, коли саме гравець вийшов із системи в тривалій браузерній грі, насправді не є дрібницею.
Ланбо

Я погоджуюся, що це нетривіально, але це проблема, з якою ви так чи інакше повинні вирішуватись у більшості ігор, навіть якщо тільки вирішити, коли їх аватар більше не з’являється. Як тільки це буде зроблено, слід зайнятися відносно простим питанням, щоб підключитися до цього сценарію і зберегти останню дійсну позицію.
Лунін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.