javascript

Я запустил GTA San Andreas на своем движке в браузере, один с Claude, за 3 недели

  • пятница, 26 июня 2026 г. в 00:00:07
https://habr.com/ru/articles/1051828/
OpenSA
OpenSA

Введение

Если лень читать - сразу дам ссылки на важные ресурсы:

Demo: https://opensa.cc

Repo: https://github.com/AlexSergey/opensa

Trailer: https://www.youtube.com/watch?v=J2P4gQd9NQo

А далее пойдёт подробная история о том, как я его создал — игровой движок с нуля, сделанный совместимым с RenderWare (движком, на котором работает GTA San Andreas), запускающийся в браузере.

Что это такое — и чем это не является. OpenSA — это эксперимент и учебный проект. Цель — сам движок: браузерный рантайм, созданный совместимым с форматами RenderWare, которые использует GTA San Andreas, — а не клонировать игру или распространять её. Он не поставляет никаких игровых ассетов; вы приносите свою легальную копию (или мод от комьюнити). Считайте это альтернативным способом запустить игру, которая у вас уже есть, в браузере. GTA San Andreas, её ассеты и торговые марки принадлежат Rockstar Games / Take-Two — это неофициальный некоммерческий фанатский проект.


Игры серии GTA для меня это не просто игры, а моё начало в ИТ: именно эти игры увлекли меня в программирование и 3D-графику. Да и, будем честны, кроме первой части ни одну я так до конца и не прошёл - так что это всё больше про разработку.

Ещё будучи студентом, в далёкие 2000-е я делал модификации для GTA Vice City, а позже и San Andreas. Работал с картой, делал модельки, писал простенькие скрипты. Это увлечение длилось несколько лет, за которые я довольно хорошо ознакомился с особенностями движка RenderWare. Но жизнь шла, я окончил институт и пошёл работать, про GTA забыл и только следил за комьюнити моделлеров - просто чтобы понимать, кто что делает.

Спустя много лет, в 2023, я снова решил установить San Andreas. Зашёл в дискорды комьюнити и был приятно удивлён - моддинг GTA жив и развивается. На этот момент у меня уже было около 15 лет в профессиональной разработке, правда работал я в основном на WEB-платформе. По вечерам, чисто ради хобби, я снова начал ковырять GTA. Пописывал скрипты на непонятном мне языке, делал обвязки на Node.js, короче развлекался как мог.

Но всё это работало нестабильно. Дебажить было сложно. Всё могло поломаться в любой момент. Никакой регрессии. Никаких тестов. Короче, ерунда какая-то.

И всё у меня крутилась в голове мысль - эх, если б это было в Web, на моём родном поле, я бы мог это всё поковырять как следует.

И тут пришёл ИИ. Потихоньку изучая новые подходы в разработке при помощи ИИ, я переписал ряд своих проектов, решил ряд разной сложности задач. И 3 недели назад я подумал: а что если…

Начало, MVP

RenderWare - довольно старый и простой движок. В нём есть ряд фундаментальных вещей, которые делают его таким лёгким и мощным одновременно - это работа с моделями и текстурами. Формат моделей DFF в GTA San Andreas поддерживает очень много функционала: от информации о геометрии и уровнях детализации до вариантов отображения днём и ночью (prelit, night vertex colors). А текстурный архив TXD хранит сами текстуры - битмапы, альфа-каналы и mip-уровни (детализацию текстур на расстоянии).

Это целая большая спецификация, которую очень сложно покрыть даже зрелыми плагинами для 3ds Max. Существовало много попыток написать свой loader для three.js, чтобы напрямую, без обработки, грузить данные модели в браузер - но это были скорее мёртвые проекты.

Это была моя отправная точка. Мой MVP. Если у меня удастся загрузить в браузер простую DFF и TXD с сохранением всех особенностей - то дальше я уже знаю, что делать.

Вооружившись Max-подпиской на Claude Code, я вначале создал простой проект React + three.js, который работал с обычной 3D-моделью. Скормив Опусу ссылки на опен-сорс-решения по открытию DFF/TXD, спецификацию и устные комментарии, через 5 минут я получил тот же проект, но уже работающий с DFF/TXD. Да, пока покрытие спецификации было процентов 15, но начало было положено.

Далее карта - у меня уже был парсер IDE/IPL-файлов, а также walker, который умеет ходить по координатам и собирать карту.

