19 Jan 2013

A Drakensang Online map viewer in emscripten

Update 2: The OSX/Radeon performance problem should be fixed now. See here: http://flohofwoe.blogspot.de/2013/01/a-radeon-fix-and-more.html

Update: Just found out that the demo runs incredibly slow on a 15"Mac when running on the discrete AMD Radeon HD 6770M chip (it's actually much faster on the integrated Intel HD 3000). This is both on Chrome and Firefox, reason unknown yet. So if you have one of these, note that the demo runs actually a lot smoother ;)

I did a very simple proof-of-concept Drakensang Online map viewer in Nebula3/emscripten (as always, Chrome or Firefox required), to see how JS+WebGL can deal with a close-to-real-world 3D scenario:

Drakensang Online map viewer
This is work in progress and I will spend more time with optimizations before moving on to the next demo.

You'll notice that there's still frame-rate-stuttering when moving around the map (with left-mouse-button + dragging). The bad type of stuttering is caused by asset loading which happens on demand when new graphics objects are pulled in as they enter the view volume. I don't know yet what causes the lighter stuttering when moving around in areas which are completed loaded. I need to do a detailed profiling session to figure out what's going on there exactly. The stuttering also happens (to a lesser extend) in the native OSX version of the demo. It's most likely the preparation and creation of OpenGL resources, like vertex buffer, index buffers and textures. I will need to figure out how to move more of the asset creation stuff out of the main thread.

The demo is also quite demanding on WebGL. Despite the pseudo-instancing which I implemented recently there's still a lot of OpenGL calls per frame. Support for the OES_vertex_array_object (Chrome already exposes this) and something like ARB_instanced_arrays would help a lot to reduce the number of GL calls drastically (the JS profiler currently shows the vertex array definition as the most expensive rendering-related code, followed by the matrix array uniform updates for the pseudo instancing code).

Finally I've added a new Nebula3 code module to this demo: the ODE-based physics and collision subsystem is now also running in emscripten (no changes were necessary), the demo sets up a static collide world at startup and uses this to perform stabbing checks under the mouse pointer. Unfortunately adding ODE almost doubled the size the of the generated Javascript code. This is another incentive to finally get rid of our (somewhat bloated) physics wrapper code and ODE, and build a new slim collision system, probably on top of the Bullet collision classes (we're mainly using the current physics wrapper for simple collision checks on a static collide world in the live version of Drakensang Online, so not much of value will be lost).

Also, originally I wanted to include SQLite into the demo, since additional map info is currently stored in an additional SQLite file (lighting information, player start position, etc...). But this didn't work out of the box because SQLite's file i/o code must be adopted.

This wouldn't be hard to fix, but I actually want to get rid of SQLite for a long time. SQLite was really useful as save-game system in the single player Drakensang games, but if you don't need to save game world changes back, a complete SQL implementation in the client is just overkill. So this is another good reason to finally get started with a nice and small TableData-subsystem in Nebula3.

The frame-stuttering is a tiny bit disheartening, but on the other hand this is to be expected when bringing a complex code base over to a new platform. Most important right now is to really know what's going on, so I will probably spend some time adding profiling code and do some performance analysis next - together with text rendering to get some continuous debug statistics output on screen.

Exciting stuff :D


Ningz said...

Very well done! I love this work.

Suppose that you or someone going to publish their game through this way, will you/they be worried about the safety of the source code or assets? Because all your codes were there, as compiled JavaScript though?

BTW. I've seen several Nebula3 in Google Code, which one of them is the TRUE Nebula 3? Some of them had no activity for a very long time.

Andre Weissflog said...

Re-engineering the code is pretty much impossible by the way emscripten works (LLVM breaks down the C++ code structure to assembly level first, then emscripten converts this to JS, which basically still looks like assembly with if()s and while()s, and then the closure optimizer rips the code apart and rebuilds the whole program again, and then minifies everything. The result is just a big soup of random characters and completely unreadable. The assets are not encrypted, but if somebody decides to use those for his own project, then this is something for our legal departement to take care of :)

Andre Weissflog said...

PS: actually I didn't keep track of public Nebula3 repositories. The one with the most recent changes and most activity is the right one I guess ;)

eRiC Werner said...

hey nice! I can imagine this platform has already quite something to offer when it comes to text rendering ^^

Andre Weissflog said...

PPS: I meant "reconstructing the code", not re-engineering... you can look at the source code through your browser. At the top there's some handwritten Javascript code, but that's just the wrapper code which handles the output console widget. Later there's a long string of gibberish, and that's the actual cross-compiled C++ code. It's just as useless as a compiled native executable without debug information.

Andre Weissflog said...

Actually I was planning to use the distance-field text rendering we recently built into Drakensang Online, which is absolute amazing, you can render any text size from a single font texture: http://www.youtube.com/watch?v=CGZRHJvJYIg