The library module

The library API: entity, player, effect, utilities and compatibility.

Importing

library is an additional library for TERA modules. Its folder must be named library, not library-master. Declare it as a dependency in module.json; access the interface through mod.require.library.

module.exports = function LibraryExample(mod) {
    const lib = mod.require.library;
    mod.command.add('lib-position', () => {
        if (!mod.game.isIngame) return;
        mod.command.message(JSON.stringify(lib.player.loc));
    });
};

Public components are entity, player, effect, packet and library. mods contains references to loaded components. Call utilities through lib.library, for example lib.library.dist3D(a, b). lib.command and lib.cmd reference the command interface.

Entity

lib.entity maintains players, mobs, npcs, unknown and entities objects indexed by gameId. State is cleared on zone loading; check that an entry exists before using it.

Entries in players/mobs/npcs/unknown expose pos with x/y/z/w coordinates/direction, info.huntingZoneId, info.templateId, name, job and race. The entities collection contains instances of the newer Entity class: huntingZoneId and templateId are direct properties and getLocation() retrieves the position. That class's info and loc getters throw; do not mix the two entry formats.

The historical README describes appearance aliases outfit, app, apperance, appearance and fields weapon, body, hand, feet, underwear, head, face, styleHead, styleFace, styleBack, styleWeapon, styleBody, styleFootprint, styleBodyDye, bodyDye. The inspected implementation does not populate those aliases: do not treat them as an available API for new development.

Method Result
getLocationForThisEntity(id) Position from a matching collection, or undefined
getLocationForPlayer(id) Player position; the entry must exist
getLocationForMob(id), getLocationForNpc(id) Mob/NPC position; the entry must exist
getEntityData(id) Entity data from the collections
getEntitiesData(huntingZoneId, templateId) Entities matching the template
isNearEntity(pos, playerRadius = 50, entityRadius = 50) Check players and the mobs collection
isNearPlayer(...), isNearBoss(...) The same checks for players/mobs separately
getSettingsForEntity(id, object) object[huntingZoneId][templateId] for an existing entity

Despite its name, isNearBoss iterates over mobs. Proximity uses positionsIntersect, whose geometry is described below; it is not a universal point-within-radius test.

Player

lib.player.isMe(gameId) checks the current character. Main properties:

Properties Meaning
serverId, playerId, templateId, gameId, name, level Identifiers and character data
race, job Numeric values derived from templateId, unlike mod.game.me strings
onMount, alive, onPegasus, inCombat Character state
loc, pos Coordinates, direction w, update timestamp updated
moving, zone, channel Movement, zone and channel
inven weapon, effects, crystals, equipment
stamina, health, maxHealth, mana, maxMana Stats after updates
attackSpeed, attackSpeedBonus, aspdDivider, aspd Attack speed values and calculated factor
playersInParty, partyLeader Party information

race = Math.floor((templateId - 10101) / 100) and job = (templateId - 10101) % 100. Player appearance aliases from the older README are also absent from the inspected implementation. Do not assume other properties are populated before their game packets arrive.

Effect

lib.effect stores abnormals, glyphs and permanentBuffs as ID → state objects. hasAbnormality(id), hasGlyph(id) and hasBuff(id) test === true. hasEffect(id) returns the first truthy state from the three stores; absent entries can produce undefined, so use it as a condition rather than expecting literal false.

getAbnormalities(), getGlyphs() and getBuffs() return the actual stores, not copies. Expired effects may leave keys with false values: check the value rather than key existence. State resets on S_LOGIN.

Coordinates and skills

Methods of lib.library:

Method Behavior
dist2D(a, b), dist3D(a, b) Distances
applyDistance(loc, distance) Mutates x/y along loc.w in radians and returns the same object
positionsIntersect(a, b, aRadius, bRadius) Tests (aRadius-bRadius)² <= distanceXY² <= (aRadius+bRadius)²
fromAngle(w), toAngle(w) Radians to the 16-bit angle scale and back
getSkillInfo(id, usingMask = true, bossSkill = false) Decodes a legacy numeric skill ID

positionsIntersect ignores Z and excludes complete containment when radii differ. For “within R”, use dist2D <= R or Vec3.sqrDist2D.

getSkillInfo returns raw, id, skill, sub and level; methods setValues, getBaseId(skill = 1, level = 1, sub = 0) and setValuesTo(skill, level, sub) update/construct the numeric form. This legacy format using mask 0x4000000 does not replace the modern parser's skillid object.

Packets and DataCenter

lib.packet chooses definitions using an internal patch table. The library uses lib.packet.get_all(name) to return arguments for mod.hook(...result, callback). This is a compatibility table for the installed library version, not automatic support for every server.

lib.library method Purpose
getEvent(opcode, version, payload) Parse a Buffer through Dispatch.fromRaw
getPayload(opcode, version, data) Serialize through Dispatch.toRaw
getPacketInformation(identifier) Resolve a definition
parseSystemMessage(message), buildSystemMessage(message) System-message API wrappers
query(query, ...args) queryData wrapper; findAll depends on whether arguments exist
queryM(queries) Sequentially run [query, ...args] arrays and concatenate results
queryF(query, concat = true, findAll = true, children = true, attributeFilter = null) Parameterless query with optional node merging
getQueryEntry(queryData, path, ...argsData) Search an already retrieved tree

For predictable result control in new code, prefer direct mod.queryData. version/protocolVersion on lib.library refer to the network protocol, not the npm package version; command is the command interface and sp is the result of an attempt to detect Skill Prediction.

Utilities

lib.library method Behavior
arraysItemInArray(a, b) Whether any element of a occurs in b; the README used a different spelling
jsonEqual(a, b) Compares JSON.stringify output; key order matters
objectLength(obj) Number of own enumerable keys
getRandomInt(min, max) Integer including min, excluding max
jsonStringify(data, spaces), parseJson(data) JSON with custom BI/- string encoding for BigInt
saveFile(filePath, data, dirname) Synchronous write; objects use ordinary JSON.stringify
readFile(dirname, filePath) Synchronous read returning a Buffer
print(...args) Diagnostic output using util.inspect

Explicitly pass your module directory for file operations: saveFile defaults to a directory inside the library itself. Ordinary JSON.stringify does not support BigInt; the library's custom encoding differs from Toolbox settings encoding.

Inheritance and deprecated API

You can directly import a class for specialized inheritance, but this couples your module to library internals. In the current version Player, like Entity, uses the second mods argument; the old super(mod) example is insufficient.

const Player = require('../library/class/player');
class CustomPlayer extends Player {
    constructor(mod, mods) {
        super(mod, mods);
    }
}
module.exports = CustomPlayer;

Additional instances register their own hooks. Usually the existing lib.player is sufficient. emptyLong() and long() throw in the current implementation: use BigInt. opositeDirection (with that spelling) and getDirectionTo are deprecated and log warnings. startSkillsPackets from the README is absent from current class/library.js; do not depend on it.

Sources: mods/library/README.md, mods/library/index.js, mods/library/class/{library,entity,player,effect,packet}.js.