Thread Tools Display Modes
05/29/17, 07:44 PM   #1
Crabby654
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 19
Saved Variable error I am running into

So I am in the process of re-writing the old ESO Toolbox addon. Basically I want to simplify the addon and add more options to the settings menu to change more CVars. But in the process of changing some names around I got an error regarding saved variables, I think.

Here is the error:
Code:
EsoUI/Libraries/Utility/ZO_SavedVars.lua:139: Can only apply saved variables to a table stack traceback:
[C]: in function 'error'
EsoUI/Libraries/Utility/ZO_SavedVars.lua:139: in function 'GetNewSavedVars' (tail call): ?
user:/AddOns/ExtendedOptions/ExtendedOptions.lua:345: in function 'OnLoaded'
I'm fairly new when it comes to bigger addons that have saved variables so I really am having an issue finding how to fix this.

Here is the current code for the addon:

ExtendedOptions.lua
Code:
local panel = {
		type = 'panel',
		name = 'Extended Options',
		displayName = 'Extended Options',
		author = 'Crabby654',
		version = '1.0.0',
		slashCommand = '/eoptions',
		registerForRefresh = true,
		registerForDefaults = true,
	}

local LAM = LibStub('LibAddonMenu-2.0')
local ExtendedOptions_SavedVars = ExtendedOptions_SavedVars or {}
local restartRequired = '|t16:16:/esoui/art/progression/lock.dds|t You have to restart the game for these changes to take effect.';

local serverbuild = 'live'

if GetCVar('LastRealm') == 'EU Megaserver' then
	serverbuild = 'liveeu'
elseif GetCVar('LastRealm') == 'PTS' then
	serverbuild = 'pts'
end

local eosettings = {
	autoperf = false,
	targetfps = 30,
	timestampchat = false,
	allowbigchat = false,
	hitindicator = false,
	hidefriends = false,
}

local lastframes = {}
local frameindex = 0
local numframes = 0
local statframes = 10

local handlerhook
local chatwidth
local friendshook
local friendsonline = 0

