Switching language in module Vocab

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
I just got a something funny in module Vocab.

My goal was to be able to switching Vocab to other language.

But, since the variables in Vocab are constant (which is unable to change), I though that was impossible.

Later ......

Since I knew the word 'require' in ruby, I planned to make a switching vocab by a script call.

def translated require 'indo_vocab'enddef english require 'english_vocab'endThe indo_vocab.rb contains translated module vocab in my language.I tried to make two events that call these two methods.

But I realized that you could only call the 'require' keyword with same parameter in one time.

Okay, my experiment was failed ...

Then, I've been wondering what if I could re-define Vocab by using script call. So, I tried to make these code

def indonesian_vocab eval(" module Vocab ShopBuy = \"Beli\" # Buy in my language end ")enddef english_vocab eval(" module Vocab ShopBuy = \"Buy\" end ")endAnd did you know? it works perfectly :D Well, I just want to share this trick. And I'm sorry if I can't explain a thing in english properly
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Though, that's a strange way to do it, re-defining your methods just to retrieve a different string.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Just store both texts and then choose which one to display. I think that's how most people do it.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
Just store both texts and then choose which one to display. I think that's how most people do it.
No, you can't do this to Constant.
I've tried this sample

Code:
SomeConstant = (condition ? "text1" : "text2")
The condition is checked one time. So it won't be checked once again in the middle of the game.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Oh, you wanted to continue to use the Vocab module rather than using something else. Missed that part.
 

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,309
Reaction score
531
First Language
indonesian
i try implementing your method but cannot make it work. where did you put the def translated

game interpreter? or module Vocab.

btw i try it like this:

class Game_Interpreterdef indonesian_vocabeval("module VocabShopBuy = \"Beli\" # Buy in my languageend")endendbut cannot change the vocab...

Found a way to change constant !!!

class Game_Interpreter  def buy_vocab(str)    Vocab::ShopBuy.replace str  endendand it change the buy vocab to any string we type

found from this articles:

http://stackoverflow.com/questions/6712298/dynamic-constant-assignment

and to revert back to 'original' value i use this:

Code:
module Vocab  Default_ShopBuy = ShopBuy  Default_ShopSell = ShopSell  Default_ShopCancel = ShopCancelendclass Game_Interpreter  def reset_shop_vocab    Vocab::ShopBuy.replace Vocab::Default_ShopBuy    Vocab::ShopSell.replace Vocab::Default_ShopSell    Vocab::ShopCancel.replace Vocab::Default_ShopCancel  endend
 
Last edited by a moderator:

richter_h

Eh? Sweetroll?
Veteran
Joined
Apr 26, 2013
Messages
598
Reaction score
1,032
First Language
Indonesian
Primarily Uses
N/A
Well, nice pick to make another module.

And obviously it needs many changes to have both modules to be checked in-game. How about adding certain method in Game_Interpreter which calls the module instead of checking each of the dialogue lines?

Also, it's only affects the basic vocabs (or the one tagged in Vocab module). If we want to make the module affects other scripts, we should alter the scripts to read the module as well.

Of course, it might need a bit more effort to include the module into scripts :guffaw:

BTW it's kinda eye-opening for me, since I need it to expand the bilingual possibility in my game. Nice one, fella.

OOT: TheoAllen, I saw your siggy and you missed a character. We have 20 playable characters, not 19 :p

You missed Schneide, I see...
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
Sorry for late reply. For some reason, I could not connect to internet back then


@estriole :


Dont define the methods in Game_Interpreter or anything. Just write "def blabablbal..." and it should works


Btw, what a nice way to change value of the constant you have found. :D


To return to original value, I use $RGSS_SCRIPTS.


I found this trick when I was observing to TDS Script Disabler


Basically. $RGSS_SCRIPTS is an array that contains the scripts in Script.rvdata2.


The default location of Vocab is in 3rd index. So, I just only need to access the 3rd index of that array ($RGSS_SCRIPTS[2])


And I also found that the $RGSS_SCRIPTS is a nested array. To access the original Vocab string, I need to access its 4th index. So, that all I need is to write down $RGSS_SCRIPTS[2][3].


Here is my concept (ready to be released)


http://pastebin.com/PRk2TzPC


It was tested and it works


@richter_h:


Great effort indeed. A great game must have a great effort too :p


And thanks for mentioning my signature :p
 

Dr.Yami

。◕‿◕。
Developer
Joined
Mar 5, 2012
Messages
1,003
Reaction score
757
First Language
Vietnamese
Primarily Uses
Other
I would prefer making an external file that store all the vocabs and parser them when open game  :rock-left:   :distrust:   :rock-right:
 

IceDragon

Elder Cookie Dragon
Veteran
Joined
Mar 8, 2012
Messages
73
Reaction score
63
First Language
English
Primarily Uses
N/A
5 cents: (copy and pasted)

Code:
## kode-xchange/lib/core/locale.rb#   by IceDragonclass Locale  ##  # @return [String] name of this Locale  attr_reader :name  ##  # @param [String] name  def initialize(name)    @name = name    @data = Hash.new  end  ##  # @param [String] locname  # @return [String]  def [](locname)    @data.fetch(locname)  end  ##  # @param [String] locname  # @param [String] translated  # @return [Void]  def []=(locname, translated)    @data[locname.dup.freeze] = translated.dup.freeze  endend
Vocab:
Code:
module Vocab  class << self    attr_accessor :locale  end  def self.param(id)    locale["param/#{id}"]  end    # loaded from a binary file  #self.locale = load_data("locale/us_english.lbin")  # set from known locale  self.locale = Locale::Englishend
English Locale example:
Code:
class Locale  English = Locale.new('us_english')  English['param/0'] = 'Max. Hp'  English['param/1'] = 'Max. Mp'  English['param/2'] = 'Attack'  English['param/3'] = 'Defense'  English['param/4'] = 'Mag. Ak'  English['param/5'] = 'Mag. Df'  English['param/6'] = 'Agility'  English['param/7'] = 'Luck'end
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
How does that deal with the constants?


The problem is that most of the default scripts reference Vocab::ConstName directly. If it's the method calls that's easy to address.
 
Last edited by a moderator:

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,309
Reaction score
531
First Language
indonesian
Sorry for late reply. For some reason, I could not connect to internet back then

@estriole :

Dont define the methods in Game_Interpreter or anything. Just write "def blabablbal..." and it should works

Btw, what a nice way to change value of the constant you have found. :D

To return to original value, I use $RGSS_SCRIPTS.

I found this trick when I was observing to TDS Script Disabler

Basically. $RGSS_SCRIPTS is an array that contains the scripts in Script.rvdata2.

The default location of Vocab is in 3rd index. So, I just only need to access the 3rd index of that array ($RGSS_SCRIPTS[2])

And I also found that the $RGSS_SCRIPTS is a nested array. To access the original Vocab string, I need to access its 4th index. So, that all I need is to write down $RGSS_SCRIPTS[2][3].

Here is my concept (ready to be released)

http://pastebin.com/PRk2TzPC

It was tested and it works

@richter_h:

Great effort indeed. A great game must have a great effort too :p

And thanks for mentioning my signature :p
ah i see. that's why i get undefined method Vocab blablabla when i put it in Game_Interpreter :D . i never know we can define def outside a class :D . and we can call it using script call box (the reason i put the method in game interpreter is so i can call it using script call). this info is really useful. since we can use the method inside another class too (not like game_interpreter).

btw i change my above concept too... too bad that i cannot use your implementation (switch auto translate) so i have to script my own... since i want to change the vocab to anything i want... (not just two language). it's used in my script to define shop vocab at run time. example in this city the shop buy vocab is "Tuku" (wong jowo bang hehehehe), in other city the shop buy vocab is "Nukar"(urang banjar). in other city the shop buy vocab is "Meuli" (sunda). LOL.

i also realize that using another constant inside vocab module i used before will not be saved to save files. so i store the default value in a nested hash inside $game_system variable whenever i change any constant value. and also store the 'used' value in a nested hash whenever i change any constant value... and change all the vocab to 'used' value when loading the save (if i don't do this when closing the game.exe and loading it will revert back to old vocab. in your case it won't happen like that since it seek the switch and translate it automatically).... in the end. it works too in my case. :D

i also made it able to change any constant in any module / class. :D . as long it's string, array, or fixnum (this one still experimental)

