Page HTML custom pour un export Web

Tandis que les export Web fournissent un modèle de page HTML absolument capable de lancer le projet sans nécessiter de customisation supplémentaire, Il peut être bénéfique de créer une page HTML customisée. Une telle page permet de customiser l'initialisation du jeu, bien que le jeu lui même ne puisse être manipulé de l’extérieur.

Quelques cas pratique où une telle page puisse être utile :

  • Chargement de fichiers à partir d'un répertoire différent de la page ;
  • Chargement d'un fichier .zip au lieu d'un fichier .pck comme paquet principal ;
  • Chargement du moteur à partir d'un répertoire différent de celui du fichier du pack principal ;
  • Ajout d'un bouton click-to-play pour que les jeux puissent être lancés en mode plein écran ;
  • Chargement de quelques fichiers supplémentaires avant le démarrage du moteur, en les rendant disponibles dans le système de fichiers du projet dès que possible ;
  • Passer des arguments de ligne de commande personnalisés, par exemple -s pour démarrer un script MainLoop.

La page HTML par défaut est disponible dans le dépôt Godot Engine à l'adresse /misc/dist/html/full-size.html et peut être utilisée comme implémentation de référence. Un autre exemple de page HTML est disponible à l'adresse suivante : /misc/dist/html/fixed-size.html. Elle diffère de la page par défaut en ayant une zone de canevas de taille fixe et un widget de sortie en dessous.

Note

Il est recommandé d'utiliser les outils développeurs fournit par le navigateur web pour déboguer le projet exporté. Les données générés en sortie par Godot peuvent en effet être limitées et n'incluent par les erreurs WebGL.

Configuration

Comme le montre la page HTML par défaut, il s'agit pour l'essentiel d'un document HTML ordinaire. Pour travailler avec les projets Godot, il doit être pleinement réalisé, avoir un code de contrôle qui appelle la classe Engine(), et fournir des places pour plusieurs espaces réservés, qui sont remplacés par leurs valeurs réelles lors de l'exportation.

../../_images/html5_export_options.png
  • $GODOT_BASENAME : Le nom de base pour le Chemin d'export ( Export Path ), tel que configuré dans les options d'exports ; les suffixes sont omis (e.g. game.html devient game). Cette variable peut être utilisé pour générer un chemin vers le fichier JavaScript principal. $GODOT_BASENAME.js, qui fournit la classe Engine() . Une image splash montré pendant le démarrage peut être accédé en utilisant cette variable à nouveau : $GODOT_BASENAME.png.
  • $GODOT_PROJECT_NAME : Le nom du projet tel qu'il est défini dans les paramètres du projet.
  • $GODOT_HEAD_INCLUDE : Une chaîne de charactère customisée à inclure dans le document HTML, juste avant la fin du tag <head>. Elle est spécifié dans les options d'export dans la section Html / Head Include . Même si vous avez le contrôle total de la page HTML que vous créez, cette variable peut être utile pour configurer une partie des éléments tagué head depuis l'éditeur Godot. Par exemple, pour différents préreglages d'export Web.
  • $GODOT_DEBUG_ENABLED : Un drapeau qui indique s'il s'agit d'une version de débogage, ou non. Cette variable est substituée par les strings true et false, et peut être utilisée pour désactiver les branches de débogage dans votre contrôleur de code.

Quand la page custom est prête, elle peut être sélectionné dans les options d'exports dans la section Html / Custom Html Shell.

Démarrage du projet

Pour être capable de démarrer le jeu, vous aurez besoin d'écrire un script qui initialise le moteur Godot : Le nœud control. Ce processus d'initialisation comporte trois phases, mais certaines d'entre elles peuvent être laissé au comportement par défaut.

Premièrement, le moteur de jeu doit être chargé en mémoire, il doit ensuite être initialisé, et après ça le projet peut finalement être démarré. Vous pouvez effectuer chacune de ces étapes manuellement avec un grand contrôle, cependant, dans le cas le plus simple la seule chose nécessaire est de créer une instance de la classe Engine() et d’appeler la méthode engine.startGame().

const execName = "path://to/executable"
const mainPack = "path://to/main_pack"

const engine = new Engine();
engine.startGame(execName, mainPack)

Cet extrait de code automatiquement charge en mémoire et initialise le moteur de jeu avant de commencer le jeu. Il utilise le chemin vers l’exécutable donné pour déduire le chemin utilisé pour charger le moteur. La méthode engine.startGame() est asynchrone et retourne une Promise (ce qui signifie promesse). Cela permet au nœud control de vérifier si le jeu a été chargé correctement sans avoir à bloquer son propre fonctionnement et de pouvoir s'en remettre au "polling" (attribuer un temps de calcul pour charger le jeu, vérifier si le jeu est entièrement chargé puis recommencer).

Si dans votre cas, votre projet à besoin qu'un argument spécial lui soit passé au début du script d'initialisation, remplacez la méthode engine.startGame() par engine.start(). Cette deuxième méthode peut en effet accepter une liste arbitrairement longue de chaîne de caractère. Comme elle ne possède pas une liste définie d'arguments, elle ne peut pas automatiquement charger le moteur.

Pour charger manuellement le moteur, la méthode statique Engine.load() doit être appelé. Comme cette méthode est statique, plusieurs instances du moteur peuvent être créer avec le même chemin de base basePath. Si une instance requiert un différent chemin de base, vous pouvez appeler la méthode engine.init() avec ce chemin avant de commencer le jeu.

Note

