Skip to content

Class API⚓︎

The main API module for SkillFramework. Access by: require('openmw.interfaces').SkillFramework


API.SPECIALIZATION
API.SKILL_INCREASE_SOURCES
API.STATS_WINDOW_SUBSECTIONS
API.getVersion Get the API version.
API.registerSkill Register a new custom skill.
API.modifySkill Modify a custom skill's properties.
API.registerSkillBook Register a new skill book for a custom skill.
API.registerRaceModifier Registers a base modifier that is automatically applied ONCE
API.registerClassModifier Registers a base modifier that is automatically applied ONCE
API.registerDynamicModifier Registers a dynamic modifier that is checked and applied every frame.
API.unregisterDynamicModifier Unregister a previously registered dynamic modifier.
API.addSkillRegisteredHandler Register a handler function to be called when a new skill is registered.
API.addSkillUsedHandler Register a handler function to be called when a skill is used via skillUsed.
API.addSkillLevelUpHandler Register a handler function to be called when a skill would level up via skillUsed or skillLevelUp.
API.addSkillStatChangedHandler Register a handler function to be called when a skill's stat changes by any means, including direct modification.
API.getSkillRecords Get all registered custom skills.
API.getSkillRecord Get the record for a specific custom skill.
API.getSkillBookRecords Get all registered skill books.
API.getSkillBookRecord Get the record for a specific skill book.
API.isSkillBookRead Checks if this actor has read a specific skill book for a specific skill.
API.setSkillBookReadState Sets the read state for a specific skill book on this actor.
API.getSkillStat Get this actor's current stat in a custom skill.
API.getSkillProgressRequirement Get the amount of XP required for this actor to level up in a custom skill.
API.skillUsed Notify the API that this actor has used a custom skill.
API.skillLevelUp Force this actor to level up in a custom skill.
API.calcStatFactor Helper function to calculate the stat factor for a custom skill, based on level, attribute, and luck.
API.calcFatigueFactor Helper function to calculate the fatigue factor for this actor.
API.bindGlobal Bind an MWScript global variable to the modified value of a custom skill for this actor (players only).
API.unbindGlobal Unbind an MWScript global variable.

Methods⚓︎


API.getVersion⚓︎

Get the API version.

function API.getVersion() -> version number

Returns⚓︎

  • version — The API version

API.registerSkill⚓︎

Register a new custom skill. Only the name property is required; other properties will be set to defaults if not provided.

function API.registerSkill(
  id: string,
  props: SkillProps {
    name = string,
    description = string?,
    icon = { bgr: string, bgrColor: Color, fgr: string, fgrColor: Color },
    attribute = string?,
    specialization = Specialization?,
    skillGain = table<any,number>,
    startLevel = number,
    maxLevel = number,
    modIntegration = SkillIntegrationProps,
    statsWindowProps = SkillStatsWindowProps,
    xpCurve = function,
}
) ->  nil

Params⚓︎

  • id — unique case-insensitive identifier for this skill
  • props — a table of skill properties

API.modifySkill⚓︎

Modify a custom skill's properties. Only the properties provided will be modified; other properties will remain unchanged.

function API.modifySkill(
  id: string,
  props: SkillProps {
    name = string,
    description = string?,
    icon = { bgr: string, bgrColor: Color, fgr: string, fgrColor: Color },
    attribute = string?,
    specialization = Specialization?,
    skillGain = table<any,number>,
    startLevel = number,
    maxLevel = number,
    modIntegration = SkillIntegrationProps,
    statsWindowProps = SkillStatsWindowProps,
    xpCurve = function,
}
) ->  nil

Params⚓︎

  • id — The ID of the skill
  • props — A table of valid skill properties

API.registerSkillBook⚓︎

Register a new skill book for a custom skill.

Multiple skills can be registered for the same book by calling this function with different skillIds.

function API.registerSkillBook(
  bookId: string,
  skillId: string,
  props: SkillBookProps?
) ->  nil

Params⚓︎

  • bookId — the record ID of the book
  • skillId — the ID of the skill this book increases
  • props — a table of skill book properties

API.registerRaceModifier⚓︎

Registers a base modifier that is automatically applied ONCE when a skill is first initialized for an actor of a specific race.

function API.registerRaceModifier(
  skillId: string,
  raceId: string,
  amount: number
) ->  nil

Params⚓︎

  • skillId — The ID of the skill
  • raceId — The (case-insensitive) ID of the race
  • amount — The amount to add to the base skill

API.registerClassModifier⚓︎

Registers a base modifier that is automatically applied ONCE when a skill is first initialized for an actor of a specific class.

function API.registerClassModifier(
  skillId: string,
  classId: string,
  amount: number
) ->  nil

