Hands-On Game Development with WebAssembly - Rick Battagline - E-Book

Hands-On Game Development with WebAssembly E-Book

Rick Battagline

0,0
36,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Make your WebAssembly journey fun while making a game with it




Key Features



  • Create a WebAssembly game that implements sprites, animations, physics, particle systems, and other game development fundamentals


  • Get to grips with advanced game mechanics in WebAssembly


  • Learn to use WebAssembly and WebGL to render to the HTML5 canvas element





Book Description



Within the next few years, WebAssembly will change the web as we know it. It promises a world where you can write an application for the web in any language, and compile it for native platforms as well as the web.






This book is designed to introduce web developers and game developers to the world of WebAssembly by walking through the development of a retro arcade game. You will learn how to build a WebAssembly application using C++, Emscripten, JavaScript, WebGL, SDL, and HTML5.






This book covers a lot of ground in both game development and web application development. When creating a game or application that targets WebAssembly, developers need to learn a plethora of skills and tools. This book is a sample platter of those tools and skills. It covers topics including Emscripten, C/C++, WebGL, OpenGL, JavaScript, HTML5, and CSS. The reader will also learn basic techniques for game development, including 2D sprite animation, particle systems, 2D camera design, sound effects, 2D game physics, user interface design, shaders, debugging, and optimization. By the end of the book, you will be able to create simple web games and web applications targeting WebAssembly.





What you will learn



  • Build web applications with near-native performance using WebAssembly


  • Become familiar with how web applications can be used to create games using HTML5 Canvas, WebGL, and SDL


  • Become well versed with game development concepts such as sprites, animation, particle systems, AI, physics, camera design, sound effects, and shaders


  • Deploy C/C++ applications to the browser using WebAssembly and Emscripten


  • Understand how Emscripten HTML shell templates, JavaScript glue code, and a WebAssembly module interact


  • Debug and performance tune your WebAssembly application





Who this book is for



Web developers and game developers interested in creating applications for the web using WebAssembly.






Game developers interested in deploying their games to the web






Web developers interested in creating applications that are potentially orders of magnitude faster than their existing JavaScript web apps






C/C++ developers interested in using their existing skills to deploy applications to the web

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Seitenzahl: 690

Veröffentlichungsjahr: 2019

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Hands-On Game Development with WebAssembly

 

 

 

 

 

Learn WebAssembly C++ programming by building a retro space game

 

 

 

 

 

 

 

Rick Battagline

 

 

 

 

 

 

 

 

 

 

BIRMINGHAM - MUMBAI

Hands-On Game Development with WebAssembly

Copyright © 2019 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

 

Acquisition Editor:Ashitosh GuptaContent Development Editor:Smit CarvalhoTechnical Editor: Ralph Rosario, Jane D'souzaCopy Editor: Safis EditingProject Coordinator:Kinjal BariProofreader: Safis EditingIndexer: Tejal Daruwale SoniGraphics:Alishon MendonsaProduction Coordinator:Jayalaxmi Raja

First published: May 2019

Production reference: 1300519

Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.

ISBN 978-1-83864-465-9

www.packtpub.com

 

To Kate, Luke, Lilly, and Cora – you are my world.
– Rick Battagline
 
mapt.io

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Mapt is fully searchable

Copy and paste, print, and bookmark content

Packt.com

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks. 

Contributors

About the author

 

Rick Battagline is a game developer who has been working with web- and browser-based technologies since 1997. He wrote his first computer game in 1996 and, in 2006, he founded BattleLine Games LLC., an independent game studio where he works to this day. That same year, his game, Epoch Star, was nominated for an award at the Slamdance Guerrilla Games Competition, and was listed in Game Informer Magazine issue 156 as one of "The top ten games you've never heard of."

Since then, Rick has written hundreds of games for platforms including the web, Windows PC, iOS, Android, Wii U, and Nintendo Entertainment System emulators. He has developed games in web technologies including WebAssembly, HTML5, WebGL, JavaScript, TypeScript, Flash, and PHP.

I want to thank Prasad Annadata and Steve Tack for their tremendous contributions to this book. Without your help, I would have never finished this. Special thanks to my editors, Ashitosh Gupta, Ralph Rosario, and Smit Carvalho, for all of their hard work. I would also like to thank my father, Richard, and my brother, John, who are there for me when I need them. Finally, I want to thank my wife, Kate, and my children, Luke, Lilly, and Cora. You mean everything to me.

About the reviewers

Prasad Annadata is a senior technologist with experience ranging from mainframes to cloud computing. His foray into game development started when he adopted classic minesweeper game to Unix. Recruited right out of college into a major consulting firm his career spawned consulting and major financial institutions. Prasad Annadata has been an author of several peer-reviewed papers on privacy and security, a professional technology reviewer for a chapter on Cyber Law in the book Chitty on Contracts: Hong Kong and a sole inventor of a B2B technology patent.

He has a bachelors and masters degrees in Computer Science and currently serves as an SVP in a major financial institution and his interests include cloud computing and cloud security.

I wish to thank the author, Rick Battagline, for thinking of me when it came to providing a technical review of this book. Also, I thank Packt Publishing for the opportunity.

 

 

Steve Tack is a software developer with 28 years of experience. Since the 1980s, he's enjoyed making computers do fun things, from programming simple games in BASIC on a Sinclair ZX81 to creating real-time 3D graphics on modern hardware.

 

 

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

Title Page

Copyright and Credits

Hands-On Game Development with WebAssembly

Dedication

About Packt

Why subscribe?

Packt.com

Contributors

About the author

About the reviewers

Packt is searching for authors like you

Preface

Who this book is for

What this book covers

To get the most out of this book

Download the example code files

Download the color images

Conventions used

Conventions used

Get in touch

Reviews

Introduction to WebAssembly and Emscripten

What is WebAssembly?

Why do we need WebAssembly?

Why is WebAssembly faster than JavaScript?

Will WebAssembly replace JavaScript?

What is asm.js?

A brief introduction to LLVM

A brief introduction to WebAssembly text

Emscripten

Installing Emscripten on Windows

Installing Emscripten on Ubuntu

Using Emscripten

Additional installation resources

Summary

HTML5 and WebAssembly

The Emscripten minimal shell file

Creating a new HTML shell and C file

Defining the CSS

HTML5 and game development

Immediate mode versus retained mode

Adding a canvas to the Emscripten template

Summary

Introduction to WebGL

WebGL and canvas contexts

An introduction to WebGL shaders

WebGL and JavaScript

WebGL coordinate system versus 2D canvas

Vertex and UV data

2D canvas to WebGL

Minor tweaks to the head tag

Major JavaScript changes

WebGL global variables

The return of vertex and texture data

Buffer constants

Defining the shaders

The ModuleLoaded function

The ShipPosition function

The MoveShip function

Summary

Sprite Animations in WebAssembly with SDL

Using SDL in WebAssembly

Initializing SDL

Clearing the SDL renderer

Using the WebAssembly virtual filesystem

Rendering a texture to the HTML5 canvas

Cleaning up SDL

Compiling hello_sdl.html

Render a sprite to the canvas

Animating a sprite

Moving the sprite

Compiling sprite.html

Summary

Keyboard Input

JavaScript keyboard input

Adding SDL keyboard input to WebAssembly

Using keyboard input to move a sprite

Summary

Game Objects and the Game Loop

Understanding the game loop

Writing a basic game loop

Compiling gameloop.html

Game objects

The player's spaceship game object

Object pooling

Pooling the player's projectiles

Creating an enemy

Compiling game_objects.html

Summary

Collision Detection

Types of 2D collision detection

Circle collision detection

Rectangle collision detection

A short refresher on trigonometry

Line collision detection

Compound colliders

Implementing circle collision detection

Destroying a spaceship on collision

Pointers in memory

Implementing compound circle colliders

Compiling collider.html

Summary

Basic Particle System

Adding to the virtual file system

A brief introduction to SVG

Vector versus raster graphics

Trigonometry again?

Adding the JavaScript

The simple particle emitter tool

The Point class

The Particle class

The Emitter class

WebAssembly interface functions

C++ name mangling

Dead code elimination

Updating the emitter

The looping function

Initialization

Compiling and testing the particle emitter

Summary

Improved Particle Systems

Modifying our HTML shell file

Scaling values

Color-blending values

Particle burst

Looping the emitter

Aligning particle rotation

Emission time

Animation frames

Modifying the JavaScript

The JavaScript UpdateClick function

Coercing color values

Additional variable coercions

Modifying the handleFiles function

Modifying the Particle class

New attributes

Aligning rotation attributes

Color attributes

Animation attributes

Size and scale attributes

The source rectangle attribute

Additional constructor parameters

The Update function's parameters

The Spawn function's parameters

Changes to particle.cpp

Particle constructor logic

Particle Update logic

Particle Spawn function

Particle Move function

Particle Render function

Modifying the Emitter class

The Emitter constructor function

Emitter update logic

Emitter Move function

External functions

Random floating-point numbers

Adding an emitter

Updating an emitter

Configuring the particle emitter

HTML shell and WebAssembly module interaction

Compiling and running the new tool

Creating a particle emitter

Changes to game.hpp

Adding the Particle class definition

Emitter class definition

Changes to emitter.cpp

Changes to the constructor function

Changes to the Update function

Adding a Run function

Changes to the Move function

Changes to ship.cpp

The Ship class' constructor function

The Ship class' Acceleration function

The Ship class' Render function

Changes to projectile_pool.cpp

Changes to main.cpp

Compiling the new particle_system.html file

Taking it further

Summary

AI and Steering Behaviors

What is Game AI?

Autonomous agents versus top-down AI

What is an FSM?

Introducing steering behaviors

The seek behavior

The flee behavior

The arrival behavior

The pursuit behavior

The evade behavior

Obstacle avoidance

The wander behavior

Combining forces

Modifying game.hpp

Adding obstacles to our game

Adding force fields

More collision detection

Circle-line collision detection

Vector projection

The Vector2D class

Writing an FSM

The AvoidForce function

Compiling the ai.html file

Summary

Designing a 2D Camera

Creating a camera for our game

Camera for tracking player movement

Projected focus and camera attractors

Modifying our code

Modifying the game.hpp file

The Vector2D class definition

The Locator class definition

The Camera class definition

The RenderManager class definition

The camera.cpp file

The render_manager.cpp file

Modifying main.cpp

New global variables

Modifying the move function

Modifying the render function

Modifying the main function

Modifying asteroid.cpp

Modifying collider.cpp

Modifying enemy_ship.cpp

Modifying finite_state_machine.cpp

Modifying particle.cpp

Modifying player_ship.cpp

Modifying projectile.cpp

Modifying shield.cpp

Modifying ship.cpp

Modifying star.cpp

Modifying vector.cpp

Compiling and playing with a locked-on camera

A more advanced camera

Changes to games.hpp

Changes to camera.cpp

Compiling and playing with the advanced camera

Summary

Sound FX

Where to get sound effects

Simple audio with Emscripten

Adding sound to our game

Updating game.hpp

Updating main.cpp

Updating ship.cpp

The new audio.cpp file

Compiling and running

Summary

Game Physics

Newton's third law

Adding gravity

Improving collisions

Modifying the code

Changing the game.hpp file

Changing collider.cpp

Changes to star.cpp

Changing the main.cpp file

Changes to asteroid.cpp and projectile.cpp

Changes to the ship.cpp file

Compiling the physics.html file

Summary

UI and Mouse Input

UI requirements

Opening screen

Play screen

Game over screen

Mouse input

Creating a button

Screen states

Changes to games.hpp

Modifying the RenderManager class

New external variables

Changes to main.cpp

Adding global variables

Input functions

The end_input function

The render functions

The collisions function

The transition state

The game loop

Play and play again callbacks

Changes to the main function

ui_button.cpp

The MouseMove function

The MouseClick function

The MouseUp function

The KeyDown function

The RenderUI function

ui_sprite.cpp

Defining the constructor

The RenderUI function

Compile ui.html

Summary

Shaders and 2D Lighting

Using OpenGL with WebAssembly

More about shaders

GLSL ES 1.0 and 3.0

WebGL app redux

Shader code

OpenGL global variables

SDL global variables

The main function

The game loop

Compiling and running our code

Mixing textures for a glow effect

Fragment shader changes

OpenGL global variable changes

Other global variable changes

Changes to main()

Updating game_loop()

Compiling and running our code

3D lighting

Ambient light

Diffuse light

Specular light

Normal maps

Creating a 2D lighting demo app

Fragment shader updates

OpenGL global variables

SDL global variables

Function prototypes

The main function

The game_loop function

The input function

The draw_light_icon function

Compiling and running our lighting app

Summary

Debugging and Optimization

Debug macro and stack trace

Source maps

Browser debugging

Compiling your code for debugging

Using asm.js as an alternative for debugging

Debugging using Chrome

Debugging using Firefox

Firefox Developer Edition

Optimizing for WebAssembly

Optimization flags

Optimizing for performance

Optimizing for size

Unsafe flags

Profiling

Problems with try/catch blocks

Optimizing OpenGL for WebAssembly

Using WebGL 2.0 if possible

Minimizing the number of OpenGL calls

Emscripten OpenGL flags

Summary

This is the end

Other Books You May Enjoy

Leave a review - let other readers know what you think

Preface

WebAssembly is a technology that will change the web as we know it within the next few years. WebAssembly promises a world where web-based applications run at near-native speeds. It is a world where you can write an application for the web in any language you like, and compile it for native platforms as well as the web. It is early days for WebAssembly, but this technology is already taking off like a rocket. If you are interested in where the web is going, as much as where it is today, read on!

I wrote this book to reflect the way I like to learn new skills. I will walk you through the development of a game using WebAssembly and all of its related technologies. I am a long-time game and web developer, and I have always enjoyed learning new programming languages by writing games. In this book, we will be covering a lot of ground on a lot of topics using both web and game development tools that go hand in hand with WebAssembly. We will learn how to write games that target WebAssembly utilizing a plethora of programming languages and tools, including Emscripten, C/C++, WebGL, OpenGL, JavaScript, HTML5, and CSS. As a long-time owner of an independent game development studio that specializes in the development of web-based games, I have found that it is essential to have a broad understanding of web- and game-based technologies and I have stuffed this book full of them. You will be learning a sample platter of skills with a focus on getting your apps up and running with WebAssembly. If you want to learn how to develop games with WebAssembly, or if you would like to create web-based applications that are lightning fast, this book is for you.

Who this book is for

This book is not an introduction to programming. It is intended for people who know how to code in at least one programming language. It would be helpful, but is not strictly necessary, to have at least a rudimentary understanding of some web-based technologies, such as HTML. This book contains instructions on how to install the required tools on Windows or Ubuntu Linux, and, out of the two, I would recommend using Ubuntu, as its installation process is much simpler.

What this book covers

Chapter 1, Introduction to WebAssembly and Emscripten, introduces WebAssembly, why the web needs it, and why it is so much faster than JavaScript. We will introduce Emscripten, why we need it for WebAssembly development, and how to install it. We will also discuss technologies related to WebAssembly, such as asm.js, LLVM, and WebAssembly Text.

Chapter 2, HTML5 and WebAssembly, discusses how WebAssembly modules integrate with HTML using the JavaScript "glue code". We will learn how to create our own Emscripten HTML shell file, and we will learn how to make calls to and from our WebAssembly module, which we will write in C. Finally, we will learn how to compile and run an HTML page that interacts with our WebAssembly module, and we will learn how to build a simple HTML5 Canvas app with Emscripten.

Chapter 3, Introduction to WebGL, introduces WebGL and the new canvas contexts that support it. We will learn about shaders, what they are, and how WebGL uses them to render geometry to the canvas. We will learn how to use WebGL and JavaScript to draw a sprite to the canvas. And finally, we will write an app that integrates WebAssembly, JavaScript, and WebGL that displays a sprite and moves it across the canvas.

Chapter 4, Sprite Animations in WebAssembly with SDL, teaches you about the SDL library and how we use it to simplify calls to WebGL from WebAssembly. We will learn how to use SDL to render, animate, and move sprites on the HTML5 canvas.

Chapter 5, Keyboard Input, looks at how to take input from the keyboard from JavaScript and make calls to the WebAssembly module. We will also learn how to accept keyboard input using SDL inside our WebAssembly module, and use the input to move a sprite around the HTML5 canvas.

Chapter 6, Game Objects and the Game Loop, explores some basic game design. We will learn about the game loop, and how a game loop in WebAssembly is different than in other games. We will also learn about game objects and how to create an object pool from within our game. We will end the chapter by coding the beginning of our game, with two spaceships that move about the canvas and shoot projectiles at each other.

Chapter 7, Collision Detection, introduces collision detection into our game. We will explore the types of 2D collision detection, implement a basic collision detection system, and learn a little about the trigonometry that makes it work. We will modify our game so that projectiles destroy the spaceships when they collide.

Chapter 8, Basic Particle System, introduces particle systems and discusses how they can visually improve our game. We will talk about the virtual filesystem, and we learn how to add files to it through a web page. We will briefly introduce SVG and Vector graphics, and how to use them for data visualization. We will further discuss trigonometry and how we will be using it in our particle systems. We will build a new HTML5 WebAssembly app that will help us to configure and test particle systems that we will later add to our game.

Chapter 9, Improved Particle Systems, goes into improving our particle system configuration tool by adding particle scaling, rotation, animation, and color transitions. We will modify the tool to allow the particle systems to loop, and add a burst effect. We will then update our game to support particle systems and add in particle system effects for our engine exhaust and explosions.

Chapter 10, AI and Steering Behaviors, introduces the concept of AI and game AI and discusses the difference between them. We will discuss the AI concepts of finite state machines, autonomous agents, and steering behaviors, and we will implement these behaviors in an enemy AI that will avoid obstacles and combat the player.

Chapter 11, Designing a 2D Camera, brings in the concept of 2D camera design. We will begin by adding a render manager to our game and creating a camera that locks on to the player's spaceship, following it around an expanded gameplay area. We will then add the advanced 2D camera features of projected focus and camera attractors.

Chapter 12, Sound FX, covers the use of SDL Audio in our game. We will discuss where we can get our sound effects online, and how to include those sounds in our WebAssembly module. We will then add sound effects to our game.

Chapter 13, Game Physics, introduces the concept of physics in computer games. We will be adding elastic collisions between our game objects. We will add Newton's third law to the physics of our game in the form of recoil when the spaceships launch projectiles. We will add a gravitational field to our star that will attract the spaceships.

Chapter 14, UI and Mouse Input, discusses adding a user interface to be managed and rendered within our WebAssembly module. We will gather requirements and translate them into new screens for our game. We will add a new button object and learn how we can manage mouse input from within our WebAssembly module using SDL.

Chapter 15, Shaders and 2D lighting, dives into how to create a new app that mixes OpenGL and SDL. We will create a new shader that loads and renders multiple textures to a quad. We will learn about normal maps, and how we can use normal maps to approximate the Phong lighting model in 2D, using OpenGL in our WebAssembly module.

Chapter 16, Debugging and Optimization, introduces the basic methods for debugging and optimizing WebAssembly modules. We will start with debug macros and stack traces from WebAssembly. We will introduce the concepts of source maps and how web browsers use them to debug WebAssembly modules. We will learn about optimizing WebAssembly code using optimization flags. We will discuss using a profiler to optimize our WebAssembly code.  

To get the most out of this book

You must understand the basics of computer programming.

It is helpful to have a basic understanding of web technologies such as HTML and CSS.

Download the example code files

You can download the code bundle for this book from here: https://github.com/PacktPublishing/Hands-On-Game-Development-with-WebAssembly.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/9781838644659_ColorImages.pdf.

Conventions used

You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

Log in or register at

www.packt.com

.

Select the

SUPPORT

tab.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR/7-Zip for Windows

Zipeg/iZip/UnRarX for Mac

7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Game-Development-with-WebAssembly. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Conventions used

There are a number of text conventions used throughout this book.

CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "We are going to copy the basic_particle_shell.html file to a new shell file that we will call advanced_particle_shell.html."

A block of code is set as follows:

<label class="ccontainer"><span class="label">loop:</span><input type="checkbox" id="loop" checked="checked"><span class="checkmark"></span></label><br/>

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

<label class="ccontainer"><span class="label">loop:</span>

<input type="checkbox" id="loop" checked="checked">

<span class="checkmark"></span></label><br/>

Any command-line input or output is written as follows:

emrun --list_browsers

Bold: Indicates a new term, an important word, or words that you see on screen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Select System info from the Administration panel."

Warnings or important notes appear like this.
Tips and tricks appear like this.

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in, and you are interested in either writing or contributing to a book, please visitauthors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packt.com.

Introduction to WebAssembly and Emscripten

Welcome to the exciting new world of WebAssembly! These are early days for WebAssembly, but the technology is currently taking off like a rocket, and by reading this book, you are in a position to get in on the ground floor. If you are interested in game development on the web, or you are interested in learning as much about this new technology as you can to position yourself for when it does reach maturity, you are in the right place. Even though WebAssembly is in its infancy, all major browser vendors have adopted it. These are early days and use cases are limited, but lucky for us, game development is one of them. So, if you want to be early to the party for the next generation of application development on the web, read on, adventurer!

In this chapter, I will introduce you to WebAssembly, Emscripten, and some of the underlying technologies around WebAssembly. I will teach you the basics of the Emscripten toolchain, and how you can use Emscripten to compile C++ code into WebAssembly. We will discuss what LLVM is and how it fits into the Emscripten toolchain. We will talk about WebAssembly's Minimum Viable Product (MVP), the best use cases for WebAssembly in its current MVP form, and what will soon be coming to WebAssembly. I will introduce WebAssembly text (.wat), how we can use it to understand the design of WebAssembly bytecode, and how it differs from other machine bytecodes. We will also briefly discuss asm.js, and its historical significance in the design of WebAssembly. Finally, I will show you how to install and run Emscripten on Windows and Linux.

In this chapter, we will cover the following topics:

What is WebAssembly?

Why do we need WebAssembly?

Why is WebAssembly faster than JavaScript?

Will WebAssembly replace JavaScript?

What is asm.js?

A brief introduction to LLVM

A brief introduction to WebAssembly text

What is Emscripten and how do we use it?

What is WebAssembly?

WebAssembly is not a high-level programming language like JavaScript, but a compiled binary format thatall major browsersare currently able to execute. WebAssembly is a kind of machine bytecode that was not designed to run directly on any real machine hardware, but runs in the JavaScript engine built into every browser. In some ways, it is similar to the old Java Virtual Machine (JVM); for example, it is a platform-independent compiled bytecode. One major problem with JavaScript bytecode is its requirement for a plugin to be downloaded and installed in the browser for the bytecode to run. Not only is WebAssembly designed to be run directly in a browser without a plugin, but it is also intended to produce a compact binary format that executes efficiently inside a web browser. The MVP version of the specification leverages existing work by the browser makers designing their JavaScript just-in-time (JIT) compiler. WebAssembly is currently a young technology and many improvements are planned. However, developers using the current version of WebAssembly have already seen performance improvements over JavaScript of 10–800%. 

An MVP is the smallest set of features that can be given to a product to allow it to appeal to early adopters. Because the current version is an MVP, the feature set is small. For more information, see this excellent article discussing the "post-MVP future" of WebAssembly: https://hacks.mozilla.org/2018/10/webassemblys-post-mvp-future/.

Why do we need WebAssembly?

JavaScript has been around for a long time. It has evolved from a little scripting language that allowed bells and whistles to be added to a web page, to a sprawling JIT compiled language with a massive ecosystem that can be used to write fully fledged applications. Today, JavaScript is doing a lot of things that were probably never imagined when it was created by Netscape in 1995. JavaScript is an interpreted language, meaning that it must be parsed, compiled, and optimized on the fly. JavaScript is also a dynamically typed language, which creates headaches for an optimizer.

Franziska Hinkelmann, a member of the Chrome V8 team, gave a great talk at the Web Rebels 2017 conference where she discusses all the performance improvements made to JavaScript over the past 20 years, as well as the difficulties they had in squeezing every bit of performance imaginable out of the JavaScript V8 engine: https://youtu.be/ihANrJ1Po0w.

WebAssembly solves a lot of the problems created by JavaScript and its long history in the browser. Because the JavaScript engine is already in bytecode format, it does not need to run a parser, which removes a significant bottleneck in the execution of our application. This design also allows the JavaScript engine to know what data types it is dealing with at all times. The bytecode makes optimization a lot easier. The format allows multiple threads in the browsers to work on compiling and optimizing different parts of the code at the same time.

For a detailed explanation of what is happening when the Chrome V8 engine is parsing code, please refer to this video from the JSConf EU 2017, in which Marja Hölttä (who works on the Chrome V8 tool) goes into more detail than you ever imagined you wanted to learn about parsing JavaScript: https://www.youtube.com/watch?v=Fg7niTmNNLg&t=123s.

