Talents and Skills

Talents are mainly used as a means to group skills together usually around a theme such as crafting. Actions related to a talent can yield talent points (TP) which can then be used to level up skills within the talent. Skills can either be passive and are always in effect or be active and require the player to use the spell.

Talents and skills are only intended for players and are added via the TalentsComponent. Talents are added to the body content which gets transferred to the player once the body is selected.

Adding New Talents

Entirely new talents can be created and added to either new or existing body types. To create a new talent start by creating a new .py file in the mods/mymod/talent/ directory such as mods/mymod/talent/cooking.py.

Any assets needed for the talent, such as icons and skills, should go in a subdirectory, mods/mymod/talent/cooking/. Inside of cooking.py we want to provide a function that creates a new Talent.

from core.talent import addSkill
from siege import game, Talent

def getTalent():
    talent = Talent("cooking", "cooking/icon.png", [1000] * 50)
    addSkill(talent, ChopSkill)
    addSkill(talent, SpiceSkill)
    game.events['create_talent'].invoke(talent)
    return talent

See the Talent constructor for the signature details. After creating a talent the create_talent() event should be invoked.

When adding the talent to a new body type then it can be inlined. See Creating Races for more thorough details.

import siege.component
import core.talent.cooking

talents = siege.component.Talents()
talents.talents.append(core.talent.cooking.getTalent())
body.addComponent(talents)

When adding the talent to an existing body then you will want to utilize the setup_body() event. Inside of cooking.py you can add the following code along with adding a registration call.

def addTalent(template, identifier):
    if identifier == 'hm':
        template.talents.talents.append(getTalent())

def register():
    game.events['setup_body'].listen(createTalent)

Adding New Skills

