quest'n'click 4.5.0 · r1

Construite pour quest'n'click 4.5.0, révision r1. Si elle est publiée, et laquelle est la courante, est dit par publication.json.

Voix : par langue et par héros

English · Type : procédure + référence + explication · Public : auteur · Contexte : dépôt du moteur, projet créé · Statut : prête · S'applique depuis : 4.4.0

Une réplique dite joue un clip enregistré quand le jeu en a un pour elle. Cette page explique comment une réplique trouve son clip, comment un jeu traduit reçoit ses propres enregistrements, comment une réplique dont les mots changent avec le héros s’enregistre une fois par valeur, ce qui joue quand un clip manque, et ce que permettent le navigateur et le jeu hors ligne. Elle finit par la table de production (voices), des répliques jusqu’aux fichiers qu’un comédien renvoie.

Comment une réplique trouve son clip

Les fichiers sont dans games/<id>/audio/voice/ dans le dépôt du moteur, game/audio/voice/ dans un projet créé ; npm run assets les encode (64 kb/s, mono) dans public/assets/audio/voices/.

Garantie · voice-keyed-then-plain · référencée · exécutée sur aff6caab7514 · portée vérifiée par son auteur (IA), pas relue Une réplique à aiguillages joue son clip par valeur pour les flags tels qu’ils sont, sinon son id seul.

Avec un flag pas encore posé, elle joue l’id seul.

La voix dans le contenu

audio: { voices: { grandma_01: 'grandma-01.mp3' } },   // fichiers dans games/<id>/audio/voice/
{ say: ['grandma', 'Pixel! Bad news.'], voice: 'grandma_01' }

Par langue : voicesByLang

La langue du jeu (lang dans game.ts, en en son absence) joue audio.voices. Pour toute autre langue que choisit le joueur (Traductions) :

audio.voicesByLang[lang]Ce qui joue
absentles clips du jeu, audio.voices : le texte traduit, dit dans la langue d’origine
présentses clips seulement, sous les mêmes ids (et les mêmes clés) ; une réplique qui y manque n’a pas de voix

Limite · no-per-line-fallback Il n’y a pas de repli réplique par réplique entre les langues : dès qu’une langue a sa table, une réplique qui y manque n’est pas dite dans la langue du jeu ; elle s’affiche pour son temps de lecture. Enregistrez toutes les répliques de cette langue, ou laissez la langue sans table.

Garantie · voices-by-language · référencée · exécutée sur aff6caab7514 · portée vérifiée par son auteur (IA), pas relue Un jeu traduit joue audio.voicesByLang[lang] à la place de audio.voices, sous les mêmes ids de répliques.

Depuis la 4.4.0, npm run assets publie aussi les clips de voicesByLang (avant, seul audio.voices était encodé et une page traduite ne jouait rien), et npm run voices -- check lit le texte propre à chaque langue.

Répliques avec des aiguillages de texte (par héros)

Une réplique dont les mots suivent un flag ({form?m=lui|f=elle}, la syntaxe est dans Héros) s’enregistre une fois par valeur : Grand-mère qui dit « lui » et « elle », ce sont deux clips. Le clip a pour clé l’id de la réplique et les valeurs des flags que lisent ses aiguillages :

audio: { voices: {
  grandma_saw: 'grandma_saw.mp3',              // l'id seul : le repli
  'grandma_saw~form=m': 'grandma_saw_m.mp3',   // {form?m=…} quand form vaut "m"
  'grandma_saw~form=f': 'grandma_saw_f.mp3',
  'greet~form=f~mood=calm': 'greet_f_calm.mp3', // deux flags dans une réplique : triés par nom, joints par "~"
} }

La vue « Heroes × languages » du Studio (4.4.0) montre, pour chacune de ces répliques, le texte que lit chaque héros dans chaque langue, le clip qui joue et le clip par valeur qui manque : Studio : voix et matrice héros × langues.

Ce que permet le navigateur

Les navigateurs refusent le son avant le premier geste du joueur sur la page. Le moteur attend le premier pointerdown, touchend ou keydown ; choisir Nouvelle partie ou Continuer sur l’écran titre en est un, donc les répliques du premier lieu peuvent s’entendre.

Une réplique pour laquelle le jeu n’a pas de clip s’affiche pour son temps de lecture. Une réplique qui a un clip qui ne peut pas jouer se termine dès que le clip renonce, sans temps de lecture :

Limite · voiced-line-without-sound En 4.4.0, une réplique doublée dont le clip ne peut pas jouer ne retombe pas sur le temps de lecture : la bulle se ferme aussitôt (src/engine/dom/speech.ts). Un joueur qui coupe les sons dans un jeu doublé ne lit ces répliques que dans la transcription d’une conversation et la zone annoncée par le lecteur d’écran. Livrez chaque clip que vous déclarez.

Hors ligne

