Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Ólafur Waage Senior Software Developer - TurtleSec AS @olafurw on Twitter 1 2

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

“ I must go forward where I have never been instead of backwards where I have. - Winnie the Pooh 4

Slide 5

Slide 5 text

“ I must go forward where I have never been instead of backwards where I have. - Winnie the Pooh 5

Slide 6

Slide 6 text

WHAT THIS TALK IS AND ISN’T 6

Slide 7

Slide 7 text

WHAT THIS TALK IS AND ISN’T This is not a game development or game design talk. A while ago I was making a game using WebAssembly and these are the walls I encountered along the way 7

Slide 8

Slide 8 text

WHAT THIS TALK IS AND ISN’T This is not a game development or game design talk. A while ago I was making a game using WebAssembly and these are the walls I encountered along the way 8 This is not a comprehensive talk about WebAssembly.

Slide 9

Slide 9 text

WHAT THIS TALK IS AND ISN’T This is not a game development or game design talk. A while ago I was making a game using WebAssembly and these are the walls I encountered along the way 9 This is not a comprehensive talk about WebAssembly. The idea here is to be pragmatic and learn what this tool has to offer and what problems it can solve.

Slide 10

Slide 10 text

What is WebAssembly?

Slide 11

Slide 11 text

What is WebAssembly? How can something be neither Web nor Assembly?

Slide 12

Slide 12 text

WHAT IS WEBASSEMBLY? WebAssembly is a binary format* originally designed to allow for performant execution of code within browsers. 12

Slide 13

Slide 13 text

WHAT IS WEBASSEMBLY? WebAssembly is a binary format* originally designed to allow for performant execution of code within browsers. ◦ Announced 2015 13

Slide 14

Slide 14 text

WHAT IS WEBASSEMBLY? WebAssembly is a binary format* originally designed to allow for performant execution of code within browsers. ◦ Announced 2015 ◦ Working Drafts in 2018 14

Slide 15

Slide 15 text

WHAT IS WEBASSEMBLY? WebAssembly is a binary format* originally designed to allow for performant execution of code within browsers. ◦ Announced 2015 ◦ Working Drafts in 2018 ◦ W3C recommendation in 2019 15

Slide 16

Slide 16 text

WHAT IS WEBASSEMBLY? WebAssembly is a binary format* originally designed to allow for performant execution of code within browsers. ◦ Announced 2015 ◦ Working Drafts in 2018 ◦ W3C recommendation in 2019 WebAssembly can be thought of as the target output of any language and in recent times can be executed outside of the web. 16

Slide 17

Slide 17 text

WEBASSEMBLY EXAMPLES? Many of you might associate WebAssembly with games only, and even though this talk is also doing that, WebAssembly has so much more to offer. 17

Slide 18

Slide 18 text

WEBASSEMBLY EXAMPLES? Many of you might associate WebAssembly with games only, and even though this talk is also doing that, WebAssembly has so much more to offer. Here are some examples of things you might not have thought are written with WebAssembly. 18

Slide 19

Slide 19 text

19

Slide 20

Slide 20 text

20

Slide 21

Slide 21 text

21

Slide 22

Slide 22 text

22

Slide 23

Slide 23 text

23

Slide 24

Slide 24 text

What is Emscripten?

Slide 25

Slide 25 text

What is Emscripten? WebAssembly before WebAssembly

Slide 26

Slide 26 text

WHAT IS EMSCRIPTEN? We originally had asm.js from Mozilla which had similar goals to WebAssembly, to run efficient code on the web. 26

Slide 27

Slide 27 text

WHAT IS EMSCRIPTEN? We originally had asm.js from Mozilla which had similar goals to WebAssembly, to run efficient code on the web. asm.js is a subset of JavaScript and your lower level code would then be transpiled into it. 27

Slide 28

Slide 28 text

WHAT IS EMSCRIPTEN? We originally had asm.js from Mozilla which had similar goals to WebAssembly, to run efficient code on the web. asm.js is a subset of JavaScript and your lower level code would then be transpiled into it. This is where Emscripten came into play. 28

Slide 29

Slide 29 text

WHAT IS EMSCRIPTEN? Emscripten is based on the LLVM/Clang toolchains which allows you target WebAssembly as the binary output. 29

Slide 30

Slide 30 text

WHAT IS EMSCRIPTEN? Emscripten is based on the LLVM/Clang toolchains which allows you target WebAssembly as the binary output. This allows you to get many different types of outputs, not only WASM files but .js and .html 30

Slide 31

Slide 31 text

INSTALLING EMSCRIPTEN Let’s go over the installation process and setup a simple development environment. - Text editor is VSCode - WSL2 running Ubuntu 20.04 - https://github.com/olafurw/talk-cppp-webassembly 31

Slide 32

Slide 32 text

32

Slide 33

Slide 33 text

33

Slide 34

Slide 34 text

34

Slide 35

Slide 35 text

35

Slide 36

Slide 36 text

36

Slide 37

Slide 37 text

37

Slide 38

Slide 38 text

38

Slide 39

Slide 39 text

39

Slide 40

Slide 40 text

40

Slide 41

Slide 41 text

41

Slide 42

Slide 42 text

HEY, WORLD, WHAT IS UP? Now we have the Emscripten compiler installed in our system. 42

Slide 43

Slide 43 text

HEY, WORLD, WHAT IS UP? Now we have the Emscripten compiler installed in our system. Time for the time honored tradition of the hello world example. 43

Slide 44

Slide 44 text

HEY, WORLD, WHAT IS UP? Now we have the Emscripten compiler installed in our system. Time for the time honored tradition of the hello world example. But there are a few more steps in this one than you’d normally expect. 44

Slide 45

Slide 45 text

45

Slide 46

Slide 46 text

46

Slide 47

Slide 47 text

47

Slide 48

Slide 48 text

48

Slide 49

Slide 49 text

49

Slide 50

Slide 50 text

50

Slide 51

Slide 51 text

JUST RUN IT ALREADY! Yes, with nodejs we can run the .js files just fine. 51

Slide 52

Slide 52 text

JUST RUN IT ALREADY! Yes, with nodejs we can run the .js files just fine. But let’s start by opening the HTML file directly. Should be no problem, right? 52

Slide 53

Slide 53 text

WALL NUMBER 1 Of CORS there’s a problem here 1 53

Slide 54

Slide 54 text

YOUR SAFETY IS PARAMOUNT Browsers don’t like opening random files from whatever location you decide. 54

Slide 55

Slide 55 text

YOUR SAFETY IS PARAMOUNT Browsers don’t like opening random files from whatever location you decide. There’s a thing called “Cross-origin resource sharing (CORS)”. By default browsers don’t like loading external files from disk using file:// 55

Slide 56

Slide 56 text

YOUR SAFETY IS PARAMOUNT Browsers don’t like opening random files from whatever location you decide. There’s a thing called “Cross-origin resource sharing (CORS)”. By default browsers don’t like loading external files from disk using file:// The browser will load the html file fine but any external dependency will probably be blocked. 56

Slide 57

Slide 57 text

RUN EM RUN! Best way to solve this is to run a webserver that is going to host the files. 57

Slide 58

Slide 58 text

RUN EM RUN! Best way to solve this is to run a webserver that is going to host the files. What I use while developing is emrun, a tool that comes with emscripten. 58

Slide 59

Slide 59 text

RUN EM RUN! Best way to solve this is to run a webserver that is going to host the files. What I use while developing is emrun, a tool that comes with emscripten. emrun is a simple webserver but for our development purposes it is good enough. 59

Slide 60

Slide 60 text

60

Slide 61

Slide 61 text

VIDEO GAMES! Now let’s look at the game we will be “making”. We are going to make a simple sliding puzzle game, similar to games like “Threes” and “2048” 61

Slide 62

Slide 62 text

ENOUGH FUN Now let’s covert this game over to WebAssembly. 62

Slide 63

Slide 63 text

ENOUGH FUN Now let’s covert this game over to WebAssembly. There are two ways to do this. 63

Slide 64

Slide 64 text

ENOUGH FUN Now let’s covert this game over to WebAssembly. There are two ways to do this. - Keep the drawing in JS and game logic in C++ 64

Slide 65

Slide 65 text

ENOUGH FUN Now let’s covert this game over to WebAssembly. There are two ways to do this. - Keep the drawing in JS and game logic in C++ - Do everything in C++ 65

Slide 66

Slide 66 text

ENOUGH FUN Now let’s covert this game over to WebAssembly. There are two ways to do this. - Keep the drawing in JS and game logic in C++ - Do everything in C++ We will look at both, and the walls we hit along the way. 66

Slide 67

Slide 67 text

LET’S START CONVERTING So let’s take some of the functions we have in the JS version and convert them over to C++ 67

Slide 68

Slide 68 text

LET’S START CONVERTING So let’s take some of the functions we have in the JS version and convert them over to C++ Some of them don’t even need to know about game state, so let’s start with them. 68

Slide 69

Slide 69 text

69

Slide 70

Slide 70 text

70

Slide 71

Slide 71 text

71

Slide 72

Slide 72 text

72

Slide 73

Slide 73 text

73 Great, onto the next function.

Slide 74

Slide 74 text

WALL NUMBER 2 Where we’re going, there is no OS 2 74

Slide 75

Slide 75 text

SO RANDOM With this standalone WASM file, there is no operating system level functionality. 75

Slide 76

Slide 76 text

