Transport Tycoon Deluxe / Emscripten part 2

Transport Tycoon (Transport tycoon) is pretty old, but still enjoyable, especially the maniacs, the game is in the genre of RTS. /.../

There is also OpenTTD, outdoor product manyatta iPhoto, resulting from the game can not be distracted even in the toilet and underground, setting her on the Communicator or PDA.
lurkmore

I can honestly say: I killed a huge amount of time playing Transport Tycoon Deluxe. I'm just a fan of this game. So when on Habre the article appeared about how the guys from mozilla have ported Doom, I hit on the idea – to migrate one of my favorite games here on the Internet. By the way, the article was scarce, but I learned the main thing – the porting can be done using emscripten. Since the inception of the thought of the possibility of such a project was not less than a year (my first attempt crashed on the rocks of misunderstanding). And now I'm in a hurry to please you all: I did it! Now to sit ass playing TTD you can be located anywhere connected to the Internet.

And here is the video:



The impatient can start play now. Please, treat with understanding, if something goes wrong. This version is only tested. The game certainly works in FF13 (the recommended browser) and Chrome(ium). I hope my kopecny the server will handle the load. And Yes, I know about the pink tiles, working on it.

the

OpenTTD


I want to say a few words about the project OpenTTD, which has donated the source code for the JavaScript version. The project includes General estimates of 300 000 lines of C++ code. Moreover, the project possibilities are staggering. Judge for yourself:
the
    the
  • Four GPUs (driver)
  • the
  • Five sound drivers
  • the
  • little/big-endian
  • the
  • In the source codes supports single-threaded and multithreaded execution
  • the
  • Work in a network environment (loading graphics and music sets from the network) and without it
  • the
  • Multiplayer
  • the
  • Compression of the save files using lzma
  • the
  • render Caching
  • the
  • the animation of the tiles through the rotation of the color palette
  • the
  • Built-in scripting language squirel

Most of the code written with a twinkle, creatively. It was very interesting to dig in the guts of this project. Unfortunately, this contrast must pay and in this case, I was faced with a monstrous build system. I had to write a perl script that automates the patching of makefiles OpenTTD, for the needs porting.

To port OpenTTD managed in the following configuration:
the
    the
  • single-threaded mode
  • the
  • little-endian
  • the
  • completely disabled networking opportunities
  • the
  • video driver – patchany SDL
  • the
  • in-house sound driver
  • the
  • patchany mechanism for saving games on the server
  • the
  • patchany resource locator of the game

Else the default.

the

Emscipten


On porting code conjured emscripten, and I put a spell on him, so he could digest this lump. Building on our previous article, will describe how this esoteric technology works.



The idea is simple: C++ code is compiled into LLVM byte code with the help clang. Bytecode, in turn, is compiled into JavaScript using emscripten. LLVM bytecode is an intermediate code that can run on a low-level virtual machine. Specifications LLVM byte code well documented and is one of the reasons why he was chosen by the sponsors as the intermediate representation of the code. The emscripten compiler tries to convert the bytecode instructions in the JavaScript code one by one, as in the figure below (left byte code, corresponding to the right of JavaScript).


For most instructions, this scheme works very well. However, we can say that the development of such a compiler a simple task. LLVM bytecode and JavaScript vary greatly. To implement more complex things (arithmetic, pointers, loops, error handling) have to do extra work. Here is a simple example of the different behavior of C++ and JavaScript.



The implementation of division in C++ will lead to discarding the fractional part of the number. To achieve the same functionality in JavaScript, you have to resort to tricks like Math.floor (the code is not correct for all cases, it is true for most).

A more complex example is the implementation of the loop in LLVM byte code and JavaScript:



Implement a similar functionality in JavaScript in numerous ways, but many of them are poorly productive, and here the problem emscripten to generate code as efficiently as possible.

In addition to these low-level things emscripten provides an implementation for: libc, libcxx, POSIX, SDL, GL, GLES and other libraries. Fully implemented, the file subsystem C (fopen, fclose, fread, ...). Most programs can be compiled using emscripten without any problems. The beauty of the ideology of emscripten is that there is no need to change the source code – it will work. In the case of successful porting of a project in JavaScript, the transition from version to version is easy and relaxed. For example, while I sawed emscripten, the community managed to release the next minor version of OpenTTD, I just synced the source and got a fresh port of the latest version, convenient.