Params⚓︎

  • skillId — The ID of the skill
  • classId — The (case-insensitive) ID of the class
  • amount — The amount to add to the base skill

API.registerDynamicModifier⚓︎

Registers a dynamic modifier that is checked and applied every frame.

The callback function should return the amount to modify the skill by, or nil. This amount will be added to the skill's modifier when first valid, and removed when no longer valid.

Warning⚓︎

Keep in mind that your callback will be called every frame on every actor it is registered for. Try to avoid expensive operations in the callback and cache results, and unless absolutely necessary, only register it for the player:

 if self.type == types.Player then
     API.registerDynamicModifier('mySkill', 'myUniqueModifierId', function()
         -- etc...
     end)
 end

function API.registerDynamicModifier(
  skillId: string,
  modifierId: string,
  callback: fun() -> number?
) ->  nil

Params⚓︎

  • skillId — The ID of the skill to modify
  • modifierId — A unique ID for this modifier (used for tracking)
  • callback — A function that returns the modifier amount (nil = 0 modifier)

API.unregisterDynamicModifier⚓︎

Unregister a previously registered dynamic modifier.

function API.unregisterDynamicModifier(
  skillId: string,
  modifierId: string
) ->  nil

Params⚓︎

  • skillId — the ID of the skill the modifier is for
  • modifierId — The ID of the modifier to unregister

API.addSkillRegisteredHandler⚓︎

Register a handler function to be called when a new skill is registered.

function API.addSkillRegisteredHandler(handler: SkillRegisteredHandler) ->  nil

Params⚓︎

  • handler — Handler function

API.addSkillUsedHandler⚓︎

Register a handler function to be called when a skill is used via skillUsed.

  • Called BEFORE skillLevelUp and skillStatChanged handlers.
  • Returning false from the handler will prevent the skill use and stop further handlers from being called.
function API.addSkillUsedHandler(handler: SkillUsedHandler) ->  nil

Params⚓︎

  • handler — Handler function

API.addSkillLevelUpHandler⚓︎

Register a handler function to be called when a skill would level up via skillUsed or skillLevelUp.

  • Called AFTER skillUsed handlers but BEFORE skillStatChanged handlers.
  • Returning false from the handler will prevent the level up and stop further handlers from being called.
function API.addSkillLevelUpHandler(handler: SkillLevelUpHandler) ->  nil

Params⚓︎

  • handler — Handler function

API.addSkillStatChangedHandler⚓︎

Register a handler function to be called when a skill's stat changes by any means, including direct modification.

  • Called AFTER skillUsed and skillLevelUp handlers.
  • This handler is called during onUpdate after the stat change occurs.
  • Any stat changes made during the handler will trigger the handler again on the next update tick.

Warning⚓︎

It is possible to create feedback loops if the handler modifies the skill stat unconditionally.

 API.addSkillStatChangedHandler(function(skillId)
     if skillId == 'my_awesome_skill' then
         API.getSkillStat(skillId).modifier = 0 -- BAD: will re-trigger handler every frame

         -- Instead, only modify conditionally
         local stat = API.getSkillStat(skillId)
         if stat.modifier ~= 0 then -- GOOD: only re-trigger if modifier is not already 0
             stat.modifier = 0
         end
     end
 end)

function API.addSkillStatChangedHandler(handler: SkillStatChangedHandler) ->  nil

Params⚓︎

  • handler — Handler function

API.getSkillRecords⚓︎

Get all registered custom skills.

function API.getSkillRecords() -> records table<string,SkillProps>

Returns⚓︎

  • records — A table of read-only registered custom skill records, indexed by ID

API.getSkillRecord⚓︎

Get the record for a specific custom skill.

function API.getSkillRecord(id: string) -> record SkillProps?

Params⚓︎

  • id — The ID of the skill

Returns⚓︎

  • record — The skill's read-only record, or nil if not found

API.getSkillBookRecords⚓︎

Get all registered skill books.

function API.getSkillBookRecords() -> records table<string,table<string,SkillBookProps>>

Returns⚓︎

  • records — A table of read-only registered skill book records, indexed by book ID and skill ID

API.getSkillBookRecord⚓︎

Get the record for a specific skill book.

function API.getSkillBookRecord(bookId: string) -> record table<string,SkillBookProps>?

Params⚓︎

  • bookId — The record ID of the book

Returns⚓︎

  • record — A table of the book's read-only skill records, indexed by skill ID, or nil if not found

API.isSkillBookRead⚓︎

Checks if this actor has read a specific skill book for a specific skill.

function API.isSkillBookRead(
  bookId: string,
  skillId: string
) -> isRead boolean

Params⚓︎

  • bookId — The record ID of the book
  • skillId — The ID of the skill

