Difference between revisions of "Addons"

From Tales of Maj'Eyal
Jump to: navigation, search
m
 
(26 intermediate revisions by 14 users not shown)
Line 1: Line 1:
[[Category:Development]]
+
[[Category:Development]][[Category:Addons]]
 +
Addons are way for third parties to modify existing modules inside t-engine, as well as publish them in the Steam Workshop. (Here's a non-comprensive [[Addon List]].)  This page covers how you write addons for ToME.
  
As of beta 35 the t-engine has support for addons.  Addons are way for third parties to modify existing modules. 
+
==Intro==
  
===== Capabilities =====
+
You're making an addon. The addon is named "coolstuff". The first thing you do is make a directory "tome-coolstuff" inside your Steam install of ToME. On my mac, that path is:
 +
~/Library/Application Support/Steam/SteamApps/common/TalesMajEyal/game/addons/
  
Addons are capable of three things to modify their parent module
+
And on Windows, it's usually something like
# '''Overloading:''' Overloading is a way to //add new// or //overwrite// files to the parent module.  This the way graphics such as talent icons are added.  Overloading can also add .lua but will replace those with the same name. So typically adding new trees, or overwriting trees. Or adding music and graphics.
+
  C:\Program Files (x86)\Steam\SteamApps\common\TalesMajEyal\game\addons
# '''Superloading:''' Superloading allows you to add completely replace, or add code to the beginning or end of an arbitrary class function. Currently only ActorTalents and ActorTemporaryEffects supports superloading.
+
# '''Data:''' Make new data like talents, NPCs, etc accessible to the game.  This data will still need to be loaded (see hooks below).
+
# '''Hooks:'''  Certain functions are capable of supporting hooks.  When that function is called they will also call whatever is in the hook. Example module shows how the "Actor:takeHit" function is hooked to make the tourist take no damage.  You can also use hooks to load add-on data in to the module, eg. new talents.
+
  
An example addon can be found here: http://te4.org/dl/tmp/tome-example.teaa
+
On Linux, the path is
A .teaa file is simply a renamed zip that contains the whole addon, this way the players do not even have to unzip it!
+
~/.steam/steam/SteamApps/common/TalesMajEyal/game/addons
The example addon illustrate how to add a new class, new talents, new timed effects and how to hook onto a few useful locations in the code.
+
  
 +
Your addons directory should have these files in it already:
 +
tome-addon-dev.teaa
 +
tome-items-vault.teaa
 +
tome-possessors.teaa
  
===== Grammar and Syntax =====
+
If you can't find the directory, search for one of those file names.
* The addon folder must be in the format <nowiki>[ModuleName]-[AddonName]</nowiki>.
+
* The short_name in init.lua must be the same as the module folder's name (excluding the module name).
+
  
  
===== Details about Superloading =====
+
===Getting Started===
  
16:42 DarkGod overload repalces a whole *file*
+
Every addon has an <nowiki>init.lua</nowiki> file. The <nowiki>init.lua</nowiki> file looks like this:
16:42 Reenen ok
+
 
16:42 DarkGod superload is hum ..
+
-- My Cool Addon
16:43 Reenen superload adds to a currently existing function
+
-- tome-coolstuff/init.lua
16:43 DarkGod when the engine wants to load a class; say mod.class.Foo
+
16:43 DarkGod it loads the module's one
+
long_name = "My Awesome Addon"
16:43 DarkGod then it checks each addons if there is a superload for it
+
short_name = "coolstuff" -- Determines the name of your addon's file.
16:43 DarkGod if there is it loads the superload, passing it the existing one
+
for_module = "tome"
16:43 DarkGod there the code can do waht it wants with it
+
version = {1,3,1}
16:44 DarkGod basically you replace a method with your own
+
addon_version = {1,0,0}
16:44 DarkGod and *if* you wish your own method to call the previous one you do it
+
weight = 100 -- The lower this value, the sooner your addon will load compared to other addons.
16:44 DarkGod (and it is a good idea to do so, so taht addons can "chain" superloads)
+
author = {'coolguy@invalid.com'}
 +
homepage = 'iamsocool.geocities.com'
 +
description = [[Oh my god this stuff is so totally cool.
 +
Holy crap I mean it's really super cool, like, wow.
 +
]] -- the [[ ]] things are like quote marks that can span multiple lines
 +
tags = {'cool', "stuff", 'cool stuff'} -- tags MUST immediately follow description
 +
 +
overload = true
 +
superload = false
 +
data = true
 +
hooks = true
 +
 
 +
''addon_version'' is (unsurprisingly) the version of your addon. This is used by the game for automatically downloading addon updates. It's also useful if players want to see which addon version they're currently using. Set it to {1,0,0} initially and increment the value when releasing updates.
 +
 
 +
''version'' is the module (i.e., ToME) version required for the addon. When making a new addon, you should typically set this to the current ToME version. When releasing addon updates, you should modify this value if your addon changes rely on features from a more recent ToME version.
 +
 
 +
Properly setting ''overload'', ''superload'', ''hooks'', and ''data'' is super important, because they determine which directories in your addon will be loaded by the game.
 +
 
 +
===Directory Structure===
 +
 
 +
* '''overload''': Files in this directory will automatically replace files in the base game. This is very powerful but also incredibly dangerous. (Of course, replacing things like icons is less dangerous than replacing code.)
 +
* '''superload''': Files in this directory will be read and executed after the base game's file of the same name. This is very powerful but much less dangerous. This is a great way to add content (like new Artifact items) or tweak content (modify a talent's cost or requirements) without accidentally stepping on other tweaks or future content updates.
 +