local optionsTable = {
	{
		type = 'header',
		name = 'Performance',
		width = 'full',
	},
	{
		type = 'description',
		text = 'These settings allow you to improve the game\'s performance while trying to keep the noticeable impact at a minimum. This section is experimental. If you\'re running into issues, disable the options and reset your graphic settings.',
		width = 'full',
	},
	{
		type = 'checkbox',
		name = 'Auto-adjust my graphic settings',
		getFunc = function()
				return eosettings.autoperf
			end,
		setFunc = function(value)
				eosettings.autoperf = value
				if eosettings.autoperf then
					EVENT_MANAGER:RegisterForUpdate("ExtendedOptions_Update", 1000, OnUpdate)
				end
			end,
		default = false,
	},
	{
		type = 'dropdown',
		name = 'Target framerate',
		choices = {'144 fps', '120 fps', '100 fps', '60 fps', '45 fps', '30 fps', '15 fps'},
		getFunc = function()
				return eosettings.targetfps .. ' fps'
			end,
		setFunc = function(value)
				eosettings.targetfps = tonumber(value:match('%d+'))
			end,
		disabled = function()
				return not eosettings.autoperf
			end,
		width = 'full',
		default = '30 fps',
	},
	{
		type = 'header',
		name = 'Chat Settings',
		width = 'full',
	},
	{
		type = 'description',
		text = 'These settings override and extend the default chat window behavior.',
		width = 'full',
	},
	{
		type = 'checkbox',
		name = 'Timestamp my chat log',
		getFunc = function()
				return eosettings.timestampchat
			end,
		setFunc = function(value)
				eosettings.timestampchat = value
			end,
		default = false,
	},
	{
		type = 'checkbox',
		name = 'Allow bigger chat box',
		getFunc = function()
				return eosettings.allowbigchat
			end,
		setFunc = function(value)
				if value then
					CHAT_SYSTEM.maxContainerWidth = 2 * chatwidth
				else
					CHAT_SYSTEM.maxContainerWidth = chatwidth
				end
				eosettings.allowbigchat = value
			end,
		default = false,
	},
	{
		type = 'checkbox',
		name = 'Fade out the number of online friends',
		tooltip = 'This option restores the classic behavior (before 1.6), where the number of online friends would only be shown while the chat window is visible.',
		getFunc = function()
				return eosettings.hidefriends
			end,
		setFunc = function(value)
				eosettings.hidefriends = value
				if eosettings.hidefriends then
					CHAT_SYSTEM.friendsButton:SetInheritAlpha(true)
					CHAT_SYSTEM.friendsLabel:SetInheritAlpha(true)
				else
					CHAT_SYSTEM.friendsButton:SetInheritAlpha(friendsonline == 0)
					CHAT_SYSTEM.friendsLabel:SetInheritAlpha(friendsonline == 0)
				end
			end,
		default = false,
	},
	{
		type = 'header',
		name = 'Misc Settings',
		width = 'full',
	},
	{
		type = 'description',
		text = 'The following settings aren\'t availalbe in the standard game UI. They\'re either hidden or new and provided by this addon.',
		width = 'full',
	},
	{
		type = 'checkbox',
		name = 'Skip logos on game start',
		getFunc = function()
				return GetCVar('SkipPregameVideos') == '1'
			end,
		setFunc = function(value)
				if value then
					SetCVar('SkipPregameVideos', '1');
				else
					SetCVar('SkipPregameVideos', '0');
				end
			end,
		default = false,
	},
	{
		type = 'dropdown',
		name = 'Screenshot format',
		choices = {'PNG', 'BMP', 'JPG'},
		getFunc = function()
				return GetCVar('ScreenshotFormat.2')
			end,
		setFunc = function(value)
				SetCVar('ScreenshotFormat.2', value)
			end,
		width = 'full',
		default = 'PNG',
	},
	{
		type = 'header',
		name = 'Troubleshooting',
		width = 'full',
	},
	{
		type = 'description',
		title = '|cff0000Warning:',
		text = '|cff4444Incorrect or incompatible settings might prevent you from starting the game again. If that happens to you, you can delete the following file to restore the default behavior:',
		width = 'full',
	},
	{
		type = 'description',
		title = '|cff8888Windows:',
		text = '|cff4444<Documents>\\Elder Scrolls Online\\' .. serverbuild .. '\\UserSettings.txt',
		width = 'full',
	},
	{
		type = 'description',
		title = '|cff8888MacOS X:',
		text = '|cff4444~/Elder Scrolls Online/' .. serverbuild .. '/UserSettings.txt',
		width = 'full',
	},
	{
		type = 'description',
		text = zo_strformat('|cff0000Removing this addon will not revert any changes you\'ve made on this page. Please use the clickable link |cff4444<<1>>|cff0000 below instead, before removing the addon!', GetString(SI_OPTIONS_DEFAULTS)),
		width = 'full',
	},
	{
		type = 'description',
		title = 'Rendering Engine',
		text = 'By default, ESO will try to use DirectX 11, if available. Some cards offer better performance when running in DirectX 9 mode. If you\'re playing on Linux or you\'re running into issues, try using OpenGL.',
		width = 'full',
	},
	{
		type = 'dropdown',
		name = 'Rendering engine to be used',
		choices = {'DirectX 9', 'DirectX 11', 'OpenGL', 'Let the game decide'},
		getFunc = function()
				local v = GetCVar('GraphicsDriver.7')
				if v == 'D3D11' then
					return 'DirectX 11'
				elseif v == 'D3D9' then
					return 'DirectX 9'
				elseif v == 'OPENGL' then
					return 'OpenGL'
				else
					return 'Let the game decide'
				end
			end,
		setFunc = function(value)
				if value == 'DirectX 11' then
					SetCVar('GraphicsDriver.7', 'D3D11')
				elseif value == 'DirectX 9' then
					SetCVar('GraphicsDriver.7', 'D3D9')
				elseif value == 'OpenGL' then
					SetCVar('GraphicsDriver.7', 'OPENGL')
				else
					SetCVar('GraphicsDriver.7', '')
				end
			end,
		width = 'full',
		warning = restartRequired,
		default = '',
	},
	{
		type = 'description',
		title = 'Multithreading and Freezes',
		text = 'While ESO tries to utilize modern multi-core CPUs as good as possible, this might cause problems with older processors. Try disabling the following option in case your game freezes or stutters.',
		width = 'full',
	},
	{
		type = 'checkbox',
		name = 'Enable multi-threading features',
		getFunc = function()
				return (GetCVar('RequestedNumJobThreads') == '-1') and (GetCVar('RequestedNumWorkerThreads') == '-1')
			end,
		setFunc = function(value)
				if value then
					SetCVar('RequestedNumJobThreads', '-1');
					SetCVar('RequestedNumWorkerThreads', '-1');
				else
					SetCVar('RequestedNumJobThreads', '0');
					SetCVar('RequestedNumWorkerThreads', '0');
				end
			end,
		default = true,
		warning = restartRequired,
	},
	{
		type = 'description',
		title = 'Expand UI Memory',
		text = 'By default, ESO reserves 64 MB of RAM for addons and UI code. If you\'re using many complex addons you might actually run out of memory.',
		width = 'full',
	},
	{
		type = 'description',
		text = 'LUA UI memory ssage',
		width = 'half',
	},
	{
		type = 'editbox',
		--text = '|ar|cffffff' .. math.ceil(collectgarbage('count') / 1024) .. 'MB/' .. GetCVar('LuaMemoryLimitMB') .. 'MB',
		width = 'half',
		getFunc = function()
				return math.ceil(collectgarbage('count') / 1024) .. 'MB of ' .. GetCVar('LuaMemoryLimitMB') .. 'MB'
			end,
		setFunc = function(value) end,
		disabled = true,
	},
	{
		type = 'description',
		text = 'LUA UI memory limit',
		width = 'half',
	},
	{
		type = 'dropdown',
		--name = 'Lua UI Memory Limit',
		choices = {'64MB', '128MB', '256MB', '512MB'},
		getFunc = function()
				return GetCVar('LuaMemoryLimitMB') .. 'MB'
			end,
		setFunc = function(value)
				SetCVar('LuaMemoryLimitMB', value:gsub('MB', ''));
			end,
		default = '64MB',
		warning = 'Reserving too much memory for the game UI might have negative impact on your game performance. Only do so if you really have to.\n\n' .. restartRequired,
		width = 'half',
	}
}