Avec offline: 'full' (le défaut dans game.ts), une fois le lieu courant et ses voisins chargés, le lecteur télécharge en arrière-plan, par lots, chaque image et chaque son du jeu, y compris les clips de toutes les langues (voicesByLang, et chaque clip par valeur d’une réplique). Le menu pause montre l’état (« Offline: complete », ou une relance). Le téléchargement en arrière-plan est sauté sur une connexion en mode « économie de données » ou en 2G. Avec offline: 'nearby', seuls le lieu courant et ses voisins sont mis en cache, et une réplique d’un lieu jamais visité a besoin du réseau : sans lui, le clip échoue et la réplique se ferme aussitôt (voir Ce que permet le navigateur). Plus : Installer comme une application.

Produire les enregistrements

La table de production vous donne, par langue, chaque clip dont le jeu a besoin, qui le dit, son texte dans cette langue, son fichier et son statut, gardés dans games/<id>/voices.json (game/voices.json dans un projet créé), et un contrôle de chaque fichier enregistré.

Où lancer les commandes

ffmpeg (avec ffprobe) est requis pour check : voir doctor.

Étapes

  1. Donner un id stable à chaque réplique. Sans id, une réplique n’est pas listée.

    # dans le dépôt du moteur
    npm run ids -- --lines --write
    
    # dans le projet créé
    npx quest-n-click ids --lines --write
    

    Sans --write, c’est un essai à blanc. --lines=all transforme d’abord chaque réplique écrite comme simple chaîne en { say: ['hero', text], id }, pour un jeu qui double chaque réplique.

  1. Exporter la table pour les comédiens, langue par langue (CSV, ou --json) :

    # dans le dépôt du moteur
    npm run voices -- export --lang fr > voices-fr.csv
    

    npm run voices -- status donne les comptes par langue : les clips nécessaires, leurs statuts (draft, record, recorded, approved), combien ont un fichier, et les clips qu’aucune réplique ne réclame.

  1. Ranger les clips. Mettez chaque fichier dans le dossier des voix, et nommez-le sous son id (ou sa clé) dans audio.voices, ou dans audio.voicesByLang.<lang> pour une traduction. Puis encodez-les :

    # dans le dépôt du moteur
    npm run assets
    
  1. Ramener les statuts : le CSV (ou le JSON) rempli par les comédiens, avec statuts, comédiens et notes.

    # dans le dépôt du moteur
    npm run voices -- import voices-fr.csv --lang fr
    

    La commande refuse une ligne dont la réplique n’existe pas dans le jeu, ou un statut inconnu, et n’écrit rien alors.

  1. Contrôler les fichiers.

    # dans le dépôt du moteur
    npm run voices -- check
    

    La commande mesure chaque clip encodé avec ffmpeg : le codec (mp3, ogg vorbis ou opus, aac, wav, flac), au moins 22 050 Hz, au moins 300 ms et au plus trois fois le temps de lecture de la réplique, un volume entre −23 et −12 LUFS (la parole est vers −16), une crête sous −1 dBFS. --release fait de « approved without a clip » une erreur au lieu d’un avertissement ; npx quest-n-click release lance voices check --release.

Résultat attendu, et comment le vérifier

npm run voices -- check finit par ✔ [<id>] voices: 0 error(s), … ; dans le jeu, la réplique joue son clip et reste à l’écran jusqu’à la fin du clip.

Erreurs fréquentes

SymptômeCauseCorrection
Une réplique manque dans la tableElle n’a pas d’id stableids --lines --write
<id>: approved without a clipApprouvée dans voices.json, aucun fichier dans la tableRanger le clip, ou changer son statut
<id>: the clip cannot be readLe fichier n’est pas encore dans public/assets/audio/voices/npm run assets, puis contrôler à nouveau
<id>: a clip no line claimsUne clé qu’aucune réplique de cette langue n’a (un id renommé, un aiguillage abandonné)Renommer la clé, ou la retirer
✖ no line "<id>" in the game (import)Une ligne venue d’une autre version du jeuExporter la table à nouveau
Un joueur français n’entend rienvoicesByLang.fr existe mais n’a pas cette répliqueL’enregistrer (voir Par langue)
Les répliques doublées défilent sans sonSons coupés, volume des voix à 0, ou fichier du clip absentVérifier le menu pause et Réglages ; npm run assets

Fichiers ou données modifiés

games/<id>/voices.json, games/<id>/audio/voice/, game.ts (audio.voices, audio.voicesByLang), les sources (ids --write ajoute des ids), public/assets/audio/voices/ et assets.gen.json (les clips d’une traduction sous <lang>:<id>).

Revenir en arrière

voices.json, les tables et les sources sont dans Git : git diff montre ce qu’ont changé ids --write et import, et git checkout -- <fichier> l’annule. npm run voices -- status et export n’écrivent rien.

Références


Modifier la source de cette page · Signaler une erreur