Релиз версии 1.9.0 Russian Railway Simulator

В 2019 году я публиковал статью о первой версии своего проекта Russian Railway Simulator. Прошло достаточно много времени, и возможно кто-то думает, что проект умер. Нет, проект не только не умеp, но и продолжает развиваться. На днях новая версия игры. В связи с этим реализую свою давнюю задумку написать о проекте еще раз, о том как он развивался все эти годы, к чему мы пришли к сегодняшнему дню и какие перспективы ожидают нас в будущем.

Зачем нужен еще один симулятор, или история одной идеи

Железнодорожных симуляторов очень много. Это и большие коммерческие продукты, и проекты с открытым исходным кодом, развиваемые энтузиастами. Первоначальной идеей Russain Railway Simulator (RRS) было создание открытого проекта, ориентированные на реалии наших железных дорог. Под нашими я понимаю колею 1520, эксплуатируемую на всем постсоветском пространстве.

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

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

Программная часть симулятора в ту пору разрабатывалась мной самостоятельно. Визуальные модели подвижного состава разработал Роман Бирюков (Ромыч РЖДУЗ), широко известный в узких кругах ж/д симмеров разработчик моделей и маршрутов. Большинство из этих моделей и сейчас используются в проекте.

Версия 1.0.4 образца декабря 2019 года, или около того
Версия 1.0.4 образца декабря 2019 года, или около того

Вышло некоторое количество версий, с 1.0.0 до 1.0.7-3 и проект перешел в фазу вялотекущей стагнации. Я использовал его в основном для разработки тренажерных комплексов и в качестве движка для разного рода выставочных демо-проектов. Как игра он не развивался совсем. Но открытые исходники, как это бывает, сработали, и проект получил новый толчок.

Команда

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

  • maisvendoo (это я) - занимается всеми аспектами понемногу, но предпочитает физику подвижного состава и с недавнего времени скриптинг сценариев.

  • ArepMM (Михаил) - работает над всеми подсистемами игры, с упором на пневматические системы подвижного состава, графику, топологическую систему путевой инфраструктуры и игровые интерфейсы.

  • avilkinnik (Николай) - разработчик графической подсистемы игры, работает над системой 3D-визуализации и редактором маршрутов.

В постоянный состав команды входят и два левел-дизайнера: Александр (Ulovskii2017) и Георгий (gkedrya), они разрабатывают 3D-модели и карты участков железных дорог.

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

Стек технологий

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

  1. С++17 совместно с фреймворком Qt6. C++ остается стандартом геймдева, наш проект не исключение, а Qt обеспечивает нам удобство реализации кроссплатформенности в части сетевой подсистемы и GUI.

  2. 64-битный компилятор - gcc и его собрат mingw для сборки под Windows.

  3. CMake в качестве системы сборки. Без комментариев, это тоже общий тренд для решений на C++.

  4. VulkanSceneGraph, vsgXchange, vsgImGui - библиотеки, предоставляющие иерархию классов для работы с 3D-графикой на Vulkan API. Разрабатываются командой разработчиком во главе с Робертом Осфилдом, создателем предыдущего фреймворка OpenSceneGraph который мы использовали вплоть до версии 1.6.0 включительно. Преемственность, об этом поговорим подробнее ниже.

  5. glslang - компилятор шейдеров с языка GLSL в формат SPIR-V.

  6. OpenAL (openal-soft) в качестве основы звуковой подсистемы.

  7. FreeType для рендеринга шрифтов, требуется как зависимость для библиотек 3D-графики.

  8. assimp как сторонний загрузчик ассетов, в частности моделей в формате glTF 2.0, однако в крайних двух версиях мы полностью перешли на нативный загрузчик, предоставляемый vsgXchange.

  9. SFML для кроссплатформенного взаимодействия с джойстиками.

  10. Lua встраиваемый интерпретатор одноименного языка. Пришлось написать свою реализацию скриптов сборки, так как оригинальный пакет исходником не содержит CMakeLists.txt. На свой репозиторий, содержащий однако оригинальные исходники, я и ссылаюсь.

  11. sol2 библиотека, предоставляющая C++ удобный интерфейс к интерпретатору Lua.

Для работы с проектом в ОС Windows и выпуска версии под нее (официальный дистрибутив выпускается под винду) большинство перечисленных зависимостей мы самостоятельно собираем из исходных текстов компилятором MinGW. Готовые билды зависимостей доступны на нашем официальном сайте.

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

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