the

Transport Tycoon Deluxe


Using emscripten to JavaScript compiled already of a sufficiently large number of major projects: Doom, zlib, Poppler, OpenJPEG, FreeType, Bullet, SQLite, Python, Ruby, Lua and others. Now in group discussion emscripten is an active discussion of the Fortran compilation.

However, in order to successfully compile a complex project, you need C++ knowledge. For example, what is the result I got with the first successful compile OpenTTD.



In this version did not work neither the mouse nor the keyboard. Only now is everything.

The emscripten authors claim the support of a large number of libraries, but support for this is not fully implemented. For example, in emscripten implemented only a small subset of SDL 2.0 SDL 1.2 admixture. Accordingly I was faced with a lack of the necessary functions in emscripten, and I had to implement them myself. But I became one of the committers of the project (CDA!!!).

The problem depicted in the screenshot above, was caused by the fact that the implementation in emscripten SDL 1.2 supported only 32-bit surface and knew nothing about the flag SDL_HWPALLETE. The image in SDL_HWPALLETE is encoded with eight bits (256 colors). This explains the compactness of the image. Why is it, the horizontally flipped I do not understand still. In addition, we had to implement the following functions: SDL_VideoModeOK, SDL_VideoDriverName, and SDL_QuitSubSystem strndump. I have identified a serious problem in performance, which was communicated to the authors and they rectified it. Unfortunately, my edits on the audio subsystem was not included in the code base emscripten at the moment.

Revealed many problems related to the optimization flags emscripten. Pink tiles you see on the video, it's just optimization problems – no flags are desired color. It is very difficult to deal with problems of this kind. The problem itself is insane (only pink tiles of water with an inclination of 45 degrees in two directions) and porting with optimizations enabled is very long (over 2 hours), so often not around. But to deliver what the project quite rapidly, bugs are closed within a day or two (mine, at least).
In General, porting a complex project with emscripten you can, if you really want. In any case have to face the necessity of making minor changes in emscripten or the project itself. But having succeeded once, you can repeat the porting again and again without any problems.

the

Is terribly slow isn't it?


Alon Zakai (the Creator of the project), speaking at the conference report about emscripten, expressed the opinion that JavaScript itself is fast enough and the bottleneck is the compiler and it is not always the optimal code translation. He gave the following sign:



SpiderMonker (SM) is a JavaScript engine Firefox; Typed Arrays (TA) is the fastest at the moment, the way to emulate the heap in JavaScript that emscripten provides. In the table cells numbers indicate how many times the execution of compiled JavaScript code is slower than native code. Scatter, as we have seen, from one to eight times (although the average is somewhere near 3-5).

The numbers in the figure below show how many times one or the other language slower than C++ test Suite http://shootout.alioth.debian.org/. (approx.: This information is already outdated and aims to show that JavaScript a fast language. If someone does not agree with this, please speak up, but other languages let's not touch it – they probably already have the other figures in these tests.)



Overall, I agree with these figures and say that the JavaScript version of OpenTTD is about 5-7 times slower than native. But only in FireFox. And here is the amazing thing I discovered. I led the development of c nodejs + chromium. I'm a fan of FF, but unfortunately, delainie JavaScript version of OpenTTD were the size of fifty megabytes and hung FF tightly, while chromium worked very fast. I thought chromium on the wave, but suddenly it turned out that the release version works in FF its faster (2-3 times) than in chromium. So I would recommend to play using FireFox.

I am very glad I took the project and brought it to completion. I learned a lot about clang, llvm, python, and javascript. Talked with interesting people. Community liked my project, recently the authors have made it onto the page of demonstration projects emscripten. I got great satisfaction from the work done. In General that and all I wish.

Again the reference: play-ttd.com
the Application in Vkontakte

UPD. project website.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

When the basin is small, or it's time to choose VPS server

Performance comparison of hierarchical models, Django and PostgreSQL

From Tomsk to Silicon Valley and Back