Як написати мережеву гру? [зачинено]


73

Виходячи з того, чому так важко розробити MMO? :

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

Я знаю теорію про сокети, сервери, клієнти, протоколи, з'єднання та подібні речі.

Тепер мені цікаво, як можна навчитися писати мережеву гру:

  • Як збалансувати проблеми з навантаженням?
  • Як керувати ігровим станом?
  • Як зберегти речі синхронізованими?
  • Як захистити зв'язок і клієнта від зворотного проектування?
  • Як вирішити проблеми із затримкою?
  • Які речі слід обчислювати локально, а які - на сервері?
  • ...

Чи є хороші книги, навчальні посібники, сайти, цікаві статті чи інші питання щодо цього?

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


4
Так, є книги, навчальні посібники, веб-сайти, цікаві статті та інші питання щодо цього.
Ricket

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

Відповіді:


61

Окрім статті, що пов'язана з іншими відповідями, я можу трохи розповісти про досвід проекту « Аріанна» .

Як зберегти речі синхронізованими?

У нас є побудова рамки „ Marauroa “ навколо концепції дій та сприйняття: дії надсилаються від клієнта на сервер, на якому вводяться дані користувача (ходіть ліворуч, атакуйте монстрів №47, скажіть „привіт”). І сприйняття надсилаються з сервера до клієнтів, які розповідають про стан світу, що їх близько. Ці сприйняття надсилаються щоразу. Залежно від гри ми використовуємо час повороту від 30 мс до 300 мс.

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

Як вирішити проблеми із затримкою?

Ми твердо віримо в те, що "сервер завжди правий". Клієнт робить деякі прогнози, такі як плавна ходьба, перевірки зіткнень тощо. Але якщо клієнт і сервер не згодні з чимось, сервер виграє. Підпроект Stendhal (2D RPG) використовує час повороту 300 мс за замовчуванням (з великою кількістю вирівнювання зроблено на стороні клієнта). Це робить Стендаля дуже стійким проти відставання.

Примітка. Деякі інші ігри довіряють клієнтові певні можливості, щоб мінімізувати вплив відставання в мережі. У WoW його часто експлуатували на одному з бойових полів під назвою «Warsong Gulch». Гравець із прапором може вибрати два способи: у середині через тунель та праворуч, піднімаючись на гору. Тож гравець, який обманює, біжить до тунелю, а потім викликає відставання для себе. Сервер та інші клієнти продовжуватимуть бачити, як він біжить до нього. Але через невеликий час цей клієнт може сказати серверу, що він пішов у гору. WoW перевірить, чи відстань між останніми переданими координатами та поточними координатами відповідає часовому відрізку, і прийме це.

Використання UDP проти TCP

У ранніх версіях ми використовували UDP, щоб зменшити накладні витрати TCP. Ми впоралися із втраченими пакетами самостійно. Це прекрасно спрацювало в перші дні проекту. Але коли сервер був перенесений з якогось домашнього підключення DSL до реального центру обробки даних кілька років тому, у нас виникли величезні проблеми. UDP є (або, принаймні, 5 років тому) надзвичайно вимогливим до енергозабезпечення брандмауера процесора: Набір правил повинен застосовуватися до кожного пакету UDP. Однак для TCP набір правил застосовується лише для перших 3 пакетів. Після цього зв’язок встановлюється. Усі наступні пакети будуть обходити звичайний набір правил, тому що вони знаходяться у сполучній таблиці відстеження або тому, що у них немає прапора SYN.

Як захистити зв'язок і клієнта від зворотного проектування?

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

Легко захистити зв’язок від несанкціонованого нюху сторонніми особами за допомогою SSL.

Однак захистити його від зворотного проектування неможливо. Впевнені, що ви можете його притупити і використовувати методи налагодження. Зрештою, ви не можете запобігти зворотному проектуванню програмного забезпечення, яке ви даруєте користувачам. Існує дуже цікава презентація про те, як інженер Skype був розроблений, незважаючи на те, що розробники доклали багато зусиль до методів анти-налагодження: http://recon.cx/en/f/vskype-part1.pdf

Примітка. Є деякі країни, в яких зворотна інженерія є незаконною або дозволяють вводити абзац у ліцензію або ToS забороняє зворотну інженерію. Але є й інші країни (на зразок тієї, в якій я живу), які явно дозволяють зворотну інженерію в контексті розробки сумісних форматів зберігання даних або протоколів передачі, абзаців у ліцензії або ToS, які намагаються заборонити недійсні. (У цьому розділі все, наскільки я знаю, я не юрист)

Які речі слід обчислювати локально, а які - на сервері?

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

Прогнозовані події - це, наприклад, зупинка руху при зіткненні. Стендаль використовує сітку для позиціонування елементів. І з точки зору сервера, верхній лівий кут кожної сутності знаходиться рівно на одному квадраті. Але клієнт плавно перемістить їх між плитками. Це також намалюватиме псевдо 3d ефект. Таким чином, особа, яка має базу 1x1, може бути вище у клієнта.

Як збалансувати проблеми з навантаженням?

Постарайтеся зробити це максимально просто, щоб полегшити технічне обслуговування.

Балансування навантаження статичного контенту добре відоме в області кластерних серверів http та мереж розповсюдження контенту.

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

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

Деякі додаткові глобальні сервіси потрібні через: Під час входу клієнтам потрібно повідомити про підключення до правильного зонного сервера. І ви можете захотіти всесвітню систему чатів.

