Compiling to JavaScript: What, Why, and How?

| by André Rieussec

Five years ago, Build New Games would not have had much to talk about. The only viable option to make web games at the time was Flash. Since then, web browsers have progressed by leaps and bounds both in performance and features; and they are now capable of running pretty complex games. How complex? We don’t know yet, we’re all just getting started really. Someone pushes the envelope and wows the rest of us on a regular basis. You could be the next one to build something impressive and I can’t wait to see it.

We hear a lot about how HTML5 is ushering in a new era, etc… but what does that mean? I think that, beyond the new version number for the markup language, the broader notion of HTML5 is the correlation of three things:

  • New features in each of the three web languages: HTML, CSS and JavaScript.
  • Significant performance improvements in all browsers.
  • Higher level of compatibility among browsers.

Altogether, this is making a new breed of web apps possible, and I think we’re only seeing the tip of it right now. But let’s refocus on games; this is why we’re here after all. To make cool HTML5 games, all we really need is the JavaScript engine and the canvas element.

One thing which hasn’t changed all that much however is the JavaScript language itself. It has gained new APIs but the language itself is still mostly the same. As more and more companies jump onto the HTML5 bandwagon, the JavaScript part of their applications gains in complexity and developers have started feeling some growing pains. People have compared their development experience in JavaScript with what they were using before, typically a server-side technology; and they’ve found that they were missing a lot of the tools that made their old life easier. So some people have started to bridge the gap.

The Universal Language

Scott Hanselman dubbed JavaScript the assembly language for the web and the number of compilers targeting JavaScript seems to confirm that statement. While there are many attempts at improving the JavaScript development experience through a different language, not all of them will be relevant to a game developer. In particular, you probably want to avoid one that will add overhead to the JavaScript virtual machine (VM) and slow it down. With that in mind, let’s take a look at some of the different approaches that are out there. I’m going to classify those approaches in a way that made sense to me; hopefully it will work for you too.

1. JavaScript Supersets

Example: TypeScript

Some developers really like JavaScript; but they feel that such and such feature is needed before it’s just right. These are probably the kind of people behind the evolution of the ECMAScript standard (which is the standard behind JavaScript). But not everyone agrees on which features are really needed, and even if those are part of the upcoming version 6 of the standard; some developers would very much like to use them right away.

TypeScript is a perfect example of this approach, and it has every chance of becoming widely used.

The TypeScript compiler considers regular JavaScript code to be completely valid; but adds new features such as type annotations, classes and interfaces. All of that is stripped out at compile time to generate readable code, ready to be used on the browser. Some of those added features are planned for the next version of ECMAScript and the TypeScript team is trying to implement them in a way that respects the future standard. As web browsers progress in their support for ECMAScript 6, we may see TypeScript’s implementation fade out in favor of the standard.

JavaScript supersets are particularly interesting to those who are already familiar and comfortable with that language. They don’t try to hide JavaScript; but merely add syntactic sugar in the form of new keywords and constructs. As a result, it’s fairly easy to look at the compiled code and relate it to the original source, which eases debugging.

2. New Languages

Examples: Dart, CoffeeScript

Other developers think that JavaScript is beyond fixing; but since there is no other choice right now, they’ll put up with it by hiding it behind a new language, one which suits them best. The motivations are varied and consequently the proposed solutions are varied as well.

CoffeeScript was released in December 2009, making it a venerable elder in the community. It’s gained a lot of popularity and also created a fair amount of controversy (just search the web for “why coffescript” to get a feel). It seems that one of the main motivations behind it is to get rid of JavaScript’s C-like syntax; some people apparently dislike curly braces and semicolons very much. From what I’ve read, CoffeeScript is inspired by Ruby, Python and Haskell; I do see the similarity with Ruby but having never used the other languages, I can’t speak to that.

Google created Dart as a replacement for JavaScript, meaning they’re hoping to one day bypass the JavaScript VM altogether and have code run in a Dart VM instead. While they should be able to easily do that in their own browser, they’re facing an uphill battle if they try to get other browsers adopt the VM as well. Most of us won’t write our games in Dart if that means they will only run on Chrome. So to woo us in, Dart can also be compiled to JavaScript. So you can program in Dart today and distribute the compiled JavaScript; then if Dart VMs start appearing in browsers, you can just detect them and send them your actual Dart code instead.

