What Is WebAssembly? The Compiled Code Behind Browser Games
What is WebAssembly? It is a compact binary format for code, which your browser checks and runs at close to the speed of a program installed on your computer. Developers write a game in a language such as C++, C# or Rust, compile it to WebAssembly, and ship it as a file next to a little JavaScript. This post explains what WebAssembly is, how it reaches your browser, and how to look inside a real game's file with two commands.
The real game is Tank City Reboot, two free tank games that run in your browser on a computer or a phone, and its game code arrives as a WebAssembly file the moment you press Play.
What is WebAssembly, in plain words
WebAssembly, often shortened to Wasm, is a set of instructions for a small virtual machine built into every major browser. MDN, the reference most web developers use, calls it "a low-level assembly-like language that brings near-native performance to the web". The project's own site, webassembly.org, calls it "a binary instruction format for a stack-based virtual machine".
Three things set it apart:
- It is a target, not a language you write. MDN says it is "not primarily intended to be written by hand". You write in another language, and a compiler turns your code into Wasm.
- It is binary. The file holds instructions packed into bytes, not readable text, which keeps it compact.
- It is sandboxed. MDN says Wasm is specified to run in "a safe, sandboxed execution environment", and it follows the same browser security rules as any other code on the page.
It is also an open standard. Its rules are written in a W3C group that includes people from all the major browsers, which is why the same file runs in each of them.
How code gets from a game to your browser
The trip has four stops:
- Write. The developer writes the game in a language they like. The Tank City games are written in C#, in files such as
Game.csandRules.cs. - Compile. A compiler turns that code into one
.wasmmodule. For C#, MDN lists it among the languages Wasm is a target for, and game engines with a web build do this step for you. - Load. The page's JavaScript fetches the module and hands it to the browser's WebAssembly interface. MDN says Wasm is "designed to complement and run alongside JavaScript".
- Run. The browser checks the module, turns it into machine code for your processor, and lets JavaScript call into it.

A worked example: look inside a real game's Wasm file
You can follow this with a terminal on any computer that has curl. The Tank City Reboot page holds a short list of the game's files in its own script. One of them is called game.wasm.unityweb, and the page passes it to createUnityInstance as the game's code. The name and that function come from the Unity engine's web build.
- Download it and count the bytes. The file is 3,127,009 bytes, about 3.1 MB. The server sends it as plain
application/octet-stream, not as Wasm. - Look at the first two bytes. They are
1f 8b, the mark of a gzip file. So this is Wasm wrapped in compression for the trip. - Unpack it. Pipe it through
gunzipand count again: 10,076,078 bytes, about 10 MB. The compression saved roughly two thirds of the download. - Read the first eight bytes of the unpacked file. They are
00 61 73 6d 01 00 00 00. The first four spell a zero byte then "asm", the label every WebAssembly module starts with. The next four say version 1.
The commands, if you want them: curl -s <address> | gunzip | head -c 8 | od -An -tx1 prints the eight bytes, and the same pipe ending in wc -c prints the size. The address is in the page's source, next to the word wasm. The second game, Tank City Zero Day, has its own Wasm file in its own folder.
That 10 MB is the whole game: every rule, every enemy route, every hit test. The two other big files are the JavaScript framework that connects it to the page, and the data file, which Unity's manual says holds the build's scenes and assets.
Why browser games use WebAssembly
The first reason is reuse. A game already written in C++ or C# can reach the web without being rewritten in JavaScript.
The second is the kind of work games do: tight loops over numbers, every frame. In the first Tank City game the board is 208 by 208 pixels, stored as 52 by 52 squares of 4 by 4 pixels, and tanks move one pixel at a time and stop flush against walls. In Zero Day, enemies find their way across a 25 by 25 grid of cells with Dijkstra's algorithm, where a step costs 1 and a step onto firewall costs 4. That is a lot of small sums, many times a second, which is what MDN means by near-native performance.
The cost is size. A compiled game is megabytes, so pages often load it only when asked. This one adds its loader only after you press Play; our post on why a web game loads only when you press Play measures each file.
What WebAssembly cannot do on its own
Wasm is boxed in on purpose. It does sums and works on its own block of memory; everything else goes through the browser:
- Drawing goes through the browser's graphics interface. These games need WebGL 2, in a current Chrome, Edge, Firefox or Safari; see what WebGL is and how games run in a browser.
- Keys and touches arrive as browser events that the page passes on, which is why a game must have focus; see why arrow keys scroll the page in browser games.
- Networking follows browser rules. Unity's manual says browsers do not allow direct access to IP sockets.
- Threads depend on the engine. Unity's manual says C# threads are not supported on the web, because WebAssembly lacks a garbage collector that works across threads.
- Making new code while running is out for a Unity web build: its manual calls the web an ahead-of-time platform.
Frequently asked questions
Is WebAssembly faster than JavaScript?
MDN describes Wasm as bringing near-native performance, and it suits heavy number work. The two are meant to work together: Wasm for the heavy loops, JavaScript for the page.
Is WebAssembly safe to run in my browser?
It runs in a sandbox and follows the same browser security rules as other web code. It can still do whatever the page itself is allowed to do, so the usual care about which sites you trust applies.
Do I need to install anything to run a WebAssembly game?
No. A current browser runs it like any page. Tank City Reboot also needs WebGL 2 for its graphics.
Why is a game's Wasm file sometimes not named .wasm?
Engines may compress or rename it for the trip. The Tank City file ends in .unityweb and is gzip on the wire, but unpacked it starts with the same four bytes as every Wasm module.
Get started
You know what is inside the button now: about 10 MB of compiled C#, sent as 3.1 MB, run in a sandbox beside a thin layer of JavaScript. Open the page, press Play, give the game focus with a click, and steer your antivirus tank with the arrow keys or WASD and Space. Then try Zero Day for eight-way moves, dashes and a boss every fifth wave.
Play Tank City Reboot: it plays in your browser on a computer or a phone, and needs no account.
The Family Computer tank classic, rebuilt inside a computer.
Visit tankcityreboot.vlvd.net↗


Comments
No comments yet.