Програміст S.T.A.L.K.E.R. 2 — про розробку рушіїв з нуля, унікальні рішення в Survarium та службу в теробороні
Дмитро Ясєнєв — Lead Programmer у GSC Game World, який захопився розробкою ігор ще у
«Ігри я почав робити від початку ознайомлення з програмуванням». Про перші розробки у 90-х
За освітою я кібернетик. Думаю, що обрав цю спеціальність через батьків. Вони закінчили факультет кібернетики, і в дитинстві я не розумів, про що вони говорять, але хотів дізнатися, що ж усі ці слова означають. Можливо, це і підштовхнуло до вибору такої освіти.
Ще часом батько брав мене на роботу, де ми грали в «Танчики»
Пам’ятаю, у
«В університеті дехто програмував на Асемблері, проте я продовжував використовувати Pascal»
А у
В університеті дехто програмував на Асемблері, проте я продовжував використовувати Pascal, з яким працював ще в ліцеї «Наукова Зміна». Втім хлопці на факультеті розповіли про переваги С++, і я вирішив спробувати.
Життя склалося так, що ігри я почав робити від початку ознайомлення з програмуванням, бо це було цікаво. Наприклад, вперше зі штучним інтелектом я стикнувся через гру Filler. За правилами один гравець стартує в лівому куті поля, інший — в правому. Ціль — захопити якомога більше клітинок поля, пофарбувавши їх у ваш колір. Я вирішив «написати» супротивника. Тоді не було, де загуглити підказки, тож я тішився, що своїм розумом дійшов до потрібного алгоритму. Щоправда, потім виявилося, що його ще у
Потім я зайнявся грою «Реверсі», яка схожа до шахів, але трохи простіша. Я грав у неї онлайн, але не міг пройти далі певного рейтингу. Гра здалася мені простою, тож я думав, що швидко напишу програму, яка всіх обіграє (бо можна було використати той самий алгоритм з Filler). Моя програма вигравала у 95% гравців. Зрештою один з модераторів платформи, де я грав, по-перше, попередив, що використовувати програми для змагань з реальними гравцями заборонено, а по-друге, підказав мені, де знайти розробки, подібні до моєї, але світового рівня. Так я заглибився в тему ще більше.
«Коли я прийшов на проєкт, там працювали троє людей». Про роботу над S.T.A.L.K.E.R.
Саме програму для «Реверсі» я приніс до GSC Game World, коли влаштовувався туди на посаду програміста штучного інтелекту. З моєю розробкою та потужною технікою компанії нам навіть вдалося виграти у найсильніших програм під час своєрідного чемпіонату світу. У студії був класний сервер, два процесори, що було рідкістю для початку
Я радів, що зміг потрапити в GSC. Тоді компанія вже була відома — випустила «Козаки». Я пишався тим, що Україна робить ігри світового рівня.
Спочатку я був на проєкті Oblivion Lost. Ті, хто цікавиться S.T.A.L.K.E.R., знають, що на виставку Е3 2002 відвезли рівень з цієї гри. Новаторство було в тому, що рослин на той момент в іграх не було. А в розробці GSC було багато трави й дерев. Цим команда привернула до себе увагу. Річ у тім, що в ті роки нове покоління комп’ютерів відкривало можливості, які рушії, створені для попереднього покоління, не могли використати. І, звичайно, майстерність наших програмістів — Олеся Шишковцова та Олександра Максимчука, які потім створили 4A Games, — зіграла роль.
Про розробку S.T.A.L.K.E.R., яка відома усім, оголосили згодом (від Oblivion Lost відмовилися у 2002, концепцію гри змінили й перенесли дію до Чорнобильської зони відчуження — ред.).
Коли я прийшов на проєкт, там працювали троє людей: двоє вже згаданих програмістів і моделер Сергій Кармальський. Здебільшого команда тоді розробляла власний рушій XRay, а не саму гру (у
Саме геймплей-програмуванням у S.T.A.L.K.E.R. я майже не займався. Коли я приєднався, розробка рушія була в самому розпалі. Основне, над чим я працював і що вдалося зробити, це симуляції життя, pathfinding і створення «мапи», за якою можна було шукати шляхи, розрахунок «прикритості» локацій від певних напрямків, що використовувалося NPC під час бою. Тобто все оберталося довкола штучного інтелекту.
Коли ж я став ведучим програмістом, довелося влазити й в інші підсистеми, хоча я й не горів бажанням. Тоді був вимушений розбиратися з усім: фізикою, рендером, редактором, collision тощо.
«Коли у
З 2006 року потрібно було зробити так, щоб S.T.A.L.K.E.R. врешті вийшов. Тому в той період довелося виправляти багато багів, один за одним, аналізувати, чому вони взагалі виникають. Я доробляв системи, які допомагали виводити так званий stack trace — послідовність викликів функцій, яка призвела до збоїв. Це давало бодай якусь інформацію. Потім я записував minidumps — знімки моменту, коли ставався збій. Їх можна було відкривати у Visual Studio й дивитися або деякі змінні, або й усе, що доступно.
А коли у
«Ніде немає того, що ми зробили у Survarium». Про унікальні рішення команди Vostok Games і найбільшу проблему free-to-play шутерів
У 2012 році я почав працювати у Vostok Games як Lead Programmer. Тоді ми запустили розробку Survarium. І знову команда взялася створювати власний рушій — тепер під назвою Vostok Engine. Одним з найбільших викликів тоді виявилася робота з багатопотоковістю й асинхронністю.
Річ у тім, що, коли у вас одночасно можуть виконуватися кілька потоків, необхідна певна синхронізація. Інакше все впаде. Щоб уникнути проблем, зазвичай використовують так звані примітиви синхронізації, але це рішення не завжди підходить. Програма не буде падати, але вона й не буде використовувати всі ядра, якщо потоки будуть час від часу чекати один одного. Також такий підхід не захищає від deadlock-ів. Щоб обійти цю проблему, використовують lockless programming. Але написати багатопотоковий код з таким підходом вкрай непросто. Можна написати три рядки й дебажити їх три тижні.
Оскільки Survarium — це free-to-play шутер, там важлива мережева синхронізація. Яка виникає проблема у гравця в грі такого жанру? Ви чітко бачите супротивника, цілитеся, стріляєте, а сервер вам фіксує промах. Наша команда розробила унікальне рішення, щоб гравці поменше нервували через це. На мій погляд, це і досі найбільш ультимативне рішення, яке дає максимальний комфорт при мережевій грі. І це при тому, що цією проблемою займаються всі ігрові компанії. Я ж стверджую, що наше рішення краще, ніж в таких іграх, як Call of Duty, Battlefield, Counter-Strike, Overwatch, Valorant, PUBG тощо.
«Гравці залежать від пінгів одне одного. Наш підхід мінімізує цю залежність»
Як геймдев-розробники роблять зазвичай? На екрані користувача має бути приблизно така сама картинка, яка буде на сервері, коли той розраховуватиме, хто в кого влучив, а хто ні. І оце «приблизно» стає проблемою. Пінг до сервера не нульовий, ще є пінг до іншого гравця, тобто час минає і стається те, що стається. Гравці залежать від пінгів одне одного. Наш підхід мінімізує цю залежність.
Бо ми зробили не приблизно, а максимально точно. Якщо немає мережевих перешкод, у конкретний момент часу гравець бачить рівно те, що буде на сервері під час розрахунків. Тобто це буде відбуватися на сервері потім, а не просто зараз. Якщо ще більш точно: в один і той самий момент реального часу ігровий час на комп’ютерах клієнтів і сервера різний і залежить від пінгу кожного клієнта, сервер іде позаду клієнтів, наче лангольєр — все, до чого він «доторкнеться», стає історією і вже не буде змінено.
Цього неабияк складно досягти на різних платформах. Побітова рівність перестає виконуватися, якщо у вас хоч трохи відрізняються процесори. Тому й виходить: коли ви тільки починали стріляти, ви вже були мертві, але ще не знали цього, бо сервер не встиг вам надіслати інформацію. Ця проблема, на жаль, залишається і при нашому підході, але це чи не єдина проблема мережевої синхронізації, яку не вдається та й ніколи не вдасться усунути, бо це закладено в природі цієї задачі.
Мій батько наводив класну аналогію для цього випадку. Уявіть, що ви дивитеся на небо, де є зірки. В цей момент ви бачите картину, яка ніколи не існувала, бо світло від зірок іде рокам. Тобто йдеться про різницю в мільйони світлових років. Ви можете бачити на небі зірки, які майже ніколи одночасно не існували. Приблизно так само і в мережевій синхронізації. Ви бачите картину, якої ніколи не існувало саме тому, що час, який потрібен, аби сигнал дійшов від клієнта до сервера, а потім до вас — це... час. Навіть у реальному світі це неможливо, бо світло не нескінченно швидке, але в цьому разі просто затримка є мінімальною. А коли граєте в такі ігри, це відчутно.
Звісно, повністю «вимкнути» нерви користувачів не вдається, але мінімізувати такі ситуації можливо. Мої колеги, які багато грають в мережеві ігри, кажуть, у що б не грали — Overwatch, Call of Duty абощо — ніде немає того, що ми зробили у Survarium. Бо наш підхід був складний, втім ефективний. Survarium мав pixel perfect correctness + server side hit detection. Звичайні ігри мають або одне, або інше. Зазвичай ігри мають перше, але не друге, що дає неймовірну можливість для читів, які можуть змінювати правила гри. В Survarium це було принципово неможливо. І друге: сервер був неймовірно ефективний.
«Я бачу, що наш підхід вже почали використовувати для 2D-ігор, втім у рушіях на кшталт Unreal Engine такого немає»
Сервер стандартної конфігурації міг підтримувати тисячі клієнтів при tickrate 20, причому це не одне й те саме, що tickrate Battlefield, бо, наприклад, кулі мали tickrate 1000. 20 стосувалося суто переміщення гравців. Клієнт з часом став не менш ефективним, ніж сервер, що було для нас подивом, бо ми вважали ефективність клієнта слабким місцем. Крім цього, клієнт мав чудові можливості, яких бракує звичайним підходам: ми могли відмотувати час, показувати, що трапилося, від іншої особи, а це корисно для killcam-камери, яка демонструє, як і хто вас вбив вже після смерті при очікуванні на нове народження. Такої якості killcam немає в жодному іншому шутері досі.
Хоча я пригадую один момент, який ледь не звів нас з розуму під час цієї розробки. Ми підготували мережеву синхронізацію на комп’ютерах в офісі, і всюди вона працювала коректно, крім одного ПК. П’ять хвилин минає, а гравець за цим ПК з місця посунутися не може. Здавалося, ніби він постійно надсилає сигнали в майбутньому часі. Які варіанти ми тільки не перебрали, поки не зрозуміли, що на цьому комп’ютері час ішов швидше, ніж на сервері — на одну секунду за хвилину. Саме ця різна швидкість плину часу і давала дивний результат. Таких приколів було багато.
На жаль, Survarium не став комерційно успішною грою, у травні
«Рушій потрохи, але стає чимось другорядним». Про глобалізацію на ринку рушіїв та її вплив на вигляд ігор
Не скажу, що я багато «пересідав» з рушія на рушій. Після трьох власних рушіїв я працював ще з Unreal Engine і трошки з Unigine. Але я скептично ставлюся до великих рушіїв, тому що, знаючи, як їх можна зробити з нуля, не завжди тішишся компромісам, на які пішли автори розробок.
Ми створювали рушій для конкретної гри, тому він був для неї зручний. А Unreal Engine — це рушій для всього, тому для кожної гри він не буде максимально зручним.
Зараз S.T.A.L.K.E.R. 2 готують на Unreal Engine 5, і я бачу, що йому бракує того, що ми колись робили на своїх платформах. Чомусь розробники вирішили нічого особливо не робити з тим, що, коли на проєкті працюють багато людей, кожен з них вносить певні зміни в нього, і Unreal Engine не дозволяє об’єднати ці зміни. Зрештою комусь доводиться переробляти свою частину, якщо він вніс зміни не останнім.
Автори рушія намагаються розв’язувати проблему тим, що розбили всі об’єкти на рівні — кожен зберігається в окремий файл. Та якщо у вас великий проєкт, це мільйони файлів. Від цього страждає все: система контролю версій, файлова система, підвищуються вимоги до комп’ютера розробника.
Чому вони не подумали виконати це в текстовому форматі, який мерджиться? Йдеться про класний текстовий формат і утиліту для мерджу, побудовану на основі вже наявних. Таке поєднання, впевнений, повністю розв’язує проблему недружніх до мерджу форматів Unreal Engine та й інших рушіїв. Причому в Unreal Engine робили кроки в цей бік, але так і не доробили досі. Ми так вчинили у Survarium. Так, це не простий текстовий формат, але це реально втілити.
«Раніше створювали власні рушії, щоб візуально відрізнятися. А тепер Physically based rendering дозволяє отримати картинку, яку важко відрізнити від фотографії»
При цьому Unreal Engine використовують усе частіше, бо йдеться про глобалізацію. У ньому багато що вже зроблено, а що далі розвивається ігрова індустрія, то складніше створювати рушій з нуля.
Зазвичай компаніям простіше трохи заплатити й скористатися вже готовою технологією Nanite (система віртуалізованої геометрії, яка використовує новий внутрішній формат мешів і технологію рендерингу для візуалізації деталей у масштабі пікселів і більшої кількості об’єктів. Вона працює лише з тими деталями, які можна побачити, має автоматичний рівень деталізації — ред.). Це рішення спеціалісти Epic Games розробляли сім років. То навіщо вигадувати щось своє? Найімовірніше, компанія отримає в результаті проєкт, який виглядатиме не так гарно, як у конкурентів, та ще й до релізу вони йтимуть довше.
Раніше створювали власні рушії, щоб якраз візуально відрізнятися. А тепер Physically based rendering дозволяє отримати картинку, яку важко відрізнити від фотографії. Втім те, якими будуть ігри, врешті-решт залежить від розробника. Одні можуть погано застосувати навіть такий потужний інструмент, який у них є в руках, а інші, навпаки, з гіршими технологіями досягти більшого.
Рушій потрохи, але стає чимось другорядним. Frostbite, Unreal, Unity — у всіх красива картинка. Я розраховую на те, що в майбутньому ігри будуть настільки деталізовані, що, граючи у VR-окулярах, ви навряд чи зможете відрізнити картинку від того, що бачите на відео з GoPro-камери.
Маю надію, що колись буде open-source рушій, який в різний спосіб можна буде розвивати. Я, наприклад, хотів би втілити свій досвід у розробці багатопотокових асинхронних систем десь ще, а не зупинятися лише на тому, що ми втілили у Survarium. Але наразі, на жаль, розробники рушіїв не хочуть публікувати код.
«Є компанії, в яких вам дозволяють працювати з челенджами, а є такі, що від них ухиляються». Про «перерву» від геймдеву та причини повернення до GSC
Я пропрацював у GSC сумарно понад 12 років. Ще майже сім — у Vostok Games, де був одним зі співзасновників, а команда складалася здебільшого з вихідців із GSC. Я стільки років не змінював студії, бо є компанії, в яких вам дозволяють працювати з челенджами, а є такі, що від них ухиляються. І я така людина, яка, по-перше, любить виклики, а по-друге, мені вдається з певною періодичністю їх розв’язувати. Тому все збіглося.
Водночас, поки я багато років працював в одних і тих самих компаніях, я взагалі не дивився на ринок програмістів. Я не знав, скільки люди заробляють, і не вірив у цифри, що мені озвучували знайомі. А коли стикнувся з цим на практиці (після того, як мені довелося покинути Vostok Games), здивувався. Компанії хантили мене одна за одною, і щоразу це відбувалося з підвищенням зарплати. Тобто виходить, що з фінансової точки зору вам до певної межі вигідно переходити з компанії в компанію.
«За час „перерви“ від геймдеву я пропрацював у двох IT-компаніях. Але мені бракувало викликів»
Але я не прихильник такого, й мені було не дуже приємно, коли я звільнявся, відпрацювавши всього кілька місяців (я не протистояв черговому хантингу тому, що мені не дуже цікаво було працювати в класичних IT-проєктах). Чому вважаю такий підхід не зовсім слушним? Бо компанія витрачає кошти на онбординг, на навчання кожного нового спеціаліста. І якщо ви йдете, не пропрацювавши навіть пів року, вона, ймовірно, навіть не встигає «відбити» гроші, що у вас вклала.
За час «перерви» від геймдеву я пропрацював у двох IT-компаніях. Але мені бракувало викликів. Певно, найкращою з фінансового погляду і найцікавішою з огляду на виклики виявилася американська MemSQL. Команда розробляла власний SQL Engine. Це нова галузь, робота з Linux, я ніколи до того не працював з Docker-контейнерами. Але це software development, заснований на тестингу. Коли ви вносите одну зміну, то не можете перейти до наступного етапу, доки не перевірите своє рішення. Крім того, ви ще самі маєте написати ці тести. Класна практика — я побачив, як круто можна це робити. Але я звик працювати швидко, а тут так не виходило. Йшлося про сотню тисяч тестів лише на рушій.
Я розумів, що більше досвіду можу використати на проєкті на кшталт S.T.A.L.K.E.R. 2. Насправді мене запрошували повернутися ще у
Звісно, можна було б задуматися про релокацію і закордонну геймдев-компанію, не ставати частиною GSC знову, у
«Хороше командне рішення — теж ваше, бо ви частина цієї команди». Про різницю між посадами Programmer і Lead Programmer і пошук нових ідей
Сьогодні я знову Lead Programmer у GSC. З досвіду можу сказати, що, коли ти на лід-посаді, потрібно навчитися бути менш авторитарним. Навчитися слухати людей. Зрештою, ви не можете знати всього, з чим доведеться стикнутися в ролі лід-програміста, бо неможливо мати досвід з усім. Через це вам неминуче знадобиться допомога інших. Тож не варто нав’язувати усім власну думку. Навіть якщо у 90% вона буде правильна, ви можете втратити ті 10%, які відберуть на пошук рішення купу часу.
Мені згадану навичку довелося в собі розвивати. Бо я така людина, яка більше орієнтується на власні рішення. Але неодноразово я мав погоджуватися, що краще обрати те, що запропонував хтось інший. У цьому цінність команди. Зрештою я почав отримувати задоволення від того, що ми маємо круте рішення проблеми, а ревнощі всередині зникли. Хороше командне рішення — теж ваше, бо ви про нього знаєте, ви частина цієї команди.
Щоб знаходити такі рішення, потрібно, з-поміж іншого, постійно грати в ігри. Я, на жаль, цього не роблю, але переконую себе: я можу компенсувати це тим, що дивлюся, як грають інші. Потрібно бачити нові ідеї, бо невідомо, що спаде на думку під час гри чи перегляду стріму. Обговорення може початися з нічого, але дасть класні результати.
До речі, з часом у моїй роботі стало більше спілкування з командою. Це цікаво, але не думаю, що на 100% моє. Люди — це не процесорні ядра, ви не можете на них так сильно покладатися. Й коли ти на лідерській посаді, потрібно завжди враховувати низку факторів, які вплинуть на проєкт. Найсумніше, що ці фактори часто від тебе самого не залежать. Тож для себе я визначив, що все ж таки більше тяжію до роботи саме з технічним боком продукту. Мені така зайнятість приносить більше задоволення.
«Я йшов у невідомість у лютому». Про тероборону, підтримку компанії та черговий челендж поза геймдевом
Я не можу щось розповідати про S.T.A.L.K.E.R. 2 через NDA. Та й з лютого я майже не працюю над грою. Лише час від часу консультую, втручаюся у робочі дискусії, якщо мені є що сказати.
Я вирішив записатися в тероборону ще після першого звернення путіна, бо розумів, що нічим добрим це не скінчиться, а я не міг просто лишатися осторонь. Вже 24 лютого нам видали зброю й відправили під Київ.
І попри те, що я вже
Зрештою я йшов у невідомість у лютому й було очевидно, що моя відсутність коштуватиме роботодавцям грошей і вплине на процеси. Але компанія поставилася до всього з розумінням й усіляко підтримує. Буквально днями GSC обладнала бункер та всю інфраструктуру, якщо потрібне місце для роботи. Також працівники компанії та їхні родини можуть там проживати (чимало колег досі в Києві) на випадок зимових відключень. В жодній компанії я не бачив такого ставлення до працівників, і це викликає велику повагу.
«Кілька місяців чергували на дахах будинків Києва у повній готовності збивати все, що летить»
У мене не було бойового контакту в цій війні. Якось так склалося, що ми з хлопцями стояли на блокпостах, перевіряли машини, чергували. Згодом тренувалися з ПЗРК збивати літальні об’єкти, кілька місяців чергували на дахах будинків Києва у повній готовності збивати все, що летить.
Але проблема ТрО в тому, що це все ж армійська структура, де діють відповідні правила. Наприклад, записалися в ТрО 90% молодших лейтенантів — що з ними робити? За правилами молодший лейтенант не може бути кулеметником, але може стати командиром роти чи взводу. Та де стільки рот взяти? Зрештою наш батальйон поїхав на схід, а позаштатників, до яких належу і я, залишили в Києві. Зараз мені вдалося перевестися туди, де я можу бути реально корисним — ближче до комп’ютерів, саме до «заліза». Зараз разом з командою ми розробляємо певне рішення, яке, на мій погляд, може серйозно вплинути на перебіг війни.
Працювати із «залізом» і щось програмувати для гри — геть різні речі. У випадку гри ви можете сісти й подумати, поекспериментувати з алгоритмами, зробити певні висновки. А «залізо», припустимо, має видавати ті чи інші дані, а воно цього не робить. Або ж видає ті самі дані постійно. І в чому проблема — ніхто не знає: може, пристрій погано припаяний, проблема з дротами, з живленням, з драйвером, може, ініціалізував пристрій некоректно чи звертаюся до нього некоректно, неправильно інтерпретую його дані, частота читання занадто велика чи просто річ у тім, що пристрій бракований, а може, це якась інша з мільярду причин. Я не спеціаліст у всіх галузях, часом важко зрозуміти, що йде не так, але це нагода для мене не лише бути корисним, а й подолати черговий виклик.
10 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів