Skills, perks and needs

The server has the final say on progression. Each XP gain in a player's game is requested from the server and granted under your rules. If progress appears that the server never allowed, it is caught, and playerProgressionRejected fires.

XP goes to tracks:

  • Stats: strength, agility, vitality, speech
  • Skills: stealth, horse_riding, fencing, thievery, alchemy, craftsmanship, drinking, survival, weapon_sword, heavy_weapons, marksmanship, weapon_large, weapon_unarmed, scholarship, houndmaster, prestige

Rules for the whole server

const { Progression } = kcds.players;

Progression.setXpGain('*', 0.5); // half XP on all tracks
Progression.setXpGain('alchemy', 2); // double on this one
Progression.setXpCap('*', 300); // up to 300 XP per minute on each track
Progression.setMaxLevel('weapon_sword', 20);
Progression.lockPerks(['Art of preservation']); // perk names or GUIDs
Progression.setGameXp(false); // only XP your scripts give counts

Two events let you decide case by case. Return false from playerXpGaining to refuse an XP gain, or from playerPerkLearning to refuse a perk chosen on the perk screen.

One player

GoalMembers
Readplayer.level, player.levels, player.skills, player.trackOf(track), player.perks, player.hasPerk(perk)
GiveaddXp(track, xp), setLevel(track, level), addPerk(perk), addPerkPoints(track, count)
Take awayremovePerk(perk), resetPerks()
Exact XPsetXp(track, totalXp), removeXp(track, xp)
RecipeslearnRecipe(id), forgetRecipe(id), knowsRecipe(id); ids from Recipe

setXp sets a track's total XP counted from level 0. removeXp subtracts from the amount the player's game last reported. With both, the level moves up or down as needed, without rewards, points or a notice. Progression.xpNeeded(track, level) gives the XP a level costs. Before version 0.3.4, setXp set the XP within the current level.

Saving progress between visits

Store player.progression when a player leaves, and pass it to loadProgression when they return:

const { Events } = kcds.core;
const savedProgress = new Map();

Events.on('playerDisconnect', (player) => {
  savedProgress.set(player.nickname, player.progression);
});

Events.on('playerReady', (player) => {
  const snapshot = savedProgress.get(player.nickname);
  if (snapshot) {
    player.loadProgression(snapshot, { notify: false });
  }
});

This map is lost when the server stops, so save to your own storage for anything lasting.

Events and the catalogue

Events: playerXpGained, playerLevelUp, playerPerkAdded, playerPerkRemoved.

To look things up: Progression.tracks(), Progression.perks(filter), Progression.perkNamed(query), Progression.xpNeeded(track, level).

Status effects

player.addBuff(name), removeBuff, hasBuff and clearBuffs(tag) use the game's buffs, which you can find with kcds.players.Buffs.find. You can also make your own: Custom buffs.

With kcds.players.Buffs.claim(classes), the server takes over whole kinds of effect. For example, players' games then stop applying alcohol or poison buffs by themselves, and playerBuffBlocked tells you when one tried.

Sleep and food

These needs are off by default, so nobody gets tired or hungry. kcds.players.Needs.setEnabled(true) turns the game's needs on for everyone. setEnabled(false) turns them off again and fills both.

Reference: Progression, Player, Buffs, Needs.