Ламаю стереотипи про GameMaker: Як я будую архітектуру гри під 8000 NPC (ECS vs OOP)

Всім привіт! Я TerraMedievale-Dev. І я роблю гру своєї мрії. Ви можете подумати: «О чергова історія де мрійник намагається зробити „Вбивцю ГТА“ де можна заходити в кожен будинок, а потім кидає коли не може закодити скроллбар?» Частково ви праві. У моїй грі дійсно можна буде заходити в кожен будинок 😀.

Але є нюанс. В мене за плечима 3 роки невдалих і кинутих проектів. Я пробував себе в різних жанрах Grand-Strategy, RPG. Де я дійсно брав на себе забагато, не розумів всю архітектуру, не було достатньо досвіду. Але тепер в мене достатньо досвіду для проекту такого масштабу.

Читайте далі і я вам ДОВЕДУ чому 8К НПС це можливо (з краплею магії оптимізації).

Важливо: Ця стаття — про архітектуру та плани. Я показую фундамент, на якому планую побудувати складну симуляцію. Зараз у білді немає тисяч юнітів чи готових замків. Це розповідь інженера про те, як підготувати ґрунт для амбітного проекту.

Що таке Terra Medievale

Terra Medievale — це 2D хардкорний симулятор життя в середньовіччі.

Головна фішка: світ живе без гравця.

Амбіція проекту: Створити симуляцію, де до 8000 НПС мають свої реальні потреби (Їсти, спати, пити), і вони їх дійсно задовольняють, а не лише імітують життя.

Гравець тут не обраний. У нього ті ж самі потреби що у лорда і селянина. Ці потреби це не рутина, щоб вам потрібно їсти кожні 3 секунди бо так потрібно, а філософія гри.

Моя філософія — Ефект Метелика:

  • Приклад: Сталася посуха > Мало врожаю > Лорд не знизив податки > Селяни збунтувалися > Гарнізон перебили > Сусідній лорд захоплює землі.

І ніхто вам не заважає бути цією «посухою» — наприклад спалити поля.

⚠️ Обережно: Далі трохи «підкапотної» магії!

Я розумію, що більшість з вас тут заради геймплейної сторони. Але я мушу пояснити технічну частину, щоб довести: чому 8000 живих НПС у фінальній версії — це не фантастика, а математика.
Якщо вам не цікаво читати про архітектуру пам’яті та оптимізацію — сміливо гортайте вниз до розділу «Структура Світу». Там ми поговоримо про замки, міста і економіку! 😀

Чому 8К НПС це можливо (ECS vs OOP)

Більшість скаже: «Сучасні ААА-ігри задихаються з 50 НПС імітаторами, а ти хочеш зробити 8К ще й з симуляцією життя? Твій процесор згорить»