* '''data''': Files in this directory will just sit there and be ignored unless you explicitly tell the game to read them. Files in this area live in their own "namespace" and filenames here will never interfere with other addons or the base game. This is a great place to put new classes, talent trees, or races.
 +
* '''hooks''': Only one file in this directory is automatically executed: <nowiki>load.lua</nowiki>. This file is a great way to get your "data" files executed at the proper time. It's also a way to augment some parts of the game which specifically support hooks: the Example module shows how the "Actor:takeHit" function is hooked to make the tourist take no damage.  You can also use hooks to load add-on data in to the module, eg. new talents. Find a list of available hooks [[hooks|here]].
 +
 
 +
The Example addon can be found here: http://te4.org/dl/tmp/tome-example.teaa
 +
 
 +
A .teaa file is simply a renamed zip that contains the whole addon, so feel free to rename and unzip your favorite addon to see a living example of all the stuff discussed in this article. The <nowiki>tome-example.teaa</nowiki> addon illustrates how to add a new class, new talents, new timed effects and how to hook onto a few useful locations in the code. (Note that it's a bit old, though.)  When zipping, make sure to zip the files but not the folder.  For example, tome-addonname.zip/init.lua, not tome-addonname.zip/tome-addonname/init.lua.
 +
 
 +
You can also just put a folder 'tome-addonname' in addons and it will be loaded directly, no need to zip or rename.
 +
 
 +
== Grammar and Syntax ==
 +
* The addon folder must be in the format <nowiki>[ModuleName]-[AddonShortName]</nowiki>. For you, that means <nowiki>tome-coolstuff</nowiki> is your folder name.
 +
 
 +
===Overloading===
 +
Each <nowiki>.teaa</nowiki> file is just a zip file. The main ToME game code is stored in <nowiki>game/modules/tome.team</nowiki>, and it is also just a renamed zip file.
 +
 
 +
Copy <nowiki>tome.team</nowiki> somewhere, rename it to <nowiki>tome-1.1.5.zip</nowiki> and unzip it.
 +
 
 +
You'll see two directories: "data" and "mod". Most of the stuff you'll want to mess with at first is in "data".
 +
 
 +
When you use overload to replace a file, the path and name must match exactly the structure in <nowiki>tome.team</nowiki>. So for example, to replace the types of leather boots in the game, I'd look in the unzipped ToME code and find:
 +
tome-1.1.5/data/general/objects/leather-boots.lua
 +
... and so to overload that, I'd create a file in my addon:
 +
tome-coolstuff/overload/data/general/objects/leather-boots.lua
 +
 
 +
===Superloading===
 +
 
 +
Just like overloading, superloading requires that you know the file structure of the game so you can make your files get read and executed at the right time. When the game reads in your superload file, you can get access to the previous file's contents using the <nowiki>loadPrevious(...)</nowiki> function.
 +
 
 +
For example, if we wanted to add a new boot ego, we could do something like this. First, we'd find the boot ego code:
 +
data/general/objects/egos/light-boots.lua
 +
 
 +
Next, we'd make a file in our <nowiki>superload</nowiki> directory:
 +
tome-coolstuff/superload/data/general/objects/egos/light-boots.lua
 +
 
 +
... and we'd make sure that our <nowiki>init.lua</nowiki> file had the line:
 +
superload = true
 +
 
 +
We're ready to add the boot ego!
  
To load the existing function you should have:
 
<code>
 
 
  local _M = loadPrevious(...)
 
  local _M = loadPrevious(...)
 +
newEntity{
 +
power_source = {arcane=true},
 +
name = " of sensing", suffix=true, instant_resolve=true,
 +
keywords = {sensing=true},
 +
level_range = {1, 50},
 +
rarity = 4,
 +
cost = 2,
 +
wielder = {
 +
see_invisible = resolvers.mbonus_material(20, 5),
 +
see_stealth = resolvers.mbonus_material(20, 5),
 +
blind_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end),
 +
},
 +
}
 
   
 
   
  local base = _M.levelup (or whatever function you are superloading)
+
  return _M
  function _M:levelup(<args>)
+
====Modifying mod Stuff====
-- Do stuff "before" loading the original file
+
 
  base(self, <args>)  -- Loads the original file
+
Hold on, that example still didn't use _M at all! So what is _M for? Since most things in the <nowiki>data</nowiki> directory are stored in easily accessible structures, you don't need _M to get them. _M is generally used for stuff in the <nowiki>mod</nowiki> directory: the most dangerous stuff to modify. Here's an example which modifies the "levelup" function in <nowiki>mod/Actor.lua</nowiki>. Your file for this code should be in <nowiki>/superload/mod/Actor.lua</nowiki>.
  -- Do stuff "after" loading the original file
+
local _M = loadPrevious(...)
  return
+
local base_levelup = _M.levelup
 +
 +
  function _M:levelup()
 +
  -- Do stuff "before" loading the original file
 +
   
 +
  -- execute the original function
 +
  local retval = base_levelup(self)
 +
   
 +
  -- Do stuff "after" loading the original file
 +
   
 +
  -- return whatever the original function would have returned
 +
  return retval
 
  end
 
  end
 
   
 
   
 
  return _M
 
  return _M
</code>
 
 
  
===== Addon MD5 =====
+
Whenever possible, superloaded functions should call the original function rather than replacing it entirely.  This maintains compatibility with other addons.
  
The MD5 is needed for uploading addons to the website.
+
==Uploading your Addon==
Make sure the final addon is in .teaa form and activated, and that cheat mode is off.
+
Start a new character, then exit the game.
+
Open the te4_log.txt and search for md5.
+
  
For those using OSX, there is no te4_log.txt. You might try running T-Engine from the Terminal (in Finder, right-click T-Engine, Show Package Contents, right-click /Contents/MacOS/t-engine and Open With -> Terminal), then follow the directions above. After exiting the game, search for 'md5' in the Terminal window and find the one for your addon.
+
{{:Addon Uploading}}
Note however, that this method does not work for some, as the last character from the md5 may be cut off when using this method. Those running into this problem are able to extract the full md5 by running the game in gdb for mac (Google is your friend) and checking the console after exiting.
+

Latest revision as of 18:54, 14 October 2022

Addons are way for third parties to modify existing modules inside t-engine, as well as publish them in the Steam Workshop. (Here's a non-comprensive Addon List.) This page covers how you write addons for ToME.

Intro

You're making an addon. The addon is named "coolstuff". The first thing you do is make a directory "tome-coolstuff" inside your Steam install of ToME. On my mac, that path is:

~/Library/Application Support/Steam/SteamApps/common/TalesMajEyal/game/addons/

And on Windows, it's usually something like

C:\Program Files (x86)\Steam\SteamApps\common\TalesMajEyal\game\addons

On Linux, the path is

~/.steam/steam/SteamApps/common/TalesMajEyal/game/addons

Your addons directory should have these files in it already:

tome-addon-dev.teaa
tome-items-vault.teaa
tome-possessors.teaa

If you can't find the directory, search for one of those file names.


Getting Started

Every addon has an init.lua file. The init.lua file looks like this:

-- My Cool Addon
-- tome-coolstuff/init.lua

long_name = "My Awesome Addon"
short_name = "coolstuff" -- Determines the name of your addon's file.
for_module = "tome"
version = {1,3,1}
addon_version = {1,0,0}
weight = 100 -- The lower this value, the sooner your addon will load compared to other addons.
author = {'coolguy@invalid.com'}
homepage = 'iamsocool.geocities.com'
description = [[Oh my god this stuff is so totally cool.
Holy crap I mean it's really super cool, like, wow.
]] -- the [[ ]] things are like quote marks that can span multiple lines
tags = {'cool', "stuff", 'cool stuff'} -- tags MUST immediately follow description

overload = true
superload = false
data = true
hooks = true

addon_version is (unsurprisingly) the version of your addon. This is used by the game for automatically downloading addon updates. It's also useful if players want to see which addon version they're currently using. Set it to {1,0,0} initially and increment the value when releasing updates.

version is the module (i.e., ToME) version required for the addon. When making a new addon, you should typically set this to the current ToME version. When releasing addon updates, you should modify this value if your addon changes rely on features from a more recent ToME version.

Properly setting overload, superload, hooks, and data is super important, because they determine which directories in your addon will be loaded by the game.

Directory Structure

  • overload: Files in this directory will automatically replace files in the base game. This is very powerful but also incredibly dangerous. (Of course, replacing things like icons is less dangerous than replacing code.)
  • superload: Files in this directory will be read and executed after the base game's file of the same name. This is very powerful but much less dangerous. This is a great way to add content (like new Artifact items) or tweak content (modify a talent's cost or requirements) without accidentally stepping on other tweaks or future content updates.
  • data: Files in this directory will just sit there and be ignored unless you explicitly tell the game to read them. Files in this area live in their own "namespace" and filenames here will never interfere with other addons or the base game. This is a great place to put new classes, talent trees, or races.
  • hooks: Only one file in this directory is automatically executed: load.lua. This file is a great way to get your "data" files executed at the proper time. It's also a way to augment some parts of the game which specifically support hooks: the Example module shows how the "Actor:takeHit" function is hooked to make the tourist take no damage. You can also use hooks to load add-on data in to the module, eg. new talents. Find a list of available hooks here.

The Example addon can be found here: http://te4.org/dl/tmp/tome-example.teaa

A .teaa file is simply a renamed zip that contains the whole addon, so feel free to rename and unzip your favorite addon to see a living example of all the stuff discussed in this article. The tome-example.teaa addon illustrates how to add a new class, new talents, new timed effects and how to hook onto a few useful locations in the code. (Note that it's a bit old, though.) When zipping, make sure to zip the files but not the folder. For example, tome-addonname.zip/init.lua, not tome-addonname.zip/tome-addonname/init.lua.

You can also just put a folder 'tome-addonname' in addons and it will be loaded directly, no need to zip or rename.

Grammar and Syntax

  • The addon folder must be in the format [ModuleName]-[AddonShortName]. For you, that means tome-coolstuff is your folder name.

Overloading

Each .teaa file is just a zip file. The main ToME game code is stored in game/modules/tome.team, and it is also just a renamed zip file.

Copy tome.team somewhere, rename it to tome-1.1.5.zip and unzip it.

You'll see two directories: "data" and "mod". Most of the stuff you'll want to mess with at first is in "data".

When you use overload to replace a file, the path and name must match exactly the structure in tome.team. So for example, to replace the types of leather boots in the game, I'd look in the unzipped ToME code and find:

tome-1.1.5/data/general/objects/leather-boots.lua

... and so to overload that, I'd create a file in my addon:

tome-coolstuff/overload/data/general/objects/leather-boots.lua

Superloading

Just like overloading, superloading requires that you know the file structure of the game so you can make your files get read and executed at the right time. When the game reads in your superload file, you can get access to the previous file's contents using the loadPrevious(...) function.

For example, if we wanted to add a new boot ego, we could do something like this. First, we'd find the boot ego code:

data/general/objects/egos/light-boots.lua

Next, we'd make a file in our superload directory:

tome-coolstuff/superload/data/general/objects/egos/light-boots.lua

... and we'd make sure that our init.lua file had the line:

superload = true

We're ready to add the boot ego!

local _M = loadPrevious(...)
newEntity{
	power_source = {arcane=true},
	name = " of sensing", suffix=true, instant_resolve=true,
	keywords = {sensing=true},
	level_range = {1, 50},
	rarity = 4,
	cost = 2,
	wielder = {
		see_invisible = resolvers.mbonus_material(20, 5),
		see_stealth = resolvers.mbonus_material(20, 5),
		blind_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end),
	},
}

