Правда чи вигадка? Розвінчуємо три основних міфи про неткод
Створити й випустити мультиплеєрну гру — доволі непросте завдання. Часто для цього потрібно більше часу, ніж для однокористувацьких ігор, адже треба подбати про синхронізацію з іншими гравцями та створити цілісну спільну реальність.
Один з ключових елементів розробки мультиплеєра — неткод. Він обробляє усі «що» і «як» під час взаємодії гравців із сервером. Водночас сам термін «netcode» має погану славу — його нерідко вважають причиною затримок і проблем у багатокористувацьких іграх. Публікуємо переклад блогу Unity про те, які стереотипи пов’язані з неткодом і що з них правда, а що вигадка. Також ці твердження прокоментував Віктор Антоненко, Unity Lead у продуктовій компанії OBRIO.
Що таке неткод
Неткод — це сукупний термін, яким позначають усі частини гри, що обробляють мережеву взаємодію та синхронізацію між клієнтами та серверами.
У багатокористувацькій грі сервери та клієнти взаємодіють через надсилання пакетів мережею. Геймери мають перебувати у спільній реальності, де події на кшталт переміщення об’єктів повністю синхронізовані. Для цього й надсилаються пакети. Частина, що відповідає за їхнє отримання та надсилання, називається транспортом.
Можна надсилати пакети вручну — через виклик функції відправки для прямого транспортування. Але це може бути складно для розробників, які не мають багато досвіду в розробці мультиплеєрних ігор або застосунків.
Неткод-бібліотека абстрагує надсилання пакетів від геймплейного рівня. Для цього вона використовує мережеві змінні та RPC-виклики (Remote Procedure Calls).
Unity має два офіційних неткод-пакети: Netcode for GameObjects (передрелізна версія) і Netcode for Entities (експериментальна).
«Також можна знайти готові рішення, наприклад, в багатьох іграх використовують Photon, який я можу порадити», — додає Віктор Антоненко.
Три поширені міфи про неткод vs реальні факти
1. «Ми завжди можемо додати мультиплеєр пізніше»
✅ Факт: мультиплеєр може бути складним у реалізації. Варто враховувати багатокористувацький режим якомога раніше — з погляду розробки та проєктування архітектури гри.
Чому? Мультиплеєр зачіпає майже всі аспекти ігрового процесу, тож він впливає і на розробку гри. Наприклад, у вас є однокористувацька гра і система інвентарю для неї. Для багатокористувацького режиму треба буде синхронізувати всі предмети інвентарю з сервером.
Є багато таких речей, що досить легко втілюються в одиночній грі й перетворюються на проблему для мультиплеєра.
Ви колись замислювались про те, чому в більшості багатокористувацьких ігор діють кінематичні контролери персонажів і фізична взаємодія мінімальна? Тому що імплементація фізичних розрахунків, які працювали б для всіх гравців одночасно, занадто ресурсоємна. З цим нелегко впоратись навіть дуже досвідченим розробникам.
Порада: не забудьте заздалегідь перевірити, чи всі ваші функції сумісні з мультиплеєром, особливо якщо в грі є унікальні механіки, які рідко трапляються в іграх.
«Це дуже абстрактна порада, теоретично, все можна зробити мультиплеєрним, правильно спроєктувавши. Питання завжди в часі», — додає Віктор Антоненко.
Хорошим прикладом тут може слугувати досвід Soaring Pixels Games: вони детально розповіли, як із самого початку додавали багатокористувацький режим у гру Breakwaters і чому це було так важливо.
2. «Що менша затримка, то краще»
✅ Факт: низька затримка справді важлива для безперебійної роботи, але не менш важливо подбати про стабільність гри. Синхронізація станів для спільного ігрового світу може потребувати дрібки часу, і гравці цього навіть не помітять.
Чому? Важливо зробити гру плавною та послідовною, а це не завжди означає мінімальну затримку.
«Я не згоден з цим твердженням. Є ігри, в яких низька затримка є ключовим моментом і втратою пакетів можна пожертвувати заради швидкості обробки даних. Наприклад, у шутерах обробка пакетів часто відбувається через UDP — тому що не так важливо обчислити кожен фрейм користувача, як швидко обробляти все, що ввів гравець, і надсилати йому відповідь на його дії, а розсинхронізація відновиться наступним повідомленням.
В інших жанрах, де не така важлива швидкість реакції гравця, набагато корисніше тримати синхронізацію ігрових станів, наприклад у покрокових стратегіях, де для всіх гравців для кожного ходу важливо мати одні й ті ж дані. Але не така важлива швидкість обміну повідомленнями. Тому я вважаю, що тут кожен сам вибирає, який підхід для його гри кращий», — каже Віктор Антоненко.
Найбільш поширеною технікою для збереження плавності гри є буферизація. Отримані з мережі пакети обробляються не негайно, а почергово. Під час кожного виклику оновлення даних гри клієнт бере один елемент із черги, намагаючись зберігати розмір черги буферизованих елементів.
Тож коли сервер надсилатиме один пакет за тикрейт, клієнт також оброблятиме один пакет за цей період.
Але чому це потрібно? Хіба клієнт не буде отримувати лише один пакет за тикрейт, якщо оброблятиме всі вхідні дані відразу? За ідеальних мережевих умов це справді так, але під час передачі пакетів мережею трапляються затримки.
Таке коливання затримки пакетів називається джитером. Метод буферизації збільшує затримки в грі, але зменшує джитер. Через це гра працює плавно й синхронізовано.
Приклад: часто у файтингах потрібно швидко натиснути комбінацію кнопок у певному ритмі, щоб персонаж виконав конкретну дію. Гравці запам’ятовують ці комбінації на м’язовому рівні та виконують їх знову й знову. Тож важливо, щоб дії у грі відповідали тому, що вводить гравець.
То як цьому дають раду розробники файтингів? Вони роблять так, щоб вхідні дані оброблялися з фіксованою швидкістю, а потім буферизувались. Тоді те, що ввели гравці, поступово переходить в ігровий фрейм. Середня затримка для введення даних збільшується, але гра працює синхронно для всіх гравців.
Додаткова буферизація сприяє плавності гри, але інколи затримка стає надто великою і гравцям здається, що гра не реагує на їхні дії. Тому існують техніки, які компенсують цю затримку під час буферизації.
Наприклад, для гри на клієнті дані локального користувача обробляються негайно. Тож для його персонажа затримка мінімальна, тим часом дії ворогів буферизуються і показуються плавніше.
Хоча для гравців такий підхід може здаватись непоганим, він іноді спричиняє проблеми, оскільки значно полегшує читерство.
Для ігор з компетативною складовою можна застосувати техніку, яка називається прогнозуванням на стороні клієнта (client-side prediction). Дії локального гравця обробляються негайно, але водночас сервер обчислює дії інших гравців (через ті ж вхідні дані) та перевіряє, чи виконав клієнт правильний хід, і вносить виправлення, якщо це потрібно.
3. «Пропускна здатність безкоштовна»
✅ Факт: Пропускна здатність не безкоштовна, її вартість може змінюватись залежно від регіону, і в деяких регіонах вона значно дорожча, ніж в інших.
Чому? Приватні контракти на широкосмуговий доступ, як правило, досить дешеві, якщо порівняти з вартістю для комерційних серверів. Ви платите мало, тому що більшість людей використовує частину своєї пропускної здатності, і то не завжди.
Комерційні ж сервери бувають дуже різними. Зазвичай вони працюють більшу частину доби, а ігрові сервери можуть підтримувати трафік для сотень або тисяч гравців одночасно. Тому хостингові компанії нерідко стягують плату за використані гігабайти.
Це означає, що вам варто економити трафік, це допоможе знизити операційні витрати й полегшить життя гравцям із повільним з’єднанням.
Впевнено розробляйте свою багатокористувацьку гру
Створення мультиплеєрної гри — це не просте, але вкрай захопливе заняття. Ви можете створювати наступний хіт Battle Royale чи затишну кооперативну онлайн-гру — та все одно маєте розуміти нюанси багатокористувацьких мереж.
Щоб дізнатися більше про підводні камені неткоду, можна завантажити електронну книгу Unity та ознайомитись з іншими статтями й документацією на цю тему.
«Також раджу ознайомитись зі статями, присвяченими протоколам TCP та UDP, які будуть корисними для розробки мультиплеєру і допоможуть збалансувати швидкість і стабільність ігор», — каже Віктор Антоненко.
Немає коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів