WoW:Saving variables between game sessions: Difference between revisions

m
Updates for 1.8/1.9
m (moved discussion)
m (Updates for 1.8/1.9)
Line 1: Line 1:
== SavedVariables.lua ==
== SavedVariables.lua ==


With the exception of a few game-managed properties (slot contents, graphics settings, etc), all custom values which need to be saved between sessions are maintained in a single file, <tt>SavedVariables.lua</tt>, which is written whenever the UI engine shuts down (either at game quit, or at the start of a forced UI reload), and then executed when the UI is started (after logging in or at the end of a forced UI reload).
With the exception of a few game-managed properties (slot contents, graphics settings, etc), all custom values which need to be saved between sessions are maintained on the player's computer in a set of .lua files, which are referred to as 'SavedVariables' files. There are three types of SavedVariables files:


The <tt>SavedVariables.lua</tt> file is executed as code (just like your addon code) some point shortly after all addons have been loaded. Since it is just executed as code, all of the values in it are loaded (regardless of whether they're still registered as saved variables). Once it has been loaded, the <b>"VARIABLES_LOADED"</b> event is fired, so that addons can update themselves.
* <tt>WTF\Account\ACCOUNTNAME\SavedVariables.lua</tt> - "Global" saved settings
* <tt>WTF\Account\ACCOUNTNAME\SavedVariables\AddOnName.lua</tt> - Per-account settings for each individual AddOn.
* <tt>WTF\Account\ACCOUNTNAME\ACCOUNTNAME\RealmName\CharacterName\AddOnName.lua</tt> - Per-character settings for each individual AddOn (NOTE: The realm part will be added in the 1.9 patch)


When the UI engine shuts down, only those variables which have been marked for saving will be written into the <tt>SavedVariables.lua</tt> file.
These files are written whenevent the UI engine shuts down (either at game quit, or at the start of a forced UI reload), and then executed when the UI is started and addons are loaded (after logging in or at the end of a forced UI reload).
 
The <tt>SavedVariables.lua</tt> files are executed as code (just like your addon code). The time at which they're executed varies slightly by file type -- The AddOn specific SavedVariables files are executed right after the addon they belong to has been loaded, and before the ADDON_LOADED event is fired for the addon. The global SavedVariables.lua file is loaded after all of the initial addons are loaded, before the player is given control, and before the VARIABLES_LOADED event is fired.
 
When the UI engine shuts down, only those variables which have been marked for saving will be written into the <tt>SavedVariables.lua</tt> files. A variable can be written to more than one file (though this is generally ill-advised since it can cause settings to be overwritten later on)


== Designating variables to save ==
== Designating variables to save ==
Line 11: Line 17:
=== SavedVariables in AddOn's .toc ===
=== SavedVariables in AddOn's .toc ===


The best way is to use the SavedVariables keyword in your Addon's .toc file.  Thus, an addon with some saved variables would have a .toc like:
The best way is to use the SavedVariables or SavedVariablesPerCharacter keywords in your Addon's .toc file.  Thus, an addon with some saved variables would have a .toc like:


  ## Interface: 1300
  ## Interface: 1300
Line 17: Line 23:
  ## Notes: This is a test to show how to save variables between game sessions
  ## Notes: This is a test to show how to save variables between game sessions
  ## SavedVariables: Demo_test, Demo_foo
  ## SavedVariables: Demo_test, Demo_foo
## SavedVariablesPerCharacter: Demo_perchar
  Demo.xml
  Demo.xml


If you have to store lots of pieces data, or data with dynamic keys, wrap it in one or two table variables rather than consuming huge quantities of global namespace.
If you have to store lots of pieces data, or data with dynamic keys, wrap it in one or two table variables rather than consuming huge quantities of global namespace.


This method is best because it works even if your module is not active (based on the ui addons menu), has a version mismatch, or fails during startup due to compilation, dependency, or other issues.
The <tt>## SavedVaraibles:</tt> heading is used for data you want to be available to your addon no matter which character is playing. <tt>## SavedVariablesPerCharacter:</tt> is used for data that you ONLY want to be available to a specific character. There is no way of accessing another character's per-character data, so if you need to access other character's data, then you should use a regular per-addon saved table, and use indexes within that for realm and character.


=== The RegisterForSave function (Do not use this) ===
=== The RegisterForSave function (Do not use this) ===
Line 28: Line 35:


LUA code can explicitly request that a variable be saved by calling the [[API RegisterForSave|RegisterForSave("varName")]] function with the variable name that should be saved. That variable then becomes flagged for saving at the end of the session.  It's important to note that since this is an active process, the variable will only be saved if it is registered during a session, so compilation execution failures that prevent the call from being made will end up without the variable being flagged.
LUA code can explicitly request that a variable be saved by calling the [[API RegisterForSave|RegisterForSave("varName")]] function with the variable name that should be saved. That variable then becomes flagged for saving at the end of the session.  It's important to note that since this is an active process, the variable will only be saved if it is registered during a session, so compilation execution failures that prevent the call from being made will end up without the variable being flagged.
Variables flagged this way go into the global <tt>SavedVariables.lua</tt> file.


Before the addition of the SavedVariables section in the .toc this was the only way to flag variables for saving, however now use of this function is not recommended unless there's a specific reason for optional saving (and you understand all the risks).
Before the addition of the SavedVariables section in the .toc this was the only way to flag variables for saving, however now use of this function is not recommended unless there's a specific reason for optional saving (and you understand all the risks).
Line 40: Line 49:
If your needs are simple, then you just have to mark your variable as saved in the <tt>.toc</tt> file, and initialize it with a reasonable default value at startup or OnLoad time. If there is a previously saved value, then it will simply overwrite the default one, otherwise the default value will remain. At the end of the play session whatever value it has ended up as will be saved.
If your needs are simple, then you just have to mark your variable as saved in the <tt>.toc</tt> file, and initialize it with a reasonable default value at startup or OnLoad time. If there is a previously saved value, then it will simply overwrite the default one, otherwise the default value will remain. At the end of the play session whatever value it has ended up as will be saved.


If your addon drives configuration from the saved variables, you will likely want to be informed when they've been loaded so the addon can reconfigure itself. In this case create an event handler and register for the <b>"VARIABLES_LOADED"</b> event. Once this is called you can re-check your configuration and set things appropriately.
If your addon drives configuration from the saved variables, you will likely want to be informed when they've been loaded so the addon can reconfigure itself. In this case create an event handler and register for the <b>"ADDON_LOADED"</b> event, when the arg1 global variable has the name of your addon. Once this is called you can re-check your configuration and set things appropriately.
 
If your addon is not 'OnDemand' loaded, then you can also just use the "VARIABLES_LOADED" event.


Finally, if you wish to do logic involving both the default and loaded value, you can use a technique as follows:
Finally, if you wish to do logic involving both the default and loaded value, you can use a technique as follows:
Line 51: Line 62:
In your OnLoad handler you add:
In your OnLoad handler you add:


   this:RegisterEvent("VARIABLES_LOADED");
   this:RegisterEvent("ADDON_LOADED");


Then, in your OnEvent handler, you have
Then, in your OnEvent handler, you have


  if (event == "VARIABLES_LOADED") then
  if ((event == "ADDON_LOADED") and (arg1 == "Demo")) then
   if (initDemo_foo == Demo_foo) then
   if (initDemo_foo == Demo_foo) then
     -- No change - Must be new user
     -- No change - Must be new user
Line 62: Line 73:
   end
   end
  end
  end
== Settings are per-ACCOUNT ==
It's important to note that settings are saved per-account, not per-character. If you wish to do per-character settings in your AddOn then you should use something like the player name as a key into a table for settings.  This does give the AddOn author some flexibility in being able to make some settings global, some per-class, some per-user, etc.


[[Category: HOWTOs]]
[[Category: HOWTOs]]
Anonymous user