LocalizationSystem

Version 1 (kervala, 04/21/2012 11:19 am)

1 1 kervala
h1. Localization system in Ryzom
2 1 kervala
3 1 kervala
Overview 
4 1 kervala
5 1 kervala
There are mainly two distinct parts in localization for Ryzom. The first part (and the easiest) concerns the static localization on the client side (eg interface names, error messages). The second part is for dynamically generated text from servers. 
6 1 kervala
7 1 kervala
8 1 kervala
9 1 kervala
10 1 kervala
11 1 kervala
As you can see in the diagram, there are four kind of file that makes the localization system to work. Each of this file must come in each localized language. In bold, you can see that each file contains the language code in its name. 
12 1 kervala
File formats are discussed below. 
13 1 kervala
Language code 
14 1 kervala
Language in Ryzom are identified by there language code as defined in ISO 639-1 plus a country code defined in ISO 3166 if necessary.
15 1 kervala
16 1 kervala
17 1 kervala
18 1 kervala
ISO 639-1 is a two character language code (e.g. ‘en’, ‘fr’). This is enough for most of the language we want to support. 
19 1 kervala
But there is some exception, like Chinese written language. 
20 1 kervala
Chinese can be written in two forms: traditional or simplified. Nonetheless, there is only one language code for Chinese: ‘hz’. 
21 1 kervala
So, we must append a country code to indicate witch form of written Chinese we discuss. The language code for simplified Chinese become ‘hz-CN’ (i.e. Chinese language, Chinese country), and for traditional Chinese, it is ‘hz’ only because all other Chinese speaking country (Taiwan, Hong Kong, ? ) use the traditional Chinese. 
22 1 kervala
Identifier definition 
23 1 kervala
Translated strings are associated to identifier. Identifiers are textual string that must follow the C identifier constraint with a little difference. 
24 1 kervala
A C identifier must consist only of the following caracteres: ‘A-Z’, ‘a-z’, ‘0-9’, ‘@‘ and ‘_’. Real C identifier can’t start with a number, string identifier can. 
25 1 kervala
26 1 kervala
27 1 kervala
Some good identifier: 
28 1 kervala
29 1 kervala
30 1 kervala
This_is_a_good_identifier 
31 1 kervala
ThisIsAGoodIdentifier 
32 1 kervala
_This@is@notherGoodId 
33 1 kervala
1234_is_a_goodId 
34 1 kervala
This_Is_Good_1234 
35 1 kervala
36 1 kervala
37 1 kervala
Some bad identifier: 
38 1 kervala
39 1 kervala
40 1 kervala
This is a bad identifier 
41 1 kervala
é#()|{[_IdBAD 
42 1 kervala
File formats 
43 1 kervala
There are three different translation file formats. But only two need to be learned ;-) 
44 1 kervala
Format 1 
45 1 kervala
This format is used for client side static text and for server side clause text. 
46 1 kervala
The file is a list of identifiant to string association (also called value string). Identifiant must conform to C identifier constraint and value string is delimited by ‘[‘ and ‘]’. 
47 1 kervala
Text layout is free; you can jump line and indent as you want. 
48 1 kervala
49 1 kervala
50 1 kervala
identifiant1 [textual value] 
51 1 kervala
identifiant2 [other textual value] 
52 1 kervala
53 1 kervala
54 1 kervala
This file can contain C style comments. 
55 1 kervala
56 1 kervala
57 1 kervala
// This is a single line comment. Continue until end of line 
58 1 kervala
identifiant1 [textual value] 
59 1 kervala
/* This is 
60 1 kervala
a multiline 
61 1 kervala
comment */ 
62 1 kervala
identifiant2 /* multiline comment here ! */ [other textual value] 
63 1 kervala
64 1 kervala
65 1 kervala
Textual value can be formated for readability. New line and tab are removed in the final string value. 
66 1 kervala
67 1 kervala
68 1 kervala
identifiant1 [textual 
69 1 kervala
value 
70 1 kervala
with 
71 1 kervala
new line 
72 1 kervala
and tab formating only for readability] 
73 1 kervala
identifiant2 [other textual value] 
74 1 kervala
75 1 kervala
76 1 kervala
If you need to specify new lines or tabulations in the value string, you must use C style escape sequence ‘\t’ for tab and ‘\n’ for new line. To write a ‘\’ in the string value, double the backslash: ‘\\’. To write a ‘]’ int the string, escape it with a backslash: ‘\]’. 
77 1 kervala
78 1 kervala
79 1 kervala
identifiant1 [tabulation: \tThis text is tabbed] 
80 1 kervala
identifiant2 [New line \nText on next line] 
81 1 kervala
identifiant3 [Backslash: \\] 
82 1 kervala
identifiant4 [a closing square bracket: \] ] 
83 1 kervala
84 1 kervala
85 1 kervala
You can split the original file in multiple small file, more easy to maintain and work with. 
86 1 kervala
This feature is achieved by using a C like preprocessor command “#include”. 
87 1 kervala
88 1 kervala
89 1 kervala
#include "path/filename.txt" 
90 1 kervala
91 1 kervala
92 1 kervala
You can have any number of include command. Included files can also contains include commands. 
93 1 kervala
The path can be either an absolute path or a path relative to the location of the master file. 
94 1 kervala
Format 2 
95 1 kervala
This format is used for phrases translation files. 
96 1 kervala
This format is a pretty complex grammar that will be described in a near LALR syntax: 
97 1 kervala
98 1 kervala
99 1 kervala
identifiant : [A-Za-z0-9_@]+ 
100 1 kervala
101 1 kervala
102 1 kervala
phrase : identifiant ‘(‘ parameterList ‘)’ 
103 1 kervala
‘{‘ 
104 1 kervala
clauseList 
105 1 kervala
‘}’ 
106 1 kervala
107 1 kervala
108 1 kervala
parameterList : parameterList ‘,’ parameterDesc 
109 1 kervala
| parameterDesc 
110 1 kervala
111 1 kervala
112 1 kervala
parameterDesc : parameterType parameterName 
113 1 kervala
114 1 kervala
115 1 kervala
parameterName : identifiant 
116 1 kervala
117 1 kervala
118 1 kervala
parameterType : ‘item’ 
119 1 kervala
| ‘place’ 
120 1 kervala
| ‘creature’ 
121 1 kervala
| ‘skill’ 
122 1 kervala
| ‘role’ 
123 1 kervala
| ‘ecosystem’ 
124 1 kervala
| ‘race’ 
125 1 kervala
| ‘brick’ 
126 1 kervala
| ‘tribe’ 
127 1 kervala
| ‘guild’ 
128 1 kervala
| ‘player’ 
129 1 kervala
| ‘int’ 
130 1 kervala
| ‘bot’ 
131 1 kervala
| ‘time’ 
132 1 kervala
| ‘money’ 
133 1 kervala
| ‘compass’ 
134 1 kervala
| ‘dyn_string_id’ 
135 1 kervala
| ‘string_id’ 
136 1 kervala
| ‘self’ 
137 1 kervala
| ‘creature_model’ 
138 1 kervala
| ‘entity’ 
139 1 kervala
| ‘bot_name’ 
140 1 kervala
| ‘bodypart’ 
141 1 kervala
| ‘score’ 
142 1 kervala
| ‘sphrase’ 
143 1 kervala
| ‘characteristic’ 
144 1 kervala
| ‘damage_type’ 
145 1 kervala
| ‘literal’ 
146 1 kervala
147 1 kervala
148 1 kervala
clauseList : clauseList clause 
149 1 kervala
| clause 
150 1 kervala
151 1 kervala
152 1 kervala
clause : conditionList identifiant textValue 
153 1 kervala
| identifiant textValue 
154 1 kervala
| conditionList identifiant 
155 1 kervala
| identifiant 
156 1 kervala
| textValue 
157 1 kervala
158 1 kervala
159 1 kervala
conditionList : conditionList condition 
160 1 kervala
| condition 
161 1 kervala
162 1 kervala
163 1 kervala
condition : ‘(‘ testList ‘)’ 
164 1 kervala
165 1 kervala
166 1 kervala
testList : testList ‘&’ test 
167 1 kervala
| test 
168 1 kervala
169 1 kervala
170 1 kervala
test : operand1 operator reference 
171 1 kervala
172 1 kervala
173 1 kervala
operand1 : parameterName 
174 1 kervala
| parameterName’.’propertyName 
175 1 kervala
176 1 kervala
177 1 kervala
propertyName : identifiant 
178 1 kervala
179 1 kervala
180 1 kervala
operator : ‘=’ 
181 1 kervala
| ‘!=’ 
182 1 kervala
| ‘«’ 
183 1 kervala
| ‘«=’ 
184 1 kervala
| ‘»’ 
185 1 kervala
| ‘«=’ 
186 1 kervala
187 1 kervala
188 1 kervala
reference : identifiant 
189 1 kervala
190 1 kervala
191 1 kervala
textValue : ‘[‘ .* ‘]’ 
192 1 kervala
193 1 kervala
194 1 kervala
195 1 kervala
As in format 1, you can include C style comment in the text and indent freely and use the include command. 
196 1 kervala
Format 3: Spreadsheet unicode export 
197 1 kervala
198 1 kervala
This format is the result of a Unicode text export from Spreadsheet. 
199 1 kervala
Encoding should be unicode 16 bits. Columns are tab separated and rows are new line separated. 
200 1 kervala
You should not write this file by hand, but only edit it with Spreadsheet. 
201 1 kervala
The first row must contain the columns names. 
202 1 kervala
203 1 kervala
204 1 kervala
Info columns 
205 1 kervala
If a column name start with a ‘*’, then all the column is ignored. 
206 1 kervala
This is useful to add information column that can help translation. 
207 1 kervala
208 1 kervala
209 1 kervala
Delete character 
210 1 kervala
It is possible to insert a ‘delete’ command in the field: ‘\d’. This is useful for article translation. 
211 1 kervala
Example: you have a string with the following replacement (in French): 
212 1 kervala
213 1 kervala
214 1 kervala
    "Rapporte moi $item.da$ $item.name$" 