First Map Progress
First Map Progress

После небольших правок - отбросил низкополигональные объекты для дальней прорисовки и поправил кватернионы (это поворот объекта относительно карты) - я получил уже что-то похожее на реально собранную карту.

More Map Objects
More Map Objects

К сожалению, всё ещё были проблемы с отсутствием некоторых зданий и поверхностей на карте, но это был большой прогресс!

Map Holes
Map Holes

MVP был готов. Этот этап показал мне, что в принципе всё реально и я смогу воспроизвести игру в браузере.

Debugger

Прежде чем начинать любую разработку сложного проекта, я всегда думаю в сторону: а как мне его дебажить?

Для дебага OpenSA я использовал несколько уровней:

Logger. Очевидно, любой проект не обойдётся без хорошего логгера, который умеет управлять уровнями логов.

In-Game debugger. Впоследствии это вылилось в проект внутри проекта. Большой редактор, позволяющий в реальном времени управлять всем, чем только можно: быстро телепортироваться в локацию, спавнить авто, настраивать погоду и графику. А самое главное - в этом дебаггере мы можем войти в режим карты и мгновенно начинаем парить над зоной, где находится игрок, можем включать другие зоны, смотреть, где какой объект, и так далее. Полноценный map editor. Дебаггер постоянно развивается с приростом фич.

In Game Map Debugger
In Game Map Debugger
In Game Collision Viewer
In Game Collision Viewer

Viewers. Каждый тип объекта имеет свой просмотрщик - это отдельно собираемое приложение, задача которого визуализировать объект и давать какие-то минимальные действия. Например, у персонажа - воспроизвести анимацию:

Objects Viewer
Objects Viewer
Vehicles Viewer
Vehicles Viewer
Characters Viewer
Characters Viewer

Также по мелочи: есть дебаг-скрипты и система ивентов самого core, но об этом позже, когда будем говорить об архитектуре.

Первые проблемы

Так вот, как я уже упоминал, после создания хорошего инструментария дебага я начал смотреть проблемы с картой, а именно - почему многих построек не хватало. Оказалось, что у объектов нет очевидного, удобного для меня признака, что это объект карты, а не интерьера. Понять можно было по косвенным принципам: большинство объектов именно карты имеют флаги больше 256, а что меньше - скорее интерьер, но и элементы карты там тоже встречались.

Тогда я придумал проверку по косвенным признакам - написал скрипт, который изучает все объекты карты: если значение меньше 256, он анализирует все остальные объекты с таким же флагом, и если там в названии встречается road, land и прочее, то номер этого флага подпадает под то, что эти объекты точно карта.

И, как ни странно, это был самый быстрый и наиболее точный способ решить проблему. После этого вся карта была готова.

Full Map
Full Map

Архитектура

Получив полную карту и уверенность в реализации проекта, я приступил к наброскам архитектуры. Ранее мне уже доводилось проектировать сложные фронтенд-системы с многослойной архитектурой. В таком проекте, как этот, самое главное - разделить логику UI, Игры и Движка.

Architecture. Beginning
Architecture. Beginning

Таким образом, у нас получилась абсолютно независимая система:

- UI написан на React, но мы можем использовать что угодно.

- Game по сути это фреймворк - набор публичных методов, которые настраивают и вызывают игру. Изначально Game работал напрямую с файловой системой игры (об этом далее).

- RenderWare - это все необходимые парсеры для GTA San Andreas, они подключаются к игре через адаптер. Таким образом, реализовав и заменив адаптер на GTA Vice City, мы можем отрендерить и Vice City - и даже больше: если смешать адаптеры, мы теоретически можем использовать, например, авто и персонажей GTA San Andreas, но в городе Vice City, или наоборот.

- Далее идёт слой библиотек - three.js, Rapier.

Так как изначально я хотел полностью воспроизвести движок, то и работать нужно было с уже существующей файловой системой и существующими форматами. Были реализованы парсеры для всех видов файлов.

В итоге я получил движок, который способен открывать не только оригинальную игру, но, например, и моды для неё — потому что он ориентирован на сами форматы RenderWare, а не на одну конкретную игру. Именно этот совместимый движок, а не демо с San Andreas, и есть настоящая суть проекта. Об этом ниже.

Архитектура по ходу будет изменяться.

Персонажи