here's the code for reference :D (will release it later too inside another script maybe or independent script. if i do i will credit you too theo :D ).

it's use two extra variables. but i guess in my case it still necessary... (open to any suggestion to reduce the variables :D )

http://pastebin.com/H0UjHukK

btw i see a new idea for your technique here. i try redefining method and it works too!!! how about redefining the entire battle system runtime :D .

so we can switch battle system easily. or maybe start with simple scenes first for experiment :D .

before i have tried it using eval inside game_interpreter. and it throw error. who know i only have to put it outside :D .

the concept maybe like this:

1) store each battle system in a txt files.

   - default battle system (might involve scene_battle, battle_manager, etc) (to reset before switching to another battle system since most people use this as base)

   - battle system 1

   - battle system 2

   - battle system 3

[will this step necessary?] then before switching destroy the class / module

2) then reset to the default battle system and then redefine the class to default battle system

3) then redefine to another battle system

it will be huge work though. :D .

edit:

I would prefer making an external file that store all the vocabs and parser them when open game  :rock-left:   :distrust:   :rock-right:
nice idea... we could create language txt files with vocab module. and redefine Vocab module when loading the game (based on the saved variable in $game_system).

but this won't solve my case though (only change one or some vocab, and change it to many different combination).
 
Last edited by a moderator:

IceDragon

Elder Cookie Dragon
Veteran
Joined
Mar 8, 2012
Messages
73
Reaction score
63
First Language
English
Primarily Uses
N/A
How does that deal with the constants?

The problem is that most of the default scripts reference Vocab::ConstName directly. If it's the method calls that's easy to address.
You can cheat.

Code:
module Vocab  constants.each(&:remove_const)  def self.ConstName    "Stuff"  endend
ruby allows ::method_name calls as well.
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Never knew you could call constants that way lol


That looks a lot more elegant than evaluating entire modules.
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
I would prefer making an external file that store all the vocabs and parser them when open game  :rock-left:   :distrust:   :rock-right:
Well, nice idea you have there. If you want to use trilingual or more, just make a filename that contains a number in its name. For example, lang_1.rb and such. Then we use Game_Variables to determine which language is currently used

ah i see. that's why i get undefined method Vocab blablabla when i put it in Game_Interpreter :D . i never know we can define def outside a class :D . and we can call it using script call box (the reason i put the method in game interpreter is so i can call it using script call). this info is really useful. since we can use the method inside another class too (not like game_interpreter).

btw i change my above concept too... too bad that i cannot use your implementation (switch auto translate) so i have to script my own... since i want to change the vocab to anything i want... (not just two language). it's used in my script to define shop vocab at run time. example in this city the shop buy vocab is "Tuku" (wong jowo bang hehehehe), in other city the shop buy vocab is "Nukar"(urang banjar). in other city the shop buy vocab is "Meuli" (sunda). LOL.

i also realize that using another constant inside vocab module i used before will not be saved to save files. so i store the default value in a nested hash inside $game_system variable whenever i change any constant value. and also store the 'used' value in a nested hash whenever i change any constant value... and change all the vocab to 'used' value when loading the save (if i don't do this when closing the game.exe and loading it will revert back to old vocab. in your case it won't happen like that since it seek the switch and translate it automatically).... in the end. it works too in my case. :D

i also made it able to change any constant in any module / class. :D . as long it's string, array, or fixnum (this one still experimental)

here's the code for reference :D (will release it later too inside another script maybe or independent script. if i do i will credit you too theo :D ).

it's use two extra variables. but i guess in my case it still necessary... (open to any suggestion to reduce the variables :D )

http://pastebin.com/H0UjHukK

btw i see a new idea for your technique here. i try redefining method and it works too!!! how about redefining the entire battle system runtime :D .

so we can switch battle system easily. or maybe start with simple scenes first for experiment :D .

before i have tried it using eval inside game_interpreter. and it throw error. who know i only have to put it outside :D .

the concept maybe like this:

1) store each battle system in a txt files.

   - default battle system (might involve scene_battle, battle_manager, etc) (to reset before switching to another battle system since most people use this as base)

   - battle system 1

   - battle system 2

   - battle system 3

[will this step necessary?] then before switching destroy the class / module

2) then reset to the default battle system and then redefine the class to default battle system