local function OnUpdate()
	if not eosettings.autoperf then
		EVENT_MANAGER:UnregisterForUpdate('ExtendedOptions_Update')
		return
	end
	lastframes[frameindex + 1] = GetFramerate()
	frameindex = (frameindex + 1) % statframes
	if numframes < statframes then
		numframes = numframes + 1
		return
	end

	local avg = 0
	for i = 1, statframes do
		avg = avg + lastframes[statframes]
	end
	avg = avg / statframes
	
	local viewdistance = GetCVar('VIEW_DISTANCE')
	
	if avg < eosettings.targetfps * 0.9 then
		viewdistance = zo_max(0.5, viewdistance * 0.975)
	elseif avg > eosettings.targetfps * 1.05 then
		viewdistance = zo_min(2, viewdistance * 1.1)
	end
	
	SetCVar('VIEW_DISTANCE', viewdistance)
end

local function OnLoaded(code, name)
	if name ~= 'ExtendedOptions' then return end
	EVENT_MANAGER:UnregisterForEvent('ExtendedOptions_Loaded', EVENT_ADD_ON_LOADED)

	LAM:RegisterAddonPanel('ExtendedOptions', panel)
	LAM:RegisterOptionControls('ExtendedOptions', optionsTable)

	eosettings = ZO_SavedVars:NewAccountWide('ExtendedOptions', 1, nil, eosettings)
	
	handlerhook = ZO_ChatSystem_GetEventHandlers()[EVENT_CHAT_MESSAGE_CHANNEL]
	ZO_ChatSystem_AddEventHandler(EVENT_CHAT_MESSAGE_CHANNEL, function(...)
		if eosettings.timestampchat then
			return '|c707070[' .. GetTimeString() .. ']|r ' .. handlerhook(...)
		else
			return handlerhook(...)
		end
	end)
	
	friendshook = CHAT_SYSTEM.OnNumOnlineFriendsChanged
	CHAT_SYSTEM.OnNumOnlineFriendsChanged = function (self, numFriends)
		friendshook(self, numFriends)
		friendsonline = numFriends
		if eosettings.hidefriends then
			CHAT_SYSTEM.friendsButton:SetInheritAlpha(true);
			CHAT_SYSTEM.friendsLabel:SetInheritAlpha(true);
		end
	end
	if eosettings.hidefriends then
		CHAT_SYSTEM.friendsButton:SetInheritAlpha(true);
		CHAT_SYSTEM.friendsLabel:SetInheritAlpha(true);
	end
	
	if eosettings.autoperf then
		EVENT_MANAGER:RegisterForUpdate('ExtendedOptions_Update', 1000, OnUpdate)
	end
	
	chatwidth = CHAT_SYSTEM.maxContainerWidth
	
	if eosettings.allowbigchat then
		CHAT_SYSTEM.maxContainerWidth = 2 * chatwidth
	end
end

EVENT_MANAGER:RegisterForEvent("ExtendedOptions_Loaded", EVENT_ADD_ON_LOADED, OnLoaded)
ExtendedOptions.txt
Code:
## Title: Extended Options
## Author: Crabby654
## Version: 1.0.0
## Description: Allows you to adjust otherwise hidden settings for the game. Type /eoptions for the settings window.
## SavedVariables: ExtendedOptions
## APIVersion: 100019

lib/LibStub/LibStub.lua
lib/LibAddonMenu-2.0/LibAddonMenu-2.0.lua

ExtendedOptions.lua
Any help or tweaks would be much appreciated. I plan on removing a couple more things like the adaptive graphics settings, but I want to add more dropdowns for more variables in the usersettings file.
  Reply With Quote
05/30/17, 08:28 AM   #2
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
Hi Crabby654,

the reason is indeed a bit tricky.
It has to do with that you name several things "ExtendedOptions". The error says, that the given global name "ExtendedOptions" is not a table = not a saved variable.
What one needs to know is, that LAM gives the settings panel the global name you use for register.
And now look at the name.
  Reply With Quote
05/30/17, 02:49 PM   #3
Crabby654
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 19
Originally Posted by votan View Post
Hi Crabby654,

the reason is indeed a bit tricky.
It has to do with that you name several things "ExtendedOptions". The error says, that the given global name "ExtendedOptions" is not a table = not a saved variable.
What one needs to know is, that LAM gives the settings panel the global name you use for register.
And now look at the name.
Oh alrighty, I'll take a look through it now! Oddly enough, I did butcher another addon and replaced all the XXXXname with ExtendedOptions, yet that addon didn't get the error before I did the swap. Hmm. Looking now!
  Reply With Quote
06/01/17, 04:10 PM   #4
Crabby654
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 19
Alrighty I fixed that issue!

There is something else that has me a bit concerned. Now I pulled this bit of code from another addon to display the old way the friend number would fade out. However there appears to be an erroneous ( in 2 places. I would really appreciate it if anyone could tell me if this makes sense since one of the ) is after an "end".

Code:
	handlerhook = ZO_ChatSystem_GetEventHandlers()[EVENT_CHAT_MESSAGE_CHANNEL]
	ZO_ChatSystem_AddEventHandler(EVENT_CHAT_MESSAGE_CHANNEL, function(...)
		if esettings.timestampchat then
			return '|c707070[' .. GetTimeString() .. ']|r ' .. handlerhook(...)
		else
			return handlerhook(...)
		end
	end)
The 2 spots I am looking at is the second line: ZO_ChatSystem_AddEventHandler(EVENT_CHAT_MESSAGE_CHANNEL, function(...)
and the 8th (final) line: end)
  Reply With Quote
06/01/17, 06:33 PM   #5
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 409
Originally Posted by Crabby654 View Post
Alrighty I fixed that issue!

There is something else that has me a bit concerned. Now I pulled this bit of code from another addon to display the old way the friend number would fade out. However there appears to be an erroneous ( in 2 places. I would really appreciate it if anyone could tell me if this makes sense since one of the ) is after an "end".

Code:
    handlerhook = ZO_ChatSystem_GetEventHandlers()[EVENT_CHAT_MESSAGE_CHANNEL]
    ZO_ChatSystem_AddEventHandler(EVENT_CHAT_MESSAGE_CHANNEL, function(...)
        if esettings.timestampchat then
            return '|c707070[' .. GetTimeString() .. ']|r ' .. handlerhook(...)
        else
            return handlerhook(...)
        end
    end)
The 2 spots I am looking at is the second line: ZO_ChatSystem_AddEventHandler(EVENT_CHAT_MESSAGE_CHANNEL, function(...)
and the 8th (final) line: end)


I don't see any problems. The end) is matched up with ZO_ChatSystem_AddEventHandler(
ZO_ChatSystem_AddEventHandler is a function, and it's given two parameters here. One is the event. (Likely a number constant) The second one is a function. You're probably more used to making a function in this format: local function doSomething(...) end. However, that's really just Lua syntax sugar for local doSomething = function(...) end. In Lua, functions don't need to have names, and function(...) is a perfectly valid thing to pass to another function. Here's a functionally equivalent version of code:


Code:
local nonAnonymousFunction = function(...)
        if esettings.timestampchat then
            return '|c707070[' .. GetTimeString() .. ']|r ' .. handlerhook(...)
        else
            return handlerhook(...)
        end
    end handlerhook = ZO_ChatSystem_GetEventHandlers()[EVENT_CHAT_MESSAGE_CHANNEL]
    ZO_ChatSystem_AddEventHandler(EVENT_CHAT_MESSAGE_CHANNEL, nonAnonymousFunction)

Hopefully this clears it up a bit, but if not let me know.
  Reply With Quote
06/02/17, 05:55 PM   #6
Crabby654
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 19
That helped a ton thank you! Very helpful
  Reply With Quote

ESOUI » AddOns » AddOn Help/Support » Saved Variable error I am running into


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