WebAssembly is not a high-level programming language, but a binary file with opcodes for a virtual machine. Currently, it is considered to be in an MVP stage of development. The technology is still in its infancy, but even now it offers notable performance and file size benefits for many use cases, such as game development. Because of the current limitations of WebAssembly, we have only two choices for languages to use for its development—C/C++ or Rust. The long-term plan for WebAssembly is to support a wide selection of programming languages for its development. If I wanted to write at the lowest level of abstraction, I could write everything in Web Assembly Text (WAT), but WAT was developed as a language to support debugging and testing and was not intended to be used by developers for writing applications.

Will WebAssembly replace JavaScript?

The short answer to this question is not anytime soon. At present, WebAssembly is still in its MVP stage. At this stage, the number of use cases is limited to applications where WebAssembly has limited back and forth with the JavaScript and the Document Object Model (DOM). WebAssembly is not currently able to directly interact with the DOM, and Emscripten uses JavaScript "glue code" to make that interaction work. That interaction will probably change soon, possibly by the time you are reading this, but in the next few years, WebAssembly will need additional features to increase the number of possible use cases.

WebAssembly is not a "feature complete" platform. Currently, it cannot be used with any languages that require GC. That will change and, eventually, almost all strongly typed languages will target WebAssembly. In addition, WebAssembly will soon become tightly integrated with JavaScript, allowing frameworks such as React, Vue, and Angular to begin replacing significant amounts of their JavaScript code with WebAssembly without impacting the application programming interface (API). The React team is currently working on this to improve the performance of React.

In the long run, it is possible that JavaScript may compile into WebAssembly. For technical reasons, this is a very long way off. Not only does JavaScript require a GC (not currently supported), but because of its dynamic nature, JavaScript also requires a runtime profiler to optimize. Therefore, JavaScript would produce very poorly optimized code, or significant modifications would be needed to support strict typing. It is more likely that a language, such as TypeScript, will add features that allow it to compile into WebAssembly.

The AssemblyScript project in development on GitHub is working on a TypeScript-to-WebAssembly compiler. This project creates JavaScript and uses Binaryen to compile that JavaScript into WebAssembly. How AssemblyScript handles the problem of garbage collection is unclear. For more information, refer to https://github.com/AssemblyScript/assemblyscript.

JavaScript is currently ubiquitous on the web; there are a tremendous number of libraries and frameworks developed in JavaScript. Even if there were an army of developers eager to rewrite the entire web in C++ or Rust, WebAssembly is not yet ready to replace these JavaScript libraries and frameworks. The browser makers have put immense efforts into making JavaScript run (relatively) fast, so JavaScript will probably remain as the standard scripting language for the web. The web will always need a scripting language, and countless developers have already put in the work to make JavaScript that scripting language, so it seems unlikely that JavaScript will ever go away.

There is, however, a need for a compiled format for the web that WebAssembly is likely to fulfill. Compiled code may be a niche on the web at the moment, but it is a standard just about everywhere else. As WebAssembly approaches feature-complete status, it will offer more choices and better performance than JavaScript, and businesses, frameworks, and libraries will gradually migrate toward it.

What is asm.js?

One early attempt to achieve native-like speed in the web browser using JavaScript was asm.js. Although that goal was reached and asm.js was adopted by all the major browser vendors, it never achieved widespread adoption by developers. The beauty of asm.js is that it still runs in most browsers, even in those that do not optimize for it. The idea behind asm.js was that typed arrays could be used in JavaScript to fake a C++ memory heap. The browser simulates pointers and memory allocation in C++, as well as types. A well-designed JavaScript engine can avoid dynamic type checking. Using asm.js, browser makers could get around many of the optimization problems created by the dynamic nature of JavaScript, by just pretending that this version of JavaScript is not dynamically typed. Emscripten, designed as a C++-to-JavaScript compiler, quickly adopted asm.js as the subset of JavaScript that it would compile to because of its improved performance in most browsers. The performance improvements driven by asm.js lead the way to WebAssembly. The same engine modifications used to make asm.js perform well could be used to bootstrap the WebAssembly MVP. Only the addition of a bytecode-to-bytecode compiler was required to take the WebAssembly bytecode and directly convert it into the IR bytecode used by the browser.

At the time of writing, Emscripten does not compile directly from LLVM to WebAssembly. Instead, it compiles to asm.js and uses a tool called Binaryen to convert the asm.js output from Emscripten into WebAssembly.

A brief introduction to LLVM

Emscripten is the tool we will be using to compile C++ into WebAssembly. Before I discuss Emscripten, I need to explain a technology called LLVM and its relationship to Emscripten.

First, take a moment to think of airlines (stay with me here). Airlines want to get passengers from one airport to another airport. But it's challenging to offer a direct flight from every single airport to every other airport on Earth. That would mean that airlines would have to provide a vast number of direct flights, such as Akron, Ohio to Mumbai, India. Let's travel back in time to the 1990s—that was the state of the compiler world. If you wanted to compile from C++ to ARM, you needed a compiler capable of compiling C++ to ARM. If you needed to compile from Pascal to x86, you needed a compiler that could compile from Pascal to x86. These are like having only direct flights between any two cities: a compiler for every combination of language and hardware. The result is either that you have to limit the number of languages you write compilers for, limit the number of platforms you can support with that language, or more likely, both.

