Sorry for the late post!!
Last week, we continued our tutorial on saving data to the save file beyond Switches and Variables. We can save all manner of things and refer to it later, which is great, because booleans and integers aren’t the cleanest way to make a complex game. The example we covered was saving quest decision data, so you could keep all decisions in one central location and not tie up all of your switches or variables.
However we noted that our global variable was being saved to the save file. Totally appropriate for things like quest decisions, but sometimes you want to save things outside a save file and relevant to the game itself. What are some examples? Well, we’ve talked about a few in March. Options!
- We built this amazing Master Volume slider in an options menu in the title screen. But it resets every time our game launches! Nobody wants to have to reset that information every time. But obviously when we launch we don’t know what save file we’re going to load yet, if any. We don’t have a reference to any save file data. So we can’t just save and load that data using the method from last week.
- Other options we’ve previewed like profanity filters, key bindings, etc. should also be saved outside of a save file.
- Last week I mentioned a New Game+ mode, a new option in the title screen that asks whether you’ve beaten the game once before letting you play a new variant on the game.
- Achievements are something that typically exist outside the save file, at a game level – a little notification that pops up the first time you’ve done something. We need to see if you’ve done it in other playthroughs, not just this save file.
For all of these, we’re going to write to the Game’s “.ini” file.
What is an INI
An INI file is just a text file. You can open it up and it is extremely readable. Here’s part of Vidar’s:
[Volume] Master=100 bgm=100 bgs=100 sfx=100
Those terms should look familiar if you’ve reviewed the volume options tutorial. An INI is broken into three parts. Sections, properties, and values.
Section – section is like a header. It’s used for organizational purposes, as an umbrella under which to group related things you want to save. In the above example, the section is Volume.
Property – a property is a particular variable, attribute, or piece of data you want to keep track of. We have four properties in the above example: Master, bgm, bgs, and sfx. When we want to load from the INI, we need to know what Section and Property we’re looking for.
Value – the data stored in the property. Here, all of our volumes are set to 100. When we load, we are asking “what is the value?”
Writing to an INI
Writing to an INI is easy! First, make sure that whatever class you’re operating in, you add the line:
WritePrivateProfileString = Win32API.new('kernel32', 'WritePrivateProfileString', 'pppp' , 'i')
This is telling the computer hey, this thing can write to the INI. Quick note: all script calls in events in RPG Maker go through the “Game_Interpreter” class. We’ve covered the GI throughout this blog, but remember that if you want to write to the INI in a script call from an event, this line needs to show up once, somewhere, in Game_Interpreter.
Next, it’s a single line to write to the file, every time we want to do it (although I recommend multiple to keep things easy to read). The only line you need is:
WritePrivateProfileString.call(section, property, value, filename)
This line will write a specific section, property, and value to our INI. Each of those four items in the parenthesis is called an argument. You need to fill in the argument details yourself, and importantly, they all need to be strings. We covered section, property, and value earlier. Filename is the name of the file you’re writing to. For our purposes, you should use “./Game.ini” – and be sure to include the quotes! Remember, it needs to be a string, so EVERYTHING needs quotes.
Now, I like to do things broken out by line so I can see it a little easier. You can define each argument, and then call the WritePrivateProfileString method. So something like:
value = $game_system.volume(:bgm) section = "Volume" property = "bgm" filename = "./Game.ini"
Before you call the method above will help you to visualize what you’ve done for each argument. BE CAREFUL: this won’t work as is. Why? Because $game_system.volume(:bgm) is a number. It’s 100. And everything needs to be a string! If you have something like a number or :symbol that needs to be converted, it’s easy! Just use .to_s. So after we’ve defined our value, section, property, and filename like this, we can do:
WritePrivateProfileString.call(section, property, value.to_s, filename)
And we’ll be good to go.
All we’ve managed to do so far is write to the INI. We still need to load from it! Check back next week!