І вони будуть праві... Якщо ми будемо дивитися з точки зору класичного ООП. В ООП це дійсно неможливо. Але з точки зору ECS (Entity, Component, System) — це не просто можливо, а вже працює (Згадайте Factorio де мільйони предметів їдуть на конвеєрах.

Я вже імплементував чисту ECS-архітектуру. Зараз вона керує інтерактивними об’єктами (Скрині та ін.) та рослинами (близько 20-50 сутностей), але оскільки це просто дані в масивах, масштабування до 8000 для процесора — це лінійна задача, а не експоненційна (як в ООП)

У чому секрет? Уявіть, що замість тисяч важких об’єктів, процесор обробляє просто суцільні масиви даних (немов колонки в Excel):

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

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

AoS (Array of Structures) — Якщо ми хочемо дістати значення X, то наша RAM має ще підгрузити Y, Z, таким чином 66% пропускної здатності пам’яті (Memory Bandwidth) витрачається на сміття, яке процесору зараз не потрібне

SoA (Structure of Array) — Ми просто беремо з глобального масиву значення X. 100% ефективність.

Дані згруповані не по об’єктах, а по Системах. Система Голоду завантажує тільки масив Голоду. Система Рендеру — тільки спрайти. Процесор не чекає, він просто працює.

Структура і Масштаб Світу: 1:1:3:8:40 (Політика та Логістика)

Я часто бачу в RPG дивну демографію: одне величезне місто і два маленькі хутори поруч. З економічної точки зору таке місто померло б з голоду за тиждень.

Тому я розробив математичну модель середньовічного розселення, яку буду реалізовувати. Ось запланована структура світу для фінальної версії,
(Примітка: Зараз світ існує на рівні базових механік. Ці локації — це моя дорожня карта на найближчі роки):

  1. Велике Місто (~2000 НПС) Аналог: Оксенфурт (Witcher 3) або Куттенберг (KCD2). Центр торгівлі, влади та ремісничих цехів. Тут крутяться найбільші гроші і найбрудніша політика.
  2. Монастир (~200 НПС) Аналог: Сазавський Монастир (KCD). Не варто знецінювати владу церкви. Це центр книгописання, медицини і знань. І так, якщо гравець захоче, він може постригтися в ченці і грати за монаха.
  3. 3 Містечка (~150 НПС кожне) Аналог: Сазава (KCD). Регіональні хаби. Менші за Місто, але мають свої ринки. Зазвичай залежні від феодала або церкви.
  4. 8 Замків (~100 НПС кожен) Військові бази. Тут може сидіти феодал, чернечий лицарьский орден або навіть барон-розбійник. Вони нічого не виробляють (окрім зброї і смерті), але є головними стовпами влади.
  5. 40 Селищ (~50 НПС кожне) Фундамент усього. Тут виробляється їжа, яку споживає вся мапа. Вони найбільш вразливі і завжди залежать від чийогось захисту.

Разом це дає ~5500 постійного населення. Решта до 8000 — це динамічні гарнізони, армії лордів, каравани та бандити, які наповнюють світ.

Щодо розмірів мапи: На релізі я планую безшовний регіон 1.5К х 1.5К тайлів з процедурною генерацією ландшафту.

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

Що вже зроблено

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

  • UI Framework: Я вбив 2 тижні лише на те, щоб закодити свій Скролбар 😂. Але це дало результат: тепер у мене є гнучка система інтерфейсу, яку легко редагувати і масштабувати.

  • Приклад зробленого Інвентарю (Повністю функціональний)
  • Інвентар: Система предметів, спорядження, ваги та стаків.
  • Навички (Skills): Система навичок, атрибутів і перків.
  • Землеробство: Повний цикл вирощування (від оранки до збору).
  • Ремесла (Crafting): Система рецептів і виробничих ланцюжків.

Що залишилося до Демки (Roadmap)

Мій план до релізу Демо чіткий:

  • Будівництво: Система розміщення стін та меблів (щоб НПС та гравець мали де спати).
  • Бойовка: Проста бойова система.
  • Штучний Інтелект (GOAP): Найважливіший етап. Навчити «болванчиків» користуватися всіма цими системами самостійно.
  • Візуал та Флейвор: Замінити «квадрати» на арт і додати атмосферні описи.

КОЛИ ДЕМО

Якщо вас зацікавила моя гра, у вас виникає логічне питання: «КОЛИ?». Я соло-розробник, і для мене це марафон, а не спринт. Я ставлю якість вище за швидкість, тому орієнтовна дата виходу публічної Демо — 2026 рік.

Чим Демо відрізнятиметься від повного Релізу? Це буде Vertical Slice (Вертикальний Зріз) гри:

  • Мапа: Замість процедурної генерації — один детально пророблений вручну регіон (1 Замок, 3 Села).
  • Геометрія: У демо світ поки що буде «плоским» (без Z-рівнів/висоти), щоб я міг сфокусуватися на відшліфуванні економіки та ШІ.

Але це не буде «обрізок» на 15 хвилин. Це буде повноцінна пісочниця з усіма основними системами (Крафт, Агрономія, Соціум). Демо буде безкоштовним, доступним завжди і отримуватиме оновлення механік паралельно з розробкою.

Стежте за розробкою

Якщо ви дочитали до кінця — значить, вам цікаві складні системи так само, як і мені.

Я запрошую вас у свій Discord-сервер. Там я буду:

  • Публікувати ексклюзивні скріншоти, які не потраплять у статті.
  • Радитися з вами щодо механік (ваша думка вплине на гру).
  • Набирати перших тестерів для закритих білдів.

👉 Приєднатися до Discord: discord.gg/DSvhXSsx6f

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини про геймдев

👍ПодобаєтьсяСподобалось12
До обраногоВ обраному3
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Створити симуляцію, де до 8000 НПС мають свої реальні потреби (Їсти, спати, пити), і вони їх дійсно задовольняють, а не лише імітують життя.

Як вже писали в коментарях, якщо це не самоціль то для емуляції живого світу немає сенсу обчислювати що їсть і скільки спить якийсь селянин на іншому континенті якого гравець можливо ніколи не побачить.
Наприклад в Космічних Рейнджерах 1-2 була ціла галактика з планетами, космічними станціями, кораблями, різними расами, фракціями, економікою, системою репутації та загальним агресором (клисани / домінатори). Але детально обчислювався та демонструвався у покроковому або реалтайм режимі тільки той сектор космосу де перебував гравець, а вся інша галактика розраховувалась по спрощеній системі: такий то сектор захоплений, такий то звільнений, ваш напарник рейнджер Лягуш загинув смертю хоробрих і таке інше..

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

Ви правильно зрозуміли. Звісно для реалізації такої кількості НПС, LoD-и необхідні. І вони імплементовані будуть. Але щоб одночасно в локації прогружати до 200 НПС (Котрі будуть деталізовано симулюватися), ECS система підходить прекрасно.

Дяка за цікаву статтю та проєкт!

Буде цікаво спостерігати за прогресом та фінальним результатом. Підписався на Дискорд)

