Содержание
Doom на регулярных выражениях теперь не шутка из программистского чата. Разработчик Artem Lytkin заставил классический шутер работать через regex, но один кадр считается около 180 секунд.
Это тот случай, когда человек точно подумал «смогу», а вопрос «зачем» оставил на потом. Doom давно превратился в неофициальный тест на инженерное упрямство. Игру запускали на тостерах, зарядках, странных дисплеях и даже устройствах, которые вообще не выглядят как игровая платформа.
Но регулярные выражения — уровень отдельной боли. Обычно regex используют для поиска и замены текста. Например, чтобы вытащить дату, номер, фрагмент строки или привести лог к читаемому виду. У разработчиков с ними сложные отношения: инструмент мощный, но синтаксис быстро превращается в набор символов, который через неделю не узнаёт даже автор.
Как Doom работает внутри одной текстовой строки
Lytkin собрал систему вокруг 96-мегабайтной plain-text строки. В ней лежат области под регистры виртуального CPU, оперативную память, видеобуфер, WAD-данные Doom, ввод-вывод и служебные блоки.
Дальше regex-машина постоянно ищет фрагменты текста и заменяет символы. Так она имитирует числа в регистрах процессора, читает «память», пишет обратно значения и постепенно двигает состояние игры. По сути, обычная строка превращается в очень медленный компьютер.
Звучит как проклятие для любого, кто писал сложные регулярки в боевом проекте. Но формально фокус работает, потому что регулярные выражения с условиями, переходами и правилами подстановки могут выполнять вычисления. В проекте это довели до запуска реальной игры, а не игрушечной демонстрации.
Автор проекта выложил демонстрационную страницу doom-regex, где видно работу regex-машины в визуальном и текстовом виде. Это напоминает старые утилиты дефрагментации: вроде ничего полезного для пользователя не происходит, но оторваться сложно.
Почти 14 млн замен на один кадр
Главная цифра проекта — почти 14 млн подстановок для рендера одного кадра. Движок выполняет около 80 000 текстовых замен в секунду, поэтому один кадр Doom занимает примерно три минуты.
Игрой можно управлять с клавиатуры. Правда, сам Lytkin описывает такой геймплей фразой «скорее шахматы по переписке с дробовиком, чем twitch-шутер». И это честное описание: при 180 секундах на кадр реакция игрока теряет привычный смысл.
Важная деталь для тех, кто любит такие инженерные извращения: Lytkin заявляет, что вывод получается byte-identical к обычному Doom. То есть проект не просто показывает похожую картинку. Он пытается повторить результат оригинального исполнения побайтно.
С памятью автор тоже поступил аккуратно. Он не заставляет regex каждый раз сканировать все 96 МБ текста ради нужного маркера. Для доступа к памяти Lytkin использовал структуру вроде бинарного дерева: машина прыгает от ветки к ветке через стандартные regex-инструкции перехода по символам.
Без этого проект, вероятно, считался бы уже в режиме «до тепловой смерти Вселенной». С деревом он всё равно остаётся чудовищно медленным, но хотя бы выдаёт кадры в человеческом масштабе. Пусть и по одному кадру за время, за которое обычный ПК успевает прогнать целый бенчмарк.
Почему это не просто мем про Doom
Запуск Doom на странных платформах давно стал культурным тестом для программистов. Но здесь интерес не в железе, а в том, насколько далеко можно растянуть идею «программа как набор правил замены».
Регулярные выражения обычно живут в редакторах кода, лог-анализаторах и скриптах обработки текста. Lytkin использовал их как вычислительную среду. Проект ближе к демонстрации пределов модели, чем к практичной разработке.
И всё же такие работы полезны. Они показывают, где проходит грань между формальной вычислимостью и нормальной инженерией. Если система может выполнить Doom, это ещё не значит, что на ней стоит играть в Doom после работы.
Код проекта открыт в репозитории doom-regex на GitHub. В описании проекта указаны ключевые параметры: строка объёмом 96 МБ, около 14 млн замен на кадр и скорость примерно 80 000 подстановок в секунду.