GameMaker Using INI file for diologue localization, won't show apostrophe

RossmanBros

Member
Hi everyone, I am still somewhat new to Gamemaker and hoping there is a simple fix for this. I am using an INI file to store all my dialogue since it is easy to assign different languages for localization. For example:

[intro convo]
english = "english sentence"
spanish = "spanish sentence"

My only problem is in game it is not displaying apostrophes. As you can see in the image I attached it says "ILL" instead of "I'LL"

Any help would be very appreciated. Thanks!
 

Attachments

CloseRange

Member
I assume game maker is reading this as a "start to a string" because in game maker you can use " " or ' ' to call a string. I could be wrong but try adding a backslash right before the apostrophe
Code:
"Bessie I\'ll avenge you"
that's usually how you tell game maker to read the next character as part of the string.
The same would go if you wanted to use quotation marks:
Code:
"That\'s when he said, \"Wha\'s up?\""
 

Dmi7ry

Member
Are you sure that used font have ' symbol? I tried just now and it works fine (without backslashes, it is not needed here).
 

RossmanBros

Member
Are you sure that used font have ' symbol? I tried just now and it works fine (without backslashes, it is not needed here).
Thanks for the reply, and thanks for testing. Yes. It works fine if I write the string into the code. It does not work when I am reading the string from an INI file, saving it to a string variable, and then in the draw_text putting string(variable). Weird.

I'm guessing you tested it writing your string straight into the code, and not getting it from an INI file? Or did you test with it from a file and it worked fine? The INI file seems to be where the issue is.
 

Dmi7ry

Member
Have you tried another font? For example, "Arial Unicode MS". And try to get chars range from ini file.

Can you share the project (or make a small example with the problem)?
 

RossmanBros

Member
Yeah the font, multiple fonts same issue.
I made a test project, not sure if there is an easy way to attach it to the forums.

But here is an example in the images. Shows the code, the INI file, and the result in game.

When you display the text and write the string into the code it displays fine.
When the string is stored in a variable read from a file it doesn't work.

Thanks for the help.
 

Attachments

Dmi7ry

Member
Oh, it's Mac. Maybe it's something Mac-related, because I do all the same and it works (on Windows).
If you share the example (google drive, dropbox, etc), I would try it on my PC.
 
J

jaydee

Guest
I'm not sure this is causing an issue or not, but in INI files you don't need to enclose strings in quotation marks. I wonder if that's causing a parsing error?

Code:
[test]
; Removed quotation marks
english=Let's see if this works
 

Tsa05

Member
in INI files you don't need to enclose strings in quotation marks
But in GameMaker you do. Not really an ini file format thing, but it's something that they added in GameMaker a while back. Now it always adds quotes around strings when you write them. I used to do a lot of text in INI stuff, and it messed me up immediately--they're not going back, though.
This seems to be a single quotation mark instead of a apostrophe.
Almost certainly the issue and the solution.

Another thing to bear in mind--especially if you're writing to a file and then reading from it--is that GameMaker creates ANSI-type files. If you are creating an ANSI file yourself, or if you're telling GameMaker to write to a new file, the text encoding will not hold many kinds of characters.


You can manually save a text file as Unicode to include more characters (and international characters). In order to get GameMaker to use UTF-8, you have to save a blank file as UTF-8, then add it to the Included Files in your game, then tell GameMaker to write to a file using the same name as the included file.
 
H

HammerOn

Guest
Another thing to bear in mind--especially if you're writing to a file and then reading from it--is that GameMaker creates ANSI-type files. If you are creating an ANSI file yourself, or if you're telling GameMaker to write to a new file, the text encoding will not hold many kinds of characters.
That's not really the case. GM just saves and read data as it is. No convertion or encoding enforced. But for some reason GMS's code editor don't accept unicode input but display it. I can't type Japanese in the editor but I can copy and paste it there and it works fine with the string functions too.
 
Last edited by a moderator:

Hyomoto

Member
I know you didn't ask for advice on this specifically but I figured it might be worthwhile to chime in here. To do 'proper' localization, it's generally easiest to have a single file dedicated to each language and to store all your strings in a ds_map. When the program loads, you populate that map with all the dialogue strings in the game from the given file. That way, if you want to change language you simply have to load a different file. I'm guessing the reason you are doing it this way in particular is because the built-in support for key pairs is fairly easy with .ini files, but depending on how much localization you need to do that file is going to get pretty large and the code you need to write to load it will too. Here's just an example of a way to handle this with normal text files:
Code:
/// @func database_open( filename )
/// @param {string} filename    - the path/name of the file to open
var _file    = ( file_exists( argument0 ) ? file_text_open_read( argument0 ) : undefined );
var _line;

if is_undefined( _file ) { exit }
else {
    var _list    = ds_list_create();
   
    while ( !file_text_eof( _file ) ) {
        _line    = file_text_read_string( _file ); file_text_readln( _file );
       
        if _line == "" { continue }
        else { ds_list_add( _list, _line ) }
       
    }
    file_text_close( _file );
   
    return _list;
   
}
Code:
///@func localization_read( list, map )
///@param {int} list    - a list containing a localization file
///@param {int} map        - the map to read the file into
var _list    = argument0;
var _map    = argument1;
var _line, _key, _value, _break;

ds_map_clear( _map );

while ( !ds_list_empty( _list ) ) {
    _line    = _list[| 0 ]; ds_list_delete( _list, 0 );
   
    _break    = string_pos( "=\"", _line );
    _key    = string_copy( _line, 1, _break - 1 );
    _value    = string_delete( _line, 1, _break + 1 );
   
    _map[? _key ] = _value;
   
}
I put together a project that demonstrates this method you can download from my dropbox. But just to explain the method a bit, basically the first script, database_open, reads the entire text file into a ds_list and throws away any 'blank' lines. The second script, localization_read then breaks those lines apart into their key/value pairs and reads them into the ds_map you specify. This prevents you from having to do a bunch of unnecessary reads to the ini file, and ensures that your game only contains in memory the current localization. That way you can simply refer to everything by it's specific name. Perhaps a script like:
Code:
///@func get_string( name )
///@param {string} name  - the name of the string to retrieve
var _string = LOCALIZATION_MAP[? argument0 ];

if is_undefined( _string ) { return "" }
return _string;
That way if, for some reason, a string isn't defined it won't cause a crash. I would also suggest pairing this with caching the result local to the object so you don't have to do a lookup each frame either.
Code:
myString = get_string( "string1" );
This should, hopefully, fix the issue you are having as well as give you a more flexible framework to build from. I realize this is a bit of an extreme example, and isn't exactly the question you had, but hopefully if nothing else this gives you another avenue to consider. Have fun and keep coding!
 
H

HammerOn

Guest
It will be great to keep the information in this thread accurate. See: Text Files. It is the case, as stated, that GameMaker writes to ANSI files by default.
You shouldn't trust the manual too much about these technical details. That isn't what actually happens and you can test it.
Code:
fname = get_save_filename("", "");
file = file_text_open_write(fname);
file_text_write_string(file, "c全然");
file_text_close(file);
This will saves UTF-8 encoding just fine and you can even open it in a hex editor to confirm.
 

SamuelSousa

Member
TIP for anyone coming here over 4 years later...

I run into this problem as well...
In your INI file copy a " ' " then do find and replace all " ' " with" ' " (pressed from your keyboard). Worked for me.
Sometimes copied text or changing file formats changes text formatting.
 
Top