Архитектура клиент-сервер

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

Самая первая версия, 1.0.0 работала именно так. В какой-то момент, а именно с версии 1.0.3, из-за ошибки интерпретации сбоев в синхронизации симуляции с реальным временем, TCP-стек был вставлен на мороз, а межпроцессорное взаимодействие было спонтанно реализовано через общую память. И на этом принципе оно работало вплоть до версии 1.5.0, когда мы постепенно вернули проект к первоначальной архитектуре.

На сегодняшний день проект состоит из четырех главный подсистем

  1. simulator - сервер физики, на котором выполняется моделирование подвижного состава, путевой инфраструктуры, подсистемы сигнализации и блокировки и диспетчерская централизация. Кроме того, в составе сервера работает интерпретатор Lua-скриптов, на которых строится система игровых сценариев. Это самодостаточный компонет, который может функционировать без остальных подсистем.

  2. viewer - мультимедийная подсистема-клиент, выполняющая 3D-визуализацию, звуковое сопровождение, реализующая пользовательский ввод и элементы игрового интерфейса.

  3. route-map - графический клиент визуализации железнодорожного полигона в виде масштабной карты, с отображением в реальном времени состояния светофоров, стрелок, подготовленных поездных и маневровых маршрутов. Через него осуществляется ручное управление движением поездов по участку, он может выступать в роли пульта поездного диспетчера.

  4. launcher - GUI-интерфейс настройки и запуска симуляции в разных её режимах.

launcher - интерфейс настройкой и запуском симуляции
launcher - интерфейс настройкой и запуском симуляции
viewer - графический клиент мультимедиа. Показан интерьер кабины пассажирского электровоза ЭП1м
viewer - графический клиент мультимедиа. Показан интерьер кабины пассажирского электровоза ЭП1м
route-map - клиент визуализации железнодорожного полигона и диспетчерского управления движением. Станция Ростов Главный, приготовлен маршрут отправления с 1 пути для пассажирского поезда
route-map - клиент визуализации железнодорожного полигона и диспетчерского управления движением. Станция Ростов Главный, приготовлен маршрут отправления с 1 пути для пассажирского поезда

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

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

Клиент-серверная архитектура, многопоточная симуляция нескольких поездов автоматически привнесла в игру режим мультиплеера. Мы не стремились создать сетевой гейплей специально, он возник из архитектуры игры сам собой. Это стало возможным начиная с версии 1.6.0, а зачатки процесса появились еще в версии 1.5.0. При этом процесс одиночной игры и мультиплеер функционально неразличимы для игрока. Роли машиниста, помощника машиниста, диспетчера, работника вагонного хозяйства - все это доступно в настоящее время в рамках игры по сети. Единственным моментом является то, что сетевая игра пока не предусматривает инструментов авторизации и разграничения доступа и явного назначения родей игроков - полная анархия, зная IP-адрес сервера можно подключится к любой мультиплеерной сессии и вмешаться в управление на любом поезде. Решение этой задачи мы откладываем на дальнюю перспективу.

Топология

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

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

Технологически описанное решение не является каким-то новшеством, подозреваю что подобная реализация присутствует во всех более-менее развитых железнодорожных симуляторах. Собственный велосипед был реализован по причине того, что мы изначально использовали для работы ресурсы другой игры - ZDSimulator (ZDS). Причина - открытый текстовый формат представления данных для маршрутов, а так же огромное количество уже реализованных участков ж/д с реальным профилем и планом пути. Недостаток, присутствующий в том проекте до сих пор - отсутствие внятного механизма отклонения по стрелкам. Не то чтобы его там нет, но реализация оставляет желать лучшего.

Расположение путей на нескольких уровнях
Расположение путей на нескольких уровнях

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

Разворотный треугольник на карте "Испытательный полигон"
Разворотный треугольник на карте "Испытательный полигон"
Тот же треугольник и та же эстакада на карте маршрута
Тот же треугольник и та же эстакада на карте маршрута

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

Новорожденный редактор маршрутов
Новорожденный редактор маршрутов

Так что разработка редактора карт и доведение его до работоспособного состояния - это задача будущих релизов. Это определенно облегчит и ускорит переработку существующих карт под возросшие возможности игры, а также создание новых участков.

Графика: от OpenGL legacy к Vulkan API

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

