LocalizationSystem

Version 5 (kervala, 06/27/2014 06:42 pm)

1 2 kervala
h1. *Localization system in Ryzom*
2 1 kervala
3 4 kervala
> TODO: improve formatting, original document is https://docs.google.com/Doc?docid=0ATbRb4Xh6srtZGhrbjluOHRfMThmemNjcDZkZw&authkey=CKTG4-QM
4 4 kervala
5 2 kervala
h2. Overview
6 1 kervala
7 2 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.
8 1 kervala
9 1 kervala
10 3 kervala
!dhkn9n8t_19f5n89nf3_b.gif!
11 1 kervala
12 2 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.
13 1 kervala
14 2 kervala
File formats are discussed below.
15 1 kervala
16 2 kervala
h2. Language code
17 1 kervala
18 2 kervala
Language in Ryzom are identified by there language code as defined in "ISO 639-1":http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes plus a country code defined in "ISO 3166":http://en.wikipedia.org/wiki/ISO_3166 *if necessary*.
19 1 kervala
20 2 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.
21 1 kervala
22 2 kervala
But there is some exception, like Chinese written language.
23 1 kervala
24 2 kervala
Chinese can be written in two forms: traditional or simplified. Nonetheless, there is only one language code for Chinese: ‘hz’.
25 1 kervala
26 2 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.
27 1 kervala
28 1 kervala
h2. Identifier definition
29 2 kervala
30 1 kervala
Translated strings are associated to identifier. Identifiers are textual string that must follow the C identifier constraint with a little difference.
31 1 kervala
32 5 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.
33 1 kervala
34 1 kervala
Some good identifier:
35 5 kervala
<pre>
36 5 kervala
This_is_a_good_identifier
37 2 kervala
ThisIsAGoodIdentifier
38 5 kervala
_This@is@notherGoodId
39 5 kervala
1234_is_a_goodId
40 5 kervala
This_Is_Good_1234
41 5 kervala
</pre>
42 1 kervala
Some bad identifier:
43 5 kervala
<pre>
44 5 kervala
This is a bad identifier
45 5 kervala
é#()|{[_IdBAD
46 5 kervala
</pre>
47 1 kervala
48 1 kervala
h2. File formats
49 1 kervala
50 1 kervala
There are three different translation file formats. But only two need to be learned ;-)
51 1 kervala
52 2 kervala
h3. Format 1
53 1 kervala
54 1 kervala
This format is used for client side static text and for server side clause text.
55 1 kervala
56 2 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 ‘]’.
57 1 kervala
58 2 kervala
Text layout is free; you can jump line and indent as you want.
59 5 kervala
<pre>
60 5 kervala
identifiant1	[textual value]
61 5 kervala
identifiant2	[other textual value]
62 5 kervala
</pre>
63 2 kervala
64 5 kervala
- This file can contain C style comments (single line or multiline)
65 1 kervala
66 5 kervala
<pre>
67 5 kervala
// This is a single line comment. Continue until end of line*
68 1 kervala
69 1 kervala
identifiant1 [textual value]
70 1 kervala
71 5 kervala
/* This is
72 5 kervala
   a multiline
73 5 kervala
   comment */
74 1 kervala
75 5 kervala
identifiant2 /* multiline comment here ! */ [other textual value]
76 5 kervala
</pre>
77 1 kervala
78 5 kervala
- Textual value can be formatted for readability. New line and tab are removed in the final string value.
79 1 kervala
80 5 kervala
<pre>
81 1 kervala
identifiant1 [textual
82 1 kervala
83 1 kervala
value
84 1 kervala
85 1 kervala
with
86 1 kervala
87 1 kervala
new line
88 1 kervala
89 1 kervala
and tab formating only for readability]
90 1 kervala
91 1 kervala
identifiant2 [other textual value]
92 5 kervala
</pre>
93 2 kervala
94 5 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: ‘\]’.
95 1 kervala
96 5 kervala
<pre>
97 1 kervala
identifiant1 [tabulation: *\t*This text is tabbed]
98 1 kervala
99 1 kervala
identifiant2 [New line *\n*Text on next line]
100 1 kervala
101 1 kervala
identifiant3 [Backslash: *\\*]
102 1 kervala
103 1 kervala
identifiant4 [a closing square bracket: *\]* ]
104 5 kervala
</pre>
105 1 kervala
106 5 kervala
- You can split the original file in multiple small file, more easy to maintain and work with.
107 2 kervala
108 1 kervala
This feature is achieved by using a C like preprocessor command “#include”.
109 1 kervala
110 5 kervala
<pre>
111 1 kervala
#include &quot;path/filename.txt&quot;
112 5 kervala
</pre>
113 1 kervala
114 1 kervala
You can have any number of include command. Included files can also contains include commands.
115 1 kervala
116 1 kervala
The path can be either an absolute path or a path relative to the location of the master file.
117 1 kervala
118 1 kervala
h3. Format 2
119 1 kervala
120 1 kervala
This format is used for phrases translation files.
121 2 kervala
122 1 kervala
This format is a pretty complex grammar that will be described in a near LALR syntax:
123 5 kervala
<pre>
124 5 kervala
identifiant :		[A-Za-z0-9_@]+
125 1 kervala
126 5 kervala
phrase	:		identifiant ‘(‘ parameterList ‘)’
127 5 kervala
				‘{‘
128 5 kervala
					clauseList
129 5 kervala
				‘}’
130 2 kervala
131 5 kervala
parameterList :	parameterList ‘,’ parameterDesc
132 5 kervala
			|	parameterDesc
133 2 kervala
134 5 kervala
parameterDesc :	parameterType parameterName
135 2 kervala
136 5 kervala
parameterName :	identifiant
137 2 kervala
138 5 kervala
parameterType :	‘item’
139 5 kervala
			|	‘place’
140 5 kervala
			|	‘creature’
141 5 kervala
			|	‘skill’
142 5 kervala
			|	‘role’
143 5 kervala
			|	‘ecosystem’
144 5 kervala
			|	‘race’
145 5 kervala
			|	‘brick’
146 5 kervala
			|	‘tribe’
147 5 kervala
			|	‘guild’
148 5 kervala
			|	‘player’
149 5 kervala
			|	‘int’
150 5 kervala
			|	‘bot’
151 5 kervala
			|	‘time’
152 5 kervala
			|	‘money’
153 5 kervala
			|	‘compass’
154 5 kervala
			|	‘dyn_string_id’
155 5 kervala
			|	‘string_id’
156 5 kervala
			|	‘self’
157 5 kervala
			|	‘creature_model’
158 5 kervala
			|	‘entity’
159 5 kervala
			|	‘bot_name’
160 5 kervala
			|	‘bodypart’
161 5 kervala
			|	‘score’
162 5 kervala
			|	‘sphrase’
163 5 kervala
			|	‘characteristic’
164 5 kervala
			|	‘damage_type’
165 5 kervala
			|	‘literal’
166 2 kervala
167 5 kervala
clauseList :		clauseList clause
168 5 kervala
			|	clause
169 2 kervala
170 5 kervala
clause :		conditionList identifiant textValue
171 5 kervala
			|	identifiant textValue
172 5 kervala
			|	conditionList identifiant
173 5 kervala
			|	identifiant
174 5 kervala
			|	textValue
175 2 kervala
176 5 kervala
conditionList :	conditionList condition
177 5 kervala
			|	condition
178 2 kervala
179 5 kervala
condition :		‘(‘ testList ‘)’
180 2 kervala
181 5 kervala
testList :		testList ‘&’ test
182 5 kervala
			|	test
183 2 kervala
184 5 kervala
test :			operand1 operator reference
185 2 kervala
186 5 kervala
operand1 :		parameterName
187 5 kervala
			|	parameterName’.’propertyName
188 2 kervala
189 5 kervala
propertyName :	identifiant
190 2 kervala
191 5 kervala
operator :		‘=’
192 5 kervala
			|	‘!=’
193 5 kervala
			|	‘<’
194 5 kervala
			|	‘<=’
195 5 kervala
			|	‘>’
196 5 kervala
			|	‘<=’
197 2 kervala
198 5 kervala
reference :		identifiant
199 2 kervala
200 5 kervala
textValue :		‘[‘ .* ‘]’
201 5 kervala
</pre>
202 2 kervala
203 2 kervala
As in format 1, you can include C style comment in the text and indent freely and use the include command.
204 2 kervala
205 2 kervala
h3. Format 3: Spreadsheet unicode export
206 2 kervala
207 5 kervala
This format is the result of a Unicode text export from Spreadsheet.
208 2 kervala
Encoding should be unicode 16 bits. Columns are tab separated and rows are new line separated.
209 2 kervala
210 2 kervala
You should not write this file by hand, but only edit it with Spreadsheet.
211 2 kervala
212 2 kervala
The first row must contain the columns names.
213 2 kervala
214 2 kervala
*Info columns*
215 2 kervala
216 5 kervala
If a column name start with a ‘*’, then all the column is ignored.
217 2 kervala
218 2 kervala
This is useful to add information column that can help translation.
219 2 kervala
220 2 kervala
*Delete character*
221 2 kervala
222 2 kervala
It is possible to insert a ‘delete’ command in the field: ‘\d’. This is useful for article translation.
223 2 kervala
224 2 kervala
Example: you have a string with the following replacement (in French):
225 2 kervala
226 5 kervala
<pre>
227 5 kervala
“Rapporte moi $item.da$ $item.name$”
228 5 kervala
</pre>
229 2 kervala
230 2 kervala
And the item words file contains the following:
231 2 kervala
232 5 kervala
<pre>
233 5 kervala
item		name		da
234 5 kervala
marteau	marteau	le
235 5 kervala
echelle	échelle	l’
236 5 kervala
</pre>
237 2 kervala
238 2 kervala
If the item is ‘marteau’, no problem, the replacement gives:
239 2 kervala
240 5 kervala
<pre>
241 5 kervala
“Rapporte moi le marteau”
242 5 kervala
</pre>
243 2 kervala
244 1 kervala
But for the ‘echelle’, there is a supplementary space in the result:
245 2 kervala
246 5 kervala
<pre>
247 5 kervala
“Rapporte moi l’ échelle”
248 5 kervala
</pre>
249 2 kervala
250 2 kervala
To remove this supplementary space, you can add a ‘delete’ marker in the article definition:
251 2 kervala
252 5 kervala
<pre>
253 5 kervala
item		name		da
254 5 kervala
marteau	marteau	le
255 5 kervala
echelle	échelle	l’\d
256 5 kervala
</pre>
257 2 kervala
258 2 kervala
This will give a correct resulting string:
259 2 kervala
260 5 kervala
<pre>
261 5 kervala
“Rapporte moi l’échelle”
262 5 kervala
</pre>
263 2 kervala
264 2 kervala
265 2 kervala
h2. Working with translation files, translator point of view
266 2 kervala
267 2 kervala
h3. Client side “&#42;.uxt” files
268 2 kervala
269 2 kervala
This file contains all static text available directly to the client. The text must conforms to format 1 described above.
270 2 kervala
271 2 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).
272 2 kervala
273 2 kervala
For example, the file en.uxt must begin with:
274 2 kervala
275 2 kervala
276 2 kervala
277 2 kervala
278 2 kervala
languageName [English]
279 2 kervala
280 2 kervala
h3. Server side files
281 2 kervala
282 2 kervala
Server side translation is a bit more complex.
283 2 kervala
284 2 kervala
We will learn how to write server side translation in four steps (guess what: from simple to complex problem!).
285 2 kervala
286 2 kervala
287 2 kervala
288 2 kervala
289 2 kervala
*Step 1: A simple string:*
290 2 kervala
291 2 kervala
For this, you only need the phrase file.
292 2 kervala
293 2 kervala
Let’s say we want a string saying “hello world!” identified by HelloWorld.
294 2 kervala
295 2 kervala
Create a phrase entry in phrase&#95;en.txt:
296 2 kervala
297 2 kervala
298 2 kervala
299 2 kervala
300 2 kervala
HelloWorld ()
301 2 kervala
302 2 kervala
{
303 2 kervala
304 2 kervala
[Hello world!]
305 2 kervala
306 2 kervala
}
307 2 kervala
308 2 kervala
309 2 kervala
310 2 kervala
311 2 kervala
That’s it! No more.
312 2 kervala
313 2 kervala
Of course, you must also provide the same phrase in all the supported language, for example, in phrase&#95;fr.txt:
314 2 kervala
315 2 kervala
316 2 kervala
317 2 kervala
318 2 kervala
HelloWorld ()
319 2 kervala
320 2 kervala
{
321 2 kervala
322 2 kervala
[Bonjour le monde!]
323 2 kervala
324 2 kervala
}
325 2 kervala
326 2 kervala
327 2 kervala
328 2 kervala
329 2 kervala
Note that only the text value has changed. The phrase identifier MUST remain the same in all the translations files.
330 2 kervala
331 2 kervala
332 2 kervala
333 2 kervala
334 2 kervala
*Step 2: Indirection to clause&#95;&lt;lang&gt;.txt*
335 2 kervala
336 2 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.
337 2 kervala
338 2 kervala
So, you can split phrase grammar in phrase file and text value in clause file.
339 2 kervala
340 2 kervala
341 2 kervala
342 2 kervala
343 2 kervala
To do this, you must assign a unique identifier to each text value.
344 2 kervala
345 2 kervala
Let’s rebuild the previous example with indirection.
346 2 kervala
347 2 kervala
In phrase&#95;en.txt, create the phrase entry like this:
348 2 kervala
349 2 kervala
350 2 kervala
351 2 kervala
352 2 kervala
HelloWorld ()
353 2 kervala
354 2 kervala
{
355 2 kervala
356 2 kervala
Hello
357 2 kervala
358 2 kervala
}
359 2 kervala
360 2 kervala
361 2 kervala
362 2 kervala
363 2 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.
364 2 kervala
365 2 kervala
Now, we can create the text value in clause&#95;en.txt:
366 2 kervala
367 2 kervala
368 2 kervala
369 2 kervala
370 2 kervala
Hello [Hello world!]
371 2 kervala
372 2 kervala
373 2 kervala
374 2 kervala
375 2 kervala
As in the first step, you must do this task for each language.
376 2 kervala
377 2 kervala
378 2 kervala
379 2 kervala
380 2 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.
381 2 kervala
382 2 kervala
Example:
383 2 kervala
384 2 kervala
385 2 kervala
386 2 kervala
387 2 kervala
HelloWorld ()
388 2 kervala
389 2 kervala
{
390 2 kervala
391 2 kervala
Hello [Bonjour le monde!]
392 2 kervala
393 2 kervala
}
394 2 kervala
395 2 kervala
396 2 kervala
397 2 kervala
398 2 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.
399 2 kervala
400 2 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.
401 2 kervala
402 2 kervala
403 2 kervala
404 2 kervala
405 2 kervala
*Step 3: Using parameters - basics *
406 2 kervala
407 2 kervala
Here we are entering in the complex stuff!
408 2 kervala
409 2 kervala
Each phrase can receive a list of parameter.
410 2 kervala
411 2 kervala
Those parameters can be of different types:
412 2 kervala
413 2 kervala
* item,
414 2 kervala
* place,
415 2 kervala
* creature,
416 2 kervala
* skill,
417 2 kervala
* ecosystem,
418 2 kervala
* race,
419 2 kervala
* brick,
420 2 kervala
* tribe,
421 2 kervala
* guild,
422 2 kervala
* player,
423 2 kervala
* int,
424 2 kervala
* bot,
425 2 kervala
* time,
426 2 kervala
* money,
427 2 kervala
* compass,
428 2 kervala
* dyn&#95;string&#95;id,
429 2 kervala
* string&#95;id,
430 2 kervala
* creature&#95;model,
431 2 kervala
* entity,
432 2 kervala
433 2 kervala
* body&#95;part,
434 1 kervala
* score,
435 2 kervala
* sphrase,
436 2 kervala
* characteristic,
437 2 kervala
438 2 kervala
* damage&#95;type,
439 2 kervala
* bot&#95;name,
440 2 kervala
* literal.
441 2 kervala
442 2 kervala
443 2 kervala
444 2 kervala
445 2 kervala
Each parameter is given a name (or identifier) when declared. We will call it paramName.
446 2 kervala
447 2 kervala
448 2 kervala
449 2 kervala
450 2 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.
451 2 kervala
452 2 kervala
The first column is very important because it associate a row of data with a particular parameter value.
453 2 kervala
454 2 kervala
455 2 kervala
456 2 kervala
457 2 kervala
Let’s begin with an example: we want to build a dynamic phrase with a variable creature race name.
458 2 kervala
459 2 kervala
First, we must build an excel sheet to define the words for creature type. This will be saved as race&#95;words&#95;&lt;lang&gt;.txt in unicode text export from excel. As always, you must provide a version of this file for each language.
460 2 kervala
461 2 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.
462 2 kervala
463 2 kervala
This is an example race&#95;words&#95;en.txt:
464 2 kervala
465 2 kervala
466 2 kervala
467 2 kervala
468 2 kervala
race name ia da p pia pda
469 2 kervala
470 2 kervala
kitifly Kitifly a the Kitiflys the
471 2 kervala
472 2 kervala
varynx Varynx a the Varynx the
473 2 kervala
474 2 kervala
etc…
475 2 kervala
476 2 kervala
477 2 kervala
478 2 kervala
479 2 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.
480 2 kervala
481 2 kervala
482 2 kervala
483 2 kervala
484 2 kervala
Next, we must create a phrase with a creature parameter in phrase&#95;&lt;lang&gt;.txt:
485 2 kervala
486 2 kervala
487 2 kervala
488 2 kervala
489 2 kervala
KILL&#95;A&#95;CREATURE (*race crea*)
490 2 kervala
491 2 kervala
{}
492 2 kervala
493 2 kervala
494 2 kervala
495 2 kervala
496 2 kervala
As you can see, after the phrase identifier KILL&#95;THIS&#95;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).
497 2 kervala
498 2 kervala
499 2 kervala
500 2 kervala
501 2 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:
502 2 kervala
503 2 kervala
504 2 kervala
505 2 kervala
506 2 kervala
KILL&#95;A&#95;CREATURE (race crea)
507 2 kervala
508 2 kervala
{
509 2 kervala
510 2 kervala
[Would you please kill a *$crea$* for me ?]
511 2 kervala
512 2 kervala
}
513 2 kervala
514 2 kervala
515 2 kervala
516 2 kervala
517 2 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.
518 2 kervala
519 2 kervala
520 2 kervala
521 2 kervala
522 5 kervala
? It is possible to recall any of the words file columns in the value string. We can for example dynamize the undefined article:
523 2 kervala
524 2 kervala
525 2 kervala
526 2 kervala
527 2 kervala
KILL&#95;A&#95;CREATURE (race crea)
528 2 kervala
529 2 kervala
{
530 2 kervala
531 2 kervala
[Would you please kill *$crea.ia$* *$crea$* for me ?]
532 2 kervala
533 2 kervala
}
534 2 kervala
535 2 kervala
536 2 kervala
537 2 kervala
538 5 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.
539 2 kervala
540 2 kervala
541 2 kervala
542 2 kervala
543 2 kervala
Last but not least, the identifier and indirection rules see in step 1 and 2 are still valid.
544 2 kervala
545 2 kervala
546 2 kervala
547 2 kervala
548 2 kervala
*Step 4: Using parameters: conditional clause*
549 2 kervala
550 2 kervala
It’s time now to unveil the conditional clause system.
551 2 kervala
552 2 kervala
553 2 kervala
554 2 kervala
555 2 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.
556 2 kervala
557 2 kervala
558 2 kervala
559 2 kervala
560 2 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.
561 2 kervala
562 2 kervala
What we need is conditions to select between three clause: no creature to kill, one creature to kill and more than one.
563 2 kervala
564 2 kervala
565 2 kervala
566 2 kervala
567 2 kervala
First, let’s write the phrase, its parameters and the three clauses:
568 2 kervala
569 2 kervala
570 2 kervala
571 2 kervala
572 2 kervala
KILL&#95;A&#95;CREATURE (race crea*, int count*)
573 2 kervala
574 2 kervala
{
575 2 kervala
576 2 kervala
// no creature to kill
577 1 kervala
578 1 kervala
579 1 kervala
[*There is no creature to kill today.*]
580 2 kervala
581 1 kervala
582 1 kervala
// 1 creature to kill
583 2 kervala
584 1 kervala
* [Would you please kill a $crea$ for me ?]*
585 2 kervala
// more than one
586 2 kervala
587 1 kervala
[Would you please kill *$count$* $crea$ for me ?]
588 2 kervala
589 1 kervala
}
590 2 kervala
591 1 kervala
592 1 kervala
593 1 kervala
594 1 kervala
We have written down three version of the text with very different meaning and gramatical structure.
595 2 kervala
596 1 kervala
Now, add the conditions. Conditions are placed before the identifier and/or string value and are marked with bracket.
597 2 kervala
598 1 kervala
599 1 kervala
600 1 kervala
601 1 kervala
KILL&#95;A&#95;CREATURE (race crea, int count)
602 2 kervala
603 1 kervala
{
604 2 kervala
605 1 kervala
// no creature to kill
606 2 kervala
607 1 kervala
*(count = 0) *[There is no creature to kill today.]
608 2 kervala
609 2 kervala
// 1 creature to kill
610 1 kervala
611 2 kervala
*(count = 1)* [Would you please kill a $crea$ for me ?]
612 1 kervala
613 2 kervala
// more than one
614 1 kervala
615 2 kervala
*(count &gt; 1)* [Would you please kill $count$ $crea$ for me ?]
616 1 kervala
617 2 kervala
}
618 1 kervala
619 1 kervala
620 1 kervala
621 1 kervala
622 2 kervala
Easy! no?
623 1 kervala
624 1 kervala
625 1 kervala
626 1 kervala
627 2 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.
628 1 kervala
629 2 kervala
Self parameter support name and gender property. You can provide a self&#95;words&#95;&lt;lang&gt;.txt file to handle special case (admin player with a translatable name for example).
630 1 kervala
631 2 kervala
Let’s rewrite the killing creature request with player gender aware style:
632 1 kervala
633 1 kervala
634 1 kervala
635 1 kervala
636 2 kervala
KILL&#95;A&#95;CREATURE (race crea, int count)
637 1 kervala
638 2 kervala
{
639 1 kervala
640 2 kervala
// -- Male player
641 1 kervala
642 2 kervala
// no creature to kill, male player
643 1 kervala
644 2 kervala
(count = 0* &amp; self.gender = Male*)
645 1 kervala
646 2 kervala
[Hi man, there is no creature to kill today .]
647 1 kervala
648 2 kervala
// 1 creature to kill, male player
649 1 kervala
650 2 kervala
(count = 1* &amp; self.gender = Male*)
651 1 kervala
652 2 kervala
[Hi man, would you please kill a $crea$ for me ?]
653 1 kervala
654 2 kervala
// more than one, male player
655 1 kervala
656 1 kervala
(count &gt; 1 *&amp; self.gender = Male*)
657 2 kervala
658 1 kervala
[Hi man, Would you please kill $count$ $crea$ for me ?]
659 2 kervala
660 1 kervala
661 1 kervala
662 1 kervala
663 1 kervala
// -- Female player
664 2 kervala
665 1 kervala
// no creature to kill, male player
666 2 kervala
667 1 kervala
(count = 0 *&amp; self.gender = Female*)
668 2 kervala
669 1 kervala
[Hi girl, There is no creature to kill today.]
670 2 kervala
671 2 kervala
// 1 creature to kill, male player
672 2 kervala
673 2 kervala
(count = 1 *&amp; self.gender = Female*)
674 2 kervala
675 2 kervala
[Hi girl, Would you please kill a $crea$ for me ?]
676 2 kervala
677 2 kervala
// more than one, male player
678 2 kervala
679 2 kervala
(count &gt; 1 *&amp; self.gender = Female*)
680 2 kervala
681 2 kervala
[Hi girl, Would you please kill $count$ $crea$ for me ?]
682 2 kervala
683 2 kervala
}
684 2 kervala
685 2 kervala
686 2 kervala
687 2 kervala
688 2 kervala
We have six clauses now. Three case on number of creature multiplied by two cases on the gender of the player.
689 2 kervala
690 2 kervala
As you can see, conditional test can be combined with a ‘&amp;’ character. This means that all the tests must be valid to select the clause.
691 2 kervala
692 2 kervala
693 2 kervala
694 2 kervala
695 2 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.
696 2 kervala
697 2 kervala
On the other hand, right test operand must be constant value (either textual or numerical value).
698 2 kervala
699 2 kervala
Available operators are =, !=, &lt;, &lt;=, &gt;, &gt;=.
700 2 kervala
701 2 kervala
702 2 kervala
703 2 kervala
704 2 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:
705 2 kervala
706 2 kervala
707 2 kervala
708 2 kervala
709 2 kervala
FOO&#95;PHRASE (int c1, int c2)
710 2 kervala
711 2 kervala
{
712 2 kervala
713 2 kervala
*(c1 = 0 &amp; c2 = 10)*
714 2 kervala
715 2 kervala
* (c1 = 10 &amp; c2 = 0)*
716 2 kervala
717 2 kervala
[This clause is selected if :
718 2 kervala
719 2 kervala
c1 equal zero *and* c2 equal ten
720 2 kervala
721 2 kervala
*or*
722 2 kervala
723 2 kervala
c1 equal ten *and* c2 equal zero]
724 2 kervala
725 2 kervala
}
726 2 kervala
727 2 kervala
728 2 kervala
729 2 kervala
730 5 kervala
? Detailed clause selection rules:
731 2 kervala
732 2 kervala
* A valid clause is a clause where the conditional combination are true with a given set of parameter value.
733 2 kervala
* Clauses are evaluated in the same order as they are written in the phrase file. The first valid clause will be selected.
734 2 kervala
* If the first clause doesn’t have condition, it is used as a fallback clause when none of the conditional clauses are selected.
735 2 kervala
* If there is no fallback clause and none of the clauses are selected, then the first clause is selected.
736 2 kervala
* For the same phrase, each language can provide its own set of condition and clause to accommodate its gammatical needs.
737 2 kervala
738 2 kervala
h3. Harcoded parameters properties reference
739 2 kervala
740 2 kervala
Here you file find an exhaustive list of harcoded parameters properties.
741 2 kervala
742 2 kervala
These properties are always available even if no words files are provided.
743 2 kervala
744 2 kervala
Futhermore, the harcoded property can’t be substituted by a word file specifying a column of the same name.
745 2 kervala
746 2 kervala
747 2 kervala
748 2 kervala
749 2 kervala
*Parameter*
750 2 kervala
751 2 kervala
*Property*
752 2 kervala
753 2 kervala
Item
754 2 kervala
755 2 kervala
756 2 kervala
757 2 kervala
758 2 kervala
Place
759 2 kervala
760 2 kervala
761 2 kervala
762 2 kervala
763 2 kervala
Creature
764 2 kervala
765 2 kervala
name : model name of the creature
766 2 kervala
767 2 kervala
gender : gender of the creature from the model
768 2 kervala
769 2 kervala
Skill
770 2 kervala
771 2 kervala
772 2 kervala
773 2 kervala
774 2 kervala
Ecosystem
775 2 kervala
776 2 kervala
777 2 kervala
778 2 kervala
779 2 kervala
Race
780 2 kervala
781 2 kervala
782 2 kervala
783 2 kervala
784 2 kervala
Brick
785 2 kervala
786 2 kervala
787 2 kervala
788 2 kervala
789 2 kervala
Tribe
790 2 kervala
791 2 kervala
792 2 kervala
793 2 kervala
794 2 kervala
Guild
795 2 kervala
796 2 kervala
797 2 kervala
798 2 kervala
799 2 kervala
Player
800 2 kervala
801 2 kervala
name : name of the player
802 2 kervala
803 2 kervala
gender : gender of the player in the mirror
804 2 kervala
805 2 kervala
Bot
806 2 kervala
807 2 kervala
career : the career of the bot
808 2 kervala
809 2 kervala
role : the role of the bot as defined in creature.basics.chatProfile
810 2 kervala
811 2 kervala
name : name of the creature
812 2 kervala
813 2 kervala
gender : gender of the creature from the model
814 2 kervala
815 2 kervala
Integer
816 2 kervala
817 2 kervala
818 2 kervala
819 2 kervala
820 2 kervala
Time
821 2 kervala
822 2 kervala
823 2 kervala
824 2 kervala
825 2 kervala
Money
826 2 kervala
827 2 kervala
828 2 kervala
829 2 kervala
830 2 kervala
Compass
831 2 kervala
832 2 kervala
833 2 kervala
834 2 kervala
835 2 kervala
dyn&#95;string&#95;id
836 2 kervala
837 2 kervala
Only != and == test available. Mainly to compare parameter with 0.
838 2 kervala
839 2 kervala
string&#95;id
840 2 kervala
841 2 kervala
Only != and == test available. Mainly to compare parameter with 0
842 2 kervala
843 2 kervala
self
844 2 kervala
845 2 kervala
name : name of the player
846 2 kervala
847 2 kervala
gender : gender of the player in the mirror
848 2 kervala
849 2 kervala
creature&#95;model
850 2 kervala
851 2 kervala
NB : use the creature&#95;words translation file !
852 2 kervala
853 2 kervala
entity
854 2 kervala
855 2 kervala
== 0, != 0: test if the entity is Unknown or not.
856 2 kervala
857 2 kervala
name : name of the creature or name of the player.
858 2 kervala
859 2 kervala
gender : gender of the creature from the model or gender of the player (from the player info).
860 2 kervala
861 2 kervala
bodypart
862 2 kervala
863 2 kervala
864 2 kervala
865 2 kervala
866 2 kervala
score
867 2 kervala
868 2 kervala
869 2 kervala
870 2 kervala
871 2 kervala
sphrase
872 2 kervala
873 2 kervala
874 2 kervala
875 2 kervala
876 2 kervala
characteristic
877 2 kervala
878 2 kervala
879 2 kervala
880 2 kervala
881 2 kervala
damage&#95;type
882 2 kervala
883 2 kervala
884 2 kervala
885 2 kervala
886 2 kervala
bot&#95;name
887 2 kervala
888 2 kervala
889 2 kervala
890 2 kervala
891 2 kervala
h2. Translation workflow
892 2 kervala
893 2 kervala
In the following translation workflow, we consider that the reference language is English.
894 2 kervala
895 2 kervala
896 2 kervala
897 2 kervala
898 2 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.
899 2 kervala
900 2 kervala
901 2 kervala
902 2 kervala
903 2 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.
904 2 kervala
905 2 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.
906 2 kervala
907 2 kervala
At least, you should NEVER make modification when there are pendings diff file.
908 2 kervala
909 2 kervala
910 2 kervala
911 2 kervala
912 2 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.
913 2 kervala
914 2 kervala
915 2 kervala
916 2 kervala
917 2 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.
918 2 kervala
919 2 kervala
920 2 kervala
921 2 kervala
922 2 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.
923 2 kervala
924 2 kervala
Moreover, for phrase files, the diff file automaticaly include comments that describe the parameter list.
925 2 kervala
926 2 kervala
h3. Translation repository structure
927 2 kervala
928 2 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.
929 2 kervala
930 2 kervala
Tools are provided to install the translated file in the client and server repository after a translation cycle is done.
931 2 kervala
932 2 kervala
933 2 kervala
934 2 kervala
935 1 kervala
translation/ Root directory for translation repository
936 1 kervala
937 1 kervala
938 1 kervala
939 1 kervala
940 1 kervala
941 2 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…).
942 1 kervala
943 1 kervala
944 1 kervala
945 1 kervala
946 2 kervala
work/ This is the starting point for addition of new content. This directory contains any files that can be edited for addition.
947 1 kervala
948 1 kervala
949 1 kervala
950 1 kervala
951 2 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.
952 1 kervala
953 5 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? ? ).
954 1 kervala
955 1 kervala
956 1 kervala
957 1 kervala
958 2 kervala
history/ Contains all the diff files that have been translated and merged. This is for backup and security reason.
959 1 kervala
960 1 kervala
961 1 kervala
962 1 kervala
963 2 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.
964 1 kervala
965 2 kervala
h3. Client side static string
966 1 kervala
967 1 kervala
968 1 kervala
969 1 kervala
970 2 kervala
*Initial task:*
971 1 kervala
972 2 kervala
Publisher
973 1 kervala
974 2 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.
975 2 kervala
* Generates static string diff files with the command make&#95;string&#95;diff.bat. This will create diff files for each language in the diff directory.
976 2 kervala
* Send the diff files to the Translator.
977 1 kervala
978 2 kervala
Translator
979 1 kervala
980 2 kervala
* Translate the diff files.
981 2 kervala
* Send them back to the Publisher.
982 1 kervala
983 2 kervala
Publisher
984 1 kervala
985 2 kervala
* Put the translated diff files in the diff directory (this will overwrite non translated diff files with translated one).
986 2 kervala
* Merge the translated diff files with the command merge&#95;string&#95;diff.bat. This will create the &lt;lang&gt;.uxt files for each language in the translated directory and move the diff in the history directory.
987 1 kervala
988 1 kervala
989 1 kervala
990 1 kervala
991 2 kervala
After the initial task is done, the workflow enters the in incremental mode.
992 1 kervala
993 1 kervala
994 1 kervala
995 1 kervala
996 2 kervala
*Incremental task:*
997 1 kervala
998 2 kervala
Publisher
999 1 kervala
1000 2 kervala
* Add string in the reference file en.uxt in the addtion directory.
1001 2 kervala
* Generates static string diff files with the command make&#95;string&#95;diff.bat. This will create diff files for each language in the diff directory.
1002 2 kervala
* Send the diff files to the Translator.
1003 1 kervala
1004 2 kervala
Translator
1005 1 kervala
1006 2 kervala
* Translate the diff files.
1007 2 kervala
* Send them back to the Publisher.
1008 1 kervala
1009 2 kervala
Publisher
1010 1 kervala
1011 2 kervala
* Put the translated diff files in the diff directory (this will overwrite non translated diff files with translated one).
1012 2 kervala
* Merge the translated diff files with the command merge&#95;string&#95;diff.bat. This will apply the diff files to the &lt;lang&gt;.uxt files for each language in the translated directory and move the diff in the history directory.
1013 1 kervala
1014 2 kervala
h3. Server side dynamic string
1015 1 kervala
1016 2 kervala
*Initial task:*
1017 1 kervala
1018 2 kervala
Publisher
1019 1 kervala
1020 2 kervala
* Creates the reference file phrase&#95;en.uxt in the addition directory and add any number of phrase entries for the English version.
1021 2 kervala
* Generates phrase diff files with the command make&#95;phrase&#95;diff.bat. This will create diff files for each language in the diff directory.
1022 2 kervala
* Translate the phrase diff file. This implie good knowledge of gramatical structure of each language to accommodate clause selection rules.
1023 2 kervala
* Merge the translated diff with the command merge&#95;phrase&#95;diff.bat. This will create all the phrase&#95;&lt;lang&gt;.txt in the translated directory from the translated diff then move diff files to history directory.
1024 2 kervala
* Generates clauses diff file with the command make&#95;clause&#95;diff.bat. This create clause diff file in the diff directory for all language.
1025 2 kervala
* Send the clause diff files to the Translator
1026 1 kervala
1027 2 kervala
Translator
1028 1 kervala
1029 2 kervala
* Translate the clause diff files.
1030 2 kervala
* Send them back to the Publisher.
1031 1 kervala
1032 2 kervala
Publisher
1033 1 kervala
1034 2 kervala
* Put the translated clause diff files in the diff directory (this will overwrite non translated clause diff files with translated one).
1035 2 kervala
* Merge the translated clause diff files with the command merge&#95;clause&#95;diff.bat. This will create the clause&#95;&lt;lang&gt;.txt files for each language in the translated directory and move the diff in the history directory.
1036 1 kervala
1037 1 kervala
1038 1 kervala
1039 1 kervala
1040 2 kervala
After the initial task is done, the workflow enters the in incremental mode.
1041 1 kervala
1042 1 kervala
1043 1 kervala
1044 1 kervala
1045 2 kervala
*Incremental task:*
1046 1 kervala
1047 2 kervala
Publisher
1048 1 kervala
1049 2 kervala
* Add new phrase in phrase&#95;en.uxt in the addition directory.
1050 2 kervala
* Generates phrase diff files with the command make&#95;phrase&#95;diff.bat. This will create diff files for each language in the diff directory.
1051 2 kervala
* Translate the phrase diff file. This implie good knowledge of gramatical structure of each language to accommodate clause selection rules.
1052 2 kervala
* Merge the translated diff with the command merge&#95;phrase&#95;diff.bat. This will append the diff to there repective phrase&#95;&lt;lang&gt;.txt file in the translated directory then move diff files to history directory.
1053 2 kervala
* Generates clauses diff file with the command make&#95;clause&#95;diff.bat. This create clause diff file in the diff directory.
1054 2 kervala
* Send the clause diff files to the Translator
1055 2 kervala
1056 2 kervala
Translator
1057 2 kervala
1058 2 kervala
* Translate the clause diff files.
1059 2 kervala
* Send them back to the Publisher.
1060 2 kervala
1061 2 kervala
Publisher
1062 2 kervala
1063 2 kervala
* Put the translated clause diff files in the diff directory (this will overwrite non translated clause diff files with translated one).
1064 2 kervala
* Merge the translated clause diff files with the comment merge&#95;clause&#95;diff.bat. This will append the diff file to there repective clause&#95;&lt;lang&gt;.txt files for each language in the translated directory and move the diff in the history directory.
1065 2 kervala
1066 2 kervala
h3. Server side words files
1067 2 kervala
1068 2 kervala
NB: ‘words’ has nothing to do with the microsoft program Word!
1069 2 kervala
1070 2 kervala
1071 2 kervala
1072 2 kervala
1073 2 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.
1074 2 kervala
1075 2 kervala
1076 2 kervala
1077 2 kervala
1078 2 kervala
So, there is only a workflow but no tools.
1079 2 kervala
1080 2 kervala
1081 2 kervala
1082 2 kervala
1083 2 kervala
*Initial task:*
1084 2 kervala
1085 2 kervala
Publisher
1086 2 kervala
1087 2 kervala
* Build the initial sheet for each type of parameter with all the possible identifier in the reference language in the translated directory.
1088 2 kervala
* Create and fill the default ‘name’ and ‘p’ columns.
1089 2 kervala
* Create the sheets for all languages by copying the reference language sheets.
1090 2 kervala
* Create and fill any basic column depending on languages.
1091 2 kervala
* Sends all the sheets to the Translator.
1092 2 kervala
1093 2 kervala
Translator
1094 2 kervala
1095 2 kervala
* Translate all the sheets in all language, eventualy, create any needed columns.
1096 2 kervala
* Send back the translated sheets to the Publisher.
1097 2 kervala
* Keep a copy of the translated sheets as reference for phrase and clause translation.
1098 2 kervala
1099 2 kervala
Publisher
1100 2 kervala
1101 2 kervala
* Put the translated sheets in the translated directory, overwriting old ones.
1102 2 kervala
1103 2 kervala
1104 2 kervala
1105 2 kervala
1106 2 kervala
After this initial task, there is two possible events:
1107 2 kervala
1108 2 kervala
1109 2 kervala
1110 2 kervala
1111 2 kervala
*New column(s) needed:*
1112 2 kervala
1113 2 kervala
Translator
1114 2 kervala
1115 2 kervala
* While translating phrase or clause diff, it comes that one or more new columns are needed for some language and parameter type.
1116 2 kervala
* Define the needed columns
1117 2 kervala
* Contact Publisher to check that no sheets updates are pending. If yes, first apply the ‘new sheets content’ workflow.
1118 2 kervala
* Add and fill the new columns into the concerned sheets/langs.
1119 2 kervala
* Send the sheets to the Publisher.
1120 2 kervala
1121 2 kervala
Publisher
1122 2 kervala
1123 2 kervala
* Put the new sheets in the translated directory, overwriting old ones.
1124 2 kervala
1125 2 kervala
1126 2 kervala
 *New sheets content:*
1127 2 kervala
Publisher:
1128 2 kervala
1129 2 kervala
* New game content is to be integrated in the game.
1130 2 kervala
* Contact Translator to check that no sheets updates are pending. If yes, first apply the ‘new column(s) needed’ workflow.
1131 2 kervala
* Create new sheets for the reference language and containing only the new content.
1132 2 kervala
* Add and fill the default columns in the new sheets (see ‘Initial task’).
1133 2 kervala
* Create new sheets for all the languages by copying the reference languages sheets.
1134 2 kervala
* Add but DON’T FILL all the columns to repect the current sheet format for each type, each language.
1135 2 kervala
* Send the new sheets to the Translator.
1136 2 kervala
1137 2 kervala
Translator:
1138 2 kervala
1139 2 kervala
* Translate the new sheets.
1140 2 kervala
* Append the new sheets at the end of the existing sheets.
1141 2 kervala
* Send the merge result to the Pushisher.
1142 2 kervala
* Keep the merge result as reference for phrase and clause translation and futur content addition.
1143 2 kervala
1144 2 kervala
Publisher:
1145 2 kervala
1146 2 kervala
* Put the new sheets in the translated directory, overwriting old ones.
1147 2 kervala
1148 2 kervala
1149 2 kervala
 *Installing the translated files*
1150 2 kervala
After a cycle of translation is terminated, you must install the translated files into the client and servers directory strucure.
1151 2 kervala
1152 2 kervala
1153 2 kervala
1154 2 kervala
1155 2 kervala
This is done via the command intall&#95;translation.bat.
1156 2 kervala
1157 2 kervala
The &lt;lang&gt;.uxt file are copied into the client strucure in Ryzom/gamedev/language.
1158 2 kervala
1159 2 kervala
All the other files are copied in Ryzom/data&#95;shard.
1160 2 kervala
1161 2 kervala
1162 2 kervala
1163 2 kervala
1164 2 kervala
To apply client side translation, Publisher needs to make a patch.
1165 2 kervala
1166 2 kervala
To apply server side translation, just enter the command ‘reload’ on the InputOutputService.
1167 2 kervala
1168 2 kervala
h2. Working with translation files: programmer view
1169 2 kervala
1170 2 kervala
As a NeL/Ryzom programmer, you can use the translation system with a very few calls.
1171 2 kervala
1172 2 kervala
h3. Accessing client static strings
1173 2 kervala
1174 2 kervala
To obtain a unicode string from a string identifier, you use the NLMISC::CI18N class.
1175 2 kervala
1176 2 kervala
1177 2 kervala
1178 2 kervala
1179 2 kervala
First of all, you must ensure that the translation file &#42;.uxt are available in the search path.
1180 2 kervala
1181 2 kervala
Then, you can load a language string set by calling NLMISC::CI18N::load(languageCode).
1182 2 kervala
1183 2 kervala
The parameter languageCode is the language code as defined in chapter 2 “Language code”.
1184 2 kervala
1185 2 kervala
After that, call the method NLMISC::CI18N::get(identifier) to obtain the unicode string associated to identifier.
1186 2 kervala
1187 2 kervala
h3. Dynamic strings
1188 2 kervala
1189 1 kervala
Dynamic string requires a bit more work and a complete shard infrastructure.
1190 2 kervala
1191 2 kervala
1192 2 kervala
1193 2 kervala
1194 2 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).
1195 2 kervala
1196 3 kervala
!dhkn9n8t_20d35g5n6d_b.gif!
1197 2 kervala
1198 2 kervala
RQS is a service that wants to send a dynamic string to the client.
1199 2 kervala
1200 2 kervala
RQS also send the dynamic string identifier to the client by using the database or any other way.
1201 2 kervala
1202 2 kervala
The proxy is a small piece of code that builds and sends the PHRASE message to IOS service.
1203 2 kervala
1204 2 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.
1205 2 kervala
1206 2 kervala
The client receives the phrase and requests any missing string element to the IOS.
1207 2 kervala
1208 2 kervala
1209 2 kervala
 *Building parameter list and sending the string*
1210 2 kervala
To access the proxy function, you need to include game&#95;share/string&#95;manager&#95;sender.h and link with game&#95;share.lib.
1211 2 kervala
1212 2 kervala
1213 2 kervala
1214 2 kervala
1215 2 kervala
You first need to build the parameters list. This is done by filling a vector of STRING&#95;MANAGER::TParam struture. For each parameter, you must set the Type field then write the appropriate member data.
1216 2 kervala
1217 2 kervala
You MUST exactly respect the phrase parameter definition in the phrase file.
1218 2 kervala
1219 2 kervala
1220 2 kervala
1221 2 kervala
1222 2 kervala
Then, you can call
1223 2 kervala
1224 2 kervala
uint32 STRING&#95;MANAGER::*sendStringToClient*(
1225 2 kervala
1226 2 kervala
NLMISC::CEntityId destClientId,
1227 2 kervala
1228 2 kervala
const std::string &amp;phraseIdentifier,
1229 2 kervala
1230 2 kervala
const std::vector&lt;STRING&#95;MANAGER::TParam&gt; parameters)
1231 2 kervala
1232 2 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.
1233 2 kervala
1234 2 kervala
This function returns the dynamic ID that is assigned to this phrase.
1235 2 kervala
1236 2 kervala
1237 2 kervala
1238 2 kervala
1239 2 kervala
Example : sending the ‘kill a creature’ phrase (see § 5.2, step 4) :
1240 2 kervala
1241 2 kervala
1242 2 kervala
1243 2 kervala
1244 2 kervala
// include the string manager proxy definition
1245 2 kervala
1246 2 kervala
#include “game&#95;share/string&#95;manager&#95;sender.h”
1247 2 kervala
1248 2 kervala
1249 2 kervala
1250 2 kervala
1251 2 kervala
uint32 killCreatureMessage(
1252 2 kervala
1253 2 kervala
EntityId destClient,
1254 2 kervala
1255 2 kervala
GSPEOPLE::EPeople race,
1256 2 kervala
1257 2 kervala
uint32 nbToKill)
1258 2 kervala
1259 2 kervala
{
1260 2 kervala
1261 2 kervala
std::vector&lt;STRING&#95;MANAGER::TParam&gt; params;
1262 2 kervala
1263 2 kervala
STRING&#95;MANAGER::TParam param;
1264 2 kervala
1265 2 kervala
1266 2 kervala
1267 2 kervala
1268 2 kervala
// first, we need the creature race
1269 2 kervala
1270 2 kervala
param.Type = STRING&#95;MANAGER::creature;
1271 2 kervala
1272 2 kervala
param.Enum = race;
1273 2 kervala
1274 2 kervala
params.push&#95;back(param);
1275 2 kervala
1276 2 kervala
1277 2 kervala
1278 2 kervala
1279 2 kervala
// second, the number of creature to kill
1280 2 kervala
1281 2 kervala
param.Type = STRING&#95;MANAGER::integer;
1282 2 kervala
1283 2 kervala
param.Int = nbToKill;
1284 2 kervala
1285 2 kervala
params.push&#95;back(param);
1286 2 kervala
1287 2 kervala
1288 2 kervala
1289 2 kervala
1290 2 kervala
// and now, send the message
1291 2 kervala
1292 2 kervala
uint32 dynId = STRING&#95;MANAGER::sendStringToClient(
1293 2 kervala
1294 2 kervala
destClient,
1295 2 kervala
1296 2 kervala
“KILL&#95;A&#95;CREATURE”,
1297 2 kervala
1298 2 kervala
params);
1299 2 kervala
1300 2 kervala
1301 2 kervala
1302 2 kervala
1303 2 kervala
return dynId;
1304 2 kervala
1305 1 kervala
}
1306 1 kervala
1307 1 kervala
1308 1 kervala
1309 1 kervala
1310 1 kervala
1311 2 kervala
*Member to fill in TParam depending on the type of parameter:*
1312 1 kervala
1313 2 kervala
item: Fill SheetId with the sheet id of the item
1314 1 kervala
1315 2 kervala
place: Fill Identifier string with the place identifier
1316 1 kervala
1317 2 kervala
creature: Fill EId with the creature entity id
1318 1 kervala
1319 2 kervala
skill: Fill Enum with the enum value from SKILLS::ESkills
1320 1 kervala
1321 2 kervala
ecosystem: Fill Enum with the enum value from ECOSYSTEM::EEcosystem
1322 1 kervala
1323 2 kervala
race: Fill Enum with the enum value from GSPEOPLE::EPeople
1324 1 kervala
1325 2 kervala
brick: Fill SheetId with the sheet id of the brick
1326 1 kervala
1327 2 kervala
tribe: not defined yet
1328 1 kervala
1329 2 kervala
guild: not defined yet
1330 1 kervala
1331 2 kervala
player: Fill EId with the player entity id
1332 1 kervala
1333 2 kervala
bot: Fill EId with the bot entity id
1334 1 kervala
1335 2 kervala
integer: Fill Int with the integer value (sint32)
1336 1 kervala
1337 2 kervala
time: Fill Time with the time value (uint32)
1338 1 kervala
1339 2 kervala
money: Fill Money with the money value (uint64)
1340 1 kervala
1341 2 kervala
compass: not defined yet
1342 1 kervala
1343 2 kervala
dyn&#95;string&#95;id: Fill StringId with a dynamic string id
1344 1 kervala
1345 2 kervala
string&#95;id: Fill StringId with a string id
1346 1 kervala
1347 2 kervala
creature&#95;model: Fill SheetId with the sheet id of the creature
1348 1 kervala
1349 2 kervala
entity: Fill EId with the creature,npc or player entity
1350 2 kervala
1351 2 kervala
body&#95;part: Fill Enum with the enum value from BODY::TBodyPart
1352 2 kervala
1353 2 kervala
score: Fill Enum with the enum value from SCORES::TScores
1354 2 kervala
1355 2 kervala
sphrase: Fill SheetId with the sheet id of the phrase
1356 2 kervala
1357 2 kervala
characteristic: Fill Enum with the enum value from CHARACTERISTICS::TCharacteristic
1358 2 kervala
1359 2 kervala
damage&#95;type: Fill Enum with the enum value from DMGTYPE::EDamageType
1360 2 kervala
1361 2 kervala
bot&#95;name: Fill Identifier with the bot name without function.
1362 2 kervala
1363 2 kervala
literal: Fill Literal with the Unicode literal string.
1364 2 kervala
1365 2 kervala
1366 2 kervala
 *Accessing the dynamic string from the client*
1367 2 kervala
On the client side, accessing the dynamic string is pretty easy. You only need to take care of transmission delay in certain case.
1368 2 kervala
1369 2 kervala
1370 2 kervala
1371 2 kervala
1372 2 kervala
Once you get the dynamic string id from anyway (eg database), you just need to pol the getDynString method of STRING&#95;MANAGER::CStringManagerClient.
1373 2 kervala
1374 2 kervala
The method return false until the requested string is incomplete or unknown.
1375 2 kervala
1376 2 kervala
Even when the method return false, it could return a partial text with missing replacement text.
1377 1 kervala
1378 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.
1379 1 kervala
1380 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.
1381 1 kervala
1382 1 kervala
1383 1 kervala
1384 1 kervala
1385 2 kervala
STRING&#95;MANAGER::CStringManagerClient is based on the singleton pattern so you must call STRING&#95;MANAGER::CStringManagerClient::instance() to get a pointer to the singleton instance.
1386 1 kervala
1387 2 kervala
1388 2 kervala
1389 1 kervala
1390 2 kervala
Here is a simple code sample.
1391 1 kervala
1392 1 kervala
1393 1 kervala
1394 1 kervala
1395 1 kervala
// include the string manager client definition
1396 2 kervala
1397 1 kervala
#include “string&#95;manager&#95;client.h”
1398 2 kervala
1399 1 kervala
1400 1 kervala
1401 1 kervala
1402 1 kervala
using namespace STRING&#95;MANAGER;
1403 1 kervala
1404 1 kervala
1405 1 kervala
1406 1 kervala
1407 1 kervala
/&#42;&#42; A method that receive the dynamic string id
1408 1 kervala
1409 1 kervala
&#42; and print the dynamic string in the log.
1410 1 kervala
1411 1 kervala
&#42; Call it each frame until it return true.
1412 1 kervala
1413 1 kervala
&#42;/
1414 1 kervala
1415 1 kervala
bool foo(uint32 dynStringId)
1416 1 kervala
1417 1 kervala
{
1418 1 kervala
1419 1 kervala
ucstring result;
1420 1 kervala
1421 1 kervala
bool ret;
1422 1 kervala
1423 1 kervala
CStringManagerClient &#42;smc = CStringManagerClient::instance();
1424 1 kervala
1425 1 kervala
1426 1 kervala
1427 1 kervala
1428 1 kervala
ret = smc-&gt;getDynamicString(dynStringId, result)
1429 1 kervala
1430 1 kervala
1431 1 kervala
1432 1 kervala
if (!ret)
1433 1 kervala
1434 1 kervala
nlinfo(“Incomplete string : %s”, result.toString().c&#95;str());
1435 1 kervala
1436 1 kervala
else
1437 1 kervala
1438 1 kervala
{
1439 1 kervala
1440 1 kervala
nlinfo(“Complete string : %s”, result.toString().c&#95;str());
1441 1 kervala
1442 1 kervala
// release the dynamic string
1443 1 kervala
1444 1 kervala
smc-&gt;releaseDynString(dynStringId);
1445 1 kervala
1446 1 kervala
}
1447 1 kervala
1448 1 kervala
1449 1 kervala
1450 1 kervala
1451 1 kervala
return ret;
1452 1 kervala
1453 1 kervala
}
1454 1 kervala
1455 1 kervala
h1. Ryzom text creation guide
1456 1 kervala
1457 1 kervala
1458 1 kervala
1459 1 kervala
1460 1 kervala
1461 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.
1462 1 kervala
1463 2 kervala
h2. 1. Identifier conventions
1464 2 kervala
1465 2 kervala
h3. 1.1. Strings identifiers in en.uxt
1466 2 kervala
1467 2 kervala
These identifiers are written lower case with capital at start of each new word.
1468 2 kervala
1469 2 kervala
Example:
1470 2 kervala
1471 2 kervala
aSimpleIdentifier
1472 2 kervala
1473 2 kervala
anotherIdentifier
1474 2 kervala
1475 2 kervala
1476 2 kervala
1477 2 kervala
h3. 1.2. Phrases identifiers in phrase&#95;en.txt
1478 2 kervala
1479 2 kervala
These identifiers are written in capitals, words are separated with an underscore.
1480 2 kervala
1481 2 kervala
Example:
1482 2 kervala
1483 2 kervala
A&#95;SIMPLE&#95;IDENTIFIER
1484 2 kervala
1485 2 kervala
ANOTHER&#95;IDENTIFIER
1486 2 kervala
1487 2 kervala
1488 2 kervala
1489 2 kervala
h3. 1.3. Strings (or clauses) identifiers in clause&#95;en.txt
1490 2 kervala
1491 2 kervala
These identifiers are written like strings identifiers in en.uxt.
1492 2 kervala
1493 2 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.
1494 2 kervala
1495 2 kervala
Example:
1496 2 kervala
1497 2 kervala
In a phrase named A&#95;SIMPLE&#95;LABEL, the identifier should be
1498 2 kervala
1499 2 kervala
aSimpleLabel
1500 2 kervala
1501 2 kervala
1502 2 kervala
1503 2 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.
1504 2 kervala
1505 2 kervala
Example:
1506 2 kervala
1507 2 kervala
In a phrases named A&#95;SIMPLE&#95;LABEL and that contains two clauses, one for singular, the other for plural, we could have the following two identifiers:
1508 2 kervala
1509 2 kervala
aSimpleLabelS
1510 2 kervala
1511 2 kervala
aSimpleLabelP
1512 2 kervala
1513 2 kervala
1514 2 kervala
1515 2 kervala
1516 2 kervala
1517 2 kervala
h2. 2. Text contexts
1518 2 kervala
1519 2 kervala
h3. 2.1. Chat contexts
1520 2 kervala
1521 2 kervala
Chat context cover any texts that come from an NPC through the chat windows and text bubbles.
1522 2 kervala
1523 2 kervala
h4. 2.1.1- Bot says/shout around
1524 2 kervala
1525 2 kervala
There is only one parameter available: the npc entity that say/shout.
1526 2 kervala
1527 2 kervala
Phrase name start with SAY&#95;
1528 2 kervala
1529 2 kervala
Phrase sample:
1530 2 kervala
1531 2 kervala
SAY&#95;XXX (bot b)
1532 2 kervala
1533 2 kervala
{
1534 2 kervala
1535 2 kervala
sayXxx [Hello there, my name’s $b$, anybody hear me?]
1536 2 kervala
1537 2 kervala
}
1538 2 kervala
1539 2 kervala
h4. 2.1.2- Bot talk to escort leader (a player)
1540 2 kervala
1541 2 kervala
Two parameters: the bot that talk and the player.
1542 2 kervala
1543 2 kervala
Phrase name start with TALK&#95;
1544 2 kervala
1545 2 kervala
Phrase sample:
1546 2 kervala
1547 2 kervala
TALK&#95;XXX (bot b, player p)
1548 2 kervala
1549 2 kervala
{
1550 2 kervala
1551 2 kervala
talkXxx [Hello $p$, my name’s $b$, I need help !]
1552 2 kervala
1553 2 kervala
}
1554 2 kervala
1555 2 kervala
h4. 2.1.3- Bot says/shout in response to target click
1556 2 kervala
1557 2 kervala
Two parameters: the bot clicked and the player.
1558 2 kervala
1559 2 kervala
Phrase name start with CLICK&#95;
1560 2 kervala
1561 2 kervala
Phrase sample:
1562 2 kervala
1563 2 kervala
CLICK&#95;XXX (bot b, player p)
1564 2 kervala
1565 2 kervala
{
1566 2 kervala
1567 2 kervala
clickXxx [Hello $p$, my name’s $b$, did you click me ?]
1568 2 kervala
1569 2 kervala
}
1570 2 kervala
1571 2 kervala
1572 2 kervala
1573 2 kervala
h3. 2.2. Interactive context (aka botchat)
1574 2 kervala
1575 2 kervala
Botchat cover any texts that come in the interactive NPC dialog.
1576 2 kervala
1577 2 kervala
1578 2 kervala
1579 2 kervala
h4. 2.2.1- Mission related phrases
1580 2 kervala
1581 2 kervala
Static missions
1582 2 kervala
1583 2 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.
1584 2 kervala
1585 2 kervala
From this root, there are several extension that must be appended to form the phrase names:
1586 2 kervala
1587 2 kervala
&#95;TITLE for mission title
1588 2 kervala
1589 2 kervala
&#95;STEP&#95;X for step X text (mission step start from 1)
1590 2 kervala
1591 2 kervala
&#95;END for the mission end text.
1592 2 kervala
1593 2 kervala
Example:
1594 2 kervala
1595 2 kervala
Given a mission named INSTRUCTOR&#95;MIS&#95;1,
1596 2 kervala
1597 2 kervala
The mission title will be INSTRUCTOR&#95;MIS&#95;1&#95;TITLE,
1598 2 kervala
1599 2 kervala
Step 1 mission text will be INSTRUCTOR&#95;MIS&#95;1&#95;STEP&#95;1,
1600 2 kervala
1601 2 kervala
Step 2 mission text will be INSTRUCTOR&#95;MIS&#95;1&#95;STEP&#95;2,
1602 2 kervala
1603 2 kervala
Mission end text will be INSTRUCTOR&#95;MIS&#95;1&#95;END
1604 2 kervala
1605 2 kervala
1606 2 kervala
1607 2 kervala
Parameters:
1608 2 kervala
1609 2 kervala
XXXXXXX&#95;TITLE (bot b, player p)
1610 2 kervala
1611 2 kervala
-b est le bot à qui le joueur parle
1612 2 kervala
1613 2 kervala
-p est le joueur
1614 2 kervala
1615 2 kervala
XXXXXXX&#95;STEP&#95;X (bot giver, bot current, bot target, bot previous, player p)
1616 2 kervala
1617 2 kervala
- giver est le donneur de la mission
1618 2 kervala
1619 2 kervala
- current est le bot à qui le joueur parle
1620 2 kervala
1621 2 kervala
- target est le bot à aller voir pour la prochaine etape
1622 2 kervala
1623 2 kervala
- previous est le bot vu à l'étape précédente
1624 2 kervala
1625 2 kervala
- p est le joueur
1626 2 kervala
1627 2 kervala
1628 2 kervala
1629 2 kervala
XXXXX&#95;END (bot current, bot giver, bot previous, player p)
1630 2 kervala
1631 2 kervala
- giver est le donneur de la mission
1632 2 kervala
1633 2 kervala
- current est le bot à qui le joueur parle
1634 2 kervala
1635 2 kervala
- previous est le bot vu à l'étape précédente
1636 2 kervala
1637 2 kervala
- p est le joueur
1638 2 kervala
1639 2 kervala
1640 2 kervala
1641 2 kervala
1642 2 kervala
1643 2 kervala
Les paramètres des textes d'étapes du journal dépendent de la nature de l'étape (voir avec Nicolas Brigand).
1644 2 kervala
1645 2 kervala
1646 2 kervala
1647 2 kervala
Pour les textes de progression de mission dans le menu contextuel, il en existe deux :
1648 2 kervala
1649 2 kervala
1650 2 kervala
 MISSION&#95;STEP&#95;GIVE&#95;ITEM&#95;CONTEXT (bot giver, bot previous, item i)
1651 2 kervala
 MISSION&#95;STEP&#95;TALK&#95;CONTEXT (bot giver, bot previous)
1652 2 kervala
1653 2 kervala
1654 2 kervala
1655 2 kervala
Le premier est le texte standard, le second est affiché quand on doit donner quelque chose au bot.
1656 2 kervala
1657 2 kervala
1658 2 kervala
1659 2 kervala
1660 2 kervala
1661 2 kervala
h4. 2.2.2- Additional context menu entry
1662 2 kervala
1663 2 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.
1664 2 kervala
1665 2 kervala
Two parameters: the bot supporting the context menu and the player.
1666 2 kervala
1667 2 kervala
Phrase name start with BC&#95;MENU&#95; for menu entry and BC&#95;MENUTEXT&#95;
1668 2 kervala
1669 2 kervala
1670 2 kervala
1671 2 kervala
h3. 2.3. System message (e.g. combat info)
1672 2 kervala
1673 2 kervala
Parameters are phrases dependent, but there are some well defined phrases types:
1674 2 kervala
1675 5 kervala
<pre>
1676 5 kervala
COMBAT_
1677 5 kervala
MAGIC_
1678 5 kervala
HARVEST_
1679 5 kervala
CRAFT_
1680 5 kervala
DEATH_
1681 5 kervala
PROGRESS_
1682 5 kervala
</pre>
1683 2 kervala
1684 5 kervala
h3. 3.4. None of the above…
1685 2 kervala
1686 2 kervala
1687 5 kervala
h2. To translate ring (Hack)
1688 2 kervala
1689 5 kervala
Set this lines in languages.txt:
1690 5 kervala
r2wk
1691 5 kervala
r2fr
1692 5 kervala
r2en
1693 5 kervala
r2de
1694 2 kervala
1695 5 kervala
!!! Don't forget to revert file before use translation tools for client !!!
1696 2 kervala
1697 5 kervala
h2. Batch Tools
1698 5 kervala
1699 5 kervala
h3. Phrases Tools
1700 5 kervala
1701 5 kervala
* Launch *1_make_phrase_diff* : Server side dynamic string / Initial & Incremental / Publisher => This will create diff files for each language in the diff directory.
1702 5 kervala
1703 5 kervala
* Translate all strings in "diff" directory files and remove the last line (// DIFF NOT TRANSLATED) when done
1704 5 kervala
1705 5 kervala
* Launch *11_clean_phrase_diff* to remove comments
1706 5 kervala
1707 5 kervala
* Launch *2_merge_phrase_diff* : Server side dynamic string / Initial & Incremental / Publisher => This will create all the phrase_<lang>.txt in the translated directory from the translated diff then move diff files to history directory.
1708 5 kervala
1709 5 kervala
update_phrase_work
1710 5 kervala
forget_phrase_diff
1711 5 kervala
1712 5 kervala
h3. Clauses Tools
1713 5 kervala
1714 5 kervala
* Launch *3_make_clause_diff* : Server side dynamic string / Initial & Incremental / Publisher => This create clause diff file in the diff directory for all language.
1715 5 kervala
1716 5 kervala
* Translate all strings in "diff" directory files and remove the last line (// DIFF NOT TRANSLATED) when done
1717 5 kervala
1718 5 kervala
* Launch *31_clean_clause_diff* to remove comments
1719 5 kervala
1720 5 kervala
* Launch *4_merge_clause_diff* : Server side dynamic string / Initial & Incremental / Publisher => This will create the clause_<lang>.txt files for each language in the translated directory and move the diff in the history directory.
1721 5 kervala
1722 5 kervala
h3. Words Tools
1723 5 kervala
1724 5 kervala
* Launch *5_make_words_diff* to create all *_words_<language>.txt diff files in diff directory for all languages.
1725 5 kervala
1726 5 kervala
* Translate all strings in "diff" directory files and remove the last line (// DIFF NOT TRANSLATED) when done
1727 5 kervala
1728 5 kervala
* Launch *6_merge_words_diff* to update *.txt files in translated directory.
1729 5 kervala
1730 5 kervala
h3. String Tools
1731 5 kervala
1732 5 kervala
* Launch *A_make_string_diff* : Client side static string / Initial & Incremental / Publisher => This will create diff files for each language in the diff directory
1733 5 kervala
1734 5 kervala
* Translate all strings in "diff" directory files and remove the last line (// DIFF NOT TRANSLATED) when done
1735 5 kervala
1736 5 kervala
* Launch *AA_clean_string_diff* to remove comments
1737 5 kervala
1738 5 kervala
* Launch *B_merge_string_diff* : Client side static string / Initial & Incremental / Publisher / Merge => This will create the <lang>.uxt files for each language in the translated directory and move the diff in the history directory
1739 5 kervala
1740 5 kervala
h3. Bot names Tools
1741 5 kervala
1742 5 kervala
C_make_bot_names_diff
1743 5 kervala
D_merge_bot_names_diff
1744 5 kervala
extract_bot_names
1745 5 kervala
1746 5 kervala
h3. Installation
1747 5 kervala
1748 5 kervala
*7 install_translation* : Installing the translated files / Publisher => install the translated files into the client and servers directory structure.
1749 5 kervala
1750 5 kervala
h3. Other tools
1751 5 kervala
1752 5 kervala
extract_new_sheet_names
1753 5 kervala
inject_clause
1754 5 kervala
local_merge
1755 5 kervala
sort_trans_phrase
1756 5 kervala
1757 5 kervala
h3. Olds
1758 5 kervala
1759 5 kervala
make_phrase_diff_old
1760 5 kervala
merge_phrase_diff_old