Slide 1

Slide 1 text

Native Native Web Web Apps Apps React and WebAssembly to Rewrite Native Apps @FlorianRival1

Slide 2

Slide 2 text

Since a long time 2

Slide 3

Slide 3 text

I ❤ apps I ❤ apps Since a long time 2

Slide 4

Slide 4 text

3

Slide 5

Slide 5 text

“ open-source, cross-platform game creator designed to be used by everyone 3

Slide 6

Slide 6 text

“ open-source, cross-platform game creator designed to be used by everyone An editor for games 3

Slide 7

Slide 7 text

“ open-source, cross-platform game creator designed to be used by everyone An editor for games Visual programming 3

Slide 8

Slide 8 text

“ open-source, cross-platform game creator designed to be used by everyone An editor for games Visual programming Output HTML5 games 3

Slide 9

Slide 9 text

4

Slide 10

Slide 10 text

5

Slide 11

Slide 11 text

6

Slide 12

Slide 12 text

The editor is getting old The editor is getting old 7

Slide 13

Slide 13 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. 7

Slide 14

Slide 14 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. Iterating on the software is slow (C++ ) 7

Slide 15

Slide 15 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. Iterating on the software is slow (C++ ) Building UI is slow... 7

Slide 16

Slide 16 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. Iterating on the software is slow (C++ ) Building UI is slow... ...and limited to old UI components... 7

Slide 17

Slide 17 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. Iterating on the software is slow (C++ ) Building UI is slow... ...and limited to old UI components... ...and UX would need some enhancements 7

Slide 18

Slide 18 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. Iterating on the software is slow (C++ ) Building UI is slow... ...and limited to old UI components... ...and UX would need some enhancements The entry barrier for new contributors is high (C++ ) 7

Slide 19

Slide 19 text

The editor is getting old The editor is getting old Lots of cross-platforms issues with the UI toolkit, support for macOS and Linux is bad. Iterating on the software is slow (C++ ) Building UI is slow... ...and limited to old UI components... ...and UX would need some enhancements The entry barrier for new contributors is high (C++ ) It's time to react! It's time to react! 7

Slide 20

Slide 20 text

Could web Could web technologies help? technologies help? 8

Slide 21

Slide 21 text

“ React is perfect for React is perfect for making complex UI making complex UI 9 . 1

Slide 22

Slide 22 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... 9 . 1

Slide 23

Slide 23 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have 9 . 1

Slide 24

Slide 24 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have list and trees of hundreds of list and trees of hundreds of elements, elements, 9 . 1

Slide 25

Slide 25 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have list and trees of hundreds of list and trees of hundreds of elements, elements, dynamic panels, dynamic panels, 9 . 1

Slide 26

Slide 26 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have list and trees of hundreds of list and trees of hundreds of elements, elements, dynamic panels, dynamic panels, 2d/3d visualizations 2d/3d visualizations 9 . 1

Slide 27

Slide 27 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have list and trees of hundreds of list and trees of hundreds of elements, elements, dynamic panels, dynamic panels, 2d/3d visualizations 2d/3d visualizations, nested , nested dialogs, dialogs, 9 . 1

Slide 28

Slide 28 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have list and trees of hundreds of list and trees of hundreds of elements, elements, dynamic panels, dynamic panels, 2d/3d visualizations 2d/3d visualizations, nested , nested dialogs, dialogs, drag'n'drop, search, drag'n'drop, search, 9 . 1

Slide 29

Slide 29 text

“ React is perfect for React is perfect for making complex UI making complex UI Well, really?... Well, really?... Can we have Can we have list and trees of hundreds of list and trees of hundreds of elements, elements, dynamic panels, dynamic panels, 2d/3d visualizations 2d/3d visualizations, nested , nested dialogs, dialogs, drag'n'drop, search, drag'n'drop, search, 9 . 1

Slide 30

Slide 30 text

color pickers, tabs, file trees, color pickers, tabs, file trees, a "real app" feeling a "real app" feeling, copy- , copy- paste things paste things, handle key- , handle key- board shortcuts board shortcuts , display , display and edit code in a rich editor and edit code in a rich editor show charts... show charts... 9 . 2

Slide 31

Slide 31 text

color pickers, tabs, file trees, color pickers, tabs, file trees, a "real app" feeling a "real app" feeling, copy- , copy- paste things paste things, handle key- , handle key- board shortcuts board shortcuts , display , display and edit code in a rich editor and edit code in a rich editor show charts... show charts... Can we make ambitious Can we make ambitious apps? apps? 9 . 2

Slide 32

Slide 32 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications 10

Slide 33

Slide 33 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications Well, really?... Well, really?... 10

Slide 34

Slide 34 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications Well, really?... Well, really?... what if we what if we 10

Slide 35

Slide 35 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications Well, really?... Well, really?... what if we what if we already have a native already have a native codebase? codebase? 10

Slide 36

Slide 36 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications Well, really?... Well, really?... what if we what if we already have a native already have a native codebase? codebase? Or have advanced Or have advanced 10

Slide 37

Slide 37 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications Well, really?... Well, really?... what if we what if we already have a native already have a native codebase? codebase? Or have advanced Or have advanced simulations/computations, simulations/computations, 10

Slide 38

Slide 38 text

“ JavaScript is perfect for JavaScript is perfect for most applications most applications Well, really?... Well, really?... what if we what if we already have a native already have a native codebase? codebase? Or have advanced Or have advanced simulations/computations, simulations/computations, or need consistent perfs? or need consistent perfs? 10

Slide 39

Slide 39 text

X-platform toolkit (wxWidgets) GDevelop C++ codebase GDevelop C++ codebase 11

Slide 40

Slide 40 text

X-platform toolkit (wxWidgets) GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler")

Slide 41

Slide 41 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler")

Slide 42

Slide 42 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler")

Slide 43

Slide 43 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler")

Slide 44

Slide 44 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler")

Slide 45

Slide 45 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler") libGDevelop.js

Slide 46

Slide 46 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase GDevelop C++ codebase Core classes (game, scene, object, textures...) 11 Game exporter (JS "transpiler") libGDevelop.js GDevelop JS codebase

Slide 47

Slide 47 text

12

Slide 48

Slide 48 text

13

Slide 49

Slide 49 text

Writing WebAssembly Writing WebAssembly 14 . 1

Slide 50

Slide 50 text

Writing WebAssembly Writing WebAssembly 14 . 1

Slide 51

Slide 51 text

Writing WebAssembly Writing WebAssembly 14 . 1

Slide 52

Slide 52 text

Writing WebAssembly Writing WebAssembly 14 . 1

Slide 53

Slide 53 text

explained 14 . 2

Slide 54

Slide 54 text

explained 14 . 2

Slide 55

Slide 55 text

LLVM IR (bitcode) explained 14 . 2

Slide 56

Slide 56 text

LLVM IR (bitcode) explained 14 . 2

Slide 57

Slide 57 text

LLVM IR (bitcode) explained 14 . 2

Slide 58

Slide 58 text

Using Emscripten Using Emscripten git clone https://github.com/emscripten-core/emsdk.git cd emsdk && ./emsdk install latest && ./emsdk activate latest ./emcc tests/hello_world.c node a.out.js For large projects, Emscripten provides replacements that swap GCC or Clang by Emscripten in build system (automake, CMake...) 15

Slide 59

Slide 59 text

Expose existing classes Expose existing classes 16

Slide 60

Slide 60 text