In 2003, a student at the University of Illinois named Chris Lattner wondered, "What if we created a hub-and-spoke model for programming languages?" His idea led to LLVM, which originally stood for "Low-Level Virtual Machine." The idea was that, instead of compiling your source code for any possible distribution, you compile it for LLVM. There are then compilers between the intermediate language and your final output language. In theory, this means that if you develop a new target platform on the right side of the following diagram, you get all languages on the left side right away:

Figure 1.5: LLVM as a hub between programming languages and the hardware
To learn more about LLVM, visit the LLVM project home page at https://llvm.org or read the LLVM Cookbook, Mayur Padney, and Suyog Sarda, Packt Publishing: https://www.packtpub.com/application-development/llvm-cookbook.

A brief introduction to WebAssembly text

WebAssembly binary is not a language, but a build target similar to building for ARM or x86. The bytecode, however, is structured differently than other hardware-specific build targets. The designers of the WebAssembly bytecode had the web in mind. The aim was to create a bytecode that was compact and streamable. Another goal was that the user should be able to do a "view/source" on the WebAssembly binary to see what is going on. WebAssembly text is a companion code to the WebAssembly binary that allows the user to view the bytecode instructions in a human-readable form, similar to the way an assembly language would let you see what opcodes execute in a machine-readable form.

