Custom HTML page for Web export
While Web export templates provide a default HTML page fully capable of launching the project without any further customization, it may be beneficial to create a custom HTML page. While the game itself cannot easily be directly controlled from the outside yet, such page allows to customize the initialization process for the engine. Some use-cases where customizing the default page is useful include:
- Loading files from a different directory than the page;
.zipfile instead of a.pckfile as the main pack;- Loading the engine from a different directory than the main pack file;
- Adding a click-to-play button so that games can be started in the fullscreen mode;
- Loading some extra files before the engine starts, making them available in the project file system as soon as possible;
-sto start aMainLoopscript. /misc/dist/html/full-size.html but the following template can be used as a much simpler example:<!DOCTYPE html><html> <head> <title>My Template</title> <meta charset="UTF-8"> </head> <body> <canvas id="canvas"></canvas> <script src="$GODOT_URL"></script> <script> var engine = new Engine($GODOT_CONFIG); engine.startGame(); </script> </body></html>
Setup
<canvas>element, and some simple JavaScript code that calls the Engine() class. The only required placeholders are:$GODOT_URL: The name of the main JavaScript file, which provides the Engine() class required to start the engine and that must be included in the HTML as a<script>. The name is generated from the Export Path during the export process.$GODOT_CONFIG: A JavaScript object, containing the export options and can be later overridden. See EngineConfig for the full list of overrides. The following optional placeholders will enable some extra features in your custom HTML template.$GODOT_PROJECT_NAME: The project name as defined in the Project Settings. It is a good idea to use it as a<title>in your template.$GODOT_HEAD_INCLUDE: A custom string to include in the HTML document just before the end of the<head>tag. It is customized in the export options under the Html / Head Include section. While you fully control the HTML page you create, this variable can be useful for configuring parts of the HTMLheadelement from the Godot Editor, e.g. for different Web export presets. Html / Custom Html Shell section.Starting the project
To be able to start the game, you need to write a script that initializes the engine — the control code. This process consists of three steps, though as shown most of them can be skipped depending on how much customization is needed (or be left to a default behavior). HTML5 shell class reference, for the full list of methods and options available. Engine() class with the exported configuration, and then call the engine.startGame method optionally overriding any EngineConfig parameters.
engine.startGame method is asynchronous and returns aconst engine = new Engine($GODOT_CONFIG);engine.startGame({ /* optional override configuration, eg. */ // unloadAfterInit: false, // canvasResizePolicy: 0, // ...});
Promise. This allows your control code to track if the game was loaded correctly without blocking execution or relying on polling. engine.start method can be used instead. Note, that this method do not automatically preload thepckfile, so you will probably want to manually preload it (and any other extra file) via the engine.preloadFile method. engine.init to perform specific actions after the module initialization, but before the engine starts. This process is a bit more complex, but gives you full control over the engine startup process.
Engine.load() static method must be called. As this method is static, multiple engine instances can be spawned if the share the sameconst myWasm = 'mygame.wasm';const myPck = 'mygame.pck';const engine = new Engine();Promise.all([ // Load and init the engine engine.init(myWasm), // And the pck concurrently engine.preloadFile(myPck),]).then(() => { // Now start the engine. return engine.start({ args: ['--main-pack', myPck] });}).then(() => { console.log('Engine has started!');});
wasm. Note unloadAfterInit override option. It is still possible to unload the engine manually afterwards by calling the Engine.unload() static method. Unloading the engine frees browser memory by unloading files that are no longer needed once the instance is initialized.Customizing the behavior
In the Web environment several methods can be used to guarantee that the game will work as intended. Engine.isWebGLAvailable() method. It optionally takes an argument that allows to test for a specific major version of WebGL. OS.get_executable_path() method and defines the name of the automatically started main pack. The executable override option can be used to override this value.Customizing the presentation
Several configuration options can be used to further customize the look and behavior of the game on your page. canvas override option can be used. It requires a reference to the DOM element itself.
canvasResizePolicy override option. onProgress callback option, which allows to set up a callback function that will be called regularly as the engine loads new bytes.const canvasElement = document.querySelector("#my-canvas-element");engine.startGame({ canvas: canvasElement });
function printProgress(current, total) { console.log("Loaded " + current + " of " + total + " bytes");}engine.startGame({ onProgress: printProgress });
totalcan be0. This means that it cannot be calculated. locale override option can be used to force a specific locale, provided you have a valid language code string. It may be good to use server-side logic to determine which languages a user may prefer. This way the language code can be taken from theAccept-LanguageHTTP header, or determined by a GeoIP service.Debugging
console.logandconsole.warnare used for the output and error streams respectively. This behavior can be customized by setting your own functions to handle messages. onPrint override option to set a callback function for the output stream, and the onPrintError override option to set a callback function for the error stream.
When handling the engine output keep in mind, that it may not be desirable to print it out in the finished product.function print(text) { console.log(text);}function printError(text) { console.warn(text);}engine.startGame({ onPrint: print, onPrintError: printError });