В оригинальной GTA San Andreas используется модульная система для главного героя - она даёт возможность менять одежду, стиль игрока и прочее. Для тестовой версии я принял решение ограничиться обычной костной моделью персонажа - как все пешеходы игры. Для узнаваемости была взята сконверченная модель Tommy Vercetti из GTA Vice City.

Tommy
Tommy

Самая забавная часть работы над любой игрой - это работа с анимациями персонажей. Чего тут только не было за весь период разработки.

Tommy. Animation Bug
Tommy. Animation Bug
Shrek
Shrek
Shrek Bug
Shrek Bug

А чего вы хотели от Шрека?

Когда был сделан анимационный менеджер, настало время физики. При движении персонажа вначале использовался куб в качестве коллизии, и он застревал на каждом шагу. Потом узнал, что лучше использовать капсулу - при таком подходе ноги не цепляются за бордюры, тело не застревает в заборе, так как оно всё округлое и обтекаемое. По сути, у нас вместо Томми по карте вот такая таблетка ходит:

Capsule
Capsule

Авто

Со стандартными автомобилями проблем особо не было. Я в студенческие годы довольно много авто сконвертил и хорошо помнил нюансы. Но мне хотелось большего - в сообществе ГТА очень много качественных кастомных моделей. Я хочу поддерживать их все! Ну, или почти все. Поэтому, установив ряд моделей от сторонних авторов, я, мягко говоря, удивился количеству багов. Большую часть удалось исправить, но и ряд остался на будущие фиксы.

Vehicles
Vehicles

Особенно интересный момент - это имплементация входа в авто. Казалось бы, ну простая задача: вот авто, вот анимация, как персонаж открыл дверь и сел внутрь. Чего проще?!

Но не всё так просто, конечно же!

1. Нам надо понять, какое авто ближайшее к игроку. Строим реестр ближайших авто - кидаем лучи, находим, меряем расстояние…

2. Находим дверь, где расположен dummy руля (водительское).

3. Строим траекторию пути, используя коллизию авто, чтобы не пройти насквозь.

4. Коллизии авто недостаточно - надо учитывать коллизию игрока + добавлять гэп, а то игрок может застрять намертво и не дойти.

5. При посадке был очень странный баг - авто улетало, персонаж вываливался. В чём причина? Оказалось, коллизия игрока влияет на авто: Томми как будто пинал авто во время посадки. Пришлось пойти на трюк - в момент посадки и езды я отключаю коллизию для Томми совсем. Это чревато эдж-кейс-проблемами в будущем: когда появится трафик, если в момент посадки другое авто влетит в садящегося Томми, оно проедет его насквозь. Решим позже.

Также реализовал игровую систему повреждений.

Vehicle Damage System
Vehicle Damage System

Физика

Самое главное в физике этого типа игр - уделить особое внимание главным действующим героям: автомобилям и персонажам. На них я и сосредоточился в первую очередь.

Я никогда не строил физ-движки для игр и вообще сильно в этом не разбирался, но целью текущего проекта было воспроизведение реального поведения. А оно такое:

В игре есть файл handling.cfg - это полное описание автомобиля: его масса, скорость и прочие характеристики. Вначале я пытался натянуть сову на глобус и, распарсив эти данные, просто вручную применял их к каждому авто, пытался сэмулировать столкновения и прочее. Спустя время я понял, что занимаюсь полной фигнёй. Изучив вопрос, выяснил, что замечательный физ-движок Rapier полностью заточен под это из коробки:

https://rapier.rs/javascript3d/classes/DynamicRayCastVehicleController.html

Буквально 5 минут - и авто начали кататься по карте.

Были, конечно, баги, куда без них. Video:

https://www.youtube.com/watch?v=N9ku0aWYy80

Но это мелочи. Дело пошло.

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

Прорисовка

Самое забавное на этом этапе было то, что я неверно думал, как устроена система прорисовки в GTA.

Каждая модель имеет высококачественное представление и низкополигональное (для отрисовки издалека). Когда герой находится вдалеке мы видим плохого качества модель, в приближении она меняется на полновесную. В оригинальной игре у нас могут быть баги, что модель не успела прогрузиться и мы видим вблизи мыльную картинку.

Я же, сам того не подозревая, сделал систему ближе к GTA 5, впоследствии узнав, что это называется система composite-lod. Суть данного подхода сводится к тому, что низкополигональные модели объединяются в район и грузятся одним куском. Таким образом, проблема прогрузки отдельных объектов уходит и багов не должно быть.

