Я створив систему сутності для FPS. Це в основному працює так:
У нас є "світ" -об'єкт, який називається GameWorld. Тут міститься масив GameObject, а також масив ComponentManager.
GameObject містить масив компонентів. Він також забезпечує механізм подій, який дійсно простий. Самі компоненти можуть надсилати подію об'єкту, яка транслюється на всі компоненти.
Компонент - це щось таке, що надає GameObject певні властивості, а оскільки GameObject насправді є лише їх контейнером, все, що стосується ігрового об’єкта, відбувається в компонентах. Приклади включають ViewComponent, PhysicsComponent та LogicComponent. Якщо комунікація між ними потрібна, це можна зробити за допомогою подій.
ComponentManager - це просто інтерфейс, як Component, і для кожного класу Component, як правило, повинен бути один клас ComponentManager. Ці менеджери компонентів відповідають за створення компонентів та ініціалізацію їх із властивостями, прочитаними з чогось на зразок XML-файла.
ComponentManager також піклується про масове оновлення компонентів, як-от PhysicsComponent, де я буду використовувати зовнішню бібліотеку (яка робить все у світі відразу).
Для налаштування я буду використовувати фабрику для сутностей, які будуть читати або XML-файл, або сценарій, створювати компоненти, визначені у файлі (що також додає посилання на нього в правильному менеджері компонентів для масових оновлень), і потім введіть їх у об’єкт GameObject.
Зараз виникає моя проблема: я збираюся спробувати використовувати це для багатокористувацьких ігор. Я поняття не маю, як до цього підійти.
По-перше: які суб'єкти повинні мати клієнти з самого початку? Я повинен почати з того, щоб пояснити, як двигун для одного гравця визначав, які сутності створювати.
У редакторі рівнів можна створити "пензлі" та "сутності". Щітки призначені для таких речей, як стіни, підлога і стеля, в основному прості форми. Суб'єкти - це GameObject, про який я вам розповідав. Створюючи об'єкти в редакторі рівнів, ви можете вказати властивості для кожного з його компонентів. Ці властивості передаються безпосередньо на щось на зразок конструктора в сценарії сутності.
Коли ви зберігаєте рівень для завантаження двигуна, він розкладається на перелік об'єктів та пов'язані з ними властивості. Пензлики перетворюються на сутність "світової фарби".
Коли ви завантажуєте цей рівень, він просто інстанціює всі сутності. Звучить просто, так?
Зараз у зв'язку з мережевими структурами у мене виникають численні проблеми. По-перше, які сутності повинні існувати у клієнта з самого початку? Якщо припустити, що і сервер, і клієнт мають файл рівня, клієнт міг би також запрограмувати всі об'єкти на рівні, навіть якщо вони є тільки для цілей правил гри на сервері.
Інша можливість полягає в тому, що клієнт створює об'єкт, як тільки сервер надсилає інформацію про нього, і це означає, що клієнт матиме лише сутності, які йому потрібні.
Інше питання - як надіслати інформацію. Я думаю, що сервер міг би використовувати дельта-компресію, це означає, що він надсилає нову інформацію лише тоді, коли щось змінюється, а не надсилає знімок клієнту в кожен кадр. Хоча це означає, що сервер повинен слідкувати за тим, що кожен клієнт знає на даний момент.
І нарешті, як слід вводити мережу в двигун? Я думаю про компонент NetworkComponent, який вводиться в кожну сутність, яка повинна бути мережевою. Але як повинен мережевий компонент знати, які змінні в мережі та як отримати доступ до них, і нарешті, як відповідний мережевий компонент клієнта повинен знати, як змінити мережеві змінні?
У мене виникають величезні проблеми підходити до цього. Я був би дуже вдячний, якби ви мені допомогли в дорозі. Я відкритий для порад щодо вдосконалення дизайну компонентної системи, тому не бійтеся пропонувати це.