As each addon loads, WoW reads its TOC file, then loads all the files listed in its TOC in order (and any files listed in them, in case of XML files, also all in order), then loads its saved variables file(s) if it has any, and then fires an ADDON_LOADED event with the addon's folder name as the first and only argument.
All addons that are not configured to load on demand are loaded before PLAYER_LOGIN fires. Unless your addon is LOD or has a LoadManager, its ADDON_LOADED event will always fire before PLAYER_LOGIN.
You should not use PLAYER_ALIVE or VARIABLES_LOADED or any other events to initialize your addon. If you are sure your addon is not load-on-demand and does not have a LoadManager, you can just do everything in PLAYER_LOGIN, since your ADDON_LOADED event will always fire before PLAYER_LOGIN.
If you are not sure, or you are still having problems, here is a good fool-proof loading process that will work regardless of whether your addon is LOD or has a LoadManager, on both a /reload and on a fresh login:
Code:
local ADDON_NAME = ...
local f = CreateFrame("Frame", "MyAddonFrame")
f:SetScript("OnEvent", function(self, event, ...) return self[event](self, event, ...) end)
-- ^ Generic event dispatcher.
f:RegisterEvent("ADDON_LOADED")
function f:ADDON_LOADED(addon)
if addon ~= ADDON_NAME then
-- Some other addon was loaded, but we don't care.
return
end
-- Initialize your saved variables here.
-- If anything was previously saved, it's now loaded.
-- We don't care about any further addon loading events, so stop listening.
self:UnregisterEvent("ADDON_LOADED")
self.ADDON_LOADED = nil
if IsLoggedIn() then
-- We're already done logging in, probably using a LoadManager.
-- Just call the login event handler manually:
self:PLAYER_LOGIN()
else
-- We're not logged in yet, so wait for that to happen:
self:RegisterEvent("PLAYER_LOGIN")
end
end
function f:PLAYER_LOGIN()
-- Now you can create/setup frames, register other events, do all the things!
-- The login event can't fire twice in a session, so send this handler off to the garbage collector:
self:UnregisterEvent("PLAYER_LOGIN")
self.PLAYER_LOGIN = nil
end