SO RANDOM With this standalone WASM file, there is no operating system level functionality. You’re all on your own* 76

Slide 77

Slide 77 text

SO RANDOM With this standalone WASM file, there is no operating system level functionality. You’re all on your own* So how do we solve this problem? 77

Slide 78

Slide 78 text

EMSCRIPTEN SAVIORS Using random, calling timer functions and many other OS level functionality has to come from somewhere. 78

Slide 79

Slide 79 text

EMSCRIPTEN SAVIORS Using random, calling timer functions and many other OS level functionality has to come from somewhere. Thankfully there is a solution to this, where if you build a .js file in addition to your .wasm file, you will get many of these functionalities from the javascript side. 79

Slide 80

Slide 80 text

EMSCRIPTEN SAVIORS Using random, calling timer functions and many other OS level functionality has to come from somewhere. Thankfully there is a solution to this, where if you build a .js file in addition to your .wasm file, you will get many of these functionalities from the javascript side. But how does it work? Can we do it ourselves? 80

Slide 81

Slide 81 text

EMSCRIPTEN RANDOM 81

Slide 82

Slide 82 text

EMSCRIPTEN RANDOM Looks great, but how do we use it? 82

Slide 83

Slide 83 text

83

Slide 84

Slide 84 text

84

Slide 85

Slide 85 text

85

Slide 86

Slide 86 text

86

Slide 87

Slide 87 text

87

Slide 88

Slide 88 text

88

Slide 89

Slide 89 text

89

Slide 90

Slide 90 text

ONWARDS Great, so now we can move over the rest of the game logic. 90

Slide 91

Slide 91 text

ONWARDS Great, so now we can move over the rest of the game logic. The board is an array of arrays of `Box` and the rest of the game logic is basically identical. 91

Slide 92

Slide 92 text

ONWARDS Great, so now we can move over the rest of the game logic. The board is an array of arrays of `Box` and the rest of the game logic is basically identical. So now the gameplay can be simulated and called from JS, now we need to draw that data. 92

Slide 93

Slide 93 text

WALL NUMBER 3 Where’s the data? 3 93

Slide 94

Slide 94 text

I REMEMBER We can communicate between C++ and JS using primitive types as you saw before, but as soon as things get a bit more complicated, we are in trouble. 94

Slide 95

Slide 95 text

I REMEMBER We can communicate between C++ and JS using primitive types as you saw before, but as soon as things get a bit more complicated, we are in trouble. We could view the raw data of a std::vector within the memory of WebAssembly, but converting between a vector and a javascript list is not automatic 95

Slide 96

Slide 96 text

WE’RE IN A BIND There is something called Embind that can help with passing more complex objects over to JS 96

Slide 97

Slide 97 text

WE’RE IN A BIND Embind even has helpers to bind common objects, like std::vector 97

Slide 98

Slide 98 text

I REMEMBER You can even define a shared block of memory that can then be used by either JS or C++ 98

Slide 99

Slide 99 text

I REMEMBER You can even define a shared block of memory that can then be used by either JS or C++ Also there is the option to return a pointer to JS 99

Slide 100

Slide 100 text

I REMEMBER You can even define a shared block of memory that can then be used by either JS or C++ Also there is the option to return a pointer to JS But this is in the territory where you need to be a bit more careful with how each byte is used and represented. 100

Slide 101

Slide 101 text

WE DON’T NEED IT Thankfully, I wrote the game logic to only use simple primitives, so we can finish converting all of the functions over to C++ and expose them to JS to use as needed. 101

Slide 102

Slide 102 text

WE DON’T NEED IT Thankfully, I wrote the game logic to only use simple primitives, so we can finish converting all of the functions over to C++ and expose them to JS to use as needed. Let’s look at this version of the implementation. 102

Slide 103

Slide 103 text

LET’S NOT STOP HERE! Now we have basically everything except the rendering in the C++ version. 103

Slide 104

Slide 104 text

LET’S NOT STOP HERE! Now we have basically everything except the rendering in the C++ version. So let’s move that over as well. 104

Slide 105

Slide 105 text

LET’S NOT STOP HERE! Now we have basically everything except the rendering in the C++ version. So let’s move that over as well. Thankfully Emscripten has great support for exactly what we need. 105

Slide 106

Slide 106 text

SDL1 and 2 Emscripten has built in support for SDL which is a cross platform library that provides among many things graphical rendering support. 106

Slide 107

Slide 107 text

SDL1 and 2 Emscripten has built in support for SDL which is a cross platform library that provides among many things graphical rendering support. There is also support for SDL2 but it needs to be downloaded (which happens on first compile) 107

Slide 108

Slide 108 text

SDL1 and 2 Emscripten has built in support for SDL which is a cross platform library that provides among many things graphical rendering support. There is also support for SDL2 but it needs to be downloaded (which happens on first compile) 108

