A library to manage and migrate to addon settings that support scopes per server, per account and per character, and to allow toggling between scopes on-the-fly.

Should I Use LibSavedVars?

If you answer "yes" to all the below, then LibSavedVars is definitely for you.

I am an addon developer

I want to add the ability to toggle between server-wide and character-specific saved variables at runtime, without reloading

I want to store different settings per megaserver (NA, EU)

I want my character-specific settings to survive character name changes.

I want to be able to version / upgrade saved vars structure without resetting all existing data while incrementing the standard "version" saved var.

I want to do this all in a standardized way without inventing my own custom logic

How Easy Is LibSavedVars to Use?

LibSavedVars is just as easy to use as ZO_SavedVars, just with some additional functionality.

It will be easiest to implement for the following kinds of addons:

Addons that don't yet have any saved vars

Addons that only have a single saved var table for player settings

Addons that have a single saved var for character settings and a single saved var for account-wide settings, and the state for which one is active for a player is stored within the character settings table.

If your addon falls into one of those two categories, migrating to LibSavedVars should only take a few lines of code beyond including the library.

What LibSavedVars Is NOT For

Server-Agnostic Saved Vars

If you don't need to separate out data between NA and EU because the data you are tracking doesn't change (e.g. furniture lists, item links, coordinate positions, etc), then LibSavedVars isn't going to really provide you with much advantage over the normal "Default" account wide ZO_SavedVars functionality.

You are certainly free to rework your addon to use LibSavedVars instead, but it's most likely not going to do everything your custom implementation does.

Addons with a saved var for character settings and one for account settings, but the state for which one is active is stored within the account settings table.

I'll probably add a function in the future to enable account-wide settings on all characters with a simple function call, but it will always retain the ability to disable account-wide settings for an individual character while having them enabled for others.

LibSavedVars is designed with the idea that account-wide settings represent a player's global default preferences, and character-specific settings act as overrides to those defaults.

Forcing a player to choose between whether they want global defaults -OR- per-character customization runs counter to the purpose of LibSavedVars.

Planned Features

Adding a function and a LibAddonMenu-2.0 button to enable account-wide settings on all characters

Utilities and LibAddonMenu-2.0 controls for copying settings between characters, accounts and servers.

If you want character-specific settings to be the default. Note, if you have an old saved var created with ZO_SavedVars:NewCharacterIdSettings(), then you will want to use :MigrateFromCharacterId() instead of :MigrateFromCharacterName().

Note: an additional key called __dataSource is included as the last key with pairs() and next() iterations. This allows you to access the internal dataSource property in Zgoo, but it is something to keep in mind when looping.

Lua Code:

for key, value inpairs(addon.settings)do

if key ~="__dataSource"then

-- do something

d("key: "..tostring(key)..", value: "..tostring(value))

end

end

If you don't want to worry about __dataSource, you can loop the raw saved vars table directly:

Lua Code:

local savedVars = addon.settings:GetActiveSavedVars()

local rawSavedVars = LibSavedVars:GetRawDataTable(savedVars)

for key, value inpairs(rawSavedVars)do

-- do something

d("key: "..tostring(key)..", value: "..tostring(value))

end

Looping with next:

Lua Code:

local key, value =next(addon.settings, nil)

while key ~="__dataSource"then

-- do something

d("key: "..tostring(key)..", value: "..tostring(value))

key, value =next(addon.settings, key)

end

Looping with ipairs:

Lua Code:

for index, value inipairs(addon.settings)do

-- do something

d("index: "..tostring(index)..", value: "..tostring(value))

end

Looping with a counter variable:

Note the use of addon.settings:GetLength() instead of #addon.settings. The # operator is not supported, because it cannot be overloaded on tables in Lua 5.1, which is what ESO uses.

Lua Code:

for index, 1, addon.settings:GetLength()do

-- do something

d("index: "..tostring(index)..", value: "..tostring(value))

end

LibAddonMenu-2 Integration
LibSavedVars has a helper method to create the "Account-wide Settings" checkbox in your LibAddonMenu-2 panel, localized for English, French, German, Japanese and Russian.

- Deprecated the following methods in LibSavedVars.lua:
* New(). See NewAccountWide() and NewCharacterSettings()
* GetClass(). You can now access classes directly by name (e.g. LSV_Data, LSV_SavedVarsManager)

- Deprecated the following methods in classes\LSV_Data.lua (formerly just Data.lua):
* New(). See NewAccountWide and NewCharacterSettings().
* Migrate(). See MigrateFrom().

- Moved Lua 5.2 pairs(), ipairs() and next() overrides into a separate library, LibLua5.2, to avoid the performance penalty for non-developers or anyone else who doesn't care about iterating saved vars.

- API bump for Update 21 Wrathstone

Version 3.0

- New methods New(), NewAccountWide() and NewCharacterIdSettings() return a data object that can be used as a 1:1 replacement for ZO_SavedVars instances
- New helper method GetRawDataTable() returns the underlying data table for a ZO_SavedVars instance, since ZO_SavedVars:New() just returns an interface, not the data itself.
- Added usage documentation / comments to all public methods in code.

- Data class features:
* data["key"] and data.key operator support
* data["key"] = value and data.key = value operator support
* next(), pairs() and ipairs() support for iterating saved vars
* GetAccountSavedVarsActive() and SetAccountSavedVarsActive(value) methods for toggling the active scope between account and character-specific settings
* Migrate(legacySavedVars, beforeCallback, addon, ...) method to call directly and control when migration is executed.
* GetActiveSavedVars() method to return a reference to the active ZO_SavedVars instance for the currently logged-in character
* GetLength() returns the # length of the data for the active ZO_SavedVars instance for the currently logged-in character
* GetLibAddonMenuAccountCheckbox() replaces the old library-wide method that took an "addon" parameter.

- DEPRECATED METHODS:
* Get() Use data["key"] or data.key of the new data class instead.
* Set(value) Use data["key"] = value or data.key = value of the new data class instead.
* Init() Legacy var migration moved to data class. Use data:Migrate() of the new data class and New(), NewAccountWide() and NewCharacterIdSettings() instead.
* GetLibAddonMenuSetting(addon) Use data:GetLibAddonMenuSetting() of the new data class instead.

Version 2
- Fix bug where account wide settings overwrite character settings when toggling in LAM2