215 1 kervala
216 1 kervala
217 1 kervala
And the item words file contains the following: 
218 1 kervala
219 1 kervala
220 1 kervala
    item name da 
221 1 kervala
    marteau marteau le 
222 1 kervala
    echelle échelle l’ 
223 1 kervala
224 1 kervala
225 1 kervala
If the item is ‘marteau’, no problem, the replacement gives: 
226 1 kervala
227 1 kervala
228 1 kervala
    "Rapporte moi le marteau" 
229 1 kervala
230 1 kervala
231 1 kervala
But for the ‘echelle’, there is a supplementary space in the result: 
232 1 kervala
233 1 kervala
234 1 kervala
    "Rapporte moi l’ échelle" 
235 1 kervala
236 1 kervala
To remove this supplementary space, you can add a ‘delete’ marker in the article definition: 
237 1 kervala
238 1 kervala
239 1 kervala
    item name da 
240 1 kervala
    marteau marteau le 
241 1 kervala
    echelle échelle l’\d 
242 1 kervala
243 1 kervala
244 1 kervala
This will give a correct resulting string: 
245 1 kervala
246 1 kervala
247 1 kervala
    "Rapporte moi l’échelle" 
248 1 kervala
249 1 kervala
Working with translation files, translator point of view 
250 1 kervala
Client side “*.uxt” files 
251 1 kervala
This file contains all static text available directly to the client. The text must conforms to format 1 described above. 
252 1 kervala
There is an additional constraint: you MUST provide as a first entry the language name, as spelled in the language (eg ‘English’ for English, ‘Français’ for French). 
253 1 kervala
For example, the file en.uxt must begin with: 
254 1 kervala
255 1 kervala
256 1 kervala
languageName [English] 
257 1 kervala
Server side files 
258 1 kervala
Server side translation is a bit more complex. 
259 1 kervala
We will learn how to write server side translation in four steps (guess what: from simple to complex problem!). 
260 1 kervala
261 1 kervala
262 1 kervala
Step 1: A simple string: 
263 1 kervala
For this, you only need the phrase file. 
264 1 kervala
Let’s say we want a string saying “hello world!” identified by HelloWorld. 
265 1 kervala
Create a phrase entry in phrase_en.txt: 
266 1 kervala
267 1 kervala
268 1 kervala
HelloWorld () 
269 1 kervala
{ 
270 1 kervala
[Hello world!] 
271 1 kervala
} 
272 1 kervala
273 1 kervala
274 1 kervala
That’s it! No more. 
275 1 kervala
Of course, you must also provide the same phrase in all the supported language, for example, in phrase_fr.txt: 
276 1 kervala
277 1 kervala
278 1 kervala
HelloWorld () 
279 1 kervala
{ 
280 1 kervala
[Bonjour le monde!] 
281 1 kervala
} 
282 1 kervala
283 1 kervala
284 1 kervala
Note that only the text value has changed. The phrase identifier MUST remain the same in all the translations files. 
285 1 kervala
286 1 kervala
287 1 kervala
Step 2: Indirection to clause_«lang».txt 
288 1 kervala
In step 4, we will see that the phrase file will become very complex. Thus, this file is not well fitted for giving it to a professional translator with no skill in complex grammar file. More, the complexity of the file can hide the work to do for translation. 
289 1 kervala
So, you can split phrase grammar in phrase file and text value in clause file. 
290 1 kervala
291 1 kervala
292 1 kervala
To do this, you must assign a unique identifier to each text value. 
293 1 kervala
Let’s rebuild the previous example with indirection. 
294 1 kervala
In phrase_en.txt, create the phrase entry like this: 
295 1 kervala
296 1 kervala
297 1 kervala
HelloWorld () 
298 1 kervala
{ 
299 1 kervala
Hello 
300 1 kervala
} 
301 1 kervala
302 1 kervala
303 1 kervala
We just have put an identifier in the phrase block. This means that the phrase refers to a string identified as “Hello” in the clause file. 
304 1 kervala
Now, we can create the text value in clause_en.txt: 
305 1 kervala
306 1 kervala
307 1 kervala
Hello [Hello world!] 
308 1 kervala
309 1 kervala
310 1 kervala
As in the first step, you must do this task for each language. 
311 1 kervala
312 1 kervala
313 1 kervala
TIPS: in order to facilitate translation work, it is possible to specify the string identifier AND the string value. This can be helpful for automatic building of translation file from the original one. 
314 1 kervala
Example: 
315 1 kervala
316 1 kervala
317 1 kervala
HelloWorld () 
318 1 kervala
{ 
319 1 kervala
Hello [Bonjour le monde!] 
320 1 kervala
} 
321 1 kervala
322 1 kervala
323 1 kervala
In such case, the translation system always look first in the clause file and fallback to string value in the phrase file only if the string is not found in the clause file. 
324 1 kervala
The other advantage is that the person who wrote the phrase file can give a simplistic version of the string that a professional translator will improve. 
325 1 kervala
326 1 kervala
327 1 kervala
Step 3: Using parameters - basics 
328 1 kervala
Here we are entering in the complex stuff! 
329 1 kervala
Each phrase can receive a list of parameter. 
330 1 kervala
Those parameters can be of different types: 
331 1 kervala
* item, 
332 1 kervala
* place, 
333 1 kervala
* creature, 
334 1 kervala
* skill, 
335 1 kervala
* ecosystem, 
336 1 kervala
* race, 
337 1 kervala
* brick, 
338 1 kervala
* tribe, 
339 1 kervala
* guild, 
340 1 kervala
* player, 
341 1 kervala
* int, 
342 1 kervala
* bot, 
343 1 kervala
* time, 
344 1 kervala
* money, 
345 1 kervala
* compass, 
346 1 kervala
* dyn_string_id, 
347 1 kervala
* string_id, 
348 1 kervala
* creature_model, 
349 1 kervala
* entity, 
350 1 kervala
* body_part, 
351 1 kervala
* score, 
352 1 kervala
* sphrase, 
353 1 kervala
* characteristic, 
354 1 kervala
* damage_type, 
355 1 kervala
* bot_name, 
356 1 kervala
* literal. 
357 1 kervala
358 1 kervala
359 1 kervala
Each parameter is given a name (or identifier) when declared. We will call it paramName. 
360 1 kervala
361 1 kervala
362 1 kervala
Each type of parameter CAN be associated with a ‘word’ file. This file is an excel sheet (in unicode text export form) that contain translations for the parameter: its name, undefined or defined article (e.g. ‘a’, ‘the’, etc), plural name and article and any useful property or grammar element needed for translation. 
363 1 kervala
The first column is very important because it associate a row of data with a particular parameter value. 
364 1 kervala
365 1 kervala
366 1 kervala
Let’s begin with an example: we want to build a dynamic phrase with a variable creature race name. 
367 1 kervala
First, we must build an excel sheet to define the words for creature type. This will be saved as race_words_«lang».txt in unicode text export from excel. As always, you must provide a version of this file for each language. 
368 1 kervala
NB: The first column MUST always be the association field and you should have a ‘name’ column as it’s the default replacement for parameter. Any other column is optional and can vary from language to language to accommodate any specific grammar constraint. 
369 1 kervala
This is an example race_words_en.txt: 
370 1 kervala
371 1 kervala
372 1 kervala
race name ia da p pia pda 
373 1 kervala
kitifly Kitifly a the Kitiflys the 
374 1 kervala
varynx Varynx a the Varynx the 
375 1 kervala
etc… 
376 1 kervala
377 1 kervala
378 1 kervala
As stated in the note above, the first column give the race identifier as defined in the game dev sheets. The second column is the ‘highly advisable’ column for the name of the race. The ‘p’ column if the plural name. ‘ia’, ‘da’ stand for indefined article and defined article. 
379 1 kervala
380 1 kervala
381 1 kervala
Next, we must create a phrase with a creature parameter in phrase_«lang».txt: 
382 1 kervala
383 1 kervala
384 1 kervala
KILL_A_CREATURE (race crea) 
385 1 kervala
{} 
386 1 kervala
387 1 kervala
388 1 kervala
As you can see, after the phrase identifier KILL_THIS_CREATURE we have the parameter list between the braket. We declare a parameter of type race named crea. Note that you choose freely your parameter name but each parameter must have a unique name (at least for one phrase). 
389 1 kervala
390 1 kervala
391 1 kervala
Now, we can build the string value. To insert parameter into the string, we must specify replacement point by using the ‘$’ sign (eg $crea$) directly into the string value: 
392 1 kervala
393 1 kervala
394 1 kervala
KILL_A_CREATURE (race crea) 
395 1 kervala
{ 
396 1 kervala
[Would you please kill a $crea$ for me ?] 
397 1 kervala
} 
398 1 kervala
399 1 kervala
400 1 kervala
As you can see, it’s not too complex. $crea$ will be replaced with the content of the field from the words file in the ‘name’ column and at the row corresponding to the race identifier. 
401 1 kervala
402 1 kervala
403 1 kervala
▪ It is possible to recall any of the words file columns in the value string. We can for example dynamize the undefined article: 
404 1 kervala
405 1 kervala
406 1 kervala
KILL_A_CREATURE (race crea) 
407 1 kervala
{ 
408 1 kervala
[Would you please kill $crea.ia$ $crea$ for me ?] 
409 1 kervala
} 
410 1 kervala
411 1 kervala
412 1 kervala
▪ Some parameter type have special replacement rules: int are replaced with their text representation, time are converted to ryzom time readable format, as well as money. 
413 1 kervala
414 1 kervala
415 1 kervala
Last but not least, the identifier and indirection rules see in step 1 and 2 are still valid. 
416 1 kervala
417 1 kervala
418 1 kervala
Step 4: Using parameters: conditional clause 
419 1 kervala
It’s time now to unveil the conditional clause system. 
420 1 kervala
421 1 kervala
422 1 kervala
Let’s say that the identifier and string value we put in a phrase in the previous step is a clause. And let’s say that a phrase can contains more than one clause that can be chosen by the translation engine on the fly depending on the parameter value. This is the conditional clause system. 
423 1 kervala
424 1 kervala
425 1 kervala
Let’s start a first example. As in step 3, we want to kill creature, but this time, we add a variable number of creature to kill, from 0 to n. 
426 1 kervala
What we need is conditions to select between three clause: no creature to kill, one creature to kill and more than one. 
427 1 kervala
428 1 kervala
429 1 kervala
First, let’s write the phrase, its parameters and the three clauses: 
430 1 kervala
431 1 kervala
432 1 kervala
KILL_A_CREATURE (race crea, int count) 
433 1 kervala
{ 
434 1 kervala
// no creature to kill
435 1 kervala
436 1 kervala
[There is no creature to kill today.]
437 1 kervala
438 1 kervala
// 1 creature to kill 
439 1 kervala
    [Would you please kill a $crea$ for me ?] 
440 1 kervala
// more than one 
441 1 kervala
[Would you please kill $count$ $crea$ for me ?] 
442 1 kervala
} 
443 1 kervala
444 1 kervala
445 1 kervala
We have written down three version of the text with very different meaning and gramatical structure. 
446 1 kervala
Now, add the conditions. Conditions are placed before the identifier and/or string value and are marked with bracket. 
447 1 kervala
448 1 kervala
449 1 kervala
KILL_A_CREATURE (race crea, int count) 
450 1 kervala
{ 
451 1 kervala
// no creature to kill 
452 1 kervala
(count = 0) [There is no creature to kill today.] 
453 1 kervala
// 1 creature to kill 
454 1 kervala
(count = 1) [Would you please kill a $crea$ for me ?] 
455 1 kervala
// more than one 
456 1 kervala
(count » 1) [Would you please kill $count$ $crea$ for me ?] 
457 1 kervala
} 
458 1 kervala
459 1 kervala
460 1 kervala
Easy! no? 
461 1 kervala
462 1 kervala
463 1 kervala
Now, a more complex case: we want the phrase to speak differently to male or female player. This is the occasion to introduce the self parameter. Self parameter if a ‘hidden’ parameter that is always available and that represent the addressee of the phrase. 
464 1 kervala
Self parameter support name and gender property. You can provide a self_words_«lang».txt file to handle special case (admin player with a translatable name for example). 
465 1 kervala
Let’s rewrite the killing creature request with player gender aware style: 
466 1 kervala
467 1 kervala
468 1 kervala
KILL_A_CREATURE (race crea, int count) 
469 1 kervala
{ 
470 1 kervala
// -- Male player 
471 1 kervala
// no creature to kill, male player 
472 1 kervala
(count = 0 & self.gender = Male) 
473 1 kervala
[Hi man, there is no creature to kill today .] 
474 1 kervala
// 1 creature to kill, male player 
475 1 kervala
(count = 1 & self.gender = Male) 
476 1 kervala
[Hi man, would you please kill a $crea$ for me ?] 
477 1 kervala
// more than one, male player 
478 1 kervala
(count » 1 & self.gender = Male) 
479 1 kervala
[Hi man, Would you please kill $count$ $crea$ for me ?] 
480 1 kervala
481 1 kervala
482 1 kervala
// -- Female player 
483 1 kervala
// no creature to kill, male player 
484 1 kervala
(count = 0 & self.gender = Female) 
485 1 kervala
[Hi girl, There is no creature to kill today.] 
486 1 kervala
// 1 creature to kill, male player 
487 1 kervala
(count = 1 & self.gender = Female) 
488 1 kervala
[Hi girl, Would you please kill a $crea$ for me ?] 
489 1 kervala
// more than one, male player 
490 1 kervala
(count » 1 & self.gender = Female) 
491 1 kervala
[Hi girl, Would you please kill $count$ $crea$ for me ?] 
492 1 kervala
} 
493 1 kervala
494 1 kervala
495 1 kervala
We have six clauses now. Three case on number of creature multiplied by two cases on the gender of the player. 
496 1 kervala
As you can see, conditional test can be combined with a ‘&’ character. This means that all the tests must be valid to select the clause. 
497 1 kervala
498 1 kervala
499 1 kervala
You can use any parameter as left operand for the test. You can also specify a parameter property (coming from words file) as operand. 
500 1 kervala
On the other hand, right test operand must be constant value (either textual or numerical value). 
501 1 kervala
Available operators are =, !=, «, «=, », »=. 
502 1 kervala
503 1 kervala
504 1 kervala
In some case, you could need to make OR’ed test combination. This is possible by simply specifiying multiple condition list before a clause: 
505 1 kervala
506 1 kervala
507 1 kervala
FOO_PHRASE (int c1, int c2) 
508 1 kervala
{ 
509 1 kervala
(c1 = 0 & c2 = 10) 
510 1 kervala
(c1 = 10 & c2 = 0) 
511 1 kervala
[This clause is selected if : 
512 1 kervala
c1 equal zero and c2 equal ten 
513 1 kervala
or 
514 1 kervala
c1 equal ten and c2 equal zero] 
515 1 kervala
} 
516 1 kervala
517 1 kervala
518 1 kervala
▪ Detailed clause selection rules: 
519 1 kervala
* A valid clause is a clause where the conditional combination are true with a given set of parameter value. 
520 1 kervala
* Clauses are evaluated in the same order as they are written in the phrase file. The first valid clause will be selected. 
521 1 kervala
* If the first clause doesn’t have condition, it is used as a fallback clause when none of the conditional clauses are selected. 
522 1 kervala
* If there is no fallback clause and none of the clauses are selected, then the first clause is selected. 
523 1 kervala
* For the same phrase, each language can provide its own set of condition and clause to accommodate its gammatical needs. 
524 1 kervala
Harcoded parameters properties reference 
525 1 kervala
Here you file find an exhaustive list of harcoded parameters properties. 
526 1 kervala
These properties are always available even if no words files are provided. 
527 1 kervala
Futhermore, the harcoded property can’t be substituted by a word file specifying a column of the same name. 
528 1 kervala
529 1 kervala
530 1 kervala
Parameter 
531 1 kervala
	Property 
