diff --git a/development/compiling/compiling_for_web.rst b/development/compiling/compiling_for_web.rst index 9c6d8e3bb..68c14c8cf 100644 --- a/development/compiling/compiling_for_web.rst +++ b/development/compiling/compiling_for_web.rst @@ -10,7 +10,7 @@ Requirements To compile export templates for the Web, the following is required: -- `Emscripten 1.37.9+ `__: If the version available +- `Emscripten 1.38.22+ `__: If the version available per package manager is not recent enough, the best alternative is to install using the `Emscripten SDK `__ - `Python 2.7+ or Python 3.5+ `__ @@ -29,6 +29,11 @@ written by the Emscripten SDK, e.g. when invoking ``emsdk activate latest``, or by your package manager. It's also created when starting Emscripten's ``emcc`` program if the file doesn't exist. +.. Attention:: + On Windows, make sure to escape backslashes of paths within the Emscripten + configuration file as double backslashes ``\\`` or use Unix-style paths with a + single forward slash ``/``. + Open a terminal and navigate to the root directory of the engine source code. Then instruct SCons to build the JavaScript platform. Specify ``target`` as either ``release`` for a release build or ``release_debug`` for a debug build:: @@ -66,18 +71,13 @@ asm.js, a highly optimizable subset of JavaScript, using Emscripten's tool called ``asm2wasm``. Emscripten automatically takes care of both processes, we simply run SCons. -The other method uses LLVM's WebAssembly backend. This backend is not yet -available in release versions of LLVM, only in development builds built with -``LLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``. -Compiling with this backend outputs files in LLVM's ``.s`` format, which is -translated into actual WebAssembly using a tool called ``s2wasm``. -Emscripten manages these processes as well, so we just invoke SCons. +The other method uses LLVM's WebAssembly backend. This backend is available +starting with LLVM 8 or in development builds. +Emscripten manages this process as well, so we just invoke SCons. In order to choose one of the two methods, the ``LLVM_ROOT`` variable in the Emscripten configuration file is used. If it points to a directory containing binaries of Emscripten's *fastcomp* fork of clang, ``asm2wasm`` is used. This is the default in a normal Emscripten installation. Otherwise, LLVM binaries built with the WebAssembly backend will be expected and -``s2wasm`` is used. On Windows, make sure to escape backslashes of paths within -this file as double backslashes ``\\`` or use Unix-style paths with a single -forward slash ``/``. +the LLVM's WebAssembly backend is used. diff --git a/getting_started/workflow/export/customizing_html5_shell.rst b/getting_started/workflow/export/customizing_html5_shell.rst deleted file mode 100644 index 685548ebe..000000000 --- a/getting_started/workflow/export/customizing_html5_shell.rst +++ /dev/null @@ -1,238 +0,0 @@ -.. _doc_customizing_html5_shell: - -Customizing the Web export HTML page -==================================== - -Rather than the default HTML page that comes with the export templates, it is -also possible to use a custom HTML page. This allows drastic customization of -the final web presentation and behavior. The path to the custom HTML page is -specified in the export options as ``Html/Custom Html Shell``. - -The default HTML page is available in the Godot Engine repository at -`/misc/dist/html/default.html `_. -Some simple use-cases where customizing the default page is useful include: - - - Loading files from a different directory - - Loading a ``.zip`` file instead of a ``.pck`` file as main pack - - Loading engine files from a different directory than the main pack file - - Loading some extra files before the engine starts, so they are available in - the file system later - - Passing custom "command line" arguments, e.g. ``-s`` to start a MainLoop script - -Placeholder substitution ------------------------- - -When exporting the game, several placeholders in the HTML page are replaced -with values depending on the export: - -+------------------------------+-----------------------------------------------+ -| Placeholder | substituted by | -+==============================+===============================================+ -| ``$GODOT_BASENAME`` | Basename of exported files without suffixes, | -| | e.g. ``game`` when exporting ``game.html`` | -+------------------------------+-----------------------------------------------+ -| ``$GODOT_DEBUG_ENABLED`` | ``true`` if debugging, ``false`` otherwise | -+------------------------------+-----------------------------------------------+ -| ``$GODOT_HEAD_INCLUDE`` | Custom string to include just before the end | -| | of the HTML ```` element | -+------------------------------+-----------------------------------------------+ - -The HTML file must evaluate the JavaScript file ``$GODOT_BASENAME.js``. This -file defines a global ``Engine`` object used to start the engine, :ref:`see -below ` for details. - -The boot splash image is exported as ``$GODOT_BASENAME.png`` and can be used -e.g. in ```` elements. - -``$GODOT_DEBUG_ENABLED`` can be useful to optionally display e.g. an output -console or other debug tools. - -``$GODOT_HEAD_INCLUDE`` is replaced with the string specified by the export -option ``Html/Head Include``. - -.. _doc_javascript_engine_object: - -The ``Engine`` object ---------------------- - -The JavaScript global object ``Engine`` is defined by ``$GODOT_BASENAME.js`` -and serves as an interface to the engine start-up process. - -The object itself has only two methods, ``load()`` and ``unload()``. - -``Engine.load(basePath)`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Loads the engine from the passed base path. - -Returns a promise that resolves once the engine is loaded. - -``Engine.unload()`` -~~~~~~~~~~~~~~~~~~~ - -Unloads the module to free memory. This is called automatically once the -module is instantiated unless explicitly disabled. - -``Engine.isWebGLAvailable(majorVersion = 1)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Returns ``true`` if the given major version of WebGL is available, -``false`` otherwise. Defaults to ``1`` for WebGL 1.0. - -Starting an ``Engine`` instance -------------------------------- - -The more interesting interface is accessed by instantiating ``Engine`` using -the ``new`` operator: - -.. code-block:: js - - var engine = new Engine(); - -This ``Engine`` instance, referred to as ``engine`` with a lower-case ``e`` -from here, is a startable instance of the engine, usually a game. To start such -an instance, the global ``Engine`` object must be loaded, then the ``engine`` -instance must be initialized and started. - -``engine.init(basePath)`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Initializes the instance. If the engine wasn't loaded yet, a base path -must be passed from which the engine will be loaded. - -Returns a promise that resolves once the engine is loaded and initialized. -It can then be started with ``engine.startGame()`` - -``engine.preloadFile(file, path)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This loads a file so it is available in the file system once the instance -is started. This must be called **before** starting the instance. - -If ``file`` is a string, the file will be loaded from that URL. If ``file`` is -an ``ArrayBuffer`` or a view on one, the buffer will used as the content of the -file. - -If ``path`` is a string, it specifies the path by which the file will be -available. This is mandatory if ``file`` is not a string. -Otherwise, the path is derived from the URL of the loaded file. - -Returns a promise that resolves once the file is preloaded. - -``engine.start(arg1, arg2, …)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Starts the instance of the engine, handing the passed strings as arguments -to the ``main()`` function. This allows great control over how the engine -is used, but usually the other methods whose names start with ``engine.start`` -are simpler to use. - -Returns a promise that resolves once the engine started. - -``engine.startGame(mainPack)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Starts the game with the main pack loaded from the passed URL string and -starts the engine with it. - -If the engine isn't loaded yet, the base path of the passed URL will be -used to load the engine. - -Returns a promise that resolves once the game started. - -Configuring start-up behaviour ------------------------------- - -Beside starting the engine, other methods of the engine instance allow -configuring the behavior: - -``engine.setUnloadAfterInit(enabled)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Sets whether the Engine will be unloaded automatically after the instance -is initialized. This frees browser memory by unloading files that are no -longer needed once the instance is initialized. However, if more instances of -the engine will be started, the Engine will have to be loaded again. - -Defaults to ``true``. - -``engine.setCanvas(canvasElem)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, the first canvas element on the page is used for rendering. -By calling this method, another canvas can be specified. - -``engine.setCanvasResizedOnStart(enabled)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Sets whether the canvas will be resized to the width and height specified -in the project settings on start. Defaults to ``true``. - -``engine.setLocale(locale)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, the engine will try to guess the locale to use from the -JavaScript environment. It is usually preferable to use a server-side -user-specified locale, or at least use the locale requested in the HTTP -``Accept-Language`` header. This method allows specifying such a custom locale -string. - -``engine.setExecutableName(execName)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, the base name of the loaded engine files is used for the -executable name. This method allows specifying another name. - -Customizing the presentation ----------------------------- - -The following methods are used to implement the presentation: - -``engine.setProgressFunc(func)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This method is used to display download progress. The passed callback -function is called with two number arguments, the first argument specifies -bytes loaded so far, the second argument specifies the total number of bytes -to load. - -.. code-block:: js - - function printProgress(current, total) { - console.log("Loaded " + current + " of " + total + " bytes"); - } - engine.setProgressFunc(printProgress); - -If the total is 0, it couldn't be calculated. Possible reasons -include: - - - Files are delivered with server-side chunked compression - - Files are delivered with server-side compression on Chromium - - Not all file downloads have started yet (usually on servers without multi-threading) - -``engine.setStdoutFunc(func)``, ``engine.setStderrFunc(func)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -These methods allow implementing custom behavior for the ``stdout`` and -``stderr`` streams. The functions passed in will be called with one string -argument specifying the string to print. - -.. code-block:: js - - function printStderr(text) { - console.warn("Error: " + text); - } - engine.setStderrFunc(printStderr); - -These methods should usually only be used in debug pages. The -``$GODOT_DEBUG_ENABLED`` placeholder can be used to check for this. - -By default, ``console.log()`` and ``console.warn()`` are used respectively. - -Accessing the Emscripten ``Module`` ------------------------------------ - -If you know what you're doing, you can access the runtime environment -(Emscripten's ``Module``) as ``engine.rtenv``. Check the official Emscripten -documentation for information on how to use it: -https://kripken.github.io/emscripten-site/docs/api_reference/module.html diff --git a/getting_started/workflow/export/exporting_for_web.rst b/getting_started/workflow/export/exporting_for_web.rst index 416663ea1..1b51505e9 100644 --- a/getting_started/workflow/export/exporting_for_web.rst +++ b/getting_started/workflow/export/exporting_for_web.rst @@ -4,12 +4,40 @@ Exporting for the Web ===================== HTML5 export allows publishing games made in Godot Engine to the browser. -This requires support for the recent technologies `WebAssembly -`__ and `WebGL 2.0 `__ -in the user's browser. **Firefox** and **Chromium** (Chrome, Opera) are -the most popular supported browsers, **Safari** and **Edge** do not work yet. -On **iOS**, all browsers must be based on WebKit (i.e. Safari), so they will also -not work. +This requires support for `WebAssembly +`__ and `WebGL `__ +in the user's browser. + +.. Important:: + Use the browser-integrated developer console, usually opened with :kbd:`F12`, + to view **debug information** like JavaScript, engine, and WebGL errors. + +.. Attention:: + Many browsers, Chromium-based browsers specifically, will not load exported + projects when **opened locally** per ``file://`` protocol. To get around this, + use a local server. + + .. Tip:: + Python offers an easy method to start a local server. Use + ``python -m SimpleHTTPServer`` with Python 2 or ``python -m http.server`` with + Python 3 to serve the current working directory at ``http://localhost:8000``. + +WebGL 2 +------- + +Until the *OpenGL ES 3* renderer is removed from Godot in favor of *Vulkan*, +HTML5 export uses *WebGL 2* when the *GLES3* option selected. + +.. Warning:: + Usage of WebGL 2 is not recommended due to its expected removal from Godot + without replacement. + +WebGL 2 is not supported in all browsers. **Firefox** and +**Chromium** (Chrome, Opera) are the most popular supported browsers, +**Safari** and **Edge** do not work. On **iOS**, all browsers are based on +WebKit (i.e. Safari), so they will also not work. + +Godot's WebGL 2 renderer has issues with 3D and is no longer maintained. Limitations ----------- @@ -18,13 +46,6 @@ For security and privacy reasons, many features that work effortlessly on native platforms are more complicated on the web platform. Following is a list of limitations you should be aware of when porting a Godot game to the web. -Exported ``.html`` file must not be reused -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -On export, several text placeholders are replaced in the **generated HTML -file** specifically for the given export options. It must not be reused in -further exports. - Using cookies for data persistence ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -40,26 +61,51 @@ cases. Full screen and mouse capture ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Browsers do not allow arbitrarily **entering full screen** at any time. The same -goes for **capturing the cursor**. Instead, these actions have to occur as a -response to a JavaScript input event. In Godot, this is most easily done by -entering full screen from within an input callback such as ``_input`` or -``_unhandled_input``. +Browsers do not allow arbitrarily **entering full screen**. The same goes for +**capturing the cursor**. Instead, these actions have to occur as a response to +a JavaScript input event. In Godot, this means entering full screen from within +a pressed input event callback such as ``_input`` or ``_unhandled_input``. +Querying the :ref:`class_Input` singleton is not sufficient, the relevant +input event must currently be active. -For the same reason, the full screen project setting is ignored. +For the same reason, the full screen project setting doesn't work unless the +engine is started from within a valid input event handler. This requires +:ref:`customization of the HTML page `. -HTTPClient -~~~~~~~~~~ +Audio autoplay +~~~~~~~~~~~~~~ -The ``HTTPClient`` implementation for the HTML5 platform has several -restrictions: +Chrome restricts how websites may play audio. It may be necessary for the +player to click or tap or press a key to enable audio. + +.. seealso:: + Google offers additional information about their `Web Audio autoplay policies `__. + +:ref:`class_HTTPClient` and :ref:`class_HTTPRequest` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The HTTP classes have several restrictions on the HTML5 platform: - Accessing or changing the ``StreamPeer`` is not possible - - Blocking mode is not available + - Threaded/Blocking mode is not available - Cannot progress more than once per frame, so polling in a loop will freeze - No chunked responses - Host verification cannot be disabled - - Subject to `same-origin policy `_ + - Subject to `same-origin policy `__ + +Exported ``.html`` file must not be reused +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On export, several text placeholders are replaced in the **generated HTML +file** specifically for the given export options. It must not be reused in +further exports. + +Boot splash is not displayed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The default HTML page does not display the boot splash while loading. However, +the image is exported as a PNG file, so :ref:`custom HTML pages ` +can display it. Unimplemented functionality ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -68,23 +114,14 @@ The following functionality is currently unavailable on the HTML5 platform: - Threads - GDNative + - C# - Clipboard synchronisation between engine and operating system - - Networking other than ``HTTPClient`` + - Networking other than :ref:`class_HTTPClient` and :ref:`class_WebSocketClient` -Check the `list of open HTML5 issues on Github `_ -to see if functionality you're interested in has an issue yet. If not, open one -to communicate your interest. - -Starting exported games from the local file system -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Many browsers, Chromium-based browsers specifically, will not load exported -projects when **opened locally** per ``file://`` protocol. To get around this, -use a local server. - -Python offers an easy method for this; using ``python -m SimpleHTTPServer`` -with Python 2 or ``python -m http.server`` with Python 3 will serve the current -working directory on ``http://localhost:8000``. +.. Tip:: + Check the `list of open HTML5 issues on Github `__ + to see if functionality you're interested in has an issue yet. If not, open + one to communicate your interest. Serving the files ----------------- @@ -97,8 +134,7 @@ The generated ``.html`` file can be used as ``DirectoryIndex`` in Apache servers and can be renamed to e.g. ``index.html`` at any time, its name is never depended on by default. -The HTML page is designed to fit the game perfectly without cutting off -parts of the canvas when the browser window is scaled to the game's dimensions. +The HTML page draws the game at maximum size within the browser window. This way it can be inserted into an ``