While these new languages are often inspired by existing ones, you can still expect a learning curve as they will deviate from their inspiration based on the author’s preferences. The differences between your source code and the compiled JavaScript may also make debugging more difficult.

3. Existing Languages

Examples: Google Web Toolkit, Script#

If you’ve already been writing games for other platforms, chances are that you’ve been using C++, C# or even Java. If you’re a web developer looking to get started writing games, you may also be coming from the ASP.NET or Java world. Regardless of where you’re coming from, it’s likely that you already know one or more languages and you like your development workflow. Wouldn’t it be nice to still be able to leverage that in your web games?

That’s the approach taken by another group of people. It’s not necessarily a dislike of JavaScript that motivates them, although there may be some of that; but more a desire to be able to use a development environment they already know and enjoy. Java and C# both lend themselves pretty well to being compiled, or more accurately translated, to JavaScript, thanks to the similarities in syntax.

Some people at Google have apparently felt that way for a long time, since the first version of the Google Web Toolkit (GWT) was released in 2006 and the latest version came out in October 2012. GWT allows you to use Java for all of your development. Having been around for so long, it’s a pretty solid environment and definitely worth a look if you are a Java developer.

Before TypeScript, an engineer at Microsoft created Script# as a personal project. It’s since been used internally by teams at Microsoft. Script# compiles C# to JavaScript, taking advantage of Visual Studio’s great support of the C# language such as IntelliSense and refactoring. I’ve personally used and enjoyed Script# for several years on a commercial project; it tremendously increased my productivity over plain JavaScript.

One drawback of Script# is that it has not managed to implement some of the features of the C# language, making development cumbersome at times. A solution to this situation came early this year in the form of Blade, which supports most C# 4.0 constructs; we’ll cover it in more detail in the latter part of this article.

4. JS Literally as Assembly

Examples: Emscripten, JSIL

Up until now, the various languages I’ve mentioned were used to produce JavaScript code that’s more or less similar to the original source. Aside from any compiler optimization such as minification of the output, it’s possible to look at it and generally understand it.

Another way to do things is to literally consider JavaScript as assembly language: compile it directly to something, preferably optimized, that’s not meant to be readable. Emscripten and JSIL both share that approach, the former uses bitcode coming from LLVM while the latter uses .NET bytecode.

So both projects start with intermediate code which is itself the result of a compilation process from another language. The main advantage to this approach is that many languages are supported out of the box. For example, with JSIL you can use C# or VB.NET. On the other hand, you’re losing a big part of the connection with the platform with an additional level of abstraction. I haven’t experimented with either project myself; but they both link to pretty impressive demos from their home pages, so they are definitely worth considering.

5. Alternatives

There are a few more options available to help developers who are happy sticking to vanilla JavaScript.

Strict mode is a feature supported by modern browsers which alters the behavior of the JavaScript VM with parts or all of the code. Its goal is basically to help you write more efficient code by throwing errors if you don’t.

JSLint is a utility that will check your JavaScript code for various possible issues. It can be a good way to enforce good coding practices.

Google’s Closure Tools include an equivalent tool to JSLint. And also the Closure Compiler which is renowned for performing some advanced optimizations on JavaScript code. Note that the compiler could be used on handcrafted code, but it could also optimize the output of another compiler.

What’s the Point?

JavaScript is already a human readable language, there are tons of books and tutorials about it and libraries abound that make it easier to use. So why make the development pipeline more complicated by adding extra tools? In this section we’ll try to explore the main reasons why one may go that route and also discuss some of the caveats.

Keep in mind that not every language or compiler will bring you the same set of advantages. Take the time to evaluate a few options before diving in and writing a game. Also, my judgment is likely biased by many years of programming in C++ and C#. If you have a similar background then chances are the following points will resonate with you; otherwise you may completely disagree with me and that’s ok too.

Static and strong typing

In short, static typing means you need to declare the type of your variables before using them; strong typing means you have to explicitly tell the compiler how to perform an operation between two variables of different types.