3) then redefine to another battle system

it will be huge work though. :D .

edit:

nice idea... we could create language txt files with vocab module. and redefine Vocab module when loading the game (based on the saved variable in $game_system).

but this won't solve my case though (only change one or some vocab, and change it to many different combination).
I knew that we can define a method outside other class in first time I learned Ruby. And my very first script call done in that way (I didn't know if we should define script call in Game_Interpreter).

Well done, what a tricky trick you have there. It's nice though.

If you release the script, I'm sure that I will make a tutorial based on your script (Indonesian tutorial of course, negara kita kurang SDM yang peduli RGSS :hammer: ) or maybe some addons implement to other scripts to allow dynamically change constant :D

And yes, we can redefine method or anything in any classes (All hail eval function!)

However, if we re-define a class which has a global instance variable (such as $game_system), you should reinitialize the instance object. Maybe, by using this script http://forums.rpgmakerweb.com/index.php?/topic/18457-rgss3-object-reinitializer/

You can cheat.

module Vocab constants.each(&:remove_const) def self.ConstName "Stuff" endendruby allows ::method_name calls as well.
I tried to implement your idea

module Theo  def self.TestConst    $game_switches[1] ? "Text 1" : "Text 2"  endendThen I did a script call using "Theo::TestConst". But it gave me an "uninitialized constant" error.
 

IceDragon

Elder Cookie Dragon
Veteran
Joined
Mar 8, 2012
Messages
73
Reaction score
63
First Language
English
Primarily Uses
N/A
Ah *facepalms*, I forgot it only works with downcased method names


:p just use Theo.TestConst or Theo.test_method


Module::method_name, is uncommon in ruby (as in, not practiced)
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
I tried that script call and it works :D

However, the RTP Scripts uses Vocab::Constant to access the string.

It still can't be done by your trick
 

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,309
Reaction score
531
First Language
indonesian
I knew that we can define a method outside other class in first time I learned Ruby. And my very first script call done in that way (I didn't know if we should define script call in Game_Interpreter).

Well done, what a tricky trick you have there. It's nice though.

If you release the script, I'm sure that I will make a tutorial based on your script (Indonesian tutorial of course, negara kita kurang SDM yang peduli RGSS :hammer: ) or maybe some addons implement to other scripts to allow dynamically change constant :D

And yes, we can redefine method or anything in any classes (All hail eval function!)

However, if we re-define a class which has a global instance variable (such as $game_system), you should reinitialize the instance object. Maybe, by using this script http://forums.rpgmakerweb.com/index.php?/topic/18457-rgss3-object-reinitializer/
HAIL eval function !!!!  (although there' some risk with it according some post in stackoverflow. but who cares :D ).

nice tips about needing to reinitialize the instance object. :D .

i define in Game_Interpreter because i didn't directly learn ruby at first (only lately i really learn ruby :D ). but learn from reading other scripter script :D . so in their script mostly put that in Game_Interpreter or in module class method. it's not requirement. just personal style perhaps.

iya nih kurang sdm >.<. gak jadi duit soalnya gan wkwkwkwk. tp mudah2an makin bermunculan sdm baru. :D .
 

richter_h

Eh? Sweetroll?
Veteran
Joined
Apr 26, 2013
Messages
598
Reaction score
1,032
First Language
Indonesian
Primarily Uses
N/A
I would prefer making an external file that store all the vocabs and parser them when open game  :rock-left:   :distrust:   :rock-right:
Well, this one is the best (and simplest) way to make the game to has more than 1 language. Maybe it could support external scripts to have the same effect as the default Vocab module could get.

An external file with extension of .rvdata, .rvdata2 or something else than .txt might works here ;)

Instead of using the variable provided in the RPG Maker, why we don't use local variable that accessible from outside the module? It might sounds unwise and hardcoded in its way, but it could prevent unwilling changes upon the variable (and well, I'm the kind of pweson who misses little things often and often changes something without checking other related things :p ).

Agreed with estriole, Game_Interpreter is one of the good places to put the "language change" method call. If using another class, it also works like a charm.

One more thing, eval function might sounds good but has some risks, but often worth it. ;)
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,865
Messages
1,017,059
Members
137,574
Latest member
nikisknight
Top