532 1 kervala
	Item 
533 1 kervala
	
534 1 kervala
535 1 kervala
	Place 
536 1 kervala
	
537 1 kervala
538 1 kervala
	Creature 
539 1 kervala
	name : model name of the creature 
540 1 kervala
gender : gender of the creature from the model 
541 1 kervala
	Skill 
542 1 kervala
	
543 1 kervala
544 1 kervala
	Ecosystem 
545 1 kervala
	
546 1 kervala
547 1 kervala
	Race 
548 1 kervala
	
549 1 kervala
550 1 kervala
	Brick 
551 1 kervala
	
552 1 kervala
553 1 kervala
	Tribe 
554 1 kervala
	
555 1 kervala
556 1 kervala
	Guild 
557 1 kervala
	
558 1 kervala
559 1 kervala
	Player 
560 1 kervala
	name : name of the player 
561 1 kervala
gender : gender of the player in the mirror 
562 1 kervala
	Bot 
563 1 kervala
	career : the career of the bot 
564 1 kervala
role : the role of the bot as defined in creature.basics.chatProfile 
565 1 kervala
name : name of the creature 
566 1 kervala
gender : gender of the creature from the model 
567 1 kervala
	Integer 
568 1 kervala
	
569 1 kervala
570 1 kervala
	Time 
571 1 kervala
	
572 1 kervala
573 1 kervala
	Money 
574 1 kervala
	
575 1 kervala
576 1 kervala
	Compass 
577 1 kervala
	
578 1 kervala
579 1 kervala
	dyn_string_id 
580 1 kervala
	Only != and == test available. Mainly to compare parameter with 0. 
581 1 kervala
	string_id 
582 1 kervala
	Only != and == test available. Mainly to compare parameter with 0 
583 1 kervala
	self 
584 1 kervala
	name : name of the player 
585 1 kervala
gender : gender of the player in the mirror 
586 1 kervala
	creature_model 
587 1 kervala
	NB : use the creature_words translation file ! 
588 1 kervala
	entity 
589 1 kervala
	== 0, != 0: test if the entity is Unknown or not. 
590 1 kervala
name : name of the creature or name of the player. 
591 1 kervala
gender : gender of the creature from the model or gender of the player (from the player info). 
592 1 kervala
	bodypart 
593 1 kervala
	
594 1 kervala
595 1 kervala
	score 
596 1 kervala
	
597 1 kervala
598 1 kervala
	sphrase 
599 1 kervala
	
600 1 kervala
601 1 kervala
	characteristic 
602 1 kervala
	
603 1 kervala
604 1 kervala
	damage_type 
605 1 kervala
	
606 1 kervala
607 1 kervala
	bot_name 
608 1 kervala
	
609 1 kervala
610 1 kervala
	Translation workflow 
611 1 kervala
In the following translation workflow, we consider that the reference language is English. 
612 1 kervala
613 1 kervala
614 1 kervala
There is a series of tools and bat file to help in getting translation in sync. Here is a step by step description of how to work on translation file, what tool to use and when. 
615 1 kervala
616 1 kervala
617 1 kervala
Only addition to existing translation file is supported by the translation tools. If you need to modify or remove existing translation string or phrase structure, this must be done ‘by hand’ with a maximum of attention to all the languages versions. 
618 1 kervala
In most case, it is better to create a new translation entry instead of dealing with a modification in all the translations files and it’s almost safe to leave old unused string in the files. 
619 1 kervala
At least, you should NEVER make modification when there are pendings diff file. 
620 1 kervala
621 1 kervala
622 1 kervala
It is highly advisable to strictly respect the described workflow in order to avoid translation problems, missing strings and other weird problems that can arise from working with many language version of a set of file. 
623 1 kervala
624 1 kervala
625 1 kervala
Translation work is done in cooperation between the publisher who is doing the ‘technical’ part of the task and a profesionnal translator contractor who only translate simple string into a very high quality and rich string with respect to the context. 
626 1 kervala
627 1 kervala
628 1 kervala
The tools that generate diff file for translation keep the comments from the reference version. This can be helpful to give additionnal information to the translator about the context of the text. 
629 1 kervala
Moreover, for phrase files, the diff file automaticaly include comments that describe the parameter list. 
630 1 kervala
Translation repository structure 
631 1 kervala
All files to translate are stored in a well defined directory structure called ‘the translation repository’. All translation work is done in this repository. 
632 1 kervala
Tools are provided to install the translated file in the client and server repository after a translation cycle is done. 
633 1 kervala
634 1 kervala
635 1 kervala
translation/ Root directory for translation repository
636 1 kervala
637 1 kervala
638 1 kervala
639 1 kervala
languages.txt A simple text file that contains all the language code (ISO 639-2) that we are working on (eg : en, fr, etc…). 
640 1 kervala
641 1 kervala
642 1 kervala
work/ This is the starting point for addition of new content. This directory contains any files that can be edited for addition. 
643 1 kervala
644 1 kervala
645 1 kervala
diff/ Contains all diff files generated by tools. This is where most of the work is done. After the merge operation is applied to integrate translated diff into translated file, the diff file are moved to the history directory. 
646 1 kervala
When diff files are generated, they are prefixed with a version number automaticaly computed from the current Unix time. This permits to generate new diff file without waiting for diff translation to be done. More, when you generate new diff file with existing none merged diff, new diff only contains the new difference (is it clear or what?  ). 
647 1 kervala
648 1 kervala
649 1 kervala
history/ Contains all the diff files that have been translated and merged. This is for backup and security reason. 
650 1 kervala
651 1 kervala
652 1 kervala
translated/ Contains all translated file. The content of this directory is installed into client and server repository when translation cycle is done. You should never change anything by hand in this directory unless you now exactly what you are doing. 
653 1 kervala
Client side static string 
654 1 kervala
655 1 kervala
656 1 kervala
Initial task: 
657 1 kervala
Publisher 
658 1 kervala
* Creates the reference file en.uxt in the work directory, fill in the required first string ‘LanguageName’ then add any number of string for the English version. 
659 1 kervala
* Generates static string diff files with the command make_string_diff.bat. This will create diff files for each language in the diff directory. 
660 1 kervala
* Send the diff files to the Translator. 
661 1 kervala
Translator 
662 1 kervala
* Translate the diff files. 
663 1 kervala
* Send them back to the Publisher. 
664 1 kervala
Publisher 
665 1 kervala
* Put the translated diff files in the diff directory (this will overwrite non translated diff files with translated one). 
666 1 kervala
* Merge the translated diff files with the command merge_string_diff.bat. This will create the «lang».uxt files for each language in the translated directory and move the diff in the history directory. 
667 1 kervala
668 1 kervala
669 1 kervala
After the initial task is done, the workflow enters the in incremental mode. 
670 1 kervala
671 1 kervala
672 1 kervala
Incremental task: 
673 1 kervala
Publisher 
674 1 kervala
* Add string in the reference file en.uxt in the addtion directory. 
675 1 kervala
* Generates static string diff files with the command make_string_diff.bat. This will create diff files for each language in the diff directory. 
676 1 kervala
* Send the diff files to the Translator. 
677 1 kervala
Translator 
678 1 kervala
* Translate the diff files. 
679 1 kervala
* Send them back to the Publisher. 
680 1 kervala
Publisher 
681 1 kervala
* Put the translated diff files in the diff directory (this will overwrite non translated diff files with translated one). 
682 1 kervala
* Merge the translated diff files with the command merge_string_diff.bat. This will apply the diff files to the «lang».uxt files for each language in the translated directory and move the diff in the history directory. 
683 1 kervala
Server side dynamic string 
684 1 kervala
Initial task: 
685 1 kervala
Publisher 
686 1 kervala
* Creates the reference file phrase_en.uxt in the addition directory and add any number of phrase entries for the English version. 
687 1 kervala
* Generates phrase diff files with the command make_phrase_diff.bat. This will create diff files for each language in the diff directory. 
688 1 kervala
* Translate the phrase diff file. This implie good knowledge of gramatical structure of each language to accommodate clause selection rules. 
689 1 kervala
* Merge the translated diff with the command merge_phrase_diff.bat. This will create all the phrase_«lang».txt in the translated directory from the translated diff then move diff files to history directory. 
690 1 kervala
* Generates clauses diff file with the command make_clause_diff.bat. This create clause diff file in the diff directory for all language. 
691 1 kervala
* Send the clause diff files to the Translator 
692 1 kervala
Translator 
693 1 kervala
* Translate the clause diff files. 
694 1 kervala
* Send them back to the Publisher. 
695 1 kervala
Publisher 
696 1 kervala
* Put the translated clause diff files in the diff directory (this will overwrite non translated clause diff files with translated one). 
697 1 kervala
* Merge the translated clause diff files with the command merge_clause_diff.bat. This will create the clause_«lang».txt files for each language in the translated directory and move the diff in the history directory. 
698 1 kervala
699 1 kervala
700 1 kervala
After the initial task is done, the workflow enters the in incremental mode. 
701 1 kervala
702 1 kervala
703 1 kervala
Incremental task: 
704 1 kervala
Publisher 
705 1 kervala
* Add new phrase in phrase_en.uxt in the addition directory. 
706 1 kervala
* Generates phrase diff files with the command make_phrase_diff.bat. This will create diff files for each language in the diff directory. 
707 1 kervala
* Translate the phrase diff file. This implie good knowledge of gramatical structure of each language to accommodate clause selection rules. 
708 1 kervala
* Merge the translated diff with the command merge_phrase_diff.bat. This will append the diff to there repective phrase_«lang».txt file in the translated directory then move diff files to history directory. 
709 1 kervala
* Generates clauses diff file with the command make_clause_diff.bat. This create clause diff file in the diff directory. 
710 1 kervala
* Send the clause diff files to the Translator 
711 1 kervala
Translator 
712 1 kervala
* Translate the clause diff files. 
713 1 kervala
* Send them back to the Publisher. 
714 1 kervala
Publisher 
715 1 kervala
* Put the translated clause diff files in the diff directory (this will overwrite non translated clause diff files with translated one). 
716 1 kervala
* Merge the translated clause diff files with the comment merge_clause_diff.bat. This will append the diff file to there repective clause_«lang».txt files for each language in the translated directory and move the diff in the history directory. 
717 1 kervala
Server side words files 
718 1 kervala
NB: ‘words’ has nothing to do with the microsoft program Word! 
719 1 kervala
720 1 kervala
721 1 kervala
Words files are always updated by hands because they are rarely updated by the publisher (and generaly, this will be for big update). Moreover, when new phrase are translated, it can be necessary to create and fill new column in one of the words file to accommodate the translation. 
722 1 kervala
723 1 kervala
724 1 kervala
So, there is only a workflow but no tools. 
725 1 kervala
726 1 kervala
727 1 kervala
Initial task: 
728 1 kervala
Publisher 
729 1 kervala
* Build the initial sheet for each type of parameter with all the possible identifier in the reference language in the translated directory. 
730 1 kervala
* Create and fill the default ‘name’ and ‘p’ columns. 
731 1 kervala
* Create the sheets for all languages by copying the reference language sheets. 
732 1 kervala
* Create and fill any basic column depending on languages. 
733 1 kervala
* Sends all the sheets to the Translator. 
734 1 kervala
Translator 
735 1 kervala
* Translate all the sheets in all language, eventualy, create any needed columns. 
736 1 kervala
* Send back the translated sheets to the Publisher. 
737 1 kervala
* Keep a copy of the translated sheets as reference for phrase and clause translation. 
738 1 kervala
Publisher 
739 1 kervala
* Put the translated sheets in the translated directory, overwriting old ones. 
740 1 kervala
741 1 kervala
742 1 kervala
After this initial task, there is two possible events: 
743 1 kervala
744 1 kervala
745 1 kervala
New column(s) needed: 
746 1 kervala
Translator 
747 1 kervala
* While translating phrase or clause diff, it comes that one or more new columns are needed for some language and parameter type. 
748 1 kervala
* Define the needed columns 
749 1 kervala
* Contact Publisher to check that no sheets updates are pending. If yes, first apply the ‘new sheets content’ workflow. 
750 1 kervala
* Add and fill the new columns into the concerned sheets/langs. 
751 1 kervala
* Send the sheets to the Publisher. 
752 1 kervala
Publisher 
753 1 kervala
* Put the new sheets in the translated directory, overwriting old ones. 
754 1 kervala
755 1 kervala
New sheets content: 
756 1 kervala
Publisher: 
757 1 kervala
* New game content is to be integrated in the game. 
758 1 kervala
* Contact Translator to check that no sheets updates are pending. If yes, first apply the ‘new column(s) needed’ workflow. 
759 1 kervala
* Create new sheets for the reference language and containing only the new content. 
760 1 kervala
* Add and fill the default columns in the new sheets (see ‘Initial task’). 
761 1 kervala
* Create new sheets for all the languages by copying the reference languages sheets. 
762 1 kervala
* Add but DON’T FILL all the columns to repect the current sheet format for each type, each language. 
763 1 kervala
* Send the new sheets to the Translator. 
764 1 kervala
Translator: 
765 1 kervala
* Translate the new sheets. 
766 1 kervala
* Append the new sheets at the end of the existing sheets. 
767 1 kervala
* Send the merge result to the Pushisher. 
768 1 kervala
* Keep the merge result as reference for phrase and clause translation and futur content addition. 
769 1 kervala
Publisher: 
770 1 kervala
* Put the new sheets in the translated directory, overwriting old ones. 
771 1 kervala
772 1 kervala
Installing the translated files 
773 1 kervala
After a cycle of translation is terminated, you must install the translated files into the client and servers directory strucure. 
774 1 kervala
775 1 kervala
776 1 kervala
This is done via the command intall_translation.bat. 
777 1 kervala
The «lang».uxt file are copied into the client strucure in Ryzom/gamedev/language. 
778 1 kervala
All the other files are copied in Ryzom/data_shard. 
779 1 kervala
780 1 kervala
781 1 kervala
To apply client side translation, Publisher needs to make a patch. 
782 1 kervala
To apply server side translation, just enter the command ‘reload’ on the InputOutputService. 
783 1 kervala
Working with translation files: programmer view 
784 1 kervala
As a NeL/Ryzom programmer, you can use the translation system with a very few calls. 
785 1 kervala
Accessing client static strings 
786 1 kervala
To obtain a unicode string from a string identifier, you use the NLMISC::CI18N class. 
787 1 kervala
788 1 kervala
789 1 kervala
First of all, you must ensure that the translation file *.uxt are available in the search path. 
790 1 kervala
Then, you can load a language string set by calling NLMISC::CI18N::load(languageCode). 
791 1 kervala
The parameter languageCode is the language code as defined in chapter 2 “Language code”. 
792 1 kervala
After that, call the method NLMISC::CI18N::get(identifier) to obtain the unicode string associated to identifier. 
793 1 kervala
Dynamic strings 
794 1 kervala
Dynamic string requires a bit more work and a complete shard infrastructure. 
795 1 kervala
796 1 kervala
797 1 kervala
Dynamic string management involves a requesting service (RQS), the InputOutputService (IOS), the FrontEnd (FE), the ryzom client plus the basic services to run the other (naming, tick, mirror). 
798 1 kervala
799 1 kervala
800 1 kervala
801 1 kervala
802 1 kervala
803 1 kervala
RQS is a service that wants to send a dynamic string to the client. 
804 1 kervala
RQS also send the dynamic string identifier to the client by using the database or any other way. 
805 1 kervala
The proxy is a small piece of code that builds and sends the PHRASE message to IOS service. 
806 1 kervala
IOS make the big task of parsing parameter, selecting the good clause and building the resulting string then sending a minimum amount of data to the client. 
807 1 kervala
The client receives the phrase and requests any missing string element to the IOS. 
808 1 kervala
809 1 kervala
Building parameter list and sending the string 
810 1 kervala
To access the proxy function, you need to include game_share/string_manager_sender.h and link with game_share.lib. 
811 1 kervala
812 1 kervala
813 1 kervala
You first need to build the parameters list. This is done by filling a vector of STRING_MANAGER::TParam struture. For each parameter, you must set the Type field then write the appropriate member data. 
814 1 kervala
You MUST exactly respect the phrase parameter definition in the phrase file. 
815 1 kervala
816 1 kervala
817 1 kervala
Then, you can call 
818 1 kervala
uint32 STRING_MANAGER::sendStringToClient( 
819 1 kervala
NLMISC::CEntityId destClientId, 
820 1 kervala
const std::string &phraseIdentifier, 
821 1 kervala
const std::vector«STRING_MANAGER::TParam» parameters) 
822 1 kervala
destClientId is the entity id of the destination client, phraseIdentifier is the indentifier like writen in the phrase file, parameters is the vector of parameter you have build before. 
823 1 kervala
This function returns the dynamic ID that is assigned to this phrase. 
824 1 kervala
825 1 kervala
826 1 kervala
Example : sending the ‘kill a creature’ phrase (see § 5.2, step 4) : 
827 1 kervala
828 1 kervala
829 1 kervala
// include the string manager proxy definition 
830 1 kervala
#include “game_share/string_manager_sender.h” 
831 1 kervala
832 1 kervala
833 1 kervala
uint32 killCreatureMessage( 
834 1 kervala
EntityId destClient, 
835 1 kervala
GSPEOPLE::EPeople race, 
836 1 kervala
uint32 nbToKill) 
837 1 kervala
{ 
838 1 kervala
std::vector«STRING_MANAGER::TParam» params; 
839 1 kervala
STRING_MANAGER::TParam param; 
840 1 kervala
841 1 kervala
842 1 kervala
// first, we need the creature race 
843 1 kervala
param.Type = STRING_MANAGER::creature; 
844 1 kervala
param.Enum = race; 
845 1 kervala
params.push_back(param); 
846 1 kervala
847 1 kervala
848 1 kervala
// second, the number of creature to kill 
849 1 kervala
param.Type = STRING_MANAGER::integer; 
850 1 kervala
param.Int = nbToKill; 
851 1 kervala
params.push_back(param); 
852 1 kervala
853 1 kervala
854 1 kervala
// and now, send the message 
855 1 kervala
uint32 dynId = STRING_MANAGER::sendStringToClient( 
856 1 kervala
destClient, 
857 1 kervala
“KILL_A_CREATURE”, 
858 1 kervala
params); 
859 1 kervala
860 1 kervala
861 1 kervala
return dynId; 
862 1 kervala
}
863 1 kervala
864 1 kervala
865 1 kervala
866 1 kervala
Member to fill in TParam depending on the type of parameter: 
867 1 kervala
item: Fill SheetId with the sheet id of the item 
868 1 kervala
place: Fill Identifier string with the place identifier 
869 1 kervala
creature: Fill EId with the creature entity id 
870 1 kervala
skill: Fill Enum with the enum value from SKILLS::ESkills 
871 1 kervala
ecosystem: Fill Enum with the enum value from ECOSYSTEM::EEcosystem 
872 1 kervala
race: Fill Enum with the enum value from GSPEOPLE::EPeople 
873 1 kervala
brick: Fill SheetId with the sheet id of the brick 
874 1 kervala
tribe: not defined yet 
875 1 kervala
guild: not defined yet 
876 1 kervala
player: Fill EId with the player entity id 
877 1 kervala
bot: Fill EId with the bot entity id 
878 1 kervala
integer: Fill Int with the integer value (sint32) 
879 1 kervala
time: Fill Time with the time value (uint32) 
880 1 kervala
money: Fill Money with the money value (uint64) 
881 1 kervala
compass: not defined yet 
882 1 kervala
dyn_string_id: Fill StringId with a dynamic string id 
883 1 kervala
string_id: Fill StringId with a string id 
884 1 kervala
creature_model: Fill SheetId with the sheet id of the creature 
885 1 kervala
entity: Fill EId with the creature,npc or player entity 
886 1 kervala
body_part: Fill Enum with the enum value from BODY::TBodyPart 
887 1 kervala
score: Fill Enum with the enum value from SCORES::TScores 
888 1 kervala
sphrase: Fill SheetId with the sheet id of the phrase 
889 1 kervala
characteristic: Fill Enum with the enum value from CHARACTERISTICS::TCharacteristic 
890 1 kervala
damage_type: Fill Enum with the enum value from DMGTYPE::EDamageType 
891 1 kervala
bot_name: Fill Identifier with the bot name without function. 
892 1 kervala
literal: Fill Literal with the Unicode literal string. 
893 1 kervala
894 1 kervala
Accessing the dynamic string from the client 
895 1 kervala
On the client side, accessing the dynamic string is pretty easy. You only need to take care of transmission delay in certain case. 
896 1 kervala
897 1 kervala
898 1 kervala
Once you get the dynamic string id from anyway (eg database), you just need to pol the getDynString method of STRING_MANAGER::CStringManagerClient. 
899 1 kervala
The method return false until the requested string is incomplete or unknown. 
900 1 kervala
Even when the method return false, it could return a partial text with missing replacement text. 
901 1 kervala
Dynamic strings are dynamicaly stored, and if your code is smart enough, it could release the dynamic string memory when they are no more needed by calling releaseDynString. 
902 1 kervala
In order to be efficient, one can call each frame the getDynString method until it return true, then store away the string and call the releaseDynString. 
903 1 kervala
904 1 kervala
905 1 kervala
STRING_MANAGER::CStringManagerClient is based on the singleton pattern so you must call STRING_MANAGER::CStringManagerClient::instance() to get a pointer to the singleton instance. 
906 1 kervala
907 1 kervala
908 1 kervala
Here is a simple code sample. 
909 1 kervala
910 1 kervala
911 1 kervala
// include the string manager client definition 
912 1 kervala
#include “string_manager_client.h” 
913 1 kervala
914 1 kervala
915 1 kervala
using namespace STRING_MANAGER; 
916 1 kervala
917 1 kervala
918 1 kervala
/** A method that receive the dynamic string id 
919 1 kervala
* and print the dynamic string in the log. 
920 1 kervala
* Call it each frame until it return true. 
921 1 kervala
*/ 
922 1 kervala
bool foo(uint32 dynStringId) 
923 1 kervala
{ 
924 1 kervala
ucstring result; 
925 1 kervala
bool ret; 
926 1 kervala
CStringManagerClient *smc = CStringManagerClient::instance(); 
927 1 kervala
928 1 kervala
929 1 kervala
ret = smc-»getDynamicString(dynStringId, result) 
930 1 kervala
931 1 kervala
if (!ret) 
932 1 kervala
nlinfo(“Incomplete string : %s”, result.toString().c_str()); 
933 1 kervala
else 
934 1 kervala
{ 
935 1 kervala
nlinfo(“Complete string : %s”, result.toString().c_str()); 
936 1 kervala
// release the dynamic string 
937 1 kervala
smc-»releaseDynString(dynStringId); 
938 1 kervala
} 
939 1 kervala
940 1 kervala
941 1 kervala
return ret; 
942 1 kervala
} 
943 1 kervala
Ryzom text creation guide 
944 1 kervala
945 1 kervala
  
946 1 kervala
There are many place for text in Ryzom, this page will clarify the text identification conventions, the available context for text insertion and contextual text parameters. 
947 1 kervala
1.     Identifier conventions 
948 1 kervala
1.1. Strings identifiers in en.uxt 
949 1 kervala
These identifiers are written lower case with capital at start of each new word. 
950 1 kervala
Example: 
951 1 kervala
     aSimpleIdentifier 
952 1 kervala
     anotherIdentifier 
953 1 kervala
  
954 1 kervala
1.2. Phrases identifiers in phrase_en.txt 
955 1 kervala
These identifiers are written in capitals, words are separated with an underscore. 
956 1 kervala
Example: 
957 1 kervala
     A_SIMPLE_IDENTIFIER 
958 1 kervala
     ANOTHER_IDENTIFIER 
959 1 kervala
 
960 1 kervala
1.3. Strings (or clauses) identifiers in clause_en.txt 
961 1 kervala
These identifiers are written like strings identifiers in en.uxt. 
962 1 kervala
But, as they are inside a phrase definition, they must contains the name of the phrases as base name. The phrases name is lowered to respect the string identifiers convention. 
963 1 kervala
Example: 
964 1 kervala
     In a phrase named A_SIMPLE_LABEL, the identifier should be 
965 1 kervala
     aSimpleLabel 
966 1 kervala
  
967 1 kervala
Furthermore, when there is more than one clause for a given phrase, the clause identifier must be followed by some tags that give clues to the translator about the meaning of each clause. 
968 1 kervala
Example: 
969 1 kervala
            In a phrases named A_SIMPLE_LABEL and that contains two clauses, one for singular, the other for plural, we could have the following two identifiers: 
970 1 kervala
     aSimpleLabelS 
971 1 kervala
     aSimpleLabelP 
972 1 kervala
            
973 1 kervala
 
974 1 kervala
2.     Text contexts 
975 1 kervala
2.1. Chat contexts 
976 1 kervala
Chat context cover any texts that come from an NPC through the chat windows and text bubbles. 
977 1 kervala
2.1.1- Bot says/shout around 
978 1 kervala
There is only one parameter available: the npc entity that say/shout. 
979 1 kervala
Phrase name start with SAY_ 
980 1 kervala
Phrase sample: 
981 1 kervala
     SAY_XXX (bot b) 
982 1 kervala
{ 
983 1 kervala
     sayXxx    [Hello there, my name’s $b$, anybody hear me?] 
984 1 kervala
} 
985 1 kervala
2.1.2- Bot talk to escort leader (a player) 
986 1 kervala
Two parameters: the bot that talk and the player. 
987 1 kervala
Phrase name start with TALK_ 
988 1 kervala
Phrase sample: 
989 1 kervala
     TALK_XXX (bot b, player p) 
990 1 kervala
{ 
991 1 kervala
     talkXxx   [Hello $p$, my name’s $b$, I need help !] 
992 1 kervala
} 
993 1 kervala
2.1.3- Bot says/shout in response to target click 
994 1 kervala
Two parameters: the bot clicked and the player. 
995 1 kervala
Phrase name start with CLICK_ 
996 1 kervala
Phrase sample: 
997 1 kervala
     CLICK_XXX (bot b, player p) 
998 1 kervala
{ 
999 1 kervala
     clickXxx  [Hello $p$, my name’s $b$, did you click me ?] 
1000 1 kervala
} 
1001 1 kervala
  
1002 1 kervala
2.2. Interactive context (aka botchat) 
1003 1 kervala
Botchat cover any texts that come in the interactive NPC dialog. 
1004 1 kervala
  
1005 1 kervala
2.2.1- Mission related phrases 
1006 1 kervala
Static missions 
1007 1 kervala
All phrase name related to mission have of root defined by the name of the mission as placed in the world editor mission node. 
1008 1 kervala
From this root, there are several extension that must be appended to form the phrase names: 
1009 1 kervala
_TITLE                        for mission title 
1010 1 kervala
_STEP_X        for step X text (mission step start from 1) 
1011 1 kervala
_END              for the mission end text. 
1012 1 kervala
Example: 
1013 1 kervala
Given a mission named                          INSTRUCTOR_MIS_1, 
1014 1 kervala
The mission title will be             INSTRUCTOR_MIS_1_TITLE, 
1015 1 kervala
Step 1 mission text will be         INSTRUCTOR_MIS_1_STEP_1, 
1016 1 kervala
Step 2 mission text will be         INSTRUCTOR_MIS_1_STEP_2, 
1017 1 kervala
Mission end text will be             INSTRUCTOR_MIS_1_END 
1018 1 kervala
  
1019 1 kervala
Parameters: 
1020 1 kervala
XXXXXXX_TITLE (bot b, player p) 
1021 1 kervala
    -b est le bot à qui le joueur parle 
1022 1 kervala
    -p est le joueur 
1023 1 kervala
XXXXXXX_STEP_X (bot giver, bot current, bot target, bot previous, player p) 
1024 1 kervala
    - giver est le donneur de la mission 
1025 1 kervala
    - current est le bot à qui le joueur parle 
1026 1 kervala
    - target est le bot à aller voir pour la prochaine etape 
1027 1 kervala
    - previous est le bot vu à l'étape précédente 
1028 1 kervala
    - p est le joueur 
1029 1 kervala
  
1030 1 kervala
XXXXX_END (bot current, bot giver, bot previous, player p) 
1031 1 kervala
    - giver est le donneur de la mission 
1032 1 kervala
    - current est le bot à qui le joueur parle 
1033 1 kervala
    - previous est le bot vu à l'étape précédente 
1034 1 kervala
    - p est le joueur 
1035 1 kervala
  
1036 1 kervala
  
1037 1 kervala
Les paramètres des textes d'étapes du journal dépendent de la nature de l'étape (voir avec Nicolas Brigand). 
1038 1 kervala
  
1039 1 kervala
Pour les textes de progression de mission dans le menu contextuel, il en existe deux : 
1040 1 kervala
1041 1 kervala
MISSION_STEP_GIVE_ITEM_CONTEXT (bot giver, bot previous, item i)
1042 1 kervala
MISSION_STEP_TALK_CONTEXT (bot giver, bot previous) 
1043 1 kervala
  
1044 1 kervala
Le premier est le texte standard, le second est affiché quand on doit donner quelque chose au bot. 
1045 1 kervala
  
1046 1 kervala
  
1047 1 kervala
2.2.2- Additional context menu entry 
1048 1 kervala
It is possible to add simple ‘informational’ entry in the bot contextual menu. This item is composed of two phrases: the menu entry display name and the text content displayed after clicking the menu entry. 
1049 1 kervala
Two parameters: the bot supporting the context menu and the player. 
1050 1 kervala
Phrase name start with BC_MENU_ for menu entry and BC_MENUTEXT_ 
1051 1 kervala
  
1052 1 kervala
2.3.   System message (e.g. combat info) 
1053 1 kervala
Parameters are phrases dependent, but there are some well defined phrases types: 
1054 1 kervala
COMBAT_ 
1055 1 kervala
MAGIC_ 
1056 1 kervala
HARVEST_ 
1057 1 kervala
CRAFT_ 
1058 1 kervala
DEATH_ 
1059 1 kervala
PROGRESS_ 
1060 1 kervala
1061 1 kervala
3.4. None of the above…