Для этих целей я объединял LOD-объекты в районы: вначале на уровне игры, а впоследствии создал отдельный инструмент

Lods
Lods

Туманом скрываем дальность прорисовки - так и визуально красивее, и не даёт видеть дыр в карте.

Fog
Fog

Конечно, предусмотрена смена как размеров сетки, так и дальности прорисовки всех типов объектов.

Время и погода

Прежде чем начинать реализовывать графику, я сделал время. Время идёт не в такт настоящим часам, а с множителем - минута = 3 секунды реального времени (тоже можем менять в конфиге).

Также был реализован погодный менеджер с процедурно генерируемыми «дешёвыми» облаками. Полная поддержка внутренней игровой системы timecyc.

https://www.youtube.com/watch?v=cmLDRV4nl2M

Графика

Итак, время подошло поговорить о графике. В старых играх, таких как GTA San Andreas, графика - это компромисс. В те годы и при тех компьютерах было просто невозможно сделать динамическое освещение или настоящие тени.

В оригинальных моделях GTA тени и свет впечатаны в геометрию. Эта система называется prelit и night vertex colors. Тем самым мы получаем уже заранее просчитанные тени, солнечные засветы и приятную атмосферу, которая никак не реагирует на источники света - потому что их почти нет.

Так как я веду разработку с нуля, я могу делать любые эксперименты. Первым делом я попробовал сделать настоящее солнце и тени.

Godrays
Godrays
Shadows
Shadows
Graphics 1
Graphics 1
Graphics 2
Graphics 2

В целом выглядело неплохо, но требовало больших переработок, и терялась аутентичность картинки. Игра стала больше напоминать GTA 4, чем San Andreas.

Поэтому эту работу я пока отложил и сделал оригинальную графику, но с добавлением крутых эффектов, таких как Sun, God Rays, Bloom, tonemapping.

В итоге получилась очень тёплая и насыщенная картинка - как днём, так и ночью, в стиле оригинала.

Graphics Final
Graphics Final

Я ещё буду над этим работать, интересно написать кастомный движок для рендеринга, посмотреть как это может выглядеть на современных технологиях.

Поддержка модов

Одна из самых сильных частей проекта - то, что я стараюсь повторить не только спецификацию моделей и текстур, но и файловой системы, системы координат и прочего. Поэтому у меня из коробки полная поддержка модов.

Был проведён тест на двух крупных модах.

GTA Carcer City (2026):

GTA Carcer City
GTA Carcer City

GTA Anderius (2009):

GTA Anderius
GTA Anderius

Вся карта работает нормально, все объекты на местах.

Оптимизация

Работа над оптимизацией - это отдельная тема. Так как эта игра не только сложна в плане рендера для клиента, но и качает большое количество моделей и текстур, к вопросу оптимизации пришлось подойти комплексно:

Во-первых, мы не грузим все файлы игры, только то, что нужно для техно-демки - карта, пара кастомных машин и Томми.

Во-вторых, все ресурсы разбиты на малые чанки, заархивированы в ZIP, чтобы их можно было быстро параллельно тянуть с CDN.

Архитектура проекта изменилась, появились две отдельные сущности:

Preloader - компонент, который ведёт скачивание ресурсов в зависимости от приоритета. Умеет докачивать неудавшиеся части, кешировать и читать из кеша. Для инвалидации используется текущая версия.

Virtual File System. В изначальной версии демка работала напрямую с img-архивом, который занимал около 1 гигабайта, но VFS позволила работать с ZIP-чанками. Когда preloader их скачал, он передаёт данные в VFS, а игра умеет работать с интерфейсом VFS. Таким образом, игра ничего не знает о том, как упакованы наши ресурсы. Для удобной локальной разработки можно работать с архивами игры напрямую, а при деплое упаковывать только нужное в чанки и читать уже из них:

Architecture Final
Architecture Final

Фатальные проблемы: Лицензирование

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

Я понял, что я просто не имею права выкладывать в сеть ассеты игры. Да, код мой, я его сделал не при помощи реверса, а просто по своим знаниям и пониманиям, но модели, текстуры, герои - не мои.

Поэтому для демо было принято решение не хранить и не распространять реальные ассеты игры. Игрок сам выбирает свою ранее купленную копию и играет. Но в этом, конечно, снижался смысл основного проекта, что может быть доступно онлайн.