Par défaut, plusieurs instances ne peuvent pas être crées car le moteur est immédiatement déchargé après son initialisation. Pour accomplir cela il faut empêcher ce déchargement en appelant la méthode engine.setUnloadAfterInit(). Il faudra alors décharger le moteur manuellement après en appelant la méthode statique Engine.unload(). Décharger le moteur libère la mémoire du navigateur Web en déchargeant les fichiers qui ne sont plus nécessaire après l'initialisation.

Pour charger le moteur correctement sur certains hôtes fournisseurs et certaines configurations réseaux, vous aurez peut être besoin de changer l'extension de fichier par défaut en utilisant la méthode Engine.setWebAssemblyFilenameExtension(). Par défaut, l'extension est wasm. Si votre hôte fournisseur bloque cette extension, utilisé cette méthode pour le changer à une autre extension supporté par votre hôte.

Engine.setWebAssemblyFilenameExtension("dat");
// Load mygame.dat as WebAssembly module.
Engine.load("mygame");

Avertissement

Si une extension de nom de fichier différente est utilisée, certains serveurs web risque de régler automatiquement le MIME-type des fichiers à quelque chose de différent de application/wasm, les conséquences sont l’absence de certaines optimisation au démarrage.

Personnaliser le comportement

Dans l'environnement web, plusieurs méthodes peuvent être utilisés pour garantir que le jeu fonctionne comme prévu.

Si vous ciblez une version spécifique de WebGL ou que voulez juste vérifier que WebGL est disponible tout court, vous pouvez appeler la méthode Engine.isWebGLAvailable(). Elle prends optionnellement un argument qui permet de faire un test pour une version majeur spécifique de WebGL.

Alors que le véritable fichier exécutable n'existe pas dans l'environnement Web, le moteur de jeu stocke seulement un nom de fichier virtuel, formé du nom de base des fichiers chargé du moteur. Cette valeur affecte les données de sorties de la méthode OS.get_executable_path() et défini le nom du paquet principal automatiquement démarré. La méthode meth:engine.setExecutableName peut être utilisé pour réécrire cette valeur.

Si votre projet requiert la disponibilité de quelques fichiers au moment de son chargement, vous pouvez les précharger en appelant la méthode engine.preloadFile() avec comme argument le chemin vers un fichier ou un objet ArrayBuffer ( auquel cas un deuxième argument devra être spécifié pour définir un chemin interne pour la ressource chargé.

Personnalisation de la présentation

Plusieurs méthodes peuvent être utilisées pour personnaliser davantage l'apparence et le comportement du jeu sur votre page.

Par défaut, le premier élément du canvas sur la page est utilisé pour le rendu graphique. Pour utiliser un élément canvas différent, la méthode engine.setCanvas() peut être utilisée. Elle nécessite une référence à l'élément DOM lui-même.

const canvasElement = document.querySelector("#my-canvas-element");
engine.setCanvas(canvasElement);

Si la largeur et la hauteur de cet élément du canvas diffèrent des valeurs définies dans les paramètres du projet, il sera redimensionné au début du projet. Ce comportement peut être désactivé en appelant la méthode engine.setCanvasResizedOnStart().

Si le chargement de votre jeu prend un certain temps, il peut être utile d'afficher une interface de chargement personnalisée qui suit la progression. Cela peut être réalisé avec la méthode engine.setProgressFunc() qui permet de mettre en place une fonction de rappel qui sera appelée régulièrement au fur et à mesure que le moteur charge de nouveaux octets.

function printProgress(current, total) {
    console.log("Loaded " + current + " of " + total + " bytes");
}
engine.setProgressFunc(printProgress);

Sachez que dans certains cas, total peut être 0. Cela signifie qu'il ne peut pas être calculé.

Si votre jeu supporte plusieurs langues, la méthode engine.setLocale() peut être utilisée pour définir une locale spécifique, à condition que vous disposiez d'un string de code de langue valide. Il peut être bon d'utiliser une logique du côté serveur pour déterminer les langues qu'un utilisateur peut préférer. De cette façon, le code de langue peut être pris dans l'en-tête HTTP Accept-Language, ou déterminé par un service GeoIP.

Débogage

Pour déboguer les projets exportés, il peut être utile de lire la sortie standard et les flux d'erreurs générés par le moteur. Ceci est similaire à la sortie affichée dans la fenêtre de la console de l'éditeur. Par défaut, les fichiers standard console.log et console.warn sont utilisés respectivement pour la sortie et le flux d'erreurs. Ce comportement peut être personnalisé en définissant vos propres fonctions pour traiter les messages.

Utilisez la méthode engine.setStdoutFunc() pour définir une fonction de rappel pour le flux de sortie. Le comportement par défaut est similaire à celui-ci :

function printStdout(text) {
    console.log(text);
}
engine.setStdoutFunc(printStdout);

Utilisez la méthode engine.setStderrFunc() pour définir une fonction de rappel pour le flux d'erreurs. Le comportement par défaut est similaire à celui-ci :

function printStderr(text) {
    console.warn("Error: " + text);
}
engine.setStderrFunc(printStderr);

Lorsque vous manipulez les données de sortie du moteur, gardez à l'esprit qu'il n'est peut-être pas souhaitable de l'imprimer dans le produit fini. Pour contrôler si l'exécution en cours est ou non une compilation de débogage, vous pouvez utiliser le caractère de remplissage $GODOT_DEBUG_ENABLED.

D'autres options de débogage et un accès de bas niveau à l'environnement d'exécution sont disponibles sous la forme d'un objet Module de Emscripten. On peut y accéder en utilisant la propriété engine.rtenv sur l'instance du moteur.