Click Counter Lua Tutorial
From ESOUI Wiki
Tutorial for Creating Lua Addons
Lua is the scripting language addons use to work with ESO.
A double dash (--) creates a comment in Lua.
-- This is a comment. Be sure to use comments a lot, and get used to reading them :)
Scripting is not trivial. Use your references extensively and frequently. Also, be prepared to spend some time troubleshooting.
1) Create a directory in %UserProfile%\My Documents\Elder Scrolls Online\live\AddOns\
The name of the directory you create is used as the name of the addon. Let us use ClickCounter for our tutorial
2) In your newly created addon directory, Create a text file named ClickCounter.txt
The game reads this text file collect information about your addon, such as title, version, dependencies, etc... be sure the name of the text file matches the addons name (directory)
3) Create another text file named ClickCounter.lua in the same folder.
Although this doesn't have to match, because we reference it in the text file, it is best practice for simplicity's sake to name the .lua file and the .txt file the same. Larger addons may use multiple components, each with their own .lua file.
4) Create your addons informational table of contents in ClickCounter.txt by entering the information. (example below)
At minimum, you need to include the API version the addon is made for, and what files the addon needs to load. It is standard to include any additional information here, such as description, version number, credits etc... Anything starting with semicolon (;) in the text file is a comment.
.txt tutorial example
## APIVersion: 100009 ## Title: Click Counter ## Description: Counts how many times you click ## Version 1.0.0 ## SavedVariables: ClickCounter100SaveData ; this is a comment ClickCounter.lua
At this point, if you reload the game's UI by typing /reloadui in the chat window and then open up the main game menu (hit esc), and select the "AddOns" button, you should see the AddOn manager panel pop up and it will contain your AddOn's name and description.
Now it's time to add a little functionality to the addon. We're just going to make a simple window frame with some text on it that updates on click.
WARNING: Never use the OnUpdate event. It runs every time the screen is redrawn (60 times at 60 frames per second). This is extremely inefficient, and will make your addon unnecessarily use huge amounts of CPU resources, resulting in a drop in overall performance, and especially FPS. However, when it is the only option, such as when you are interacting with objects that do not have an event for them (harvest nodes is a prime example), then get out of it as soon as possible or use the second value to only use it every x seconds.
5) Open up the lua file you created, with any text editor, and create the script. Here's an example. I highly encourage you to write it out for yourself. This will give you good practice, and help you learn.
--AUTHORS COMMENTS -- Click Counter for ESO -- Counts how many times you've clicked. -- Written by me on May 11th, 2014! -- Don't copy and paste my script, write your own. It will help you learn. :) -- It is best practice to always write a function before a call to that function -- This can be confusing at first, but is a key point to remember. -- -- File structure is generally as follows -- 1) Authors comments -- 2) Declaration of variables and constants to be accessible throughout this file -- 3) Functions (blocks of code) -- 4) Event hooks -- 5) Slash command registration -- 6) EOF (end of file) -- VARIABLE DECLARATION -- These will be usable throughout the whole file -- BE SURE to state local so they cannot be overwritten by another file (such as another addon) local tlw = nil -- this may seem odd, but it sets the access level for "tlw" local wm = GetWindowManager() -- we want to use whatever window manager the game is local strformat = string.format -- shortcut local round = zo_round -- shortcut local lblCounter = nil -- set access level for the label to display our counter local ClickedCount = 0 -- start off with the counter at 0 -- FUNCTIONS -- Quick notes about how the UI works -- TopLevelWindow acts as a frame for you to work in -- Make sure to create a backdrop for the frame, so there is something to see! -- The information for controls (such as setDimensions) are available on this wiki. -- Refer to your references on an extremely frequent basis! --lets make a function to run when the frame gets clicked local function tlwClicked() -- increment the counter by one ClickedCount = ClickedCount + 1 -- update the label lblCounter:SetText("Click Counts: "..ClickedCount) -- the .. joins the text and number for display -- we create the GUI (with label) below -- end the function end -- this function will be triggered when the addon is loaded. -- again remember to use local to protect your UI -- note that the addon is loading, not loaded yet, and neither is most of the UI, so debugging is tricky. local function loadCC() -- Initialize UI -- first, let us make our frame -- no local here, because it was already declared above, so it can be accessed anywhere in the file tlw = wm:CreateTopLevelWindow("ccTLW") -- set the properties of the TopLevelWindow (see references for info) tlw:SetDimensions(450,600) tlw:SetResizeToFitDescendents(true) tlw:SetAnchor(CENTER, GuiRoot, CENTER, 0,0) tlw:SetMovable(true) -- don't forget to enable the mouse! XD tlw:SetMouseEnabled(true) -- this tells the addon to run the tlwClicked function whenever the frame is clicked. -- More on events below, and in references. tlw:SetHandler("OnClicked", tlwClicked) -- now the backdground (backdrop) for the frame -- local, because we have no reason to access it again local bdBackdrop = wm:CreateControl("bdBackDrop", tlw, CT_BACKDROP) bdBackDrop:SetEdgeColor(0.4,0.4,0.4) bdBackDrop:SetCenterColor(0.1,0.1,0.1) bdBackDrop:SetAnchor(TOPLEFT, tlw, TOPLEFT, 0, 0) bdBackDrop:SetDimensions(450,600) bdBackDrop:SetAlpha(1) bdBackDrop:SetDrawLayer(0) -- now a label, so we can display the information -- not local, because it is declared above, so we can modify it later lblCounter = wm:CreateControl("lblCounter", tlw, CT_LABEL) lblCounter:SetColor(0.8, 0.8, 0.8, 1) lblCounter:SetFont("ZoFontAlert") lblCounter:SetScale(1) lblCounter:SetWrapMode(TEX_MODE_CLAMP) lblCounter:SetDrawLayer(1) lblCounter:SetText("Click Counts: 0") lblCounter:SetAnchor(CENTER, GuiRoot, CENTER, 0,0) lblCounter:SetDimensions(200,25) -- that's all we need for now, so let's stop waiting for the addon to load -- this step is very important for optimization. the addon can't load after it's already loaded, -- so we free up the event hook, and everything associated with it -- we will register the hook in the next section EVENT_MANAGER:UnregisterForEvent("Click Counter", EVENT_ADD_ON_LOADED) -- and end the init function end -- create a function to handle our slash command. -- we'll register the command later local function slashHandler() local VariableValue = 5 -- Edit by Mitsarugi ,Variable usage in debug messages -- simply print a debug statement d("Clickety is not a mouse click. No cheating!" .. VariableValue) -- Edit by Mitsarugi ,Variable usage in debug messages -- the game UI is loaded by this point, so you should see it in your chat box -- end the function end --declared a variable used as a switch to turn window display ON & OFF local IsHidden = true local function ShowWindow() --If Switch is true if IsHidden == true then --Show window tlw:SetHidden(false) IsHidden = false --or else else --hide window tlw:SetHidden(true) IsHidden = true end end --Height & Width slash commands local H = 766 local W = 766 local function WindowSizeHeight(Height) H = Height tlw:SetDimensions(H,W) bdBackDrop:SetDimensions(H,W) end local function WindowSizeWidth(Width) W = Width tlw:SetDimensions(H,W) bdBackDrop:SetDimensions(H,W) end --EVENT HOOKS -- now we need to get our init function to run when the addon is loaded -- this is called event hooking -- there is an event handler in the game, which we can tell to run our code when an event happens. -- we do this by registering our functions with the eventmanager -- Load Event -- We unregistered this at the end of the loadCC function for optimization. -- Here we register it (after all the functions). EVENT_MANAGER:RegisterForEvent("Click Counter", EVENT_ADD_ON_LOADED, loadCC) EVENT_MANAGER:RegisterForEvent("Click Counter Click", EVENT_GLOBAL_MOUSE_DOWN, tlwClicked) -- Edit by Mitsarugi, addon wont work without this line of code --SLASH COMMAND REGISTRATION -- simply add our slash command to the list, and tell it which function to run SLASH_COMMANDS["/click"] = slashHandler -- Edit by Mitsarugi, an "S" was missing at SLASH_COMMANDS making the addon display an error SLASH_COMMANDS["/showw"] = ShowWindow -- Edit by Mitsarugi, added a new slash command example --Type /wsh<space><value> SLASH_COMMANDS["/wsh"] = WindowSizeHeight -- Edit by Mitsarugi, added a new slash command example --Type /wsw<space><value> SLASH_COMMANDS["/wsw"] = WindowSizeWidth -- Edit by Mitsarugi, added a new slash command example --EOF
It is as simple as that. Good luck! :)
http://wiki.esoui.com/UI_XML (information on UI controls/pieces)
http://wiki.esoui.com/API (information on the API)
http://wiki.esoui.com/Globals (constants and globals)