Як часто оновлювати Ігровий клієнт про світ?


10

Використовуючи socket.io , у мене є зв’язок, схожий на інші MMORPG, стійкий зв’язок із повідомленнями.

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

Було б кращою ідеєю "збирати" їх і транслювати, скажімо, раз у 1/10 секунди?

Крім того, чи повинен клієнт надсилати багато різних повідомлень (отримані досвіду, натиснуті на товар), як тільки вони з’являються, або скоріше лише одне зібране? Перше було б реалізовано простіше.

Відповіді:


16

Я підходжу до цього з обговорення на високому рівні, а потім працюю над вашими питаннями. Заради розкриття, у мене немає особистого досвіду використання socket.io, але дуже багато впливу на проблемний простір щодо MMORPG.

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

Як розробники MMORPG, ми плануємо великий успіх (часто також відомий як катастрофічний успіх), коли велика кількість спрацьовує попереджувальних ламп та сирен. Одне із страшно великого числа, яке з'являється, полягає в алгоритмах, які мають N-квадрат (далі N ^ 2), у вашому питанні перше, що вискочило для мене, це те, що це звучало як дизайн, який вимагає від суб'єкта господарювання передавати інформацію до всі інші пов'язані об'єкти. Це класичний приклад задачі N ^ 2.

ЗМО зазвичай підходять до вирішення N ^ 2 питань шляхом атаки на проблему декількома різними способами; системи обізнаності (ситуаційні, просторові тощо), коли суб'єкт господарювання обізнаний про деякий підмножина всіх інших об'єктів, розподіляє гравців на різні "осколки", розподіляє гравців на "зони" та / або інстанціює, застосовуючи ігрову механіку, яка відбиває занадто багато гравці разом збираються (шторми телепорту Asheron Call) тощо.

Більшість MMORPG та багато FPS двигунів мають досить складну мережеву архітектуру, яка підтримує різноманітні функції, зокрема:

  • надійні та ненадійні комунікаційні шляхи (TCP, спеціальна реалізація надійних пакетів UDP та UDP)
  • формування пропускної здатності (пріоритетність, тривалість життя тощо)
  • автоматична реплікація польових / життєздатних викликів даних та функцій
  • атомні набори даних (тобто дані, які передаються разом)
  • дискретні оновлення (тобто, де важливий кожен перехід)
  • корекція затримки
  • різноманітні хитрощі, щоб клієнт почував себе чуйним

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

Отже, тепер давайте підійдемо до питань.

Було б кращою ідеєю "збирати" їх і транслювати, скажімо, раз у 1/10 секунди?

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

Клієнт для MMORPG і FPS ігор, як правило, розроблений таким чином, що вони візуалізують щось, що "виглядає" правильно, навіть якщо вони не отримують оновлення для набагато більше кадрів оновлення, ніж це "нормально". Використовуючи ненадійну комунікацію (UDP), ви можете просто розраховувати втратити деяку кількість оновлень у порожнечу, клієнти можуть компенсувати це, надсилаючи більш часті оновлення, ніж це може бути використано при надійному транспорті.

З короткого огляду документації на socket.io, схоже, вона підтримує надійні та ненадійні (нестабільні у своїй термінології) шляхи зв'язку.

Я б підійшов до цього спочатку, вирішивши, на якій частоті потрібні оновлення ...

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

Незважаючи ні на що, мабуть, не потрібно (як правило) надсилати оновлення кожного кадру від клієнта на сервер. Сам сервер може вирішити надсилати повідомлення кожному кадру там, де він є, або затримувати їх (див. Формування пропускної здатності, встановлення пріоритетів та час оновлення).

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

чи повинен клієнт надсилати багато різних повідомлень (отримані досвіду, натиснуті на товар), як тільки вони з’являються, а точніше лише одне зібране?

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

Збір повідомлень для певного об'єкта, що надсилається як одне повідомлення, може (залежно від реалізації) зменшити накладні витрати на передачу повідомлення (зменшити ваші витрати) навпаки (залежно від реалізації, наприклад, відображення поля / значення, передані рядками), може збільшити пропускну здатність. вимоги порівняно з більш простим конкретним типом повідомлення.

Переглядаючи документацію на socket.io, мені здається, що накладні повідомлення знаходяться на верхньому кінці спектру, що сприятиме збору оновлень для надсилання у вигляді сукупного повідомлення на відміну від безлічі одиничних оновлень.

Я рекомендую переглянути всі оновлення, про які ви плануєте реплікувати, наприклад, більшість MMORPG та FPS не намагаються надсилати гравця, натиснутого на X події, спостереженням за клієнтами, якщо це не призведе до зміни стану об'єкта, про який вони також знали. .


3
+1 Відмінна відповідь. Я б також запропонував почати просто і оптимізувати звідти. Незважаючи на спам-повідомлення, дивіться і бачите, що пропускна здатність починає чіткіше. Ось чому добре пройти поетапне стрес-тестування. Ви реалізовуєте найактивніший підхід і робите тестування; Ви робите деякі оптимізації; ви знову стрес-тест, ви додатково оптимізуєте, промиєте, повторите. Якщо в перший день реально оптимізувати оптимізацію, продовжуйте роботу; але майте на увазі, що навіть самі тривіальні оптимізації можуть мати припущення, які згодом можуть бути спростовані у виробничих умовах.
Інженер

5

Ось приклад із реального світу: RuneScape "тикає" раз на 0,6 секунди. Про це можна прочитати тут . Я думаю, що це спрощує речі з їхньої точки зору, оскільки в їхніх сценаріях вони, ймовірно, вказують таймінги та затримки в тиках замість мілісекунд. І звичайно, при такій великій / повільній ставці галочок користувачі з повільним зв’язком не знаходяться у величезному недоліку порівняно з іншими гравцями.


0

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

О, і зазвичай ви не надсилаєте анімаційні кадри на сервер чи інші клієнти. Точний стан анімації зазвичай вважається детальною презентацією та залишається кожному клієнту для вирішення, і натомість ви просто переконайтеся, що кожен клієнт знає, яка анімація в даний час відтворюється.


Я б не став? А щодо поз чи чогось, я повинен бути впевнений, що всі клієнти бачать однакове?
Ланбо

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