Creating new skills is a much more complicated task but there are some tools to help simplify things. As long as you have a Talent you can easily add a skill to it with addSkill() in ``core.talent.addSkill`.

addSkill(talent, skill)

Adds the skill to the talent.

Parameters:
  • talent (Talent) – The talent to add the skill to.
  • skill (BaseSkill class or instance) – The skill to add to the talent. This can either be an instance of a BaseSkill or a class inheriting from BaseSkill.

Skills can either be passive which are always in effect or active which requires use. Each skill will need to have a skill tuning data associated with it.

Passive Skills

Passive skills can range from a simple stat boost to much more complicated skills such as giving a damage boost ever 5 attacks. For the most basic passive skill where you just need to track the skill level because you use logic elsewhere you can use PassiveSkill.create from core.talent All you just have to do is pass in the related skill tuning data.

addSkill(talent, PassiveSkill.create(SkillTuning.WAND_PROFICIENCY))

When creating a stat boost skill it is almost the same but instead use StatBoostSkill.create from core.talent.

addSkill(talent, StatBoostSkill.create(SkillTuning.MIND_BOOST))

Slightly more involved skills will require you to create a new class and derive from core.talent.PassiveSkill. Whenever a skill is activated, such as when it is learned, the onActivate() method will be called. Similarly whenever a skill is deactivated the onDeactivate() method will be called. Be sure to use these properly by reversing everything in onDeactivate() that onActivate() did.

On occasion you will need to perform an action only on the client and not the host. This can easily be done by using the analogous onClientActivate() and onClientDeactivate().

In the example below you can see that we add a listener to use_delay() event in onActivate() and then remove the listener in onDeactivate().

class ToolSpeed(PassiveSkill):
    TUNING = SkillTuning.TOOL_SPEED
    MODIFIERS = ['STAT_AMOUNT']

    def onActivate(self, level, player):
        player.entity.event["use_delay"].listen(partial(ToolSpeed.handleUseDelay, level))

    def onDeactivate(self, level, player):
        player.entity.event["use_delay"].remove(partial(ToolSpeed.handleUseDelay, level))

    @staticmethod
    def handleUseDelay(level, item, delay):
        if item.has("tool"):
            delay.final -= int(delay.start * (getTuningData(ToolSpeed.TUNING, level, 'STAT_AMOUNT') / 100.0))

Active Skills

Active skills must be used from the toolbar to take effect. Skills are expected to be usable and consequently require a onUse(). Skills on a client can also perform logic by providing onClientUse().

class ActiveSkill
onUse(player, level, position, toolItem, isModified)
Called when the player has used the skill and it should perform whatever actions it does.
Parameters:
  • player (Player) – The player performing the skill.
  • level (int) – The current level of the skill.
  • position (Vector) – The position the player’s cursor is targeting.
  • toolItem (ToolItem) – The item on the toolbar this skill is being used from.
  • isModified (bool) – Whether the player is holding down the modifier button while using the skill.
onClientUse(player, level, position, toolItem, isModified)
Called on a client when the player uses a skill. This should only perform immediate graphical changes such as playing an animation.
Parameters:
  • player (Player) – The player performing the skill.
  • level (int) – The current level of the skill.
  • position (Vector) – The position the player’s cursor is targeting.
  • toolItem (ToolItem) – The item on the toolbar this skill is being used from.
  • isModified (bool) – Whether the player is holding down the modifier button while using the skill.
isAvailable(player, level, toolItem)
Called when checking if this skill is available for use. When unavilable the skill will be grayed out on the toolbar.
When unprovided the skill is assumed to always be available.
Parameters:
  • player (Player) – The player performing the skill.
  • level (int) – The current level of the skill.
  • toolItem (ToolItem) – The item on the toolbar this skill is being used from.
Returns:

Whether the skill is available or not.

Return type:

bool

isUsable(player, level, position, toolItem)
Called when checking if this skill can be used. This is only called when the skill is available.
When unprovided the skill is assumed to always be usable.
Parameters:
  • player (Player) – The player performing the skill.
  • level (int) – The current level of the skill.
  • position (Vector) – The position the player’s cursor is targeting.
  • toolItem (ToolItem) – The item on the toolbar this skill is being used from.
Returns:

Whether the skill is usable or not.

Return type:

bool

canRepeatUse(player, level, position, toolItem, isModified)
Called when checking if this skill can be repeatedly used without releasing the action button.
When unprovided the skill is assumed it can be used repeatedly.
Parameters:
  • player (Player) – The player performing the skill.
  • level (int) – The current level of the skill.
  • position (Vector) – The position the player’s cursor is targeting.
  • toolItem (ToolItem) – The item on the toolbar this skill is being used from.
  • isModified (bool) – Whether the player is holding down the modifier button while using the skill.
Returns:

Whether the skill can be repeatedly used.

Return type:

bool

There are a few base classes available to help make active skills easier. core.talent.UsableSkill is the main bass class and provides a great number of default methods that may be overridden. There are several classes that derive from this class: core.talent.ArmsSkill, core.talent.RangeSkill, core.talent.SpellSkill, and core.talent.SpellForm. The first three are used to determine which stats are used to calculate the skill’s power. core.talent.SpellForm is for skills that change when the player channels a different Aer such as core.talent.syle.BaseForm.

Skill Modifiers

Most skills have multiple levels and as they are leveled up will be modified in some way. To help convey this information we have a list of MODIFIERS as a class attribute. The listed modifiers correspond to a value in the tuning data. The game automatically detects when the modifier value changes or will change for a given skill level and display it in the tooltip.

The following is an example of a skill with modifiers and what it looks like in game.

Excerpt from mods/core/talent/syle.py

class BaseForm(SpellForm):
    TUNING = SkillTuning.BASE_FORM
    DEFAULT_AER = SkillTuning.CHANNEL_AEGNIX
    MODIFIERS = ['POWER', 'STATUS_EFFECT_CHANCE', 'SP_COST']

Excerpt from mods/core/tuning/skill.py

BASE_FORM = AttrDict(
    NAME = "BaseForm",
    TYPE = "Base",
    DESCRIPTION = "BaseFormDesc",
    ICON = "mods/core/talent/syle/base_icon.png",
    ICON_TEMPLATE = "mods/core/talent/syle/base_{}_icon.png",
    UNLOCK_LEVELS = [1, 1, 7, 12, 17, 23, 30, 35, 40, 45],
    LEVEL_COSTS = [0, 350, 375, 375, 375, 400, 400, 400, 400, 450],
    CAST_TIME = 500,
    COOLDOWN = seconds(3),
    POWERS = [120, 120, 126, 126, 126, 135, 135, 135, 145, 145],
    SP_COSTS = [45, 40, 40, 35, 35, 35, 30, 30, 30, 25],
    TP_AMOUNT = 12,
    TP_CHANCE = 30,
    STATUS_EFFECT_CHANCES = [0, 0, 0, 0, 20, 20, 20, 40, 40, 40],
    SOUND = "mods/core/audio/sfx/talent/syle/fire.ogg",
    SOUND_TIMING = 300
)
_images/fireball_tooltip.png

Modifiers can be associated with more than just a number. In addition to numbers, modifiers can be a time, text or a name of content. The type of modifier, specified with a value from core.talent.SkillModifierTypes, can be paired with the name as a tuple.

MODIFIERS = ['POWER', 'RANGE', ('COOLDOWN', SkillModifierTypes.Time)]
class SkillModifierTypes
Int
Content
String
Time

Awarding Talent Points

Whenever a player performs an action related to a talent the player should at least have a chance to gain some talent points. Generally actions yield somewhere between 20-50TP based on the ease and frequency the action is performed. This is achieved with either chanceToGainTalentPoints() or gainTalentPoints(). Here is an example gaining craft talent points after a craft finishes by listening to the craft_finish() event.

from core.talent import chanceToGainTalentPoints

def craftFinish(player, results, craft, count, result, item, remainder):
    level = craft.level
    rate = int(min(120 * math.sqrt(float(count)), 220))
    amount = craft.experience * (level / 5 + 1) * min(count, math.sqrt(count) * 2)
    chanceToGainTalentPoints(player, player.entity.talents.craft, level, rate, amount)
chanceToGainTalentPoints(player, talent, level, rate, amount)

Chance to grant talent points to the player’s talent. The higher the ratio is between the provided level and your talent level the more talent points will be gained with a higher likelyhood.

Parameters:
  • player (Player) – The player that may gain the talent points.
  • talent (ActiveTalent) – The talent to gain the talent points.
  • level (int) – The level of the action that resulted in this being called.
  • rate (int) – The likelyhood that the talent points will be gained. 0 is never and 255 is very likely.
  • amount (int) – The amount of talent points to award. This changes depending on the level matchup.
calculateTpPoints(player, talent, level, rate, amount)

Calculates how many talent points should be gained.

Parameters:
  • player (Player) – The player that may gain the talent points.
  • talent (ActiveTalent) – The talent to gain the talent points.
  • level (int) – The level of the action that resulted in this being called.
  • rate (int) – The likelyhood that the talent points will be gained. 0 is never and 255 is very likely.
  • amount (int) – The amount of talent points to award. This changes depending on the level matchup.
Returns:

The amount of talent points that should be gained.

Return type:

int

gainTalentPoints(player, talent, amount)

Grants talent points to the player’s talent.

Parameters:
  • player (Player) – The player that may gain the talent points.
  • talent (ActiveTalent) – The talent to gain the talent points.
  • amount (int) – The amount of talent points to gain.