return _M

Modifying mod Stuff

Hold on, that example still didn't use _M at all! So what is _M for? Since most things in the data directory are stored in easily accessible structures, you don't need _M to get them. _M is generally used for stuff in the mod directory: the most dangerous stuff to modify. Here's an example which modifies the "levelup" function in mod/Actor.lua. Your file for this code should be in /superload/mod/Actor.lua.

local _M = loadPrevious(...)
local base_levelup = _M.levelup

function _M:levelup()
  -- Do stuff "before" loading the original file

  -- execute the original function
  local retval = base_levelup(self)

  -- Do stuff "after" loading the original file

  -- return whatever the original function would have returned
  return retval
end

return _M

Whenever possible, superloaded functions should call the original function rather than replacing it entirely. This maintains compatibility with other addons.

Uploading your Addon

Once your addon works and you want the world to see it you need to follow some simple steps to get it up on te4.org (and Steam Workshop if you own ToME on Steam):

  • Check to make sure your addon has tags specified in the init.lua file (tags = { 'races', 'human', 'challenge'}). The tags should be descriptive to assist searching on the te4.org website.
  • Create a folder with the format "tome-[short_name]", where the short_name is the same as that specified in the init.lua (tome-humansextended).
  • Place your addon folder in the [TOME install folder]/game/addons folder, and copy into it all of your addon files (init.lua, data folder, hooks folder, overload folder, superload folder).
  • Make sure developer mode is on (from the main menu: Options >> Developer mode >> Yes).
  • Make sure you are logged in-game.
  • Make sure the addon developer addon is enabled.
  • Make a new character with the addon enabled.
  • Enter debug menu (ctrl+a if you didn't re-bind it), and choose the Addon Developer menu.
  • Select the option to register a new addon if this is the first time uploading this addon.
  • Select the option to publish the addon to the te4.org website.
  • Wait as the game packages and uploads your addon.
  • Optional: do the same thing with the Steam upload.
  • If you are having trouble uploading to steam. Try Purging Cloud Saves (From the main menu: Options >> Steam >> Purge Cloud Saves). These can be in a bad state and block uploading.
  • You're done, your addon should now appear on te4.org addons list.
  • Optional (but recommended): Create a te4.org forum account and start a new topic in the Addons section to give players a place to provide feedback about your addon and link to the topic from the te4.org addon page created for your addon. You will have to wait for a moderator to approve your topic before you can link to it.


To update your addon on the Steam Workshop: Edit your addon on your profile page to be able to enter the addon steam workshop id (check workshop page url for id), allowing you to update your old workshop entry.

Notice: If you are having trouble updating the addon with steam where it updates but doesn't really update, but not with te4.org, you could be running into an exotic bug with steam synchronization. This set of steps discovered by stuntofthelitter has fixed several people who have run into this problem: Re-enable steam cloud in ToME. Let steam sync. Ran the game, disabled steam cloud saves, did NOT purge data.

A second fix for steam because that first one didn't help me : go to C:\Users\[username]\T-Engine\4.0\tome\user-generated-addons and replace the old zip file with the new one, done.