Elements of a Basic Skill
I haven't seen a lot of tutorials on Skills out here in the wild. I've written a few here and there that have been lost to the sands of the Message Forums, but never anything on creating a “basic” one. Anyway, I'm taking a short break from working on my mods tonight and wanted to help share this info to take the edge off of the learning curve for people.
This tutorial focuses on Skill building with a skill that already exists. I did this because that way anyone who reads this can easily understand what the spell is intended to do. If I have time I'll revisit later with a couple of different kinds of skills.
The skill I selected for this tutorial is Embermage's Elemental Boon. I picked this spell because it is one of the most straightforward skills in the game, and because it covers multiple concepts that are useful for skill building. In case you're not familiar with it, here's the skill's description from the game:
There are a couple of ways to find the skill you're looking for. In this case, the easiest way is probably to just open the Skills editor, and scroll to media/skills/arbiter. This will get you a list of all Arbiter (“Arbiter” is the internal name for Embermage). Click the “Display Name” field. This gives you a list of all spells the Arbiter/Embermage has. Select the one labeled Elemental Boon.
I am a firm believer that to understand what a Skill does, you must understand its code. The various point and click tools and the settings grid at the bottom of the page are useful, but a lot of working with skills is understanding EVENTS and other objects at a glance.
We're going to divide the Skill code into 2 parts: the top section, and the level descriptions. You will always do the top section first. Let's take a look at its contents:
<STRING>NAME:ElementalBoon <TRANSLATE>DISPLAYNAME:Elemental Boon <TRANSLATE>BASE_DESCRIPTION:You imbue yourself with a bolstering aura which increases your elemental damages and resistances. Boon's benefits are also applied to any allies within 12 meters. <TRANSLATE>TIER1_DESCRIPTION:Gains resistance to slowing and immobilization effects <TRANSLATE>TIER2_DESCRIPTION:Gains mana recharge <TRANSLATE>TIER3_DESCRIPTION:Faster cast and less mana <STRING>SKILL_ICON:skillicon_elementalboon <STRING>SKILL_ICON_INACTIVE:skillicon_elementalboon_gray <STRING>ACTIVATION_TYPE:NORMAL <STRING>TARGET_ALIGNMENT:GOOD <STRING>TARGET_TYPE:SELF <STRING>ANIMATION:special_lightning_storm <STRING>MANA_COST_GRAPH:MANACOST_NORMAL <FLOAT>SPEED:1.5 <INTEGER>COOLDOWNMS:30000 <FLOAT>FINDTARGETANGLE:360 <FLOAT>TURNRATEOVERRIDE:-1 <STRING>REQUIREMENT_GRAPH:SKILLTIER4 <INTEGER>LEVEL_REQUIRED:0 <INTEGER>MAX_INVEST_LEVEL:15 <INTEGER64>UNIQUE_GUID:48111940504044895
TL2 skills, as well as most other objects, use an additive method. Values are only set in the Skill if the vary from the defaults. That is why you do you not see the same settings in every skill.
Now let's look at each element one piece at a time.
<STRING>NAME:ElementalBoon The NAME is the internal reference name of the skill. Each skill will need a unique name that is not repeated anywhere. (For custom skills: To make 100% sure my custom skills are all unique, I label all of them with a personal prefix. You will be highly served to come up with one of your own. In this case, the name is ElementalBoon, had I created it myself I would have used something like XCVC_ElementalBoon, where XCVC were my personal prefix I put on everything. Labeling everything with a prefix is a best practice that has saved me HOURS of work and keeps your mod identifiable among a sea of content.)
<TRANSLATE>DISPLAYNAME:Elemental Boon The name that will show in game.
<TRANSLATE>BASE_DESCRIPTION: This is just the text that will show on the screen when the player rolls over the power in the skills tree.
<STRING>SKILL_ICON:skillicon_elementalboon <STRING>SKILL_ICON_INACTIVE:skillicon_elementalboon_gray References to the skill icons. These icon names are defined in IMAGESET files. Reusing one of Runic's pre-existing icons is very easy. It's a bit trickier to import your own (and beyond the scope of this walkthrough).
<STRING>ACTIVATION_TYPE:NORMAL Activation type refers to how the spell is cast. A setting of NORMAL indicates that the spell is a clickable spell that can be placed on the player's castbar. Other options here are PASSIVE (for Passive skills), PROC (for skills called by other skills) and ANY (for cases, particularly with Monster skills, where the spell just “exists” and is castable under all conditions, eg the aura created by Berserker banners). Elemental Boon is set to Normal because we want players to be able to click it.
<STRING>TARGET_ALIGNMENT:GOOD Target alignment indicates whether by default the spell hits good units (from the perspective of the caster) or enemies. Elemental Boon is set to GOOD because we want it to affect the caster and his or her party. Note that TARGET_ALIGNMENT is not the only way to control who gets hit by a spell, just one way, and in most cases the easiest.
<STRING>TARGET_TYPE:SELF Target type indicates how the game should process the position of the cursor when the spell is cast. A setting of SELF basically means the cursor is meaningless; the spell is targeted directly on top of the caster (although the cursor could cause the character to turn and face a different direction). Anther common setting is POSITION (for spells dropped in a specific place). Many spells leave TARGET_TYPE off completely if they are not targeted at self or position.
<STRING>ANIMATION:special_lightning_storm Animation refers to the animation played the player character unit when executing the skill. In this case, that animation is special_lightning_storm. You can grab animations from various skills and reuse them; however, note that the animation you select can effect which EVENTS are available later on. Sometimes it is best to start out coding a skill using an animation you know very well and swap it out later.
<STRING>MANA_COST_GRAPH:MANACOST_NORMAL The mana cost graph to use for this skill. Using a graph allows the skill to autocalculate its mana cost for each level without you having to do anything more than specify the graph. Very handy.
<FLOAT>SPEED:1.5 Speed refers to the cast speed of this power. Increasing speed normally increases both the Animation and any Events found in the skill. 1.0 is default speed. 1.5 means “50% faster than default.”
<INTEGER>COOLDOWNMS:30000 This is the cooldown of the power, in milliseconds. There are 1000 milliseconds in one second, so if you just think of this as seconds and add three zeros you're usually okay. In this case it means a 30 second cooldown.
<FLOAT>FINDTARGETANGLE:360 This appears to refer to how much leeway to give the character model if the player casts the spell with the cursor located somewhere other than on top of the enemy. The setting “360” means the model doesn't turn at all. 0 will make the model always turn to face the cursor. Or so I think.
<STRING>REQUIREMENT_GRAPH:SKILLTIER4 This graph determines that this skill is a Tier 4 skill, unlocking at level 21.
<INTEGER>MAX_INVEST_LEVEL:15 How many ranks does this skill have? Used by the GUI.
<INTEGER64>UNIQUE_GUID:48111940504044895</code> A unique numeric code that identifies this skill. Every skill (and item, monster, class, and really everything) needs its own. Never change this value if you can help it. Also, if copy pasting info from one skill to another, make sure each one keeps its unique GUID. If two skills end up with the same GUID, GUTS eats one of them. Not pretty. Also, keep constant backups of your work because if this happens to you you could lose everything in your skill file.
Now that we got the basic settings for the power out of the way, let's talk about Levels.
In TL2, each power typically has 15 levels. Each one starts with a [LEVEL#] tag and ends with [/LEVEL#] tag, where # is a number representing the level.
To continue with the Elemental Boon example, let's look at its LEVEL1 object.
[LEVEL1] [EVENT_TRIGGER] <STRING>FILE:media/skills/arbiter/elementalboon/elementalboon.layout <BOOL>FOLLOWS:1 <BOOL>NOSTEALEFFECTS:0 <BOOL>STATSHIDDEN:1 [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:FRIEND <STRING>TARGETTYPE:PET <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:SELF <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:FRIEND <STRING>TARGETTYPE:PLAYER <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [/EVENT_TRIGGER] [EVENT_TRIGGER_FOUR] [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:FRIEND <STRING>TARGETTYPE:PET <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [/EVENT_TRIGGER_FOUR] [/LEVEL1]
Inside of a LEVEL object there will be one or more EVENT objects. Each EVENT represents something happening. In this example, we have an EVENT_TRIGGER and an EVENT_TRIGGER_FOUR.
EVENT_START doesn't appear in this skill, but it is worth mentioning that is similar to EVENT_TRIGGER except that it starts immediately when the skill is called, not waiting for the trigger to fire in the cast animation).
Let's talk about what's inside the EVENT_TRIGGER first.
This is a reference to the Layout file that does a couple of things. In this case, it defines our particle effects, sound effects, and damage shape. More on this later. The main thing you need to know right now is that this Layout file defines an area of the screen to which the effects of this Event, such as damage, affixes, and so on, apply.
<BOOL>FOLLOWS:1 Refers to the Layout file above. FOLLOWS indicates that the Layout file for this event will Follow the target. (Reminder: In this case, the target is SELF, as discussed in the previous post). FYI “Follow” differs from “Attach” in that the Layout file will travel with the player, but its particle system will not rotate with the character model when s/he changes directions.
<BOOL>STATSHIDDEN:1 STATSHIDDEN is a very common setting. It means that anything done within this event should not be displayed as preview text within the skill's description on the Skill Tree. Why is this set for this Event? It's because of the section below, with the Affixes.
[AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:FRIEND <STRING>TARGETTYPE:PET <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:SELF <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:FRIEND <STRING>TARGETTYPE:PLAYER <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [/EVENT_TRIGGER]
The [AFFIXES] marker allows for the assignment of Affixes to a Unit. Here we see three AFFIXES objects, all identical to each other, but with one difference: the type of target. One object is there for SELF, one is there for other players, and one is there for pets. The name of the Affix being assigned is the same for all three: EMBERMAGE_ELEMENTALBOON. If we open up the Affix editor we can see it.
Now, there are a couple of things going on in this Affix that are slightly complicated. We won't get into it too deeply, except to say that this Affix is granting 4 cases of PERCENT DAMAGE BONUS and 4 cases of damage reduction (in the form of PERCENT DAMAGE TAKEN written as a negative). This Affix is where Elemental Boon is getting its effects.
And that's this EVENT_TRIGGER!
Now let's take a look at EVENT_TRIGGER_FOUR.
[EVENT_TRIGGER_FOUR] [AFFIXES] <INTEGER>AFFIXLEVEL:1 <STRING>TARGET:FRIEND <STRING>TARGETTYPE:PET <STRING>AFFIX:EMBERMAGE_ELEMENTALBOON [/AFFIXES] [/EVENT_TRIGGER_FOUR]
I said earlier that the animation used by this power never calls EVENT_TRIGGER_FOUR. So why the heck is it here? The answer is that because EVENT_TRIGGER_FOUR will never be called, it can be used as a dummy to make the Affix description text look correct for the power. Remember how the EVENT_TRIGGER had STATSHIDDEN set to true? That was because the Affix occurs 3 times. If we didn't hide the stats, they'd show up 3 times in the skill description. By adding the affix again in an EVENT_TRIGGER_FOUR with STATSHIDDEN turned off, we basically trick the game into listing what the spell does only one time. :)
Continue the Walkthrough with Layout Files