WebAssembly text may initially look unfamiliar to someone used to writing assembly for hardware such as ARM, x86, or 6502 (if you're old school). You write WebAssembly text in S-expressions, which has a parentheses-heavy tree structure. Some of the operations are also strikingly high level for an assembly language, such as if/else and loop opcodes. That makes a lot more sense if you remember that WebAssembly was not designed to run directly on computer hardware, but to download and translate into machine code quickly.

Another thing that will seem a little alien at first when you are dealing with WebAssembly text is the lack of registers. WebAssembly is designed to be a virtual stack machine, which is an alternative to a register machine, such as x86 and ARM, with which you might be familiar. A stack machine has the advantage of producing significantly smaller bytecode than a register machine, which is one good reason to choose a stack machine for WebAssembly. Instead of using a series of registers to store and manipulate numbers, every opcode in a stack machine pushes values on or off a stack (and sometimes does both). For example, a call to i32.add in WebAssembly pulls two 32-bit integers off the stack, adds them together, then pushes their value back on to the stack. The computer hardware can make the best use of whichever registers are available to perform this operation.

Emscripten

Now that we know what LLVM is, we can discuss Emscripten. Emscripten was developed to compile LLVM IR into JavaScript, but has recently been updated to compile LLVM into WebAssembly. The idea is that, when you get the LLVM compiler working, you can have the benefit of all the languages that compile to LLVM IR. In practice, the WebAssembly specification is still in its early days and does not support common language features such as GC. Therefore, only non-GC languages such as C/C++ and Rust are currently supported. WebAssembly is still in the early MVP phase of its development, but the addition of GC and other common language features are coming soon. When that happens, there should be an explosion of programming languages that will compile to WebAssembly.

When Emscripten was released in 2012, it was intended to be an LLVM-to-JavaScript compiler. In 2013, support was added for asm.js, which is a faster, easily optimized subset of the JavaScript language. In 2015, Emscripten began to add support for LLVM-to-WebAssembly compiling. Emscripten also provides a Software Development Kit (SDK) for both C++ and JavaScript that provides glue code to give users better tools for interaction between JavaScript and WebAssembly than those currently offered by the WebAssembly MVP alone. Emscripten also integrates with a C/C++-to-LLVM compiler called Clang, so that you can compile your C++ into WebAssembly. In addition, Emscripten will generate the HTML and JavaScript glue code you need to get your project started.

Emscripten is a very dynamic project and changes to the toolchain happen frequently. To stay up to date with the latest changes in Emscripten, visit the project home page at https://emscripten.org.

Installing Emscripten on Windows

I am going to keep this section brief because these instructions are subject to change. You can supplement these instructions with the official Emscripten download and install instructions found on the Emscripten website:https://emscripten.org/docs/getting_started/downloads.html.

We will need to download and build Emscripten from the emsdk source files on GitHub. First, we will walk through what to do on Windows.

Python 2.7.12 or higher is a prerequisite. If you do not have a version of Python higher than 2.7.12 installed, you will need to get the windows installer from python.org and install that first: https://www.python.org/downloads/windows/.

If you have installed Python and you are still getting errors telling you that Python is not found, you may need to add Python to your Windows PATH variable. For more information, refer to this tutorial: https://www.pythoncentral.io/add-python-to-path-python-is-not-recognized-as-an-internal-or-external-command/.

If you have Git installed already, cloning the repository is relatively simple:

Run the following command to clone the repository:

git

clone

https

:

//

github

.

com

/

emscripten

-

core

/

emsdk

.

git

Wherever you run this command, it will create an

emsdk

directory. Enter that directory using the following:

cd emsdk

You may not have Git installed, in which case, the following steps will bring you up to speed:

Go to the following URL in a web browser:

https://github.com/emscripten-core/emsdk

.

You will see a green button on the right-hand side that says

Clone or download

. Download the ZIP file:

Unzip the downloaded file to the

c:\emsdk

directory.

Open up a Windows Command Prompt by typing 

cmd

 into the start menu and pressing

Enter

.

From there, you can change to the

c:\emsdk\emsdk-master

directory by typing the following:

cd \emsdk\emsdk-master

At this point, it does not matter whether you had Git installed or not. Let's move forward:

Install

emsdk

from the source code running the following command:

emsdk install latest

Then activate the latest

emsdk

:

emsdk activate latest

Finally, set up our path and environment variables:

emsdk_env.bat

This last step will need to be rerun from your install directory every time you open a new command-line window. Unfortunately, it does not permanently set the Windows environment variables. Hopefully, that will change in the future.

Installing Emscripten on Ubuntu

If you are installing on Ubuntu, you should be able to use the apt-get package manager and git for the complete install. Let's move forward:

Python is required, so if you do not have Python installed, be sure to run the following:

sudo apt-get install python

If you do not already have Git installed, run the following:

sudo apt-get install git

Now you will need to clone the Git repository for

emsdk

:

git

clone

https

:

//

github

.

com

/

emscripten

-

core

/

emsdk

.

git

Change your directory to move into the

emsdk

directory:

cd emsdk

From here, you need to install the latest version of the SDK tools, activate it, and set your environment variables:

./emsdk install latest

./emsdk activate latest

source ./emsdk_env.sh

To make sure everything was installed correctly, run the following command:

emcc --version

Using Emscripten

We run Emscripten from the command line; therefore, you can use any text editor you choose to write your C/C++ code. Personally,I am partial to Visual Studio Code, which you can download here: https://code.visualstudio.com/download.

One beautiful thing about Visual Studio Code is that it has a built-in command-line terminal, which lets you compile your code without switching windows. It also has an excellent C/C++ extension that you can install. Just search for C/C++ from the extensions menu and install the Microsoft C/C++ Intellisense extension.

Whatever you choose for your text editor or integrated development environment, you need a simple piece of C code to test out the emcc compiler.

Create a new text file and name it

hello.c

.

Type the following code into

hello.c

:

#include <emscripten.h>

#include <stdlib.h>#

include

<

stdio.h

>

int main() {

printf("hello wasm\n");

}

Now I can compile the

hello.c

file into WebAssembly and generate a

hello.html

file:

emcc hello.c --emrun -o hello.html

The

--emrun

flag is necessary if you want to run the HTML page from

emrun

. This flag adds code that will capture

stdout

,

stderr

, and exit in the C code and

emrun

will not work without it:

emrun --browser firefox hello.html

Running emrun with the --browser flag will pick the browser where you would like to run the script. The behavior of emrun seems to be different between browsers. Chrome will close the window when the C program exits. That can be annoying because we are just trying to display a simple print message. If you have Firefox, I would suggest running emrun using the --browser flag.

I do not want to imply that Chrome cannot run WebAssembly. Chrome does have different behavior when a WebAssembly module exits. Because I was trying to keep our WebAssembly module as simple as possible, it exits when the main function completes. That is what is causing problems in Chrome. These problems will go away later when we learn about game loops.

To find out what browsers are available to you, run the following:

emrun --list_browsers

 emrun should open an Emscripten-templated HTML file in a browser.

Make sure you have a browser capable of running WebAssembly. The following versions of the major browsers should work with WebAssembly:

Edge 16

Firefox 52

Chrome 57

Safari 11

Opera 44

If you are familiar with setting up your own web server, you may want to consider using it rather than emrun. After using emrun for the first few chapters of this book, I returned to using my Node.js web server. I found it easier to have a Node-based web server up and running at all times, rather than restarting the emrun web server every time I wanted to test my code. If you know how to set up an alternative web server (such as one for Node, Apache, and IIS), you may use whatever web server you prefer. Although IIS requires some additional configuration to handle WebAssembly MIME types.

Additional installation resources

Creating an installation guide for Emscripten is going to be somewhat problematic. The WebAssembly technology changes frequently and the installation process for Emscripten may be different by the time you read this. I would recommend consulting the download and install instructions on the Emscripten website if you have any problems: https://emscripten.org/docs/getting_started/downloads.html.

You may also want to consult the Emscripten page on GitHub: https://github.com/emscripten-core/emsdk.

Google Groups has an Emscripten discussion forum where you may ask questions if you are having installation problems: https://groups.google.com/forum/?nomobile=true#!forum/emscripten-discuss.

You can also contact me on Twitter (@battagline), and I will do my best to help you: https://twitter.com/battagline.

Summary

In this chapter, we learned what WebAssembly is and why it will be the future of application development on the web. We learned why we need WebAssembly, even though we already have a robust language like JavaScript. We learned why WebAssembly is so much faster than JavaScript, and how it has the potential to increase its performance lead. We have also discussed the possibility of WebAssembly replacing JavaScript as the de facto standard for application development on the web.

We have discussed the practical side of creating a WebAssembly module as it is done today using Emscripten and LLVM. We have talked about WebAssembly text and how it is structured. We have also discussed using Emscripten to compile our first WebAssembly module, as well as using it to create the HTML and JavaScript glue code to run that module.