Я детально розглядав цю тему в розділі Як досягається балансування навантаження в ММО?


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

2
@Danny, Для ініціювання нового TCP-з'єднання потрібно три пакети: клієнт до сервера: SYN, сервер до клієнта: SYN ACK, клієнт до сервера: ACK + дані. Це на одну поїздку більше, ніж UDP, але це відбувається лише на самому початку, коли клієнт звертається до сервера вперше. У встановленому з'єднанні кожен пакет обробляється негайно без додаткових зворотних поїздок. Буде відповідь ACK, але отримані дані вже обробляються, поки пакети ACK повертаються назад.
Гендрік Бруммерман

1
@Danny, TCP обробляє втрати пакетів автоматично та досить ефективно. Важко повторити, що ти сам використовуєш UDP; за винятком випадків, коли ваш протокол не вподобаний із випадковими недоставленими пакетами. Наступна проблема полягає в тому, що TCP забезпечує порядок пакетів, тоді як пакети UDP можуть бути отримані в неправильному порядку. Знову ж таки, важко повторно реалізувати це, якщо ви не можете просто проігнорувати старіші пакети, наприклад на основі лічильника пакетів. Якщо для TCP потрібен дуже короткий час відповіді, алгоритм Nagle потрібно відключити.
Хендрік Бруммерман

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

27

http://gafferongames.com/networking-for-game-programmers/

Це великий набір статей з різних проблем та рішень, що стосуються ігрових мереж.


1
+1, але, будь ласка, не довіряйте їм сліпо. Наприклад, згідно з моїм досвідом, це не дуже гарна ідея використовувати UDP і винаходити функцію TCP. UPD корисний лише в тому випадку, якщо втрачені пакети взагалі не впливають, тобто кожен пакунок UDP містить повний відповідний стан світу. WoW використовує TCP, SL перебуває в процесі переходу від UDP до TCP (навіть HTTP для статичного вмісту) і значно покращила продуктивність за допомогою цих змін.
Гендрік Бруммерманн

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

2
Друге життя значно покращило продуктивність, переходячи від UDP до HTTP через TCP: blogs.secondlife.com/community/technology/blog/2010/08/13/…
Хендрік Браммерманн

5
Не так, вони покращили продуктивність потокового потоку активів, змінивши спосіб його роботи. Використання HTTP / TCP у цьому випадку полегшило їх реалізацію, не швидше. Я також можу зазначити, що zeromq - це цікавий проект, і він може дуже добре поєднуватися з ігровими мережами. zeromq.org
jsimmons

8

Залежно від типу гри, яку ви пишете, ви можете уникнути деяких мережевих програмувань низького рівня. Деякі види ігор не вимагають багато зворотнього зв'язку між клієнтами та сервером. У таких випадках можна вибрати рамку вищого рівня. Наприклад, я розробляю покрокову стратегічну гру в C # /. NET. Покрокові стратегічні ігри дещо унікальні тим, що переважна більшість комунікацій із клієнтом / сервером відбувається на початку та в кінці черги, порівняно мало між ними. Таким чином, я вирішив використовувати Фонд комунікацій Windows (WCF), комунікаційну систему високого рівня, розроблену головним чином для веб-служб. Замість того, щоб працювати безпосередньо з сокетами та всією цією мережевою рушницею низького рівня, я можу зробити те, що здається стандартним викликом методу, і нехай WCF займається протоколом і транспортними шарами для мене. Єдиний раз, коли мені довелося мати справу з низькорівневими мережевими речами, це було, коли я налаштовував свої кінцеві точки, що в значній мірі одноразова угода в конфігураційному файлі. Можливо, все-таки знадобиться реалізувати якусь власну логіку серіалізації, але вам потрібно робити таку річ незалежно.


8

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

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

(Зверніть увагу, що я розповідаю більше про MMO в оригінальному запитанні - "мережева гра" може означати всілякі речі від текстової гри на основі PHP аж до MMO, а вищезазначені підпитання не всі застосовуватись до кожного типу.)


7

Як збалансувати проблеми з навантаженням?

фіксований географічний розмір + кілька примірників є найпростішим рішенням. Хлопці, що працюють на SWG, спробували динамічний розмір і пошкодували його.

Як керувати ігровим станом?

Сервер є авторитетним.

Як зберегти речі синхронізованими?

Періодичні оновлення синхронізації з сервера. (не зовсім впевнений, що тут хвилює)

Як захистити зв'язок і клієнта від зворотного проектування?

Неможливо. просто переконайтеся, що ви не довіряєте нічому, що отримуєте від клієнта, і що сервер є авторитетним.

Як вирішити проблеми із затримкою?

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

Які речі слід обчислювати локально, а які - на сервері?

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

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


4

Це питання дуже широке. Це також дуже хитра область для освоєння, мережеві програмісти досить затребувані в галузі з відповідною оплатою, яка ніби вказує, що це "не вирішена" область. Є книги там, так, багато. Чи є там хороші книги, без сумніву. Чи є книги там, які дадуть відповіді на ваші запитання? ... Я не думаю, що так. Вони можуть мати рішення, які працюють у деяких ситуаціях або вказівки на те, на що звернути увагу, але майже всі ваші питання залежать від гри .... це сфера, де вам дійсно доведеться багато працювати самостійно, це так здається тривіально, і це може піти не так, як багато (неконтрольований) спосіб.

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