Дякую! Підтримка це найкрайща нагорода за труди <3

Колоночні БД, очевидне рішення. Питання більше навіщо користувачу 8000 NPC? З більшістю яких він ніколи не буде взаємодіяти? По хвилині це вже 133 години, це вже достатньо багато часу. Якщо ставити питання побудувати всесвіт, де дія кожного з NPC трансформується у певну реакцію саме всесвіту на події, то це вже набагато складніший виклик, ніж 8000 NPC.

Для Вас очевидно завдяки вашому досвіду. А до мене лише через 3 роки прийшло розуміння) Тому вирішив поділитися з більш молодими, може комусь знадобиться.

В цій статті я вирішив сфокосуватися на технічному питанні гри. Щоб пояснити скептикам (Коли будуть), чому це можливо.

Мета гри це генератор історій, як Ви сказали «дія кожного з NPC трансформується у певну реакцію саме всесвіту на події». Але без правильної архітектури це було б неможливо.

Куди ж без караванів))

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

Але, у кожного свій шлях — то сил та наснаги!

а що ви маєте на увазі під «навпаки» на конкретному прикладі?

Якщо дуже скоротити все що можна сказати на цю тему і зосередитись на конкретному кейсі.

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

Проілюструю. Герой приїжджає у регіон, в котрому був неврожай та голод, собаки поїдають трупи, селища вимерли, тучи ворон... І приїжджає він туди заради чого? Шо він там буде робити? Щоб поїхати далі, туди де є хтось живий?

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

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

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

Цей етап вже був пройдений. Якщо коротко — Генератор Історій. НПС будуть взаємодіяти з світом і гравцем, а також його змінювати. Для гравця ж це висока кількість опцій взаємодії з НПС. Якщо Ви маєте на увазі ціль гравця, то тут опцій багато.

На самих ситуаціях не зосереджувався в статті бо вирішив зфокусуватись більше на масштабі проекту, бо хотів висвітлити саме технічну сторону. Чому це можливо і таке інше. Бо такий, наскільки я зрозумів, формат форуму.

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

Механіки і концепт в голові з’явилися достатньо давно. Це Генератор Історій, де НПС самі створять історію, а Ви можете за нею спостерігати, чи впливати напряму.

Але як вже казав. Реалізувати запланований мною масштаб без «важкого підходу» неможливо. Тому і я вирішив поділитися своїми нахідками, щоб іншим це допомогло.

66% пропускної здатності пам’яті (Memory Bandwidth) витрачається на сміття

Там не лише канал витрачається на сміття, яке до обчислень не має ніякого відношення. Там ще кеш-памʼять витрачається на сміття, що потребує частіше ходити в оперативну памʼять.

Я не знайомий з GameMaker. На якій мові ви пишете свій алгоритм? Якщо є можливість писати на Сі, або на С++, то є певні рекомендації як оптимізувати обчислення. Найкращі мануали, що я бачив — це Agner Fog: agner.org/optimize Подивіться на Vector class library — вона надає можливість

Modern CPU’s have Single Instruction Multiple Data (SIMD) instructions for handling vectors of multiple data elements in parallel.

тобто за один такт процесора обробляти 2, 4 або 8 елементів вашого глобального масиву X.

Цікаво було би подивитись на ваші бенчмарки.

Підписався на вас на ДОУ.

Як сказав інший коментатор в GM своя мова. Під капотом це C++. І лишається сподіватися що компілятор правильно Векторизує прості масиви. Але є розширення C++ DLL котре дозволяє писати на плюсах. Тому якщо рівень оптимізації буде не достатньо буде писати на плюсах, з котрими я знайомий)

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

звучить цікаво.
але візуальний інтерактив очікувати як від dwarf fortress?

Ні. В сучасному білді технічний візуал, фокусуюсь на механіках.

У Демці буде охайний та читабельний піксель-арт. Фінальна мета (К релізу) — рівень деталізації (High-End Pixel Art) і атмосфера як у Battle Brothers (Брудна і приземлена).

Погоджуюсь. Недооцінена імба :D

Гарно підмітили. Але рівень симуляції я планую зробити ще глибшим)

Підписатись на коментарі