Writing simple addon for The Elder Scrolls Online


World of Warcraft, The Elder Scrolls Online and many other games allow users to write scripts to modify and extend the user interface of the game. This is allowed, because the underlying logic is not being changed nor abused. Abusing the underlying logic would be cheating (if you want more about this, check one of my previous presentations about exactly this topic).

In this tutorial we’re going to build an addon, that writes to the console how much experience your character got.

Minimal Setup

Each addons consists atleast of:
1. a .txt file containing addons metadata like the name, stored variables, dependencies etc.

2. a .lua file containing code for the addon

You can add more files, like resources, definitions of UI elements (in a .xml file) but this is the minimal setup for our addon.

Let’s begin

First create directory for your addon in your Addons directory and create 3 files in it. Since my addon is called CombatXP, I’m gonna create 2 files in a directory CombatXP:
1. CombatXP.txt
2. CombatXP.lua


CombatXP.txt is the Manifest File of your addon and it contains the metadata about the addon, a list of files

## This Add-on is not created by, affiliated with or sponsored by ZeniMax Media Inc. or its affiliates.
## The Elder Scrolls® and related logos are registered trademarks or trademarks of ZeniMax Media Inc. in the United States and/or other countries.
## All rights reserved
## You can read the full terms at https://account.elderscrollsonline.com/add-on-terms

## Title: CombatXP
## APIVersion: 100021
## Author: Mikolaj Wawrzyniak


We have to include disclaimer about Zenimax, then we specify our metadata and list of files used by our addon.

Remember, if the APIVersion is lower than the current APIVersion of the game, your addon will be listed as “Out of Date” in menu.


Let’s get some real coding done!

Let’s create our addons namespace, a variable for the name of our addon and get current amount of experience points of our character.

CombatXP = {}
CombatXP.name = "CombatXP"

CombatXP.currentXP = GetUnitXP('player')

This is how easy it is to get the current value of any stat in ESO.

Next we have to create a function, that will be called everytime our addon loads.
In this function we’re going to register something called event handler. EventHandler reacts to events emmited by the game and acts on them.

function CombatXP:Initialize()
    EVENT_MANAGER:RegisterForEvent(self.name, EVENT_EXPERIENCE_UPDATE, self.onPlayerExperienceGained)

We register our addon (self.name) for event called EVENT_EXPERIENCE_UPDATE
and call a function onPlayerExperienceGained in reaction to this event.

But hold up! We need to implement onPlayerExperienceGained.

function CombatXP.onPlayerExperienceGained(event, unitTag, currentExp, maxExp, reason)

    if ( unitTag ~= 'player' ) then return end
       local xp_gained = currentExp - CombatXP.currentXP
       local percent_to_next_level = (currentExp / maxExp) * 100
       local percent_to_next_as_string = string.sub(tostring(percent_to_next_level),0,2) .. "%"
       local current_gain_in_percent = (xp_gained / maxExp) * 100
       local current_gain_in_percent_as_string = string.sub(tostring(current_gain_in_percent),0,4) .. "%"
       CHAT_SYSTEM:AddMessage(tostring(xp_gained) .. " experience gained! " .. percent_to_next_as_string)
       CombatXP.currentXP = currentExp



Our function takes 5 arguments:
* event
* unitTag
* currentExp
* maxExp
* reason

All of them are provided by our event manager.

We check if this event is caused by the player. If not, we return from the function.
After that we calculate experience gained, how much experience we need for next level etc. and then output it to the console.

Adding messages to the console is very simple – we just call CHAT_SYSTEM::AddMessage and write our message.

Looks like we have everything we need..No! We have to register our addon to call the initialize function after the addon gets loaded by the game.

function CombatXP.OnAddOnLoaded(event, addonName)
  if addonName == CombatXP.name then



EVENT_MANAGER:RegisterForEvent(CombatXP.name, EVENT_ADD_ON_LOADED, CombatXP.OnAddOnLoaded)


That’s it. You just learned how to use basic functions from the ESO UI api. Next thing you could try is to create UI elements and store their position in “Stored Variable”.

Comments are closed, but trackbacks and pingbacks are open.