JavaScript is a dynamically and weakly typed language: you never explicitly specify types and a variable’s value can be of any type. In addition, the language will let you do all sorts of operations between values of different types without much complaining. This is a great feature when you’re just trying to write some small script to perform a specific task on a web page; but as your code base grows, it becomes more and more difficult to maintain.

A statically and strongly typed language may feel too constraining, but it has undeniable advantages when dealing with a large or modular code base:

Compile Time Error Checking

One of my pet peeves when I worked on a large amount of vanilla JavaScript code was that a simple typo in a variable name would cause me hours of debugging. Because when you type something like:

1
countr = 1;

The JavaScript VM will not catch on to the fact that you really meant to assign counter and just made a typo, it will just create a new variable named countr. This could lead to bugs which are really annoying to track. A compiler would require you to declare counter and would show an error when it comes across an unknown symbol called countr. By catching many errors like this one at compile time, you save yourself a great deal of debugging later.

Test driven development (TDD) is particularly popular among web developers who use dynamic languages like Ruby, in part because it helps catch some of the issues a compiler would catch. But when writing a game, it’s not as straightforward to use TDD because you’re typically dealing with a highly interactive and graphical program. This makes a compiler that much more valuable.

Static Analysis

A statically and strongly typed language enables much more accurate static analysis. This allows the development environment to know a lot about your code without having to run it; and by knowing a lot about your code, it can offer you advanced functionality that will help organize and maintain your code.

Many editors and IDEs have improved their support for JavaScript in recent years. But the language’s dynamic nature makes static analysis useless; and dynamic analysis limited. So they are still unable to help developers with the level of sophistication that one gets when programming in C# with Visual Studio for example.

A number of developers feel that integrated development environments (IDEs) are slow and bloated and get in the way more than they help; they prefer to use lighter weight tools such as vim. But even vim has language specific extensions, one of the most common being syntax highlighting.

Some features which I find particularly useful in a modern IDE are:

  • Code navigation: I can easily go to the declaration of a function or a variable, which not only helps refresh my memory of how my old code works, but also lets me explore someone else’s code.
  • Refactoring: it’s important to organize a large code base; but you can’t always get it right on the first try. When your IDE has strong refactoring features, it can help you reorganize your code effortlessly.
  • Code completion: a long time ago, I used books a lot when programming, I couldn’t search the web because there was no web; so they were my only reference. After looking for the same thing enough times, I’d eventually remember it… until I stopped using it for a while, then I’d be stuck opening the book again. Now, IDEs are capable of showing us a list of relevant items when we start typing. Making it really easy to use rarely needed functionalities without having to remember exactly what something is called.

It’s perfectly possible to program without all of these bells and whistles; but when used properly they can save you a lot of time, make you more productive, and help you focus on what’s important: getting things done. This is one of the reasons why Microsoft came up with TypeScript and Google came up with Dart: they reasoned that better tools would be easier to create if the language had certain features currently missing in JavaScript. If you compile to JavaScript from a language which already has strong tools, then you’ll get most of the benefits of these tools as well.

Class-based objects

JavaScript is an object oriented language in that it considers everything as an object. However, it implements an unusual model based on prototypes. Many developers prefer a more familiar concept based on classes and inheritance; and over the years, several patterns have emerged to reproduce variations of such models in JavaScript. If you compile from a class based language into JavaScript, the compiler will take care of the boiler plate code that simulates classes. Additionally, if your language of choice is statically typed and your editor supports that, you may benefit from all the features I mentioned in the previous section on static analysis.

Code Organization and Reuse

I’m sure you already know that organizing your code is important. As your game grows and you write more and more code, it becomes very helpful to be able to split it among various files and folders. In C# for example, Microsoft has encouraged developers to place each class in its own file and each namespace in its own folder.

It’s easy even for a small game to grow to dozens of code files; however on the web, having too many files is a bad thing. For that reason, many developers have come up with ways to combine multiple JavaScript files together in order to serve a single file to the browser. Some compilers will take care of that for you, without having to specify which files to merge together. The JavaScript file will really be the equivalent of a library or a compiled program.

