Де продати хабар і що дають приховані стати. Як я створив ультимативну мапу S.T.A.L.K.E.R.
Досить давно в мене крутилася ідея зробити щось на кшталт інтерактивної карти для S.T.A.L.K.E.R. Хотілося зробити щось за аналогією з Death Stranding: щоб гравці могли залишати на карті мітки, наприклад, «тут захований хабар», ставити лайки/дизлайки тощо.
Спочатку це мав бути повноцінний frontend + backend проєкт із базою даних, модерацією і всією супутньою інфраструктурою.
До реалізації нарешті приступив у 2022 році.
Перші кроки і Blazor
Для frontend вирішив спробувати Blazor — хотілося помацати цей фреймворк, а можливість використовувати .NET і спільні класи між frontend та backend досить сильно підкупала.
Оскільки якихось даних по S.T.A.L.K.E.R. 2 тоді ще не було, для початку вирішив робити все на базі оригінальної трилогії. Першим кроком стало вилучення даних безпосередньо з гри, щоб мати сирі дані для візуалізації і на чомусь бойовому тестувати логіку.
І саме тут прийшла досить закономірна думка: навіщо робити систему, де дані вносяться вручну, їх потрібно модерувати, зберігати в базі, обробляти на backend і потім віддавати користувачу, якщо я можу просто витягнути їх безпосередньо з гри?

Так поступово відпали backend, база даних, лайки та коментарі. Замість цього проєкт перетворився на спосіб представити реальні ігрові дані у зручному для гравця вигляді.
В оригінальному сталкері все конфігурується через синтаксис, схожий на ini-файли, деякі конфіги сидять в xml. Як regexp-кун, я спочатку писав монструозні регулярки, щоб витягнути потрібні дані. Зі сторони це виглядало жахливо — треба було враховувати купу edge-кейсів, на які так багатий сталкер. Зрештою мені на очі попалася бібліотека, написана спеціально для читання сталкерських ltx-конфігів, яку я оперативно інтегрував у свій парсер. Далі, читаючи гру, я брав лише потрібні дані і клав їх у json у зрозумілому для сайту форматі.
Leaflet і перехід на Angular
Згодом виникла ще одна проблема. Тултіпи і попапи на мітках працювали через Blazor events, і коли кількість міток почала множитися, досить гостро постала проблема продуктивності. Хитрі хаки особливо не допомагали.
У процесі гуглення я натрапив на Leaflet — одну з найпопулярніших JavaScript-бібліотек для інтерактивних карт.
Так як ми не шукаємо легких шляхів, спочатку я зробив костиль, де в Blazor через JavaScript-прокладку прокинув API до Leaflet. Так це проіснувало якийсь час: дані бралися з JSON, парсилися на стороні Blazor, а потім через той самий костиль прокидалися в Leaflet, де вже відпрацьовувала логіка додавання об’єктів на карту і їх рендерингу.
Зрештою, вирішив відмовитися і від Blazor на користь Angular, бо до того моменту вже встиг набити на ньому руку.
І тут функціональність карти почала досить швидко розростатися: з’явився пошук, шари та різні додаткові дані.

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

Аналогічно підступився до техніків. Система апгрейдів у S.T.A.L.K.E.R. досить неочевидна з точки зору їхнього реального впливу: важко оцінити, що краще — абстрактні +30 до вогнестійкості або +50 до псі-захисту, що за настильність чи зручність.
Тому для механіків реалізував відображення впливу апгрейдів на сирі характеристики, які безпосередньо беруть участь у розрахунках гри. Так стало трохи простіше зрозуміти, що саме дає конкретний апгрейд і вибрати те, що краще підходить саме тобі.

Підготовка до S.T.A.L.K.E.R. 2
Після цього основний вектор моїх зусиль змістився на підготовку до S.T.A.L.K.E.R. 2. Благо, GSC Game World дала мені солідну фору — серією переносів гри.
Маса міток на карті знову нагадала про себе просадками продуктивності, тому довелося ще й застосувати Canvas rendering — мітки почали рендеритися на Canvas, а не бути окремими елементами HTML-дерева.
Для S.T.A.L.K.E.R. 2 довелося написати власний парсер .cfg файлів, які в цій грі, зокрема, відповідають за конфігурацію та спавн.
Пайплайн спочатку був досить муторним: через FModel — програма для перегляду запакованих асетів ігор на Unreal Engine — я експортував геймдату на диск у вигляді звичайних папок і файлів, а потім запускав свій парсер, який читав ці дані і витягував потрібну мені інформацію.

Проблема була в тому, що спавн у грі складається з сотні тисяч файлів. Сумарно вони важать близько 200 МБ, але через те, що кожен файл потрібно окремо відкрити й прочитати, отримувався досить великий input lag під час обробки — пару хвилин так точно.
Причому при повторному проході по тих самих файлах процес був значно швидшим. Так я дізнався, що Windows має механізми кешування нещодавно прочитаних даних.
Тут я вже почав розбиратися, як саме FModel працює з ігровими архівами, і виявив бібліотеку CUE4Parse. Виявилося, що можна читати дані безпосередньо з архівів, без необхідності попередньо розпаковувати їх на диск. І о чудо — файли почали читатися буквально на швидкості світла.
Бінарні конфіги і рік паузи
А потім з новим патчем розробники вирішили ускладнити мені життя і почали пакувати вже самі .cfg файли. З’явилося багато бінарних .cfg.bin.
Я азартний в питаннях reverse engineering і деобфускації цікавих мені проектів, але цей момент мене скоріше деморалізував — можна сказати, я вигорів з цього проекту, тому це не стало ще одним викликом на нові звершення, і я майже на рік не повертався до цієї теми.
На початку цього літа мене знову змотивувало взятися за .cfg.bin, і виявилося, що структура формату насправді досить примітивна.

Умовно файл можна представити приблизно так:
строка1 : об'єкт строка2 = строка3 строка4 = строка5 строка6 = строка3енд
Унікальні текстові значення зберігаються на початку файлу списком, а структура конфігурації далі кодується побайтово. Після розбору цієї структури бінарні конфіги теж стали читабельними.
Результат
Окремо прикрутив Firebase Analytics — важко було уникнути спокуси попідглядати, хто там і що в мене кляцає.
Я особливо не запарювався над SEO — гугл, за запитом «сталкер карта», видає мій сайт десь в кінці другої сторінки, але, схоже, завдяки сарафанному радіо карта досить стабільно має близько 100 активних користувачів на день, приблизно 600 за тиждень і понад 2 тисячі за місяць.

Для проєкту, який спочатку робився просто «бо було цікаво», досить приємно бачити такі цифри. Друзі жартують, що пора вже рекламу прикручувати.
У результаті проєкт, який починався як досить наївна ідея «зробити карту з мітками» з бекендом і модераторами, поступово відкинув усе зайве й значно переріс початкову задумку. Як на мене, вийшла досить зручна візуалізація даних із усіх ігор серії S.T.A.L.K.E.R.
Це мій перший, надіюсь далеко не останній, серйозний pet project, який дійшов до релізу і продовжує потроху шліфуватися й зараз.
Подивитися можна тут: www.stalker-map.online
Репозиторій з кодом у вільному доступі: github.com/thexii/stalker-map
P.S. Задизайнено професійними програмістами, тому особливо на телефонах ваше естетичне чуття може трохи постраждати.
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарівдякую за твій код для декомпайлу bin файлів :)
лайк, спробую
користувався оцим до цього
mapgenie.io/...f-chornobyl/maps/the-zone