Returns⚓︎

  • isRead — True if the book has been read for this skill, false otherwise

API.setSkillBookReadState⚓︎

Sets the read state for a specific skill book on this actor. This will not trigger a skill level up; it is for manually setting flags.

function API.setSkillBookReadState(
  bookId: string,
  skillId: string,
  isRead: boolean?
) ->  nil

Params⚓︎

  • bookId — The record ID of the book
  • skillId — The ID of the skill
  • isRead — True to mark as read, false or nil to mark as unread

API.getSkillStat⚓︎

Get this actor's current stat in a custom skill.

The returned stat table's base, modifier, and progress fields can be modified directly. The modified field is read-only and will be recalculated automatically.

Direct modification will not trigger skillUsed or skillLevelUp handlers, but will trigger skillStatChanged handlers on the next update tick.

function API.getSkillStat(id: string) -> statInfo SkillStat?

Params⚓︎

  • id — The ID of the skill

Returns⚓︎

  • statInfo — A table containing the skill's current stat info, or nil if the skill is not registered

API.getSkillProgressRequirement⚓︎

Get the amount of XP required for this actor to level up in a custom skill.

function API.getSkillProgressRequirement(id: string) -> xp number?

Params⚓︎

  • id — The ID of the skill

Returns⚓︎

  • xp — The amount of XP required to level up, or nil if the skill is not registered

API.skillUsed⚓︎

Notify the API that this actor has used a custom skill.

function API.skillUsed(
  id: string,
  options: SkillUseOptions {
    skillGain = number?,
    useType = any,
    scale = number?,
}
) ->  nil

Params⚓︎

  • id — The ID of the skill
  • options — A table of options

API.skillLevelUp⚓︎

Force this actor to level up in a custom skill.

function API.skillLevelUp(
  id: string,
  source: SkillIncreaseSource {
    Book = "book",
    Jail = "jail",
    Trainer = "trainer",
    Usage = "usage",
},
  amount: number?
) ->  nil

Params⚓︎

  • id — The ID of the skill
  • source — The source of the skill increase
  • amount — The amount to increase the skill by (default: 1)

API.calcStatFactor⚓︎

Helper function to calculate the stat factor for a custom skill, based on level, attribute, and luck.

Based on Morrowind's default skill factor calculation: factor = skill + (attribute * 0.2) + (luck * 0.1)

function API.calcStatFactor(
  id: string,
  attribute: string?
) -> factor number?

Params⚓︎

  • id — The ID of the skill
  • attribute — The attribute to consider for the calculation (if different from the skill's governing attribute). Set to false to ignore attribute bonus.

Returns⚓︎

  • factor — The stat factor, or nil if the skill is not registered

API.calcFatigueFactor⚓︎

Helper function to calculate the fatigue factor for this actor.

Based on Morrowind's default fatigue factor calculation: factor = fFatigueBase - fFatigueMult * (1 - (currentFatigue / baseFatigue))

Example usage:

 local statFactor = API.calcStatFactor('mySkill')
 local fatigueFactor = API.calcFatigueFactor()
 local taskDifficulty = 30
 local successChance = statFactor * fatigueFactor - taskDifficulty

function API.calcFatigueFactor() -> factor number

Returns⚓︎

  • factor — The fatigue factor

API.bindGlobal⚓︎

Bind an MWScript global variable to the modified value of a custom skill for this actor (players only).

The global variable will be updated automatically whenever the skill's modified value changes.

function API.bindGlobal(
  globalId: string,
  skillId: string
) ->  nil

Params⚓︎

  • globalId — The ID of the global variable to bind
  • skillId — The ID of the skill to bind to

API.unbindGlobal⚓︎

Unbind an MWScript global variable. This will also set the global's value to 0.

function API.unbindGlobal(globalId: string) ->  nil

Params⚓︎

  • globalId — The ID of the global variable to unbind

Fields⚓︎


API.SPECIALIZATION⚓︎

API.SPECIALIZATION : Specialization {
    Combat: string = "combat",
    Magic: string = "magic",
    Stealth: string = "stealth",
}

API.SKILL_INCREASE_SOURCES⚓︎

API.SKILL_INCREASE_SOURCES : SkillIncreaseSource {
    Book: string = "book",
    Jail: string = "jail",
    Trainer: string = "trainer",
    Usage: string = "usage",
}

API.STATS_WINDOW_SUBSECTIONS⚓︎

API.STATS_WINDOW_SUBSECTIONS : StatsWindowSubsection {
    Arts: unknown,
    Combat: unknown,
    Crafts: unknown,
    Language: unknown,
    Magic: unknown,
    Misc: unknown,
    Movement: unknown,
    Nature: unknown,
    Social: unknown,
    Theology: unknown,
}