Slide 109

Slide 109 text

GLUE THAT CODE Also since we will use SDL2 and other built in functionality, we will use the generated JS glue code. 109

Slide 110

Slide 110 text

GLUE THAT CODE Also since we will use SDL2 and other built in functionality, we will use the generated JS glue code. So instead of creating the importObject ourselves and implementing the functions that are needed, Emscripten has does this for us. 110

Slide 111

Slide 111 text

111

Slide 112

Slide 112 text

RENDERING FUN Now I port over the rendering code, which thankfully for this example is just a simple colored rectangle. (I wait with displaying the text for now) 112

Slide 113

Slide 113 text

RENDERING FUN Now I port over the rendering code, which thankfully for this example is just a simple colored rectangle. (I wait with displaying the text for now) Everything compiles and looks like it should be. 113

Slide 114

Slide 114 text

RENDERING FUN Now I port over the rendering code, which thankfully for this example is just a simple colored rectangle. (I wait with displaying the text for now) Everything compiles and looks like it should be. I run the code, I see the box and then… 114

Slide 115

Slide 115 text

115

Slide 116

Slide 116 text

WALL NUMBER 4 The sandbox isn’t infinite 4 116

Slide 117

Slide 117 text

MEMORY MANAGEMENT Up to this point I have been using the default memory size and it has just happened to fit. 117

Slide 118

Slide 118 text

MEMORY MANAGEMENT Up to this point I have been using the default memory size and it has just happened to fit. But we need more memory now since SDL is involved. 118

Slide 119

Slide 119 text

MEMORY MANAGEMENT Up to this point I have been using the default memory size and it has just happened to fit. But we need more memory now since SDL is involved. 119

Slide 120

Slide 120 text

TEXT ADVENTURE Great, this compiles and we see the box drawn in the canvas as before. 120

Slide 121

Slide 121 text

TEXT ADVENTURE Great, this compiles and we see the box drawn in the canvas as before. So let’s draw the text that should appear within the box. 121

Slide 122

Slide 122 text

WALL NUMBER 5 File not found 5 122

Slide 123

Slide 123 text

EMPTY SANDBOX The environment we are in does not have much else outside of what we have given it. 123

Slide 124

Slide 124 text

EMPTY SANDBOX The environment we are in does not have much else outside of what we have given it. So the font file we want to use does not exist, and the idea of a filesystem is different from what we expect. We have to provide the files. 124

Slide 125

Slide 125 text

EMPTY SANDBOX The environment we are in does not have much else outside of what we have given it. So the font file we want to use does not exist, and the idea of a filesystem is different from what we expect. We have to provide the files. 125

Slide 126

Slide 126 text

EMPTY SANDBOX The environment we are in does not have much else outside of what we have given it. So the font file we want to use does not exist, and the idea of a filesystem is different from what we expect. We have to provide the files. 126

Slide 127

Slide 127 text

CMAKE What Emscripten also provides is helper utilities to use common development tools like make and cmake. So I also wrote a simple CMake file for building the project. 127

Slide 128

Slide 128 text

CMAKE What Emscripten also provides is helper utilities to use common development tools like make and cmake. So I also wrote a simple CMake file for building the project. 128

Slide 129

Slide 129 text

129

Slide 130

Slide 130 text

IT’S RUNNING! Great! So now we have everything running. Let’s look at it in action! 130

Slide 131

Slide 131 text

SUMMARY Let’s summarize the walls we encountered. 131

Slide 132

Slide 132 text

SUMMARY Let’s summarize the walls we encountered. - Files need to be served while developing 132

Slide 133

Slide 133 text

SUMMARY Let’s summarize the walls we encountered. - Files need to be served while developing - All functionality you depend on (ie. OS) needs to be implemented or given to you 133

Slide 134

Slide 134 text

SUMMARY Let’s summarize the walls we encountered. - Files need to be served while developing - All functionality you depend on (ie. OS) needs to be implemented or given to you - Data needs to be primitives or converted in some way before sending to JS 134

Slide 135

Slide 135 text

SUMMARY Let’s summarize the walls we encountered. - Files need to be served while developing - All functionality you depend on (ie. OS) needs to be implemented or given to you - Data needs to be primitives or converted in some way before sending to JS - Memory size and growth needs to be thought about 135

Slide 136

Slide 136 text

SUMMARY Let’s summarize the walls we encountered. - Files need to be served while developing - All functionality you depend on (ie. OS) needs to be implemented or given to you - Data needs to be primitives or converted in some way before sending to JS - Memory size and growth needs to be thought about - Required files need to be embedded or preloaded with the output 136

Slide 137

Slide 137 text

Ólafur Waage Senior Software Developer - TurtleSec AS @olafurw on Twitter https://github.com/olafurw/talk-cppp-webassembly 1 137