Поэтому я добавил свободно распространяемый глобальный мод - Gostown Paradise, который не содержит ассетов оригинала (а те, что были, я вырезал). К сожалению, это незавершённый проект и он имеет множество багов, поэтому всё выглядит хуже, чем в оригинальной игре.

Фатальные проблемы: Браузер

Заставить рендериться в браузере карту и пару моделей - это полдела. Основная проблема в том, что если добавить трафик (а в оригинальной GTA 212 моделей автомобилей), а также персонажей, а также скрипт-логику, браузер просто это не потянет!

Я хотел написать свою систему трафика, чтобы город выглядел живым: с высоты птичьего полёта мы могли бы наблюдать крупные заторы на дорогах, толпы людей на пляже, несущиеся в потоке скорые помощи и полицейские авто и прочее. Но, к сожалению, такое в браузер не засунуть.

Мобильные устройства

Очень экспериментально добавил поддержку мобилок. У меня лично играть на мобильном телефоне в такие игры никогда не получалось, поэтому я не эксперт, как делать это удобно:

https://www.youtube.com/watch?v=OF1uCpIZ2eU

Работа с Claude Code

Этот проект на 85% сделан при помощи Claude Code - отличный эксперимент, демонстрирующий, насколько сейчас изменилась разработка. Активная фаза всего девелопмент-процесса велась в свободное время, на протяжении всего 3 недель. Одним человеком. Но таких результатов невозможно добиться, если не соблюдать ряд правил:

Прежде чем начать работу, была собрана очень агрессивная линтинг-система, которая отсекала весь шум и мусор разработки.

Я строго понимал алгоритм движка, строго понимал, как мне выстроить роадмап, как приоритизировать задачи. Без этогопонимания запрос в стиле «сделай мне клон GTA» работать, конечно, не будет.

Каждая задача сопровождалась планированием. Все идеи, наработки, изменения - строго документированы. Измененияревьюились. Если контекст был потерян, я точно знал, где находятся эти знания. За этим приходилось очень активноследить, так как Claude Code всеми силами пытался избегать документации, даже после добавления в память.

Тесты, тесты и ещё раз тесты. Сразу было выделено правило - использовать реальные данные для тестов: если мы тестиммодель DFF, мы именно работаем на уровне файла, а не эмуляции. Отдельной итерацией, после завершения основных фич, былополное покрытие недостающих участков тестами, создание e2e-платформы для тестов, а также верификация всей документации.

Баги, идеи, leftovers - всё это тоже документировано, с тегами, на будущее. Сразу писались development guide.

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

Итоги и дальнейшие планы

Данный проект это очень интересный эксперимент, результатами которого я и хотел поделиться с вами.

Во-первых, передовые средства ИИ реально меняют правила игры для опытных разработчиков, давая невероятные возможности тем, кто понимает, чего хочет достичь.

Во-вторых, браузер - как платформа для игр, не сильно подходящее плато. Мы ограничены в рамках браузера не только пропускной способностью интернета у конечного пользователя, не только должны поддерживать ряд устройств, но и имеем внутренние лимиты самого браузера.

Как итог, конечно нет смысла полного порта подобных проектов в браузер, но тот полученный опыт, что я освоил в данном проекте дает мне возможность сделать ряд полезных инструментов, например:

Я уже сделал инструмент который фиксит проблемы хрома в некоторых кастомных моделях автомобилей и может изменять их масштаб для реальной игры:

Veh Optimizer. Before
Veh Optimizer. Before
Veh Optimizer. After
Veh Optimizer. After

В процессе инструмент для создания системы лодов для оригинальной игры как я сделал в этой версии.

В процессе инструмент, который добавляет полигоны в низкополигональные части карты, чтобы всё выглядело плавнее.

Map Optimizer. Before
Map Optimizer. Before
Map Optimizer. After
Map Optimizer. After

И конечно очень интересно написать свой рендерер, чтобы посмотреть на что способен браузер, добавить туда модные примочки, такие как:

- Volumetric Cloud

- Per-Pixel Lighting

- Real shadows

На этом у меня все, спасибо за внимание!

Продублирую ссылки:

Demo: https://opensa.cc

Repo: https://github.com/AlexSergey/opensa

Trailer: https://www.youtube.com/watch?v=J2P4gQd9NQo