You can also easily organize your code in various libraries that you can reuse between projects.

Share Code with the Server

At some point you may decide that you want your web game to interact with a server. Whether you just want to save high scores or write a massively multiplayer game, you will end up sharing structured data between the clients (web browsers) and the server. Using the same language for your server side and client side code offers some interesting possibilities.

You can place your data structures in code files which will be included in both projects, so you only need to maintain them in one place. And because you’re using a compiler, you can safely make a change in one project and the compiler will let you know if it breaks the other one.

It may even be possible to share some logic between client and server depending on the language and tool you choose.

Performance

In order to achieve drastic performance gains, the various browser teams have resorted to many advanced techniques involving just in time (JIT) compilation. As a result, JavaScript is now closer to traditional compiled languages such as C++ than ever before.

Very recently, a particular session held during Microsoft’s Build event caught my interest. It explored in great detail how the way a JavaScript program is written can dramatically influence performance. The conclusion being that to get the best results, you need help the JIT compiler by treating JavaScript as a statically and strongly typed language. It’s also OK to simulate classes because so many people do it that JIT compilers have been made to optimize such pattern.

You could implement these optimizations manually in plain JavaScript. But a compiler can provide properly formatted code for you and ensure you don’t accidentally perform unnecessary type conversions.

Caveats

No matter what, it’s still JavaScript

When choosing a compiler, keep in mind that your platform remains JavaScript. It’s still a good idea to understand how things work under the hood: you may be tempted to use some fancy feature from your language of choice only to realize that it takes a lot of code to implement it in JavaScript, resulting in a performance hit.

Debugging

At one point or another, you’re probably going to want to debug your code and figure out why something isn’t behaving as expected. Thankfully all modern desktop browsers now include very potent debuggers that will make your life easier. However you may have a bad surprise the first time, as the code you’ll be dealing with is not the one you typed.

Depending on the language and compiler you choose, the resulting JavaScript code may be very similar or completely different from the source. This could complicate debugging quite a bit.

Google has come up with a way to make debugging easier in Chrome using source maps, which describe the relationship between a JavaScript file and the source code it was compiled from. The feature is likely coming to other Webkit based browsers and it’s also coming to Firefox. Some compilers already have built-in support for source maps such as Closure and TypeScript.

Keep that in mind as you decide on whether you want to use a compiler and which one you’d rather pick.

Performance Concerns

Most compilers will require your game to download some sort of core JavaScript file. That file contains support code that helps implement features in JavaScript which are specific to the language being compiled. The size of that file will give you a hint as to how much overhead your compiler may be adding.

Certain languages favor syntax and conciseness: they make complicated things seem simple by only taking a line of code. This may result in a lot of code behind the scene. What makes business applications easy to write may not be as useful to game developers.

A Concrete Example: JavaScript Game Development in C# using Blade

What would be a programming article without some code samples? In the remainder of this article, we will go over the creation of a game project using the Blade compiler. The complete code is available on GitHub.

Why Blade?

In the first part of this article, I’ve attempted to keep a panoramic view of the landscape. With so many languages available, it’s quite likely that you will prefer a different one than me and I hope I gave you enough pointers to do some experimentation and make your choice. Now that we’re getting into some code, I should explain why I chose Blade.

A few years ago, I was working on an ASP.NET project that involved a fairly complex single page application. The large amount of JavaScript code was becoming very hard to maintain, and reusing UI controls was also difficult. Using Script# allowed me to implement new features at a pace and complexity level I would not have been able to sustain if I had used plain JavaScript.

More recently, a good friend of mine released the Blade C# to JS compiler which supports most C# 4.0 constructs; so I decided to make the switch as Script# is still limited to C# 2.0. I like programming in C# because I think it’s a well-designed language; I also enjoy Visual Studio very much. Blade is a C# to JavaScript compiler; but by adopting JavaScript coding style and base types, it really feels like a kind of JS#.

C# has many constructs which just make life easier, and mapping them to JavaScript is simple in most cases. Let’s look at a few examples of how Blade does it:

Classes

Below is a simple class declaration in C#:

Blade will compile it to the following:

In this particular case, there is a bit of boilerplate code. Remember that JavaScript does not support classes so Blade actually simulates that using a pretty common pattern. It’s nice to have classes, but it’s even better not having to write all of that extra code every time.

Types

Here is an example of how C# variables are represented in JavaScript. As you can see, the compiler simply strips the type information: static typing is just a programming time convenience with virtually no overhead on the compiled code.

C# code:

Compiled JavaScript:

The i.toString() call is a result of strong typing. While this may seem counterproductive to someone who writes a lot of plain JavaScript code; this actually helps the JIT compiler by avoiding changing the type of variables at runtime.

Note that C# also supports type inference, meaning this:

1
var d = new Date();

is valid C# code, the compiler just figures out the type of d based on its first assignment. The JavaScript code produced will be identical.

Generics

Generics must be one of the easiest feature to implement, there’s pretty much nothing to do:

Becomes:

Etc..

Many other features fit in nicely, such as lambdas. The dynamic keyword makes it easy to use JavaScript fields and functions which are not known to Blade, such as vendor extensions or third party libraries.

The Smiling Face sample

I intended this article to be an introduction. There are many more game programming subjects I’d like to cover, but I thought it was important to explain why all of my code will be C#. Hopefully this is clear now, and we can move on to looking at some code.

The sample I’ve written to accompany this article is also an introduction. We’re going to lay the base for what will hopefully become a long series. While my preference went to Blade, everything should still apply no matter what language you choose to use; even plain JavaScript. It’s just easier with Blade.

As mentioned above, you can find the code on GitHub. I will be using screenshots from Visual Studio 2010, but you may just as easily use Visual Studio 2012 or even SharpDevelop which is free. You will find more detail on the project page.

Three Projects

One of the benefits of using Blade is Visual Studio’s ability to manage large code bases. While it’s a bit early to have that large code base, we will hopefully get there after a few more articles. In the meantime, let’s plan for that to happen.

I’ve divided the code into three projects:

  • Web is a simple website which will serve our static resources: some HTML pages, CSS style sheets, images and of course our JavaScript code. Our code will remain purely client side for now, so there’s no need for a server side technology.
  • Framework is a Blade class library project which will contain a reusable game framework. It’s not much right now but we’ll flesh it out over time.
  • 1. Smiling Face is another Blade class library and also our first demo. Its only real purpose is to have something we can run that will show the features implemented so far in the Framework.

Stay Classy…

Another aspect I really wanted to demonstrate is the advantage of being able to use classes and inheritance. If you run the demo, you will notice a little screen icon at the bottom right of the page. Click it and you’ll get a simple configuration menu allowing you to change the graphic settings of our demo.

This menu is built by a hierarchy of classes designed to be easily extended in order to support more configuration options. The Menu class handles both the icon and popup, and then the various settings are built as such:

If you look at the content of these classes, for example StretchToWindowSetting, you will see that the code is pretty small. Of course, I’m cheating a bit here: it took me a few days to come up with this setup. But that’s a benefit of being able to easily refactor code: it’s possible to experiment and reorganize everything very quickly until it’s just right.

With all of these classes, creating a settings menu for a game is very easy. The demo uses the default menu from the Game class, the code looks like this:

But it would be very easy to override this method in SmilingFaceGame and provide a custom menu for our demo. This leads us to another example of using classes: the framework contains a Game and a Scene class which are base classes with functionality that will be useful to most games (or demos).

A game will have a class that inherits the Game class: this will be the main object. Then it will have any number of classes implementing Scene. These will represent things such as a title screen, each level and cut scene. In our first demo, the game is SmilingFaceGame and the only scene is SmilingFaceScene.

The web page that will host our game is as simple as it gets. With just a bit of JavaScript to instantiate our game object:

You can also look at the whole file.

When building the code, post build events in the Blade projects properties will copy the output JavaScript files to the appropriate location in the Web project. If you look at the framework’s code, you will see that it’s relatively easy to follow and relate to the original C# code. While you’re there, take a look at Blade’s core file. As you can see, it’s very small and won’t cause much overhead to your code.

Take some time to look at the code, build it on your computer, play with it and let me know what you think in the comments!

in JavaScript .

Comments