nskins / goby

Command-line role-playing game framework
MIT License
123 stars 58 forks source link

Internationalization support #105

Open pablofullana opened 7 years ago

pablofullana commented 7 years ago

Hello there. I was taking a look at this repository (not sure how I got here...) and it looks quite interesting. Something I found while checking the code out is that there are several messages hardcoded inside the classes. So I thought it would be quite useful to have i18n in place.

I started to add i18n, added the gem as a dependency, required it in goby.rb and put a very basic locales/en.yml in place. Even everything seems to be working just fine, I got a concern/question. I was thinking on a user trying to change this default messages (located at locales/en.yml) and had a hard time trying to figure it out. I thought that a good approach may be to have some sort of configuration in a top level object representing the game itself. Do you think this is a good approach? If so, is there any object (Game, Goby, w/e) in which general settings are being stored? It guess that it would be nice, as a developer using Goby, to be able to do something in the fashion of: Goby.config.i18n_load_path = ...

So far, what I have coded can be found at: https://github.com/pablofullana/goby/tree/add-i18n-support

Your thoughts.

nskins commented 7 years ago

Hi @pablofullana. Thanks for checking out Goby and opening this issue. This sounds like a promising feature, although I can't say that I have any immediate ideas about the implementation. I think our "top-level object" would be Player since we serialize this data for saving and loading the game. Can't say for sure if this is the best approach, however.

If we did implement this feature, I would want it to be completely optional from the end-user's point of view (changing the load path, choosing language, etc.). Also, we have many strings that are "somewhat" hardcoded - meaning a long string of text with maybe one or two arguments:

def HI(name)
  "Hi #{name}!"
end

Do you know if we could use i18n for these kinds of strings? I am opening the branch i18n in case anyone wishes to send a pull request.

pablofullana commented 7 years ago

Great hearing back from you and I'm glad you are interested in this feature!

First, regarding message customization. Developers would be able to define their own translation by simply adding the following line to their application:

I18n.load_path += Dir["#{File.expand_path File.dirname(__FILE__)}/locales/*.yml"]

Or wherever their translation files will be placed at. And then just overwriting any message inside those files.

Secondly, regarding language selection. Just by creating a new translation file and setting the translation messages accordingly, the developer would simply have to add the following line to his application:

# for Spanish, for example:
I18n.locale = :es

As long as there is a es.yml file in one of the above loaded directories, translations will be loaded automatically.

Finally, regarding the arguments for translations. I18n supports, out of the box, variables. Simply like this:

I18n.t('no_such_item', item_name: item.name)

And having defined something in the fashion of:

# .../locales/en.yml
en:
  ...
    no_such_item: "What?! You don't have any %{item_name}!"

More documentation at: http://guides.rubyonrails.org/i18n.html#passing-variables-to-translations

If you are with the above stated behavior, I could submit you a PR with the basic configuration for i18n support and a some documentation that could be added to the wiki to describe how developers could customize messages.

nskins commented 7 years ago

All of that sounds good, and I would be happy to review the PR and documentation. Could you explain again what you need the "top-level object" for? Reading your explanation, I don't have a good idea about what its purpose would be.

cvandermeer commented 3 years ago

If you need Dutch translations, let me know