NPC dialog source #173
Replies: 8 comments 17 replies
-
I can see why this feature would be desired; however, I'm not knowledgeable enough about how localization would work without the keys here. @exectails Would you mind explaining this in depth? Technically, the only issue that I could see using this method is that the packet size would increase due to sending long character strings. We would do well to make sure that they are zipped before being sent. And of course, whatever process that we use to convert keys into strings needs to be robust and maintained (which involves tools not part of Melia). |
Beta Was this translation helpful? Give feedback.
-
Sure. There are various ways you can tackle localization, but my personal favorite is gettext. Here you use keys as well, but instead of something like "SOME_TEXT", which is then turned into "This is some text.", you actually write it out, and that becomes the default for when no translation is available. All strings that are to be localized need to be wrapped in a function call, for example To create a localization database for a project you use a specialized parser that basically runs over all the source code, and searches for these function calls, creating a file out of them that you can then, for example, give to translators. The special thing about gettext is that it supports plurals properly. And not only the 1 plural form we know from English, but even the 6 or so forms of plurals that exist in other languages, so something like "You have X items." can be translated in a proper way. var text = string.Format(LN("You have {0} item.", "You have {0} items.", itemCount), itemCount); Gettext will choose the correct plural form based on the amount and return the string, which is then used in the format to get the final result. Fun fact: Languages like Japanese and Korean actually don't have plurals, which might explain why they usually use 1:1 key-value translation systems, which make it hard to localize certain things, resulting in strings like "You have X item(s)." The one disadvantage to this system is the function wrapper around all strings. if select(L("It would not be strange if the world ended tomorrow.{nl}However, I just want to know. Why the goddesses disappeared.."), L("Ask about the disappearance of the goddesses"), L("Cancel")) ~= 1 then
return
end
if select(L("I'm not sure I understand it completely, but what I'm sure of is that the goddesses didn't disappear all at once."), L("Ask what happened"), L("Cancel")) ~= 1 then
return
end
if select(L("Goddess Vakarine left us shortly before Medzio Diena.{nl}Both Zemyna and Ausrine disappeared soon after.{nl}It's already been four years since."), L("I think you forgot to mention Goddess Laima"), L("Cancel")) ~= 1 then
return
end
msg(L("She has never appeared before.{nl}Although I've read somewhere that she does appear every now and then..."))
It does increase the packet size, but I think it's fine. Players don't spend so much time in dialogues that it would create a bottle neck. Many games don't send keys, but the full dialog. Though we could certainly compress it, provided that the dialog packets support it. I don't see any compression setup though. |
Beta Was this translation helpful? Give feedback.
-
I guess there's one more route one could go here, though it would be a little crazy. Technically, you could use actual dialog in the NPCs, which, under normal circumstances, should be equal to the current English localization, and then do a reverse lookup for the dictionary key, which you then send to the client. That way you can see the dialog, but still choose the translation on the client side. Though this option would be more work and could break just as easily as using the first option. |
Beta Was this translation helpful? Give feedback.
-
My opinion in this matter would be the following: We should adhere to the ICU Message Format and create a simple i18n Localization Library. What does this mean?
The structure of a JSON file:{
"language": {
"code": "en_US",
"name": "English (United States)",
"revision": "1.0.01",
},
"translations": {
"TUTO_GIRL_basic_02": "You have {itemCount, plural, =0 {no items.} =1 {one item.} other {# items.}}",
...
}
}
How we decide which Language to set.The translation system is bounded to the Session of the User. We load all existing When the User initialises a Session the Client will send which Language the user set his Locale to be (Eg.: French, English, etcetera). And basically, we maintain that information (The Language Code) set in a way that it's easy to access. How it would work in practice?msg(T("TUTO_GIRL_basic_02", UserSession.CurrentLocale, { itemCount })); The
Observation: When the User Logs in and sends a Language Code that doesn't exist in the Cache we also set the Which Libraries would be used?I found two libraries that might be interesting for us: But might need to be extended or to have modifications. As far as I remember, .NET natively supports ICU and Localization... We might also want to give a peek in these solutions. |
Beta Was this translation helpful? Give feedback.
-
If we're not going to include official content in the core repo, maybe we should think about whether we even want to include all those dummy NPCs we generated. Right now, it's difficult to even find an NPC that does something, because the few there are, are mixed in with all the dummies that exist for fields, cities, and dungeons. I find this kind of annoying every time I go in there. Having these dummies stand around the world makes it feel less empty, but if we want users to set up their own content, NPCs, quests, etc, then including the dummies, or official NPCs once they're implemented, in the core would just mean that they would have to get disabled before you can do anything. They also take up space. I once searched for a nice place for a custom NPC in Klaipeda, and those dummies were just everywhere. Does it make sense to have them? Or maybe they should at least be easy to disable? Or to enable? Like a script list with dummy NPCs, that you uncomment if you want to? |
Beta Was this translation helpful? Give feedback.
-
News about the client telling the server about the selected language: apparently they did add packets for that, and @SalmanTKhan implemented them without telling anyone about it! D=< The "new" packets are
That means, aside from it being slightly more complicated, we could absolutely send dialog in the language selected by the player. |
Beta Was this translation helpful? Give feedback.
-
I just remembered one minor problem with using custom dialogues, NPC portraits don't work with them. I don't know if anyone would see those as vital, but it is kind of unfortunate. These are tied to the dialog elements that you would otherwise use, like |
Beta Was this translation helpful? Give feedback.
-
Over the past couple of months it's become more and more apparent to me that most people who're interested in Melia don't care very much about the official content, including the NPCs and quests. As such, it seems unlikely that we'll ever copy a lot of official complex and dialog heavy NPCs, where it might make sense to use the client-side localization system. And as I have mentioned previously, we should really stick to one system for consistency. That's why we're going to go with server-side dialog by default while keeping support for dialog keys for those who want to use them. |
Beta Was this translation helpful? Give feedback.
-
Our NPC's dialog code currently looks something like this:
We take advantage of the fact that the client has the dialogues for all NPCs, and just send localization keys. This has the advantage that it's pretty easy to create NPCs from logs, and we don't have to worry about localization, as long as there is an official translation for your language.
However, we also put ourselves at the mercy of the client. Any string can change at any time, just like their keys, and the script we wrote might not make any sense anymore after a few updates. That wouldn't be a problem if we sent the actual text, without relying on the client. It would also allow users to actually figure out what's going on in a script, instead of just guessing, based on structure and keys.
Typing all this out is certainly more work though, even if a Pale plugin could help with that, and I don't know if anyone will actually care about the dialog. It should be said though that writing the script would also be easier with actual text.
I thought I'd create a discussion for it, because I'm not sure which is better, and we should definitely stick to one.
Beta Was this translation helpful? Give feedback.
All reactions