Expose existing classes Expose existing classes class ObjectsContainer { Object& InsertObject(const Object& object, size_t position) { ... }; Object& GetObject(const gd::String& name) { ... }; } class Layout : public ObjectsContainer { public: void setName(const gd::String & name_) { name = name_; }; const gd::String & getName() { return name; }; // ... } 16

Slide 61

Slide 61 text

Expose existing classes Expose existing classes class ObjectsContainer { Object& InsertObject(const Object& object, size_t position) { ... }; Object& GetObject(const gd::String& name) { ... }; } class Layout : public ObjectsContainer { public: void setName(const gd::String & name_) { name = name_; }; const gd::String & getName() { return name; }; // ... } interface Layout { void setName([Const] DOMString name); [Const, Ref] DOMString getName(); // Inherited from ObjectsContainer [Ref] Object insertObject([Ref] gdObject object, unsigned long pos); [Ref] Object getObject([Const] DOMString name); } "WebIDL" bindings for Emscripten WebIDL binder: 16

Slide 62

Slide 62 text

Use Emscripten classes Use Emscripten classes 17

Slide 63

Slide 63 text

Use Emscripten classes Use Emscripten classes Module().then(gd => { const layout = new gd.Layout(); layout.setName("My game level"); const object = new gd.Object(); object.setName("My character"); layout.insertObject(object, 0); console.log(layout.getName()); // "My game level" console.log(object.getObject("My character")); // Returns a gd.Object }); 17

Slide 64

Slide 64 text

Use Emscripten classes Use Emscripten classes Module().then(gd => { const layout = new gd.Layout(); layout.setName("My game level"); const object = new gd.Object(); object.setName("My character"); layout.insertObject(object, 0); console.log(layout.getName()); // "My game level" console.log(object.getObject("My character")); // Returns a gd.Object }); Converted, including JS strings (to char*) Primitive types? 17

Slide 65

Slide 65 text

Use Emscripten classes Use Emscripten classes Module().then(gd => { const layout = new gd.Layout(); layout.setName("My game level"); const object = new gd.Object(); object.setName("My character"); layout.insertObject(object, 0); console.log(layout.getName()); // "My game level" console.log(object.getObject("My character")); // Returns a gd.Object }); Converted, including JS strings (to char*) Primitive types? If I pass an object? Objects references are converted to pointers (or references) by the webIDL generated glue code 17

Slide 66

Slide 66 text

Use Emscripten classes Use Emscripten classes Module().then(gd => { const layout = new gd.Layout(); layout.setName("My game level"); const object = new gd.Object(); object.setName("My character"); layout.insertObject(object, 0); console.log(layout.getName()); // "My game level" console.log(object.getObject("My character")); // Returns a gd.Object }); Converted, including JS strings (to char*) Primitive types? If I pass an object? std::iostream is binded to console.log Objects references are converted to pointers (or references) by the webIDL generated glue code Can I debug? 17

Slide 67

Slide 67 text

18

Slide 68

Slide 68 text

Things to know Things to know 19

Slide 69

Slide 69 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! 19

Slide 70

Slide 70 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! console.log(layout); // { ptr: 6804120 } 19

Slide 71

Slide 71 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! console.log(layout); // { ptr: 6804120 } Wasm memory 19

Slide 72

Slide 72 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! console.log(layout); // { ptr: 6804120 } Wasm memory 19

Slide 73

Slide 73 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! console.log(layout); // { ptr: 6804120 } Wasm memory The content of gd.Layout 19

Slide 74

Slide 74 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! console.log(layout); // { ptr: 6804120 } Wasm memory The content of gd.Layout 19

Slide 75

Slide 75 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! console.log(layout); // { ptr: 6804120 } Wasm memory The content of gd.Layout 19

Slide 76

Slide 76 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! For React: console.log(layout); // { ptr: 6804120 } Wasm memory The content of gd.Layout 19

Slide 77

Slide 77 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! For React: componentDidMount() { this._project = new gd.Project(); } componentWillUnmount() { gd.destroy(this._project); } console.log(layout); // { ptr: 6804120 } Wasm memory The content of gd.Layout 19

Slide 78

Slide 78 text

Things to know Things to know const layout = new gd.Layout(); // ... gd.destroy(layout); // Binded objects need manual destruction Memory management requires care! For React: componentDidMount() { this._project = new gd.Project(); } componentWillUnmount() { gd.destroy(this._project); } or use an Effect Hook console.log(layout); // { ptr: 6804120 } Wasm memory The content of gd.Layout 19

Slide 79

Slide 79 text

Things to know (2) Things to know (2) 20

Slide 80

Slide 80 text

Things to know (2) Things to know (2) Output files can be large (~3mb for GDevelop), but Output files can be large (~3mb for GDevelop), but gzip helps. gzip helps. 20

Slide 81

Slide 81 text

Things to know (3) Things to know (3) 21

Slide 82

Slide 82 text

Things to know (3) Things to know (3) A complete test set is invaluable for ensuring that no errors are in the bindings. 21

Slide 83

Slide 83 text

Things to know (3) Things to know (3) A complete test set is invaluable for ensuring that no errors are in the bindings. abort(16). Build with -s ASSERTIONS=1 for more info. 21

Slide 84

Slide 84 text

Things to know (3) Things to know (3) A complete test set is invaluable for ensuring that no errors are in the bindings. abort(16). Build with -s ASSERTIONS=1 for more info. What can go wrong? 21

Slide 85

Slide 85 text

Things to know (3) Things to know (3) A complete test set is invaluable for ensuring that no errors are in the bindings. abort(16). Build with -s ASSERTIONS=1 for more info. Wrong type for a parameter What can go wrong? 21

Slide 86

Slide 86 text

Things to know (3) Things to know (3) A complete test set is invaluable for ensuring that no errors are in the bindings. abort(16). Build with -s ASSERTIONS=1 for more info. Wrong type for a parameter Parameter forgotten What can go wrong? 21

Slide 87

Slide 87 text

Things to know (3) Things to know (3) A complete test set is invaluable for ensuring that no errors are in the bindings. abort(16). Build with -s ASSERTIONS=1 for more info. Wrong type for a parameter Parameter forgotten Using a deleted object What can go wrong? 21

Slide 88

Slide 88 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase Core classes (game, scene, object, textures...) Game exporter (JS "transpiler") libGDevelop.js 22 GDevelop JS codebase

Slide 89

Slide 89 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase Core classes (game, scene, object, textures...) Game exporter (JS "transpiler") libGDevelop.js 22 GDevelop JS codebase

Slide 90

Slide 90 text

Creating a complex UI? Creating a complex UI? 23

Slide 91

Slide 91 text

Find a component library Find a component library 24

Slide 92

Slide 92 text

Find a component library Find a component library Extensive list of high quality components 24

Slide 93

Slide 93 text

Find a component library Find a component library Extensive list of high quality components Good theming support 24

Slide 94

Slide 94 text

Find a component library Find a component library Extensive list of high quality components Good theming support Accessibility 24

Slide 95

Slide 95 text

Find a component library Find a component library Extensive list of high quality components Good theming support Accessibility Documentation quality 24

Slide 96

Slide 96 text

Large lists (with drag'n'drop) Large lists (with drag'n'drop) 25

Slide 97

Slide 97 text

Virtualized lists Virtualized lists 26

Slide 98

Slide 98 text

Virtualized lists Virtualized lists react-sortable-hoc react-virtualized 26

Slide 99

Slide 99 text

Virtualized lists Virtualized lists const ObjectRow = () =>
...
; const ObjectsList = (props) => props.map(group => ) react-sortable-hoc react-virtualized 26

Slide 100

Slide 100 text

Virtualized lists Virtualized lists const ObjectRow = () =>
...
; const ObjectsList = (props) => props.map(group => ) const SortableObjectRow = SortableElement(props => ( )); const ObjectsList = (props) => ( { }) /> ); const SortableObjectsList = SortableContainer(ObjectsList); ...} ... react-sortable-hoc react-virtualized 26

Slide 101

Slide 101 text

Panels/resizable editors Panels/resizable editors 27

Slide 102

Slide 102 text

Use a Use a tiling window library tiling window library 28

Slide 103

Slide 103 text

react-mosaic Use a Use a tiling window library tiling window library 28

Slide 104

Slide 104 text

Large trees (with drag'n'drop) Large trees (with drag'n'drop) 29

Slide 105

Slide 105 text

Virtualization again! Virtualization again! 30

Slide 106

Slide 106 text

Virtualization again! Virtualization again! react-sortable-tree 30

Slide 107

Slide 107 text

Levels rendering or visualizations Levels rendering or visualizations 31

Slide 108

Slide 108 text

Forget the DOM Forget the DOM 32

Slide 109

Slide 109 text

Forget the DOM Forget the DOM 32

Slide 110

Slide 110 text

Forget the DOM Forget the DOM 32

Slide 111

Slide 111 text

Don't forget the DOM Don't forget the DOM 33

Slide 112

Slide 112 text

Don't forget the DOM Don't forget the DOM 33

Slide 113

Slide 113 text

Don't forget the DOM Don't forget the DOM `${vertex.getX()},${vertex.getY()}` ).join(' ')} /> {vertices.map((vertex, j) => ( ))} 33

Slide 114

Slide 114 text

When things aren't fast enough When things aren't fast enough 34

Slide 115

Slide 115 text

Profile the rendering Profile the rendering 35

Slide 116

Slide 116 text

Profile the rendering Profile the rendering 35

Slide 117

Slide 117 text

Profile the rendering Profile the rendering shouldComponentUpdate/memoization is often the answer 35

Slide 118

Slide 118 text

Profile the rendering Profile the rendering shouldComponentUpdate/memoization is often the answer Measure performance in production (React development build is way slower) 35

Slide 119

Slide 119 text

Inspect calls to WebAssembly Inspect calls to WebAssembly 36

Slide 120

Slide 120 text

Inspect calls to WebAssembly Inspect calls to WebAssembly Beware of overhead in binding code/wasm call when calling functions, in particular if renderings 36

Slide 121

Slide 121 text

Inspect calls to WebAssembly Inspect calls to WebAssembly Beware of overhead in binding code/wasm call when calling functions, in particular if renderings objects.filter(object => object.getType() !== "") // N wasm calls + string conversion .map(object => object.getVariables(project)); // N wasm calls + string conversion Won't be noticeable in most UI situations, but can be if used in renderings or long lists/trees 36

Slide 122

Slide 122 text

Inspect calls to WebAssembly Inspect calls to WebAssembly Beware of overhead in binding code/wasm call when calling functions, in particular if renderings objects.filter(object => object.getType() !== "") // N wasm calls + string conversion .map(object => object.getVariables(project)); // N wasm calls + string conversion Won't be noticeable in most UI situations, but can be if used in renderings or long lists/trees It might be useful to store strings/values on the JS side if you know they won't change. 36

Slide 123

Slide 123 text

When your codebase is growing When your codebase is growing 37

Slide 124

Slide 124 text

Stick to your components Stick to your components 38

Slide 125

Slide 125 text

Stick to your components Stick to your components Help ☺ ☺ 38

Slide 126

Slide 126 text

Stick to your components Stick to your components Help Help ☺ ☺ Avoid custom/adhoc styles, that won't scale: 38

Slide 127

Slide 127 text

Stick to your components Stick to your components Help Help ☺ ☺ Avoid custom/adhoc styles, that won't scale: Make a component for it! #DesignSystem 38

Slide 128

Slide 128 text

Don't unit test your visual Don't unit test your visual components... components... 39

Slide 129

Slide 129 text

Don't unit test your visual Don't unit test your visual components... components... Well actually, do, but only for part where there Well actually, do, but only for part where there is is logic logic 39

Slide 130

Slide 130 text

...but create visual stories ...but create visual stories 40

Slide 131

Slide 131 text

...but create visual stories ...but create visual stories Storybook React Styleguidist 40

Slide 132

Slide 132 text

Use types Use types 41

Slide 133

Slide 133 text

Use types Use types Flow Typescript 41

Slide 134

Slide 134 text

Use types Use types Will tell you that you (or someone else) forgot to Will tell you that you (or someone else) forgot to pass/remove a prop pass/remove a prop Flow Typescript 41

Slide 135

Slide 135 text

Use types Use types Will tell you that you (or someone else) forgot to Will tell you that you (or someone else) forgot to pass/remove a prop pass/remove a prop Flow Typescript Help auto-completion Help auto-completion 41

Slide 136

Slide 136 text

Use types Use types Will tell you that you (or someone else) forgot to Will tell you that you (or someone else) forgot to pass/remove a prop pass/remove a prop Flow Typescript Help auto-completion Help auto-completion Avoid most silly (or not so silly) mistakes Avoid most silly (or not so silly) mistakes 41

Slide 137

Slide 137 text

Use types Use types Will tell you that you (or someone else) forgot to Will tell you that you (or someone else) forgot to pass/remove a prop pass/remove a prop Flow Typescript Help auto-completion Help auto-completion Avoid most silly (or not so silly) mistakes Avoid most silly (or not so silly) mistakes Help to "document" your objects Help to "document" your objects 41

Slide 138

Slide 138 text

Use types Use types Will tell you that you (or someone else) forgot to Will tell you that you (or someone else) forgot to pass/remove a prop pass/remove a prop Flow Typescript Help auto-completion Help auto-completion Avoid most silly (or not so silly) mistakes Avoid most silly (or not so silly) mistakes Help to "document" your objects Help to "document" your objects ... all of these which becomes really useful when you're back on some module you (or someone else) wrote a few months ago 41

Slide 139

Slide 139 text

Use types Use types Will tell you that you (or someone else) forgot to Will tell you that you (or someone else) forgot to pass/remove a prop pass/remove a prop Flow Typescript Help auto-completion Help auto-completion Avoid most silly (or not so silly) mistakes Avoid most silly (or not so silly) mistakes Help to "document" your objects Help to "document" your objects ... all of these which becomes really useful when you're back on some module you (or someone else) wrote a few months ago Types shine when you or someone else is refactoring some parts of the app 41

Slide 140

Slide 140 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase Core classes (game, scene, object, textures...) Game exporter (JS "transpiler") libGDevelop.js 42 GDevelop JS codebase

Slide 141

Slide 141 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase Core classes (game, scene, object, textures...) Game exporter (JS "transpiler") libGDevelop.js 42 GDevelop JS codebase

Slide 142

Slide 142 text

Consider your packaging options Consider your packaging options 43

Slide 143

Slide 143 text

Consider your packaging options Consider your packaging options Web app Squoosh.app 43

Slide 144

Slide 144 text

Consider your packaging options Consider your packaging options GDevelop Electron Web app Squoosh.app 43

Slide 145

Slide 145 text

Consider your packaging options Consider your packaging options GDevelop Electron Web app Embed in a native app Squoosh.app Spotify Steam Chat 43

Slide 146

Slide 146 text

Build over Electron APIs Build over Electron APIs 44

Slide 147

Slide 147 text

Build over Electron APIs Build over Electron APIs class MaterialUIContextMenu extends React.Component { ... } class ElectronContextMenu extends React.Component { ... } 44

Slide 148

Slide 148 text

Build over Electron APIs Build over Electron APIs class MaterialUIContextMenu extends React.Component { ... } class ElectronContextMenu extends React.Component { ... } export default class MaterialUIMenuImplementation { buildFromTemplate(template) { return template.map((item, id) => { if (item.type === 'separator') { return ; } else if (item.type === 'checkbox') { return ( } else { return ( } } showMenu() { ... } } 44

Slide 149

Slide 149 text

Build over Electron APIs Build over Electron APIs export default class ElectronMenuImplementation { buildFromTemplate(template) { this.menuTemplate = template; return undefined; } showMenu(dimensions) { if (!electron) return; const { Menu } = electron.remote; const browserWindow = electron.remote.getCurrentWindow(); this.menu = Menu.buildFromTemplate(this.menuTemplate); this.menu.popup({ window: browserWindow, x: Math.round(dimensions.left), y: Math.round(dimensions.top + dimensions.height), async: true, // Ensure the UI is not blocked on macOS. }); } } class MaterialUIContextMenu extends React.Component { ... } class ElectronContextMenu extends React.Component { ... } export default class MaterialUIMenuImplementation { buildFromTemplate(template) { return template.map((item, id) => { if (item.type === 'separator') { return ; } else if (item.type === 'checkbox') { return ( } else { return ( } } showMenu() { ... } } 44

Slide 150

Slide 150 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase Core classes (game, scene, object, textures...) Game exporter (JS "transpiler") libGDevelop.js 45 GDevelop JS codebase

Slide 151

Slide 151 text

X-platform toolkit (wxWidgets) GUI (windows, dialogs...) Filesystem React.js powered interface Node.js/browser adapters GDevelop C++ codebase Core classes (game, scene, object, textures...) Game exporter (JS "transpiler") libGDevelop.js 45 GDevelop JS codebase Result? Result?

Slide 152

Slide 152 text

46

Slide 153

Slide 153 text

What are users saying? What are users saying? 47

Slide 154

Slide 154 text

What are users saying? What are users saying? “ Wow, what a difference a year can make 47

Slide 155

Slide 155 text

What are users saying? What are users saying? “ Wow, what a difference a year can make “ Amazing how much easier and streamlined the engine has become 47

Slide 156

Slide 156 text

What are users saying? What are users saying? “ Wow, what a difference a year can make “ but I have to admit, once you worked a bit with it, it could be really more productive on many aspects than GD4 “ Amazing how much easier and streamlined the engine has become 47

Slide 157

Slide 157 text

What are users saying? What are users saying? “ Wow, what a difference a year can make “ but I have to admit, once you worked a bit with it, it could be really more productive on many aspects than GD4 “ Amazing how much easier and streamlined the engine has become It works! It works! 47

Slide 158

Slide 158 text

“ The The native web app native web app is is better better than the native app than the native app 48

Slide 159

Slide 159 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, 48

Slide 160

Slide 160 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook) 48

Slide 161

Slide 161 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook), near , near perfect cross-platform perfect cross-platform 48

Slide 162

Slide 162 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook), near , near perfect cross-platform perfect cross-platform, faster , faster startup time startup time 48

Slide 163

Slide 163 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook), near , near perfect cross-platform perfect cross-platform, faster , faster startup time startup time, auto updates, , auto updates, 48

Slide 164

Slide 164 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook), near , near perfect cross-platform perfect cross-platform, faster , faster startup time startup time, auto updates, , auto updates, more contributors, more contributors, 48

Slide 165

Slide 165 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook), near , near perfect cross-platform perfect cross-platform, faster , faster startup time startup time, auto updates, , auto updates, more contributors, more contributors, "try it "try it online", online", 48

Slide 166

Slide 166 text

“ The The native web app native web app is is better better than the native app than the native app Ultra fast iterations, Ultra fast iterations, ultra ultra fast testing (storybook) fast testing (storybook), near , near perfect cross-platform perfect cross-platform, faster , faster startup time startup time, auto updates, , auto updates, more contributors, more contributors, "try it "try it online", online", tablets/phones port tablets/phones port 48

Slide 167

Slide 167 text

@FlorianRival @FlorianRival gdevelop-app.com gdevelop-app.com github.com/4ian/GDevelop github.com/4ian/GDevelop Ping me Ping me Check GD Check GD 49

Slide 168

Slide 168 text

Thanks! ☺ Thanks! ☺ @FlorianRival @FlorianRival gdevelop-app.com gdevelop-app.com github.com/4ian/GDevelop github.com/4ian/GDevelop Ping me Ping me Check GD Check GD 49