Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédenteDernière révisionLes deux révisions suivantes | ||
fr:rc_localisation_traduction [2016/03/07 21:35] – ↷ Page déplacée de fr:rc_localisation_traduction à ds:sitem:rc_localisation_traduction zatalyz | fr:rc_localisation_traduction [2021/12/03 19:19] – modification externe 127.0.0.1 | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== Système de localisation/ | ||
+ | |||
+ | {{INLINETOC}} | ||
+ | |||
+ | ===== Généralités ===== | ||
+ | Il y a, en gros, deux parties distinctes pour la localisation dans Ryzom. La première partie (et la plus simple) concerne la localisation statique côté serveur (autrement dit, les noms d' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Comme vous pouvez le voir sur le diagramme, il y a quatre types de fichiers qui font fonctionner le système de localisation. Chacun de ces fichiers doit venir dans chaque langue localisée. En gras, vous pouvez voir que chaque fichier inclut le code de la langue dans son nom. | ||
+ | |||
+ | Les formats de fichiers sont détaillés ci-dessous. | ||
+ | |||
+ | ==== Code Langue ==== | ||
+ | |||
+ | Les langues, dans Ryzom, sont identifiées par leur code langue tel que défini dans [[wp> | ||
+ | |||
+ | ISO 639-1 est un code langue sur deux caractères (par exemple ' | ||
+ | |||
+ | Mais il y a quelques exceptions, comme le chinois écrit. Le chinois peut s' | ||
+ | |||
+ | Nous devons donc ajouter un code pays pour indiquer de quelle forme de chinois écrit nous parlons. Le code langue pour le chinois simplifié devient ' | ||
+ | |||
+ | ==== Définition de l' | ||
+ | Les chaînes traduites sont associées à un identifiant. Les identifiants sont des chaînes de texte qui doivent suivent la contrainte de <wrap hi> | ||
+ | Un identifiant C ne doit contenir que les caractères suivants : '' | ||
+ | Un véritable identifiant C ne peut pas commencer par un nombre, un identifiant de chaîne le peut. | ||
+ | |||
+ | Quelques bons identifiants : | ||
+ | |||
+ | < | ||
+ | CeciEstUnBonIdentifiant | ||
+ | _Ceci@est@unautreBonId | ||
+ | 1234_est_un_bonId | ||
+ | Ceci_est_un_Bon_1234</ | ||
+ | |||
+ | Quelques mauvais identifiants : | ||
+ | |||
+ | < | ||
+ | é# | ||
+ | </ | ||
+ | |||
+ | ==== Formats de fichier ==== | ||
+ | Il y a trois formats différents pour les fichiers de traduction. Mais on n'a besoin d'en connaître que deux. | ||
+ | |||
+ | === Format 1 === | ||
+ | |||
+ | Ce format est utilisé pour le texte statique côté client et pour le texte à clauses côté serveur. | ||
+ | Ce fichier est une liste d' | ||
+ | |||
+ | identifiant1 [valeur de texte] | ||
+ | identifiant2 [autre valeur de texte] | ||
+ | |||
+ | Le fichier peut inclure des commentaires de style C. | ||
+ | |||
+ | < | ||
+ | identifiant1 [valeur de texte] | ||
+ | /* Ceci est | ||
+ | un commentaire | ||
+ | sur plusieurs lignes */ | ||
+ | identifiant2 /* commentaire sur plusieurs lignes ici ! */ [autre valeur de texte]</ | ||
+ | |||
+ | Les valeurs de texte peuvent être mises en forme pour une meilleure lisibilité. La nouvelle ligne et les tabulations sont supprimées dans la valeur finale de la chaîne. | ||
+ | |||
+ | < | ||
+ | de texte | ||
+ | avec une | ||
+ | nouvelle ligne | ||
+ | et des tabulations rien que pour la lisibilité] | ||
+ | identifiant2 [autre valeur de texte]</ | ||
+ | |||
+ | Si vous voulez indiquer de nouvelles lignes ou des tabulations dans une chaîne de valeur, vous devez utilisers la séquence d' | ||
+ | |||
+ | < | ||
+ | identifiant2 [Nouvelle ligne \nTexte sur une nouvelle ligne] | ||
+ | identifiant3 [Backslash : \\] | ||
+ | identifiant4 [un crochet fermant : \] ]</ | ||
+ | |||
+ | Vous pouvez découper le fichier d' | ||
+ | Ceci se fait en utilisant une commande de préprocesseur de type C “# | ||
+ | |||
+ | #include " | ||
+ | |||
+ | Vous pouvez avoir un nombre quelconque de commandes “include”. Les fichiers inclus peuvent également contenir des commandes “include”. | ||
+ | Le chemin peut être aussi bien absolu que relatif à l' | ||
+ | |||
+ | === Format 2 === | ||
+ | |||
+ | Ce format est utilisé pour les fichiers de phrases de traduction. | ||
+ | Ce format a une grammaire assez compliquée qui va être décrite dans une syntaxe proche de LALR : | ||
+ | |||
+ | < | ||
+ | |||
+ | phrase : identifiant ‘(‘ parameterList ‘)’ | ||
+ | ‘{‘ | ||
+ | clauseList | ||
+ | ‘}’ | ||
+ | |||
+ | parameterList : parameterList ‘,’ parameterDesc | ||
+ | | parameterDesc | ||
+ | |||
+ | parameterDesc : parameterType parameterName | ||
+ | |||
+ | parameterName : identifiant | ||
+ | |||
+ | parameterType : ‘item’ | ||
+ | | ‘place’ | ||
+ | | ‘creature’ | ||
+ | | ‘skill’ | ||
+ | | ‘role’ | ||
+ | | ‘ecosystem’ | ||
+ | | ‘race’ | ||
+ | | ‘brick’ | ||
+ | | ‘tribe’ | ||
+ | | ‘guild’ | ||
+ | | ‘player’ | ||
+ | | ‘int’ | ||
+ | | ‘bot’ | ||
+ | | ‘time’ | ||
+ | | ‘money’ | ||
+ | | ‘compass’ | ||
+ | | ‘dyn_string_id’ | ||
+ | | ‘string_id’ | ||
+ | | ‘self’ | ||
+ | | ‘creature_model’ | ||
+ | | ‘entity’ | ||
+ | | ‘bot_name’ | ||
+ | | ‘bodypart’ | ||
+ | | ‘score’ | ||
+ | | ‘sphrase’ | ||
+ | | ‘characteristic’ | ||
+ | | ‘damage_type’ | ||
+ | | ‘literal’ | ||
+ | |||
+ | clauseList : clauseList clause | ||
+ | | clause | ||
+ | |||
+ | clause : conditionList identifiant textValue | ||
+ | | identifiant textValue | ||
+ | | conditionList identifiant | ||
+ | | identifiant | ||
+ | | textValue | ||
+ | |||
+ | conditionList : conditionList condition | ||
+ | | condition | ||
+ | |||
+ | condition : ‘(‘ testList ‘)’ | ||
+ | |||
+ | testList : testList ‘&’ test | ||
+ | | test | ||
+ | |||
+ | test : operand1 operator reference | ||
+ | |||
+ | operand1 : parameterName | ||
+ | | parameterName’.’propertyName | ||
+ | |||
+ | propertyName : identifiant | ||
+ | |||
+ | operator : ‘=’ | ||
+ | | ‘!=’ | ||
+ | | ‘<’ | ||
+ | | ‘<=’ | ||
+ | | ‘>’ | ||
+ | | ‘<=’ | ||
+ | |||
+ | reference : identifiant | ||
+ | |||
+ | textValue : ‘[‘ .* ‘]’</ | ||
+ | |||
+ | Comme dans le format 1, vous pouvez insérer des commentaires en style C dans le text, indenter à loisir, et utiliser la commande include. | ||
+ | |||
+ | === Format 3 : Export de feuille de calcul Unicode === | ||
+ | Ce format est le résultat d'un export de feuille de calcul en texte Unicode. | ||
+ | L' | ||
+ | |||
+ | Vous ne devez pas les modifier manuellement, | ||
+ | |||
+ | La première ligne contiendra le nom des colonnes. | ||
+ | |||
+ | == Colonnes d' | ||
+ | Si le nom d'une colonne commence par ' | ||
+ | Ceci est utile pour ajouter une colonne d' | ||
+ | |||
+ | == Caractère d' | ||
+ | |||
+ | Il est possible d' | ||
+ | |||
+ | Exemple : vous avez une chaîne avec les remplacements suivants (en français) : | ||
+ | |||
+ | '' | ||
+ | |||
+ | Et le fichier des noms d' | ||
+ | |||
+ | item name da | ||
+ | marteau marteau le | ||
+ | echelle échelle l’ | ||
+ | |||
+ | Si l'item est ' | ||
+ | |||
+ | ''" | ||
+ | |||
+ | Mais pour ' | ||
+ | |||
+ | ''" | ||
+ | |||
+ | Pour supprimer cet espace supplémentaire, | ||
+ | |||
+ | item name da | ||
+ | marteau marteau le | ||
+ | echelle échelle l’\d | ||
+ | |||
+ | Ceci donnera une chaîne correcte comme résultat : | ||
+ | |||
+ | ''" | ||
+ | |||
+ | ===== Travailler avec des fichiers de traduction, du point de vue du traducteur ===== | ||
+ | ==== Fichiers “*.uxt” sur le client ==== | ||
+ | Ce fichier contient tous les textes statiques disponibles directement sur le client. Le texte doit suivre le format 1 décrit ci-dessus. | ||
+ | |||
+ | Il y a une contrainte supplémentaire : vous **DEVEZ** fournir le nom de la langue comme première entrée, telle qu' | ||
+ | |||
+ | Par exemple, le fichier en.uxt doit commencer par : | ||
+ | languageName [English] | ||
+ | |||
+ | ==== Fichiers sur le serveur ==== | ||
+ | |||
+ | La traduction côté serveur est un peu plus compliquée. | ||
+ | Nous allons voir comment écrire des traductions côté serveur en quatre étapes (devinez quoi : des problèmes les plus simples au plus compliqués !). | ||
+ | |||
+ | === 1ère étape : Une chaîne simple === | ||
+ | |||
+ | Pour cela, vous n'avez besoin que du fichier de phrases. | ||
+ | Disons que nous voulons une chaîne qui dise “hello world!”, identifiée par '' | ||
+ | Créez une entrée de phrase dans '' | ||
+ | |||
+ | < | ||
+ | { | ||
+ | [Hello world!] | ||
+ | }</ | ||
+ | |||
+ | Et voilà ! C'est tout. | ||
+ | |||
+ | Bien sûr, vous devrez aussi fournir la même phrase dans toutes les langues supportées, | ||
+ | |||
+ | < | ||
+ | { | ||
+ | [Bonjour le monde!] | ||
+ | }</ | ||
+ | |||
+ | Remarquez que seule la valeur du texte a changé. L' | ||
+ | |||
+ | === 2ème étape : Contournement pour " | ||
+ | Dans la 4ème étape, nous verrons que le fichier de phrases peut devenir très complexe. Par conséquent, | ||
+ | |||
+ | On peut donc séparer la grammaire de la phrase en fichiers de phrases et la valeur textuelle en fichier de clauses. | ||
+ | |||
+ | Pour cela, vous devez assigner un identifiant unique à chaque valeur de texte. | ||
+ | Reprenons l' | ||
+ | |||
+ | Dans '' | ||
+ | < | ||
+ | { | ||
+ | Hello | ||
+ | }</ | ||
+ | |||
+ | Nous avons juste à mettre un identifiant dans le bloc de phrase. Ce qui signifie que la phrase se réfère à une chaîne identifiée comme '' | ||
+ | |||
+ | Maintenant, nous pouvons créer la valeur textuelle dans '' | ||
+ | |||
+ | Hello [Hello world!] | ||
+ | |||
+ | Comme dans la première étape, vous devrez faire ça pour chaque langue. | ||
+ | |||
+ | <WRAP center round tip 80%> | ||
+ | Pour faciliter le travail de traduction, il est possible de spécifier l' | ||
+ | |||
+ | Exemple : | ||
+ | |||
+ | < | ||
+ | { | ||
+ | Hello [Bonjour le monde!] | ||
+ | }</ | ||
+ | |||
+ | Dans un cas comme celui-ci, le système de traduction regarde toujours d' | ||
+ | |||
+ | L' | ||
+ | </ | ||
+ | |||
+ | === 3ème étape : Utiliser des paramètres – les bases === | ||
+ | C'est là qu'on attaque la partie compliquée ! | ||
+ | |||
+ | Chaque phrase peut recevoir une liste de paramètres. | ||
+ | |||
+ | Ces paramètres peuvent être de différents types : | ||
+ | * item, //(objet)// | ||
+ | * place, // | ||
+ | * creature, // | ||
+ | * skill, // | ||
+ | * ecosystem, // | ||
+ | * race, //(race)// | ||
+ | * brick, // | ||
+ | * tribe, //(tribu)// | ||
+ | * guild, // | ||
+ | * player, // | ||
+ | * int, //(nombre entier)// | ||
+ | * bot, //(robot)// | ||
+ | * time, //(date)// | ||
+ | * money, // | ||
+ | * compass, // | ||
+ | * dyn_string_id, | ||
+ | * string_id, // | ||
+ | * creature_model, | ||
+ | * entity, // | ||
+ | * body_part, //(partie du corps)// | ||
+ | * score, //(score)// | ||
+ | * sphrase, // | ||
+ | * characteristic, | ||
+ | * damage_type, | ||
+ | * bot_name, //(nom du robot)// | ||
+ | * literal. //(?)// | ||
+ | |||
+ | Chaque paramètre reçoit un nom (ou identifiant) à sa déclaration. Nous l’appelons paramName. | ||
+ | |||
+ | Chaque type de paramètre **PEUT** être associé avec un fichier de ' | ||
+ | |||
+ | La première colonne est très importante car elle associe une ligne de donnée avec une valeur particulière du paramètre. | ||
+ | |||
+ | Commençons par un exemple : nous voulons construire une phrase dynamique avec une variable de nom d' | ||
+ | |||
+ | D' | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | NB : La première colonne **DOIT** toujours être le champ d' | ||
+ | </ | ||
+ | |||
+ | |||
+ | Voici un exemple de '' | ||
+ | < | ||
+ | kitifly Kitifly a the Kitiflys the | ||
+ | varynx Varynx a the Varynx the | ||
+ | etc…</ | ||
+ | |||
+ | Comme énoncé ci-dessus, la première colonne donne l' | ||
+ | |||
+ | Ensuite, il faut créer une phrase avec un paramètre créature dans '' | ||
+ | |||
+ | < | ||
+ | {}</ | ||
+ | |||
+ | Comme vous pouvez le voir, après l' | ||
+ | |||
+ | Maintenant, nous pouvons construire la valeur de chaîne. Pour insérer le paramètre dans la chaîne, nous devons préciser le point de remplacement à l'aide du signe '' | ||
+ | |||
+ | < | ||
+ | { | ||
+ | [Would you please kill a $crea$ for me ?] | ||
+ | }</ | ||
+ | |||
+ | Comme vous le voyez, ce n'est pas trop compliqué. '' | ||
+ | |||
+ | Il est possible de rappeler n' | ||
+ | |||
+ | < | ||
+ | { | ||
+ | [Would you please kill $crea.ia$ $crea$ for me ?] | ||
+ | }</ | ||
+ | |||
+ | Certains types de paramètres ont des règles de remplacement spéciales : les '' | ||
+ | |||
+ | Enfin, un dernier point mais non des moindres, les règles pour les identifiants et les contournements vues aux étapes 1 et 2 sont toujours valides. | ||
+ | |||
+ | === 4ème étape : Utiliser les paramètres – clause conditionnelle === | ||
+ | Il est temps maintenant de dévoiler le système de clause conditionnelle. | ||
+ | |||
+ | Disons que l' | ||
+ | |||
+ | Commençons par un premier exemple. Comme pour l' | ||
+ | Ce dont nous avons besoin, c'est la condition à partir de laquelle choisir entre les trois clauses : pas de créature à tuer, une créature à tuer, ou plusieurs. | ||
+ | |||
+ | D' | ||
+ | |||
+ | < | ||
+ | { | ||
+ | // no creature to kill (Pas de créature à tuer) | ||
+ | [There is no creature to kill today.] | ||
+ | // 1 creature to kill (1 créature à tuer) | ||
+ | [Would you please kill a $crea$ for me ?] | ||
+ | // more than one (plus d'une) | ||
+ | [Would you please kill $count$ $crea$ for me ?] | ||
+ | }</ | ||
+ | |||
+ | Nous avons écrit trois versions du texte avec un sens et une structure grammaticale très différents. | ||
+ | Maintenant, ajoutons les conditions. Les conditions sont placées avant l' | ||
+ | |||
+ | < | ||
+ | { | ||
+ | // no creature to kill (Pas de créature à tuer) | ||
+ | (count = 0) [There is no creature to kill today.] | ||
+ | // 1 creature to kill (1 créature à tuer) | ||
+ | (count = 1) [Would you please kill a $crea$ for me ?] | ||
+ | // more than one (plus d'une) | ||
+ | (count > 1) [Would you please kill $count$ $crea$ for me ?] | ||
+ | }</ | ||
+ | |||
+ | Facile, non ? | ||
+ | |||
+ | Maintenant, prenons un cas un peu plus compliqué : nous voulons écrire une phrase différente selon que le joueur soit masculin ou féminin. Voici une occasion d' | ||
+ | |||
+ | Le paramètre '' | ||
+ | |||
+ | Réécrivons la requête pour tuer des animaux en tenant compte du genre du joueur : | ||
+ | < | ||
+ | { | ||
+ | // -- Joueur masculin | ||
+ | // pas de créature à tuer, joueur masculin | ||
+ | (count = 0 & self.gender = Male) | ||
+ | [Hi man, there is no creature to kill today .] | ||
+ | // 1 créature à tuer, joueur masculin | ||
+ | (count = 1 & self.gender = Male) | ||
+ | [Hi man, would you please kill a $crea$ for me ?] | ||
+ | // plus d'une, joueur masculin | ||
+ | (count > 1 & self.gender = Male) | ||
+ | [Hi man, Would you please kill $count$ $crea$ for me ?] | ||
+ | |||
+ | // -- Joueur féminin | ||
+ | // pas de créature à tuer, joueur féminin | ||
+ | (count = 0 & self.gender = Female) | ||
+ | [Hi girl, There is no creature to kill today.] | ||
+ | // 1 créature à tuer, joueur féminin | ||
+ | (count = 1 & self.gender = Female) | ||
+ | [Hi girl, Would you please kill a $crea$ for me ?] | ||
+ | // plus d'une, joueur féminin | ||
+ | (count > 1 & self.gender = Female) | ||
+ | [Hi girl, Would you please kill $count$ $crea$ for me ?] | ||
+ | }</ | ||
+ | |||
+ | Nous avons six clauses maintenant. Trois pour le nombre de créatures, multipliées par les deux genres du joueur. | ||
+ | |||
+ | Comme vous pouvez le voir, les tests conditionnels peuvent être combinés avec le caractère ''&'' | ||
+ | |||
+ | Vous pouvez utiliser n' | ||
+ | |||
+ | De l' | ||
+ | Les opérateurs disponibles sont | ||
+ | = | ||
+ | != | ||
+ | < | ||
+ | <= | ||
+ | > | ||
+ | >= | ||
+ | |||
+ | Dans certains cas, vous pourriez avoir besoin de faire des combinaisons de tests avec '' | ||
+ | |||
+ | < | ||
+ | { | ||
+ | (c1 = 0 & c2 = 10) | ||
+ | (c1 = 10 & c2 = 0) | ||
+ | [On passe dans cette clause si : | ||
+ | c1 égal zéro et c2 égal dix | ||
+ | ou | ||
+ | c1 égal dix et c2 égal zéro] | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Règles détaillées de sélection des clauses : | ||
+ | * Une clause valide est une clause où les combinaisons conditionnelles sont vraies pour un ensemble donné de valeurs du paramètre. | ||
+ | * Les clauses sont évaluées dans l' | ||
+ | * Si la première clause n'a aucune condition, elle sera utilisée comme clause par défaut si aucune clause conditionnelle n'a été choisie. | ||
+ | * S'il n'y a pas de clause par défaut, et qu' | ||
+ | * Pour la même phrase, chaque langue peut fournir son propre ensemble de conditions et de clauses pour s' | ||
+ | |||
+ | ==== Liste des propriétés des paramètres codés en dur ==== | ||
+ | Vous trouverez ici une liste exhaustive des propriétés des paramètres codés en dur. | ||
+ | Ces propriétés sont toujours disponbible, | ||
+ | De plus, les propriétés codées en dur ne peuvent pas être remplacées par un fichier de nom qui utiliserait une colonne du même nom. | ||
+ | |||
+ | ^ Paramètre ^ Propriété ^ | ||
+ | | Item | | | ||
+ | | Place | | | ||
+ | | Creature | "name : nom du modèle pour la créature | | ||
+ | | ::: | gender : genre de la créature (tiré ?) du modèle" | ||
+ | | Skill | | | ||
+ | | Ecosystem | | | ||
+ | | Race | | | ||
+ | | Brick | | | ||
+ | | Tribe | | | ||
+ | | Guild | | | ||
+ | | Player | "name : nom du joueur | | ||
+ | | ::: | gender : genre du joueur dans le miroir" | ||
+ | | Bot | " | ||
+ | | ::: | role : rôle du bot tel que défini dans creature.basics.chatProfile | | ||
+ | | ::: | name : nom de la créature | | ||
+ | | ::: | gender : genre de la créature (tiré ?) du modèle" | ||
+ | | Integer | | | ||
+ | | Time | | | ||
+ | | Money | | | ||
+ | | Compass | | | ||
+ | | dyn_string_id | Seuls les tests != et == sont possibles. Essentiellement pour comparer un paramètre avec 0. | | ||
+ | | string_id | Seuls les tests != et == sont possibles. Essentiellement pour comparer un paramètre avec 0. | | ||
+ | | self | "name : nom du joueur | | ||
+ | | ::: | gender : genre du joueur dans le miroir" | ||
+ | | creature_model | NB : utiliser le fichier de traduction creature_words ! | | ||
+ | | entity | "== 0, != 0 : teste si l' | ||
+ | | ::: | name : nom de la créature ou nom du joueur | | ||
+ | | ::: | gender : genre de la créature (tiré ?) du modèle ou genre du joueur (d' | ||
+ | | bodypart | | | ||
+ | | score | | | ||
+ | | sphrase | | | ||
+ | | characteristic | | | ||
+ | | damage_type | | | ||
+ | | bot_name | | | ||
+ | |||
+ | ===== Workflow de traduction ===== | ||
+ | Dans le worklow de traduction ci-dessous, nous considérons que la langue de référence est l' | ||
+ | |||
+ | Il y a une série d' | ||
+ | |||
+ | Seuls les ajouts aux fichiers de traduction existants sont supportés par les outils de traduction. Si vous souhaitez modifier ou supprimer une chaîne ou une phrase de traduction existante, ce sera à faire 'à la main' avec un maximum d' | ||
+ | |||
+ | Dans la plupart des cas, il vaut mieux créer une nouvelle entrée de traduction, plutôt que de gérer une modification dans tous les fichiers de traduction, et il est à peu près sûr de laisser les vieilles chaînes inutilisées dans les fichiers. | ||
+ | |||
+ | En tous cas, vous ne devez **JAMAIS** faire de modifications quand il y a des fichiers diff en attente. | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | Il est fortement recommandé de respecter scrupuleusement le workflow décrit pour éviter les problèmes de traduction, les chaînes manquantes ou autres problèmes bizarres qui pourraient se produire en travaillant avec plusieurs versions linguistiques d'un ensemble de fichiers. | ||
+ | </ | ||
+ | |||
+ | Le travail de traduction se fait en collaboration entre l' | ||
+ | |||
+ | L' | ||
+ | |||
+ | De plus, pour le fichier de phrases, le fichier diff inclut automatiquement les commentaires qui décrivent la liste de paramètres. | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | Par défaut il semble que le système travaille avec des fichiers ISO-8859-15 etpas UTF8 donc si vous obtenez des résultats étranges avec les commandes, c'est sûrement dû à un encodage UTF8 de votre fichier. | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Structure de l' | ||
+ | Tous les fichiers à traduire sont stockés dans une structure de répertoire bien définie, appelée '' | ||
+ | |||
+ | Des outils sont fournis pour installer le fichier traduit dans le client et le répertoire du serveur après la fin du cycle de traduction. | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ==== Traduction des noms de bot ==== | ||
+ | |||
+ | La commande '' | ||
+ | |||
+ | <WRAP center round info 60%> | ||
+ | Test à effectuer cf HexChatlog kerv30/ | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Chaîne statique sur le client ==== | ||
+ | === Tâche initiale === | ||
+ | **Editeur | ||
+ | * Créer le fichier de référence '' | ||
+ | * Générer les fichiers diff de chaînes statiques avec la commande '' | ||
+ | * Envoyer les fichiers diff au traducteur. | ||
+ | |||
+ | **Traducteur : ** | ||
+ | * Traduire les fichiers diff. | ||
+ | * Les renvoyer à l' | ||
+ | |||
+ | **Editeur : ** | ||
+ | * Mettre les fichiers diff traduits dans le répertoire '' | ||
+ | * Fusionner les fichiers diff traduits à l'aide de la commande '' | ||
+ | |||
+ | Une fois la tâche initiale terminée, le workflow entre en mode incrémental. | ||
+ | |||
+ | === Tache incrémentale === | ||
+ | **Editeur** | ||
+ | * Ajouter des chaînes dans le fichier de référence '' | ||
+ | * Générer les fichiers diff de chaînes statiques avec la commande '' | ||
+ | * Envoyer les fichiers diff au traducteur. | ||
+ | |||
+ | **Traducteur** | ||
+ | * Traduire les fichiers diff. | ||
+ | * Les renvoyer à l' | ||
+ | |||
+ | **Editeur** | ||
+ | * Déposer les fichiers diff traduits dans le répertoire '' | ||
+ | * Fusionner les fichiers diff avec la commande '' | ||
+ | |||
+ | ==== Chaînes dynamiques sur le serveur ==== | ||
+ | === Tâche initiale === | ||
+ | **Editeur** | ||
+ | * Créer le fichier de référence '' | ||
+ | * Générer les fichiers de phrase diff avec la commande '' | ||
+ | * Traduire le fichier de phrases diff. Ceci implique de bonnes connaissances de la structure grammaticale de chaque langue pour s' | ||
+ | * Fusionner le fichier diff traduit à l'aide de la commande '' | ||
+ | * Générer le fichier de clauses diff avec la commande '' | ||
+ | * Envoyer les fichiers de clauses diff au traducteur. | ||
+ | |||
+ | **Traducteur** | ||
+ | * Traduire les fichiers de clauses diff. | ||
+ | * Les renvoyer à l' | ||
+ | |||
+ | **Editeur** | ||
+ | * Déposer les fichiers de clause diff traduits dans le répertoire '' | ||
+ | * Fusionner les fichiers de clause diff avec la commande '' | ||
+ | |||
+ | Une fois la tâche initiale accomplie, le workflow entre en mode incrémental. | ||
+ | |||
+ | === Tache incrémentale === | ||
+ | **Editeur** | ||
+ | * Ajouter la nouvelle phrase dans '' | ||
+ | * Générer les fichiers de phrase diff avec la commande '' | ||
+ | * Traduire le fichier de phrase diff. Ceci implique de bonnes connaissances de la structure grammaticale de chaque langue pour s' | ||
+ | * Fusionner les fichiers diff traduits à l'aide de la commande '' | ||
+ | * Générer les fichiers de clauses diff avec la commande '' | ||
+ | * Envoyer les fichiers de clause diff au traducteur. | ||
+ | |||
+ | **Traducteur** | ||
+ | * Traduire les fichiers de clauses diff. | ||
+ | * Les renvoyer à l' | ||
+ | |||
+ | **Editeur** | ||
+ | * Déposer les fichiers de clause diff traduits dans le répertoire '' | ||
+ | * Fusionner les fichiers de clause traduits avec la commande '' | ||
+ | |||
+ | ==== Fichiers de mot côté serveur ==== | ||
+ | <WRAP center round important 60%> | ||
+ | |||
+ | <fs x-large> | ||
+ | |||
+ | Il faut désormais recourir à des outils également, comme pour les autres: | ||
+ | |||
+ | https:// | ||
+ | |||
+ | How to update translations in words files : | ||
+ | |||
+ | 1. Update original texts in " | ||
+ | 2. Launch 5_make_words_diff script | ||
+ | 3. Open files in " | ||
+ | 4. Replace original text with translation (separators are < | ||
+ | 5. The 2 last lines : REMOVE THE FOLOWING TWO LINE WHEN TRANSLATION IS DONE and DIFF NOT TRANSLATED | ||
+ | 6. Save files | ||
+ | 7. Launch 6_merge_words_diff to merge your translations in " | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | NB : ‘mot’ (N.d.T. ' | ||
+ | </ | ||
+ | |||
+ | Les fichiers de mots sont toujours mis à jour à la main parce qu'ils sont rarement mis à jour par l' | ||
+ | |||
+ | Il y a donc juste un workflow, mais pas d' | ||
+ | |||
+ | === Taches initiales === | ||
+ | |||
+ | **Editeur** | ||
+ | * Créer la feuille initiale pour chaque type de paramètre avec tous les identifiants possibles dans le langae de référence dans le répertoire translated. | ||
+ | * Créer et remplire les colonnes par défaut '' | ||
+ | * Créer les feuilles pour toutes les langues en copiant les feuilles de la langue de référence. | ||
+ | * Créer et remplir toutes les colonnes de bases dépendantes de la langue. | ||
+ | * Envoyer toutes les feuilles au traducteur. | ||
+ | |||
+ | **Traducteur** | ||
+ | * Traduire toutes les feuilles dans toutes les langues, en ajoutant éventuellement toutes les colonnes nécessaires. | ||
+ | * Renvoyer les feuilles traduites à l' | ||
+ | * Garder une copie des feuilles traduites comme référence pour la traduction des phrases et des clauses. | ||
+ | |||
+ | **Editeur** | ||
+ | * Déposer les feuilles traduites dans le répertoire '' | ||
+ | |||
+ | Après cette tache initiale, il y a deux événements possibles : | ||
+ | |||
+ | == Besoin d'une nouvelle colonne == | ||
+ | **Traducteur** | ||
+ | * Au moment de traduire un diff de phrase ou de clause, il apparaît qu'il manque une ou plusieurs nouvelles colonnes pour l'une des langues et un type de paramètre. | ||
+ | * Définir les colonnes nécessaires. | ||
+ | * Contacter l' | ||
+ | * Ajouter les nouvelles colonnes et les remplir dans les feuilles / langues concernées. | ||
+ | * Envoyer les feuilles à l' | ||
+ | |||
+ | **Editeur** | ||
+ | * Déposer les nouvelles feuilles dans le répertoire translated, ce qui écrasera les anciennes. | ||
+ | |||
+ | == Nouveau contenu de feuilles == | ||
+ | **Editeur** | ||
+ | * Le nouveau contenu de jeu est à intégrer dans le jeu. | ||
+ | * Contacter le traducteur pour vérifier qu' | ||
+ | * Créer de nouvelles feuilles pour le langage de référence, | ||
+ | * Ajouter et remplir les colonnes par défaut pour les nouvelles feuilles (voir //Taches initiales// | ||
+ | * Créer les nouvelles feuilles pour toutes les langues en copiant les feuilles de la langue de référence. | ||
+ | * Ajouter toutes les colonnes pour respecter le format de feuille en cours, pour chaque type et chaque langue, mais NE PAS LES REMPLIR. | ||
+ | * Envoyer les nouvelles feuilles au traducteur. | ||
+ | |||
+ | **Traducteur** | ||
+ | * Traduire les nouvelles feuilles. | ||
+ | * Ajouter les nouvelles feuilles à la fin des feuilles existantes. | ||
+ | * Envoyer le résultat de la fusion à l' | ||
+ | * Conserver le résultat de la fusion pour référence pour la traduction des phrases et des clauses, et les futurs ajouts de contenu. | ||
+ | |||
+ | **Editeur** | ||
+ | * Déposer les nouvelles feuilles dans le répertoire '' | ||
+ | |||
+ | ==== Installer les fichiers traduits ==== | ||
+ | A la fin d'un cycle de traduction, il faut installer les fichiers traduits dans les structures d' | ||
+ | |||
+ | Pour cela, on utilise la commande '' | ||
+ | Les fichiers ''< | ||
+ | Tous les autres fichiers sont copiés dans '' | ||
+ | |||
+ | Pour appliquer la traduction sur le client, l' | ||
+ | |||
+ | Pour appliquer la traduction sur le serveur, il faut juste entrer la commande '' | ||
+ | |||
+ | ===== Travailler avec des fichiers de traduction, du point de vue du programmeur ===== | ||
+ | Les programmeurs NeL/Ryzom peuvent utiliser le système de traduction avec un nombre d' | ||
+ | |||
+ | ==== Accéder aux chaînes statiques du client ==== | ||
+ | Pour obtenir la chaîne unicode à partir d'une chaîne d' | ||
+ | |||
+ | Tout d' | ||
+ | |||
+ | Ensuite, il est possible de charger un ensemble de chaînes de langue en appelant '' | ||
+ | |||
+ | Le paramètre '' | ||
+ | Ensuite, appeler la méthode '' | ||
+ | |||
+ | ==== Chaînes dynamiques ==== | ||
+ | Une chaîne dynamique nécessite un peu plus de travail et une infrastructure d' | ||
+ | |||
+ | La gestion des chaînes dynamiques implique un service de requête //(RQS)//, le InputOutputService //(IOS)//, le FrontEnd //(FE)//, le client ryzom, plus les services de bases pour faire tourner les autres (nommage, tick, miroir). | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | RQS est un service qui nécessite d' | ||
+ | |||
+ | RQS envoie également l' | ||
+ | |||
+ | Le proxy est un petit morceau de code qui construit et envoie le message de PHRASE au service IOS. | ||
+ | |||
+ | IOS a la lourde charge de parser (analyser ?) les paramètres, | ||
+ | |||
+ | Le client reçoit la phrase et demande tout élément manquant de la chaîne à l'IOS. | ||
+ | |||
+ | ==== Construire une liste de paramètres en envoyer la chaîne ==== | ||
+ | Pour accéder au proxy, il faut inclure '' | ||
+ | |||
+ | Il faut d' | ||
+ | |||
+ | Il FAUT respecter exactement la définition des paramètres de phrase du fichier de phrases. | ||
+ | |||
+ | On peut alors appeler : | ||
+ | < | ||
+ | NLMISC:: | ||
+ | const std::string & | ||
+ | const std:: | ||
+ | |||
+ | '' | ||
+ | |||
+ | Cette fonction renvoie l'ID dynamique attribué à cette phrase. | ||
+ | |||
+ | Exemple : envoyer la phrase ‘kill a creature’ (cf. § 5.2, étape 4) : | ||
+ | |||
+ | < | ||
+ | #include “game_share/ | ||
+ | |||
+ | uint32 killCreatureMessage( | ||
+ | EntityId destClient, | ||
+ | GSPEOPLE:: | ||
+ | uint32 nbToKill) | ||
+ | { | ||
+ | std:: | ||
+ | STRING_MANAGER:: | ||
+ | |||
+ | // d' | ||
+ | param.Type = STRING_MANAGER:: | ||
+ | param.Enum = race; | ||
+ | params.push_back(param); | ||
+ | |||
+ | // ensuite, le nombre de créatures à tuer | ||
+ | param.Type = STRING_MANAGER:: | ||
+ | param.Int = nbToKill; | ||
+ | params.push_back(param); | ||
+ | |||
+ | // et maintenant, envoyer le message | ||
+ | uint32 dynId = STRING_MANAGER:: | ||
+ | destClient, | ||
+ | “KILL_A_CREATURE”, | ||
+ | params); | ||
+ | |||
+ | return dynId; | ||
+ | }</ | ||
+ | |||
+ | ==== Membre à remplir dans TParam en fonction du type de paramètre ==== | ||
+ | * item: Remplit le SheetId avec l' | ||
+ | * place: Remplit l' | ||
+ | * creature: Remplit EId avec l'id de l' | ||
+ | * skill: Remplit Enum avec la valeur enum de SKILLS:: | ||
+ | * ecosystem: Remplit Enum avec la valeur enum de ECOSYSTEM:: | ||
+ | * race: Remplit Enum avec la valeur enum de GSPEOPLE:: | ||
+ | * brick: Remplit SheetId avec l' | ||
+ | * tribe: pas encore défini | ||
+ | * guild: pas encore défini | ||
+ | * player: Remplit EId avec l' | ||
+ | * bot: Remplit EId avec l' | ||
+ | * integer: Remplit Int avec la valeur integer/ | ||
+ | * time: Remplit Time avec la valeur time/ | ||
+ | * money: Remplit Money avec la valeur money/ | ||
+ | * compass: pas encore défini | ||
+ | * dyn_string_id: | ||
+ | * string_id: Remplit StringId avec un identifiant de chaîne | ||
+ | * creature_model: | ||
+ | * entity: Remplit EId avec l' | ||
+ | * body_part: Remplit Enum avec la valeur enum value de BODY:: | ||
+ | * score: Remplit Enum avec la valeur enum de SCORES:: | ||
+ | * sphrase: Remplit SheetId avec l' | ||
+ | * characteristic: | ||
+ | * damage_type: | ||
+ | * bot_name: Remplit Identifier avec le nom du bot sans la fonction | ||
+ | * literal: Remplit Literal avec la chaîne Unicode littérale | ||
+ | |||
+ | ==== Accéder aux chaînes dynamiques depuis le client ==== | ||
+ | Côté client, accéder aux chaînes dynamiques est assez simple. Il faut juste faire attention au délai de transmission dans certains cas. | ||
+ | |||
+ | Une fois l' | ||
+ | |||
+ | La méthode renvoie faux tant que((N.d.T. : le texte d' | ||
+ | |||
+ | Même si la méthode renvoie faux, elle peut ramener un texte partiel, avec du texte de remplacement manquant. | ||
+ | |||
+ | Les chaînes dynamiques sont stockées dynamiquement, | ||
+ | |||
+ | Pour être plus efficace, on peut appeler chaque cadre(((NDT : each frame ?)) la méthode '' | ||
+ | |||
+ | '' | ||
+ | |||
+ | Voici un exemple de code simple. | ||
+ | |||
+ | < | ||
+ | #include “string_manager_client.h” | ||
+ | |||
+ | using namespace STRING_MANAGER; | ||
+ | |||
+ | /** Une méthode qui reçoit l' | ||
+ | * et qui imprime la chaîne dynamique dans le log. | ||
+ | * L' | ||
+ | */ | ||
+ | bool foo(uint32 dynStringId) | ||
+ | { | ||
+ | ucstring result; | ||
+ | bool ret; | ||
+ | CStringManagerClient *smc = CStringManagerClient:: | ||
+ | |||
+ | ret = smc-> | ||
+ | |||
+ | if (!ret) | ||
+ | nlinfo(“Incomplete string : %s”, result.toString().c_str()); | ||
+ | else | ||
+ | { | ||
+ | nlinfo(“Complete string : %s”, result.toString().c_str()); | ||
+ | // libérer la chaîne dynamique | ||
+ | smc-> | ||
+ | } | ||
+ | |||
+ | return ret; | ||
+ | }</ | ||
+ | |||
+ | ===== Guide de création de texte pour Ryzom ===== | ||
+ | |||
+ | Il y a beaucoup de places pour le texte dans Ryzom, cette page va clarifier les conventions d' | ||
+ | |||
+ | ==== Conventions pour les identifiants ==== | ||
+ | === Identifiants de chaînes dans en.uxt === | ||
+ | |||
+ | Ces identifiants sont écrits en minuscule, avec une majuscule pour chaque nouveau mot. | ||
+ | Exemple: | ||
+ | unIdentifiantSimple | ||
+ | unAutreIdentifiant | ||
+ | |||
+ | === Identifiants de phrases dans phrase_en.txt === | ||
+ | |||
+ | Ces identifiants sont écrits en majuscules, et les mots sont séparés par “underscore”. | ||
+ | |||
+ | Exemple: | ||
+ | UN_IDENTIFIANT_SIMPLE | ||
+ | UN_AUTRE_IDENTIFIANT | ||
+ | |||
+ | === Identifiants de chaînes (ou de clauses) dans clause_en.txt === | ||
+ | |||
+ | Ces identifiants sont écrits comme des identifiants de chaîne dans '' | ||
+ | |||
+ | Mais, comme ils sont à l' | ||
+ | |||
+ | Exemple, dans une phrase appelée '' | ||
+ | unePhraseSimple | ||
+ | |||
+ | De plus, lorsqu' | ||
+ | Exemple, dans une phrase nommée '' | ||
+ | unePhraseSimpleS | ||
+ | unePhraseSimpleP | ||
+ | |||
+ | ==== Contextes des textes ==== | ||
+ | === Contexte “Chat” === | ||
+ | Le contexte “Chat” englobe tous les textes qui viennent d'un PNJ via une fenêtre de chat et des bulles de texte. | ||
+ | |||
+ | == Le bot dit/crie en alentours == | ||
+ | |||
+ | Il n'y a qu'un paramètre disponible : l' | ||
+ | |||
+ | Le nom de la phrase commence par '' | ||
+ | |||
+ | Exemple de phrase : | ||
+ | |||
+ | < | ||
+ | { | ||
+ | sayXxx [Bonjour ici, je m' | ||
+ | }</ | ||
+ | |||
+ | == Le bot parle au chef de l' | ||
+ | |||
+ | Deux paramètres : le bot qui parle, et le joueur. | ||
+ | |||
+ | Le nom de la phrase commence par '' | ||
+ | |||
+ | Exemple de phrase : | ||
+ | < | ||
+ | { | ||
+ | talkXxx [Bonjour $p$, je m' | ||
+ | }</ | ||
+ | |||
+ | == Le bot parle/crie en réponse à un clic sur lui == | ||
+ | |||
+ | Deux paramètres : le bot cliqué et le joueur. | ||
+ | |||
+ | Le nom de la phrase commence par '' | ||
+ | |||
+ | Exemple de phrase | ||
+ | < | ||
+ | { | ||
+ | clickXxx [Bonjour $p$, je m' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | === Contexte interactif (également appelé botchat) === | ||
+ | Le botchat couvre tous les textes dans le dialogue interactif avec un PNJ. | ||
+ | |||
+ | == Phrases liées aux missions == | ||
+ | **Missions statiques** | ||
+ | |||
+ | Tous les noms de phrases liées à des missions ont une racine définie par le nom de la mission telle que positionnée dans le noeud de mision de l' | ||
+ | |||
+ | A partir de cette racine, plusieurs extensions peuvent être ajoutées pour former des noms de phrase : | ||
+ | * _TITLE : pour le titre de la mission | ||
+ | * _STEP_X : pour le texte de l' | ||
+ | * _END : pour le texte de fin de mission. | ||
+ | |||
+ | Exemple: | ||
+ | ^ A partir d'une mission appelée ^ INSTRUCTEUR_MIS_1, | ||
+ | | Le titre sera | INSTRUCTEUR_MIS_1_TITLE | | ||
+ | | Le texte de l' | ||
+ | | Le texte de l' | ||
+ | | Le texte de fin de mission sera | INSTRUCTEUR_MIS_1_END | | ||
+ | |||
+ | Paramètres : | ||
+ | * XXXXXXX_TITLE (bot b, player p) | ||
+ | * b est le bot à qui le joueur parle | ||
+ | * p est le joueur | ||
+ | * XXXXXXX_STEP_X (bot giver, bot current, bot target, bot previous, player p) | ||
+ | * giver est le donneur de la mission | ||
+ | * current est le bot à qui le joueur parle | ||
+ | * target est le bot à aller voir pour la prochaine etape | ||
+ | * previous est le bot vu à l' | ||
+ | * p est le joueur | ||
+ | * XXXXX_END (bot current, bot giver, bot previous, player p) | ||
+ | * giver est le donneur de la mission | ||
+ | * current est le bot à qui le joueur parle | ||
+ | * previous est le bot vu à l' | ||
+ | * p est le joueur | ||
+ | |||
+ | Les paramètres des textes d' | ||
+ | |||
+ | Pour les textes de progression de mission dans le menu contextuel, il en existe deux : | ||
+ | |||
+ | * MISSION_STEP_GIVE_ITEM_CONTEXT (bot giver, bot previous, item i) | ||
+ | * MISSION_STEP_TALK_CONTEXT (bot giver, bot previous) | ||
+ | |||
+ | Le premier est le texte standard, le second est affiché quand on doit donner quelque chose au bot. | ||
+ | |||
+ | == Contexte supplémentaire pour les entrées de menu == | ||
+ | Il est possible d' | ||
+ | |||
+ | Deux paramètres : le bot support du menu de contexte et le joueur. | ||
+ | |||
+ | Le nom de la phrase commence par '' | ||
+ | |||
+ | === Messages système (info de combat) === | ||
+ | Les paramètres dépendent des phrases, mais il y a quelques types de phrases bien définis : | ||
+ | * COMBAT_ | ||
+ | * MAGIC_ | ||
+ | * HARVEST_ | ||
+ | * CRAFT_ | ||
+ | * DEATH_ | ||
+ | * PROGRESS_ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | {{tag> |