Thread Tools Display Modes
03-22-24, 09:25 AM   #1
Codger
An Aku'mai Servant
AddOn Author - Click to view addons
Join Date: Mar 2021
Posts: 30
Saved variables not working

I've created a very simple addon to see how saved variables work but the saved variables are not working.
Here is what I have so far:

My .toc file:

Lua Code:
  1. ## Title: MyAddon
  2. ## Interface: 100206
  3. ## Version: 1.0
  4. ## Author:
  5. ## Notes: A simple WoW addon using a database
  6. ## SavedVariablesPerCharacter: MyAddonDb
  7. MyAddon.lua

and my lua code is:

Lua Code:
  1. -- Create a saved variable to store last time
  2. local lastLogoffTime = nil
  3.  
  4. -- Create a new frame
  5. local frame = CreateFrame("Frame")
  6.  
  7. -- Load last logoff time from saved variable
  8. local function LoadLastLogoffTime()
  9.     if MyAddonDB then
  10.         lastLogoffTime = MyAddonDB.lastLogoffTime
  11.         print("Last logoff time loaded:", lastLogoffTime)
  12.     else
  13.         print("Trying to load logoff time but MyAddonDB is nil.")
  14.     end
  15. end
  16.  
  17. -- Save last time to saved variable
  18. local function SaveLastLogoffTime(time)
  19.     if not MyAddonDB then
  20.         print("Trying to save logoff time but MyAddonDB is nil")
  21.     else
  22.         MyAddonDB.lastLogoffTime = time
  23.     end
  24. end
  25.  
  26. -- Hook the Logout event to update last logoff time
  27. frame:RegisterEvent("PLAYER_LOGIN")
  28. frame:RegisterEvent("PLAYER_LOGOUT")
  29. frame:SetScript("OnEvent", function(self, event)
  30.     if event == "PLAYER_LOGIN" then
  31.         if not MyAddonDB then
  32.             MyAddonDB = {}
  33.             print ("MyAddonDB was nil")
  34.         end
  35.         LoadLastLogoffTime()
  36.     elseif event == "PLAYER_LOGOUT" then
  37.         SaveLastLogoffTime()
  38.     end
  39. end)
  40.  
  41. -- Slash command handler function
  42. local function SlashCommandHandler(msg)
  43.     LoadLastLogoffTime()
  44. end
  45.  
  46. -- Register slash command
  47. SLASH_MYADDON1 = "/myaddon"
  48. SlashCmdList["MYADDON"] = SlashCommandHandler

When I login I see these messages:
My AddonDB was nil
Lastlogofftimeloaded: nil

and after logging out, the contents of the saved variable file 'MyAddon.lua' is:
MyAddonDb = nil

I've looked at so many posts but can't seem to figure out what I'm doing wrong.
I've logged out of my character and deleted the WTF saved variables file - didn't help.
I've restarted my computer in case the file was somehow preventing writing but no help.
I appreciate any help you can provide.
  Reply With Quote
03-22-24, 09:33 AM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,879
Code:
MyAddonDB.lastLogoffTime = time
Should probably be
Code:
MyAddonDB.lastLogoffTime = time()
for the time function rather than a non-existant variable because you're not passing anything to SaveLastLogoffTime (and if you were it would just be time() presumably.

That and lua is case sensitive. MyAddonDb in the .toc is not the same as MyAddonDB in the code.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 03-22-24 at 09:38 AM.
  Reply With Quote
03-22-24, 09:53 AM   #3
Codger
An Aku'mai Servant
AddOn Author - Click to view addons
Join Date: Mar 2021
Posts: 30
Saved variables work now

Thank you Fizzlemizz!!
I changed the time to a date function and renamed the db file in the toc.

Here is the final code, toc file first:
Lua Code:
  1. ## Title: MyAddon
  2. ## Interface: 100206
  3. ## Version: 1.0
  4. ## Author:
  5. ## Notes: A simple WoW addon using a database
  6. ## SavedVariablesPerCharacter: MyAddonDB
  7. MyAddon.lua

Lua Code:
  1. -- Create a saved variable to store last time
  2. local lastLogoffTime = nil
  3.  
  4. -- Create a new frame
  5. local frame = CreateFrame("Frame")
  6.  
  7. -- Load last logoff time from saved variable
  8. local function LoadLastLogoffTime()
  9.     if MyAddonDB then
  10.         lastLogoffTime = MyAddonDB.lastLogoffTime
  11.         print("Last logoff time loaded:", lastLogoffTime)
  12.     else
  13.         print("Trying to load logoff time but MyAddonDB is nil.")
  14.     end
  15. end
  16.  
  17. -- Save last time to saved variable
  18. local function SaveLastLogoffTime(time)
  19.     if not MyAddonDB then
  20.         print("Trying to save logoff time but MyAddonDB is nil")
  21.     else
  22.         MyAddonDB.lastLogoffTime = date("%m/%d/%y %H:%M:%S")
  23.     end
  24. end
  25.  
  26. -- Hook the Logout event to update last logoff time
  27. frame:RegisterEvent("PLAYER_LOGIN")
  28. frame:RegisterEvent("PLAYER_LOGOUT")
  29. frame:SetScript("OnEvent", function(self, event)
  30.     if event == "PLAYER_LOGIN" then
  31.         if not MyAddonDB then
  32.             MyAddonDB = {}
  33.             print ("MyAddonDB was nil")
  34.         end
  35.         LoadLastLogoffTime()
  36.     elseif event == "PLAYER_LOGOUT" then
  37.         SaveLastLogoffTime()
  38.     end
  39. end)
  40.  
  41. -- Slash command handler function
  42. local function SlashCommandHandler(msg)
  43.     LoadLastLogoffTime()
  44. end
  45.  
  46. -- Register slash command
  47. SLASH_MYADDON1 = "/myaddon"
  48. SlashCmdList["MYADDON"] = SlashCommandHandler
  Reply With Quote
03-22-24, 10:06 AM   #4
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,879
Saving
Code:
MyAddonDB.lastLogoffTime = date("%m/%d/%y %H:%M:%S")
just saves a string of "03/23/24 03:03:38"

No very useful in future if you just want the date part or just the time part (having to slice up a string).
Probably better saving as
Code:
MyAddonDB.lastLogoffTime = date()
And you can do the formatting when you display whatever part(s).
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-22-24, 10:13 AM   #5
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,879
As an aside, all addons and the Blizzard UI share the same global table so any variable that will be global like frame names and SaveVariable names should be unique. Blizzard will use "common" names so addons should use things like prefixing with the addon name.

Saying this because MyAddonDB might be unknowingly used by any first time addon author that doesn't know.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-22-24, 10:33 AM   #6
Codger
An Aku'mai Servant
AddOn Author - Click to view addons
Join Date: Mar 2021
Posts: 30
Here is updated code for the Saved Variables example

Thank you Fizzlemizz. Those are both very good points and I appreciate your thoughtful replies.
This code has been modified to use a unique database name and a more generic form of the date function.
I might have overdone the db name a little bit, but it makes a good point.

Here is the saved variables toc file:
Lua Code:
  1. ## Title: MyAddon
  2. ## Interface: 100206
  3. ## Version: 1.0
  4. ## Author:
  5. ## Notes: A simple WoW addon using a database
  6. ## SavedVariablesPerCharacter: MyAddonDBExampleMarch2024 --must be unique
  7. MyAddon.lua

Here is the saved variables lua file:
Lua Code:
  1. -- Create a saved variable to store last time
  2. local lastLogoffTime = nil
  3.  
  4. -- Create a new frame
  5. local frame = CreateFrame("Frame")
  6.  
  7. -- Load last logoff time from saved variable
  8. local function LoadLastLogoffTime()
  9.     if MyAddonDBExampleMarch2024 then
  10.         lastLogoffTime = MyAddonDBExampleMarch2024.lastLogoffTime
  11.         print("Last logoff time loaded:", lastLogoffTime)
  12.     else
  13.         print("Trying to load logoff time but MyAddonDBExampleMarch2024 is nil.")
  14.     end
  15. end
  16.  
  17. -- Save last time to saved variable
  18. local function SaveLastLogoffTime()
  19.     if not MyAddonDBExampleMarch2024 then
  20.         print("Trying to save logoff time but MyAddonDBExampleMarch2024 is nil")
  21.     else
  22.         MyAddonDBExampleMarch2024.lastLogoffTime = date()
  23.     end
  24. end
  25.  
  26. -- Hook the Logout event to update last logoff time
  27. frame:RegisterEvent("PLAYER_LOGIN")
  28. frame:RegisterEvent("PLAYER_LOGOUT")
  29. frame:SetScript("OnEvent", function(self, event)
  30.     if event == "PLAYER_LOGIN" then
  31.         if not MyAddonDBExampleMarch2024 then
  32.             MyAddonDBExampleMarch2024 = {}
  33.             print ("MyAddonDBExampleMarch2024 was nil")
  34.         end
  35.         LoadLastLogoffTime()
  36.     elseif event == "PLAYER_LOGOUT" then
  37.         SaveLastLogoffTime()
  38.     end
  39. end)
  40.  
  41. -- Slash command handler function
  42. local function SlashCommandHandler(msg)
  43.     LoadLastLogoffTime()
  44. end
  45.  
  46. -- Register slash command
  47. SLASH_MYADDON1 = "/myaddon"
  48. SlashCmdList["MYADDON"] = SlashCommandHandler

One more question, if I had an extremely unique database name that was 50 or 60 characters long, how could I set up an alias?
Something like a local variable defined at the top and set in event PLAYER_LOGIN?
  Reply With Quote
03-22-24, 10:38 AM   #7
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,879
After the gobal has been created you can alway do

Code:
local db = MyVeryLongGlobaVariableName
When using tables, making changes to the local eg.

Code:
db.SomeVariable = "SomeThing New"
Will change the entry in the MyVeryLongGlobaVariableName table.

With other simple types (strings, numbers etc.) changing the local variable won't change the global.

Global names don't have to be uber long, just unique. The addon (folder) name will always be unique (or acronym with something like _DATA after it.)

locals are scope restricted so a local defined in anything the ends with an END (if, function etc.) will only be available in that scope.
Code:
local a = 2
print(a) -- prints 2
if 1 == 1 then
    print(a) -- prints 2
    local a = 3
    print(a) -- prints 3
end
print(a) -- prints 2, back to original "scope"
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 03-22-24 at 10:48 AM.
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » Saved variables not working


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off