На начальных этапах разработки вопросы графики для меня были вторичны - рисует как-то да и пусть. И, несмотря на то, что OSG поддерживает OpenGL 3+ (с помощью задания специальных опций сборки), мы до самого конца применения этого фреймворка использовали legacy OpenGL.

С версии 1.6.0, после реализации полноценного мультиплеер, мы поняли, что так жить нельзя и надо искать более современный и производительный рендер. Ориентироваться на GL-based проекты не хотелось, при этом хотелось что-то компактное, производительное и кроссплатформенное. И такая технология была на заметке еще в 2018 году, до первого публичного релиза - VulkanSceneGraph.

Эта библиотека - почти ровесница нашей игры в 2018 году пребывала в зачаточном состоянии. Разрабатывает её тот же автор что и OSG - Роберт Осфилд. Она является преемницей предыдущего проекта в части основных архитектурных решений, но переработанных с учетом особенностей Vulkan API. Первые эксперименты по портированию моделей в VSG я сам проводил еще году в 2019, но на тот момент библиотека была совсем еще новорожденная. Выход её первого публичного релиза в 2022 году подтолкнул нас к работе по портированию на неё графического клиента, фактически начатые в конце 2023 года.

Основу этой работы взял на себя Николай, и через полтора года мы получили рабочий прототип, который и представили в июне 2025 года в версии 1.7.0.

Тонкость процесса - отсутствие какой бы то ни было внятной документации по данной библиотеке. Есть общие соображения изложенные автором на официальном сайте, есть технический форум на Github, есть в конце-то концов LLM, способные анализировать исходники и предлагать реализацию тех или иных вещей. Сыграла свою роль и дружественная атмосфера на форуме разработчиков VSG и участие самого Роберта в решении некоторых наших проблем и его внимание к нашим предложениям, оформленных Михаилом в виде нескольких значимых для нашего проекта пулл-реквестов.

Клиент-серверная архитектура отлично сыграла в этой ситуации - по сути мы переписали viewer, совершенно не трогая физику. Некоторое время параллельно существовало два клиента: viewer на OSG и viewer2 на VSG.

Встречаем утро на разъезде Витаминный СКЖД
Встречаем утро на разъезде Витаминный СКЖД

На сегодняшний день мы располагаем потенциально высокопроизводительным многопоточным рендером на Vulkan API и формата glTF 2.0. Появилась возможность использовать современные подходы к программированию GPU и это вылилось долгожданную реализацию суточного освещения в версии 1.8.0.

Ночь на станции Ростов Пригородный вокзал
Ночь на станции Ростов Пригородный вокзал

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

В кабине дизель-поезда РА-3 на станции Батайск
В кабине дизель-поезда РА-3 на станции Батайск
Один из первых тестов работы с освещением и PBR-материалами
Один из первых тестов работы с освещением и PBR-материалами
Эксперименты наших пользователей по настройке освещения и теней
Эксперименты наших пользователей по настройке освещения и теней
Еще один скриншот от наших пользователей
Еще один скриншот от наших пользователей

Графический клиент определенно нуждается прежде всего в оптимизации - на больших локациях с большим количеством подвижного состава разница в производительности между 50 и 70-й серией видеокарт NVidia становится угрожающе драматической. Основной бич - расход видеопамяти - для комфортной игры с применением всех доступных в игре дополнений и большим количеством поездов требуется не менее 8 Гб видеопамяти.

Мы планируем внедрить relatime-профилировку на базе Tracy и интерфейса vsg::Instrumentation, с целью выявления и исправления узких мест, а так же не против любой посильной помощи в этом вопросе.

Lua-скриптинг сценариев

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

Сценарии всё изменили. Теперь все аспекты управления движением реализуются на Lua-скриптах. За это в системе отвечают два компонента: scenario-manager как встроенный интерпретатор Lua взаимодействующий с бэкэндом на C++ и модули автоведения на подвижном составе, обеспечивающие превращение любого игрового поезда бот, движущийся по графику, соблюдающий ограничения скорости и реагирующий на сигнализацию. При игре по сценарию эта система способна самостоятельно решать возможные коллизии, обеспечивая разъезд нескольких поездов без ручного вмешательства диспетчера.

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

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

Планы и перспективы

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

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

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

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

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

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

Официальном сайте: https://rusrailsim.ru

Репозиторий на Github: https://github.com/maisvendoo/RRS

Официальной группе VK: https://vk.com/rusrailsim

Пользовательская документация доступна в RRS-wiki

Решить вопросы касающиеся разработки можно на техническом форуме Github