Hacker News new | past | comments | ask | show | jobs | submit login
OpenTTD Compiled to WebAssembly (milek7.pl)
343 points by garaetjjte on Mar 31, 2019 | hide | past | web | favorite | 88 comments

The combination of C++ and OpenGL is really the ultimate in portability. A language supported on almost every platform by one if not more implementations (sometimes 3), coupled with probably the most widely supported graphics API. Of course you lose accessibility, and many platform API conveniences, but you get a more stable and performant platform to work with. In fact it's the platform that most web browser themselves are heavily based on. For another example just look at what Epic was able to do with Fortnite, one code base that literally runs everywhere.

Magnum [0] is a favorite of mine for creating portable OpenGL C++ applications. It also has support for compiling to WebAssembly [1] and using WebGL2.

0 - https://magnum.graphics

1 - https://magnum.graphics/showcase/picking/

Yeah there is MoltenGL which will probably be open sourced eventually. The real future is Vulkan which is moving to replace OpenGL and for the Apple platforms there is MoltenVK [0] (Vulkan re-implemented on top of Apple's new Metal) which is open source. Magnum has an initial Vulkan backend [1], and many other engines have them or are building them as well.

0 - https://github.com/KhronosGroup/MoltenVK

1 - https://blog.magnum.graphics/announcements/2018.10/

MoltenGL proprietary and not the only implementation of the GL library on top of modern APIs. There's also ANGLE.

It worked pretty OK-ish in my project running OpenGL game on Windows Phone 8. I was using Microsoft's fork [2].

Another alternative is GLOVE [3], which is a software OpenGL on top of Vulkan.

Another interesting project is WebGPU [4] which targets to provide Vulkan-like APIs across various platforms in browsers.

As it's offshoot which is not quite related is GFX-rs, which became a cross-platform Rust library providing low level graphics API (HAL layer).

looking forward seeing ANGLE getting Metal backend, which been just a promise so far.

[1] https://github.com/google/angle

[2] https://github.com/Microsoft/angle

[3] https://think-silicon.com/products/software/glove/

[4] https://en.wikipedia.org/wiki/WebGPU

[5] https://github.com/gfx-rs/gfx

That’s cool I didn’t realize MoltenVK was maintained by Khronos.

From what I understand it was bought out by Valve and donated to community in its quest to promote gaming on Linux (where no Metal or Dx12). I can only speculate that it wasn't most successful commercial product.

I think it was donated to them.

Valve acquired the project and made it open source.

OpenGL is deprecated, not removed, you can still use it in current versions of macOS as long as you are fine with the version it ships (which in general should be fine for a ton of 3D games, remember that something like Doom 3 was built on OpenGL 1.5 + extensions and Rage was built on OpenGL 2.0 + extensions). Apple might break it sometime in the future, but Apple might break any API in the future (i have several applications and games that stopped worked every time i upgraded macOS and the developers had abandoned them - one of the reasons i decided to stick with Windows over the years is that old apps keep working) so that comes with the territory.

Doom 3 was released 15 years ago. A lot has changed since then

It is still technically more advanced and looks better than the vast majority of indie games and my point was that if something like Doom 3 (or Rage) can be made using OpenGL 1.5+exts (or OpenGL 2.0+exts, for Rage) then OpenGL 4.1+exts that macOS provides is more than enough for a ton of games.

Yeah, it'd be nice if macOS supported OpenGL 4.6 and even better if Apple wasn't braindead enough to deprecate OpenGL instead of fixing one of the worst implementations (and still the only that has the core/compatibility divide that makes matters even worse), but even with all that taken into account, OpenGL on macOS is still capable enough for almost every game bar the more high end ones.

No browser by default runs WebGL on native OpenGL on Windows either.

Also, keep in mind, that while WebGL is based on OpenGL ES, it is emulated using Microsoft Direct X on all Windows machines (by all mainstream browsers through the Angle project https://github.com/google/angle).

Nitpick: angle is the default but you can run at least Firefox on Windows native OpenGL drivers. Maybe Chrome as well?

And emulated on game consoles as well.

> Fortnite, one code base that literally runs everywhere

Except Linux?

It runs on Android. They probably haven't released a desktop Linux version because of the small market share, but there's probably no technical reason why they couldn't.

If so, then I'm going to guess it's about whatever anti-cheating invasive NSA-in-the-box DRM they use; it probably won't work on Linux.

Indeed. Unreal engine looks compatible since ~2015 https://www.unrealengine.com/en-US/blog/unreal-engine-4-and-...

The Linux kernel is an implementation detail on Android, in what concerns userspace.

I'm not sure Fortnite is a very good example, it uses OpenGL on very few of it's platforms.

> Fortnite, one code base that literally runs everywhere

Dude, you made me think that I've missed the Linux release of the Fortnite!

Fortnite doesn't run on my mac though

OpenGL never was a thing on game consoles.

All Sony console use a derivative of OpenGL[0].

[0] https://en.wikipedia.org/wiki/PSGL

Actually, only as footnote on the history of 3D APIs.

PSGL was largely ignored by everyone that matters in the game industry and eventually dropped.


"At one point, Sony was asking developers whether they would be interested in having PSGL conform to the OpenGL ES 2.0 specs (link here). This has unfortunately never happened however, as developers seem to have mostly preferred to go with libGCM as their main graphics API of choice on PS3. This has meant that the development environment has started becoming more libGCM-centric over the years with PSGL eventually becoming a second-class citizen – in fact, new features like 3D stereo mode is not even possible unless you are using libGCM directly."

Just like everyone raves around Switch having Vulkan support, when most studios are using Unreal, Unity and the main 3D API, NVN.

As rule of thumb, instead of believing what gets posted on FOSS friendly web sites regarding 3D APIs, GDC Vault, Making Games, IGDA, Connect, EDGE, Retro Gamer, and AAA studio dev blogs are a much better source of information.

> The combination of C++ and OpenGL is really the ultimate in portability.

Wouldn't the credit belong to Magnum rather that C++ plus OpenGL, given the tremendous amount of work that goes into making things seem portable to the end user of the library?

A viable alternative is Rust + OpenGL, using gfx[1]. I've had success cross-compiling one Rust codebase to Windows, Mac, and Linux native applications that can render OpenGL graphics. I even got the compilation for all three targets working from within a single docker image, meaning the build can easily be set up in any modern CI system.

[1] https://github.com/gfx-rs/gfx

Rust still lacks support for many platforms where there is a C and C++ compiler, and on Windows it is found lacking regarding COM/UWP.

Go + OpenGL works too, though the sizes of binaries when generating to WebAssembly isn't yet very good.

Needs some optimisation done on that part. ;)

For anyone else wondering OpenTTD is Open Transport Tycoon Deluxe.

I wondered too.

"OpenTTD is a business simulation game in which players try to earn money via transporting passengers and freight by road, rail, water and air. It is an open-source[2] remake and expansion of the 1995 Chris Sawyer video game Transport Tycoon Deluxe."


It was and is a fantastic game. I played it for many hours growing up.

EDIT: the original, Transport Tycoon.

Never heard of that before.

What occurred to me was "Test to Destruction".

I ran it for a few minutes and then it said:

  Uncaught RuntimeError: float unrepresentable in integer range
    at wasm-function[3502]:49
    at wasm-function[6940]:395
    at wasm-function[6939]:347
    at wasm-function[3103]:334
    at wasm-function[3284]:30
    at wasm-function[4902]:3105
    at wasm-function[4903]:654
    at wasm-function[8083]:442
    at wasm-function[8082]:3
    at wasm-function[9782]:13

You can avoid that issue by using clamp mode when compiling: https://emscripten.org/docs/compiling/WebAssembly.html#trap-...

Thanks, changed that setting.

Looks like there's a bug in wasm-function.

I'm not so sure.

Porting c/c++ codebases to WebAssembly is both super fun and frustrating.

Network stuff, as mentioned in other comments, is futzy because of the limitations of running in a browser environment. A surprising amount of network code "works," in the sense that it compiles and runs translated to web sockets. (Great work from the WebAssembly and Emscripten community.) But, you know, web sockets.

pthreads support landed in Chrome recently: https://developers.google.com/web/updates/2018/10/wasm-threa...

Pipes, select, and unix domain sockets aren't really supported (afaik).

It's a shame the online content functionality isn't working because of a missing zlib library. OpenTTD really has quite an active community of modders and asset creators.

You want the trains from your home country? They are available, and probably up to date to the current year. Just download them from within the game, enable them, and start a new game.

It looks amazing, but for some reason it's not polished on my machine. There are many small bugs that don't exist in the native version. For example, when I scroll, the pointer stay frozen till I finish scrolling, and only then "jumps" to the new location.

It makes a huge difference between enjoyment and suffering in games.

This is super cool, TTD always has a special place in my heart. Any technical explanation why level generation is so much quicker? Not even a loading screen

TTD or Open TTD?

TT on my 486 took time to generate a map, (TTD is basically the same code I believe). Open TTD when you've cranked up the map size takes time too.

Perhaps you were playing TTD on a relatively powerful pc?

One of the coolest things to do is go on one of the many multiplayer servers and see some of the super train systems that have been built. 16 lanes high speed rail connecting thousands of nodes.

Multiplayer functionality doesn't seem to be working for me. Is this just me, or an artifact of the compilation?

The browser doesn't provide the usual POSIX api for opening TCP connections. With some work you can write a shim library that implements it in terms of websockets, but it still can't connect to arbitrary hosts. Instead you have to run a proxy server for it to connect to.

Could you use WebRTC instead, for true P2P?

You can. I've used WebRTC for multiplayer support in Quake 3 compiled to WebAssembly.

Do you have a link for that? Sounds super cool

The forked ioquake3 is available at https://github.com/seemk/ioq3

However it's not trivial to get it working at the moment, will hopefully soon come back to this project and finish it :D

You still need a proxy server, unless the OpenTTD game browser supports WebRTC connections.

Yeah, you'd need a proxy server (websockets) to establish WebRTC connections. Even after a WebRTC connection is established, you'd need a STUN or a TURN (coturn supports both) server to get around NATs. Pls somebody correct me if I'm wrong!

You should only need a STUN or TURN server if you are attempting to connect to a machine that is behind a NAT. OpenTTD servers are usually on public IPs (similar to HTTP servers), so a STUN or TURN server should not be required.

The biggest issue is that WebRTC connections do not allow you to send raw data over TCP or UDP[1].

That being said, it shouldn't be too difficult to just create a WebSocket server that translates between the native network protocol and HTTP WebSockets[2].

  [1] https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel
  [2] https://wiki.openttd.org/Network_Protocol

You're entirely correct. Here's a demo if you're interested: http://vrcade.io/win311

It even runs on my IOS phone. Incredible!

It runs on my old android phone too, but I don't think the game is actually playable. I couldn't move the camera around.

Actually it's quite playable as soon as you learn UI and used to multi touch that game is using. E.g as far as I can recall you just need 2-finger touch to move camera.

Didn't work for me.

IIRC you use the right mouse button to drag, so that makes sense.

Any idea how battery usage of webassembly version vs native looks like?

I'd assume that webassembly would consume more but maybe difference is not significant?

The original Transport Tycoon Deluxe game was written in assembly so it could run quickly on modest hardware, like a 486 at 50MHz.

OpenTTD isn't as efficient, but it's not that demanding either.

Not interested how quick it runs. Just energy expended through native and webassembly.

How quick it runs to an extent is correlated to energy usage. I know it's not the same but for a single threaded low memory usage game the correlation would be close.

On any given number of cores, sure. The original Transport Tycoon came about before multi-core systems and, as it was DOS based, even threads.

Power consumption is a product of cycles plus memory read/write operations.

I'm surprised at how good the sound is; that's where I've had the most trouble.

It's just uses Emscripten SDL2 for audio output. Here's build with MIDI music enabled: https://milek7.pl/openttd-wasm-music/

Hasn't OpenTTD been ported to JS in 2015? https://epicport.com/en/ttd Regardless, a WebAssembly port is perhaps more useful since improvements can be merged from upstream more easily.

Moving the cursor was really sluggish on Safari for the first two to five minutes and afterwards I didn't notice lag. Maybe it's some JIT-compiler warm-up phase?

this is really cool. Can't wait for GTA2

is GTA2 opensource yet?

no but neither TTD, the OpenTTD is a brilliant remake that is based on TTD.

Really amazing!

Yep, go Flash.


Everything old is new again.

It's not a fair comparison. Flash was a closed source non-standard technology.

That's not why most people hated it.

But it's part of the reason. It was also notorious for it's security flaws.

One reason I liked flash: You could disable malicious ads with flashblock without breaking 90% of the internet. With the cancerous growth of JavaScript APIs embrancing and extending on all that made flash evil that is no longer possible.

That train has sailed already anyways with JS, so I see no difference in that. Though I do expect websites to become more obfuscated - rendered by wasm so that adblocks and privacy protectors can't reach as well.

Flash now lives as Animate CC, however I can easily see future Websites being something like an Unity export.

WebAssembly on its current state still doesn't prevent internal memory corruption, due to lack of bounds checking enforcement.

Yes it does not escape the sandbox, however triggering stack corruption of local variables opens the door to explore changing the behaviour of function calls, while getting some goodies in the process.

It remains to be seen how secure is WebAssembly at scale, when black hats start actually turning their sights into it.

Given the runtime environment and limitations, I SERIOUSLY doubt WebAsm will be LESS secure than JavaScript's runtime in browsers itself.

You should have read all the way to the end.

"In 2013, Adobe open-sourced the Flash Runtime C++ Compiler as CrossBridge, and released it on the GitHub code hosting website"

That was not a release, was a code dump. It died and nobody cared about it.

It doesn't change the fact we are down the same road, and the user UI/UX of getting a web page that is nothing more than WebAssembly + WebGL will be hardly different than Flash used to be, open source or not.

I don't care, I used to enjoy playing with Flash, gave some sanity to the div/CSS soup pretending to be native UI controls.

Webasm is much faster. I never heard anything about quake 3 being compiled to flash.

No one bothered to port it. Where are those benchmarks?

All the following games are hardware accelerated on 2010-11 GPUs.

"Adobe Flash Stage 3D demo video by Frima Studio"


"Stage3D - The Demo of Porting Epics Unreal Engine to Flash"


"3D Gaming Powered by Adobe Flash Player"


"Flash Stage3D Demo "BIRTS" by SQUARE ENIX at ADC MEETUP"


For anyone curious how the 3D API actually looked like, https://www.adobe.com/devnet/flashplayer/stage3d.html

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact