Transport Tycoon Deluxe / Emscripten ч. 2

    Transport Tycoon (Транспортный магнат) — изрядно древняя, но до сих пор доставляющая, особенно маньякам, игра в жанре экономической RTS. /.../

    Также существует OpenTTD, открытый продукт маньяццтва unixоидов, вследствие чего от игры можно не отвлекаться даже в сортире и метро, установив её на коммуникатор или КПК.
    lurkmore

    Могу честно признаться: я убил огромное количество времени, играя в Transport Tycoon Deluxe. Да я просто фанат этой игры. Поэтому, когда на хабре появилась статья про то, как ребята из mozilla портировали Doom, я загорелся этой идей – перенести одну из моих любимейших игр сюда, в интернет. К слову, статья была скудная, но я узнал главное – портирование можно осуществить с помощью emscripten. С момента зарождения самой мысли о возможности реализации такого проекта прошло не меньше года (первая моя попытка разбилась о скалы непонимания). И вот сегодня я спешу обрадовать вас всех: я сделал это! Теперь просиживать попу за игрой в TTD можно из любой точки, подключенной к интернету.

    А вот и видео:



    Нетерпеливые могут начать играть уже сейчас. Прошу отнестись с пониманием, если что-то пойдет не так. Эта версия только тестируется. Игра точно работает в FF13 (рекомендуемый браузер) и Chrome(ium). Надеюсь, мой слоупочный сервер справится с нагрузкой. И да, я знаю про розовые тайлы, работаю над этим.

    OpenTTD


    Хочу сказать пару слов о проекте OpenTTD, который стал донором исходного кода для JavaScript-версии. Проект включает в себя по общим оценкам порядка 300 000 строк C++ кода. Причем, возможности проекта потрясают. Судите сами:
    • Четыре графических подсистемы (драйвера)
    • Пять звуковых драйверов
    • little/big-endian
    • На уровне исходных кодов поддерживается возможность однопоточного и многопоточного исполнения
    • Работа в сетевом окружении (загрузка графических и музыкальных сетов из сети) и без него
    • Многопользовательская игра
    • Сжатие файлов сохранения с помощью lzma
    • Кэширующий рендеринг
    • Анимация тайлов через вращение палитры цветов
    • Встроенный скриптовый язык squirel

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

    Портировать OpenTTD удалось в следующей конфигурации:
    • однопоточный режим
    • little-endian
    • полностью отключенные сетевые возможности
    • видео драйвер – патченый SDL
    • самописный звуковой драйвер
    • патченый механизм для сохранения игр на сервере
    • патченый локатор ресурсов игры

    Остальное по умолчанию.

    Emscipten


    Над портированием кода колдовал emscripten, а я колдовал над ним, дабы он мог переварить эту глыбу. Развивая свою предыдущую статью, опишу, как эта эзотерическая технология работает.



    Идея проста: C++ код компилируется в LLVM байт-код с помощью clang. Байт-код же в свою очередь компилируется в JavaScript с помощью emscripten. LLVM байт-код это промежуточный код, который может выполняться на низкоуровневой виртуальной машине. Спецификации LLVM байт-кода отлично документированы и это одна из причин, почему он был выбран авторами проекта в качестве промежуточного представления кода. Компилятор emscripten пытается преобразовывать инструкции байт-кода в JavaScript-код один к одному, как на рисунке ниже (слева байт-код, справа соответствующий JavaScript).



    Для большинства инструкций эта схема действует прекрасно. Однако нельзя сказать, что разработка такого компилятора простая задача. LLVM байт-код и JavaScript в значительной степени различаются. Для реализации более сложных вещей (арифметика указателей, циклы, обработка ошибок) приходится выполнять дополнительную работу. Вот простой пример различного поведения C++ и JavaScript.



    Выполнение деления в C++ приведет к отбрасыванию дробной части числа. Для получения такой же функциональности в JavaScript приходится прибегать к ухищрениям вроде Math.floor (приведенный код не корректен для всех случаев, он верен для большинства).

    Более сложный пример – реализация цикла в LLVM байт-коде и JavaScript:



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

    Помимо этих низкоуровневых вещей emscripten предоставляет реализации для: libc, libcxx, POSIX, SDL, GL, GLES и других библиотек. Полностью реализована файловая подсистема C (fopen, fclose, fread, ...). Большинство программ могут компилироваться с помощью emscripten без особых проблем. Вся прелесть идеологии emscripten заключается в том, что нет необходимости править исходный код – он и так будет работать. При этом в случае успешного портирования какого-либо проекта на JavaScript, переход с версии на версию осуществляется легко и непринужденно. Например, пока я пилил emscripten, сообщество успело выпустить следующую минорную версию OpenTTD, я просто синхронизировал исходники и получил свежий порт последней версии, удобно.

    Transport Tycoon Deluxe


    С помощью emscripten в JavaScript скомпилировано уже достаточное большое число серьезных проектов: Doom, zlib, Poppler, OpenJPEG, FreeType, Bullet, SQLite, Python, Ruby, Lua и прочие. Сейчас в группе обсуждения emscripten идет активная дискуссия компиляции Fortran.

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



    В этой версии не работала ни мышь, ни клавиатура. Только вот такое изображение и все.

    Авторы emscripten заявляют о поддержке большого числа библиотек, но поддержка эта реализована не полностью. Например, в emscripten реализовано лишь небольшое подмножество SDL 2.0 с примесью SDL 1.2. Соответственно я столкнулся с отсутствием нужных функций в emscripten, и мне пришлось их реализовать самому. Зато я стал одним из коммиттеров проекта (ЧСВ!!!).

    Проблема, запечатленная на скриншоте выше, была вызвана тем, что реализация SDL 1.2 в emscripten поддерживала лишь 32-битные поверхности и ничего не знала про флаг SDL_HWPALLETE. Изображение в режиме SDL_HWPALLETE кодируется восемью битами (256 цветов). Именно с этим связана сжатость изображения. Почему же оно отражено по горизонтали мне не понятно до сих пор. Помимо этого пришлось реализовать следующие функции: SDL_VideoModeOK, SDL_VideoDriverName, SDL_QuitSubSystem и strndump. Мною была выявлена серьезная проблема в производительности, о которой было сообщено авторам и они ее исправили. К сожалению, мои правки по звуковой подсистеме не вошли в кодовую базу emscripten на данный момент.

    Было выявлено множество проблем, связанных с оптимизационными флагами emscripten. Розовые тайлы, которые вы видите на видео, это как раз проблемы оптимизации – без флагов они нужного цвета. Очень сложно разбираться с проблемами такого рода. Проблема сама по себе невменяемая (розовые лишь тайлы воды с наклоном в 45 градусов по двум направлениям) и портирование с включенными оптимизациями происходит очень долго (более 2 часов), так что часто не потестируешь. Зато доставляет то, что проект достаточно быстро развивается, баги закрываются в течение дня-двух (мои, по крайней мере).

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

    Это ужасно медленно не так ли?


    Alon Zakai (автор проекта), выступая на конференции с докладом о emscripten, высказал мнение, что JavaScript сам по себе достаточно быстр и узким местом является компилятор и его не всегда оптимальные преобразования кода. Он привел следующую табличку:



    SpiderMonker (SM) – это JavaScript-движок Firefox; Typed Arrays (TA) – самый быстрый на данный момент способ эмуляции кучи в JavaScript, который предоставляет emscripten. В ячейках таблицы числа указывают, во сколько раз выполнение скомпилированного в JavaScript кода оказалось медленнее, чем нативный код. Разброс, как мы видим, от одного до восьми раз (хотя среднее где-то возле 3-5).

    Цифры на рисунке ниже показывают, во сколько раз тот или иной язык медленнее C++ в наборе тестов http://shootout.alioth.debian.org/. (прим.: Данная информация уже достаточно устаревшая и преследует цель показать, что JavaScript – быстрый язык. Если кто не согласен с этим, прошу высказываться, а другие языки давайте не трогать – наверняка они уже имеют другие цифры в этих тестах.)



    В целом, я согласен с этими цифрами и скажу, что JavaScript-версия OpenTTD работает примерно в 5-7 раз медленнее, чем нативная. Но только в браузере FireFox. И вот это самый удивительный момент, который я для себя открыл. Я вел разработку c nodejs + chromium. Сам-то я фанат FF, но, к сожалению, дебажные версии JavaScript OpenTTD были размером с полусотню мегабайт и вешали FF намертво, в то время как хромиум работал очень шустро. Я думал хромиум на волне, но внезапно оказалось, что релизная версия работает неиллюзорно быстрее в FF (в 2-3 раза), нежели в хромиум. Поэтому я всем рекомендую играть, используя FireFox.

    Я очень рад, что занялся проектом и довел его до завершения. Я узнал много нового о clang, llvm, python и javascript. Пообщался с интересными людьми. Сообществу очень понравился мой проект, совсем недавно авторы внесли его на страницу демонстрационных проектов emscripten. Я получил огромное удовлетворение от проделанной работы. В общем-то чего и всем желаю.

    Еще раз ссылочка: play-ttd.com
    Приложение во вконтакте

    UPD. Новый сайт проекта.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 54

      +8
      Отличная работа. Единственная претензия к качеству скриншотов.
        –1
        реализация цикла в LLVM байт-коде и JavaScript

        Это ни разу не цикл в LLVM версии…
        • UFO just landed and posted this here
          +2
          Супер, хотя и маньячество! :) Впрочем, если сам бы такое делал, в первую очередь попробовал бы NaCl.
            +1
            Если б ещё некоторые умерили ЧСВ и прикрутили поддержку к своему браузеру.
            +1
            Я все таки предпочитаю нативную сборку =) Но за труды человеческое спасибо
              0
              кстати я играю в эту игру еще со времен создания Transport Tycoon — когда она еще была досовой и даже в 95 винде с трудом запускалась.
              +1
              А вообще насчет OpenTDD у меня давно чешутся руки придумать и реализовать для него tuch-friendly интерфейс, что бы можно было играть на планшете, а то андроид-порт работает отлично, но играть в режиме эмуляции мышки совершенно невозможно. Проблема, что это просто огромнейший проект, и вряд ли когда-нибудь дойдут руки :(
                +2
                Да было бы здорво, только вот UI там вообще не заточен под пальцы — иконки маленькие, много таблиц. По сути нужна полная переделка LookAndFeel, а возможно и механики игры. Так бы с удоволствием сам играл на планшетнике.
                  0
                  Согласен — интерфейс нужен другой. Пробовал играть с модом который увеличивает иконки, но этого оказалось совершенно недостаточно. Механику, ИМХО, менять не надо, но почти весь UI — да.
                0
                Сразу первый найденный баг — в FF 13.0.1 не меняется разрешение экрана в настройках. Когда его меняешь и нажимаешь ОК, появляется стандартные splash окно и ничего не происходит.

                А вообще, Вам респект и уважуха! Игра потрясающая, не так давно в нее рубился!
                  0
                  Спасибо, баги будем потихонечку исправлять их уже набралось прилично :)
                  0
                  Вы гений! Фанат этой игры с самой первой версии! Спасибо Вам и таким людям как Вы, которые несут флаг TTD вперед сквозь времена!
                    +1
                    Сам не люблю комментарии вида "+1", но в данном случае не могу удержаться — мое искреннее уважение!
                      +3
                      Сударь, вы маньяк и знаете толк. Снимаю шляпу.
                        0
                        Я год уже хотел поиграть в эту игру, вспомнить юность, но на новых компах они не идут (а тем более мак), огромное спасибо за проделанную работу: "+1"
                          +3
                          OpenTTD идет на всех современных системах и есть нативная версия под маки
                          www.openttd.org/en/download-stable
                            0
                            Спасибо за ссылочку, обязательно поиграю, вспомню молодость!
                            0
                            Есть ее порт OpenTTD, с поддержкой нового оборудования и всех популярных ОС.
                              0
                              Если мне не изменяет память, это не порт, а альтернативная реализация.
                                0
                                Насколько я понимаю, проект начинался как реверс-инженернутый мод (изначально TT и TDD были написаны на ассемблере) но постепенно весь код переписали, графику перерисовали (что бы не нарушать копирайт) и технически сейчас проект имеет мало общего с оригинальной игрой (геймплей, естественно, в основном сохранили).
                            0
                            Супер, супер! Тоже в молодости потратил на неё кучу времени и ни капли не жалею! Там конечно самый прибыльный транспорт — железная дорога. Не зря позже вышел «Железнодорожный магнат». Пробовал в него играть — ну не то совсем.
                              0
                              Это неимоверно круто! Приятно еще раз осознать, что этим миром движут маньяки :)
                              Кстати, если в браузере включено управление мышиными жестами, да еще и по правой кнопке, то карта не движется, плюс непонятные эффекты проявляются.
                                0
                                На Firefox 13, Ubuntu Linux 12.04, Intel Atom 1.6 GHz подтормаживает весьма сильно, конечно (2-3 FPS и поезда с автобусами еле ползают), но всё-равно очень здорово.
                                  0
                                  Большое спасибо! Даже не мечтал о таком!
                                    +1
                                    True. Правда самый кайф в OTTD — рубаться по сети, надеюсь в веб-версии это появится, тогда это будет ещё более интересная и полезная вещь.

                                    Дальше, наверное, SimCity?
                                      0
                                      Не, дальше по плану доведение до ума онлайн версии. А потом возможно и появится социальный элемент.
                                      0
                                      Домой приеду и обязательно попробую. Тоже фанател от этой игрушки. Спасибо за ваш труд.
                                        0
                                        но внезапно оказалось, что релизная версия работает неиллюзорно быстрее


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

                                        прогоняется ли сборка на последнем этапе через closure compiler? бывает, что он принимает решения вредные для V8 (но полезные для других VM, которые сами не могут скажем делать инлайн), и из-за этого производительность после компиляции им падает, а не возрастает.
                                          0
                                          На последнем этапе работает closure compiler, без него слишком тяжелый js будет. К сожелению формальных тестов нет, все так на глазок. Цель была другая как вы понимаете. Однако, в emscripten есть механизмы для профайлинга и при желании такие тесты можно сделать.
                                          +4
                                          Одна из лучших игр на моей памяти. С возрастом как-то перестаешь играть в новые игры, а вот ностальгия по старым никуда не девается
                                            0
                                            Хм, оно действительно работает… Круто!
                                            В FF 13.0.1 после возвращения из full screen не вернулось меню верхнее. Пришлось жать F11.
                                              0
                                              Круть, круть и ещё раз КРУТЬ!!!
                                                0
                                                Вах! Вы молодец!
                                                Правда у меня как-то не адекватно обрабатывается скролинг местности — не возможно попасть экраном, в нужную часть — всё время к краям уносит (не фулскрин режим).
                                                  0
                                                  Согласен есть проблема, будем исправлять. Сам скролю кнопками)
                                                  0
                                                  МУЖИК!!!11
                                                  Любил, люблю и, думаю, буду любить эту игруху! Работает в последней опере без проблем. Правда на моем ноуте заметно так лагает, но все равно был рад почидеть повтыкать пол часика! :)
                                                    0
                                                    Это круто! Однозначно.

                                                    Кстати, подскажет кто, чем отличается TT от Locomotion? В последнего я рубался куда больше и куда с большим интересом.
                                                      0
                                                      Locomotion более современен и сделан на базе Roller Coaster Tycoon и не всем нравится механика постройки дорог в нем. И да в TTD нет трамваев. Как говорил автор, поле TTD или TT должен был быть TT 2, но все вылилось в серию Roller Coaster Tycoon, которые 2d.
                                                      0
                                                      Огромное спасибо за статью!
                                                      Новости про Дум и видеокодек на JavaScript не смогли мне открыть глаза и помочь преодолеть стереотипы о медленных браузерах, но вот после Вашей статьи я понял — в вебе можно писать полноценные и мощные приложения, а не надстройки над HTML и это реально круто. Надо двигаться в этом направлении.
                                                        0
                                                        Вы мой герой! )
                                                        Даже представить себе не могу какой титанический труд.
                                                          0
                                                          Интересно почему ТТD на винду не перенесли. Это же коммерчески-успешная игра! Или перенесли?? Но тогда почему забросили развитие? Там ж столь всего можно было придумать!
                                                            0
                                                            Видимо слишком дорого. TT/TTD еще на ASM писалась. Но «народные» порты и реализации очень преуспели там, где коммерческая разработка сбуксовала.
                                                            0
                                                            подскажите плиз, как размер окна изменить, очень уж неудобно в маленьком играть…
                                                              0
                                                              В правом нижнем углу множетели (x1, x1.5, x2). В FF13 полноэкранный режим дествительно выводит изображение на весь экран, в других браузерах не замечал такого.
                                                              –1
                                                              После нажатия на ссылку у меня не что Firefox умер, я систему еле оживил.
                                                                0
                                                                FF дествительно подвисает при загрузке, зато играется в нем хорошо.
                                                                0
                                                                в фулскрине при смени масштаба скачит курсор
                                                                  0
                                                                  Спасибо постораюсь исправить.
                                                                  +2
                                                                  Да, это нереально круто!
                                                                  Маленький фичреквест: сделать аккаунты, к которым будут привязаны сохраненные игры. Чтобы можно было зайти с другого компьютера/браузера и загрузиться в свою старую игру.
                                                                    0
                                                                    Сделал бы кто порт ru.wikipedia.org/wiki/Mine_Bombers, я был бы счастлив!
                                                                      0
                                                                      Ой вспомнил…

                                                                      В своё время играл в досовую версию, наверное, года полтора-два. Такую инфраструктуру построил ух… Жаль что сейвы не сохранились. :(
                                                                        0
                                                                        У меня игра быстрее всего идет, ВНЕЗАПНО, на IE10
                                                                        И передвижение с помощью правого клика самое плавное.
                                                                          0
                                                                          Что-то шрифты под мак версию в оконном режиме (при разрых разрешениях) неочень читабельны как-то. Режит глаз…

                                                                          Only users with full accounts can post comments. Log in, please.