> For the complete documentation index, see [llms.txt](https://visionstore.gitbook.io/visionstore-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://visionstore.gitbook.io/visionstore-docs/scripts/crafting/configuration/mastery.md).

# Crafting Mastery

The player's own perk tree in config/mastery.lua - branches, slots, XP and anti-farm rules.

A bench's **level** belongs to the bench. A player's **Mastery** belongs to the character. Two players at the same level 5 bench aren't equally good at using it: one has spent months crafting, the other bought a bench this morning.

Players earn **Mastery XP** by crafting and spend it to unlock perks in a tree. It's a separate currency from bench XP. Everything is in `config/mastery.lua`.

{% hint style="info" %}
**Unlocking is not equipping.** Unlocking a perk is permanent and costs Mastery XP. Equipping it costs a **slot**, and only equipped perks do anything. With 2 slots, a player who unlocked the whole tree still runs only two perks, so they specialise.
{% endhint %}

## Basics

```lua
Config.Mastery = {
    enabled = true,
    debug   = false,
    command = 'craftingperks',
    xpScale = 1.0,
    -- ...
}
```

| Option    | Default           | What it does                                                                                                                       |
| --------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `enabled` | `true`            | Turn the whole system off with `false`.                                                                                            |
| `debug`   | `false`           | Extra server logging for XP, unlock and equip maths.                                                                               |
| `command` | `'craftingperks'` | Opens the tree fullscreen, away from a bench. `false` = no command. The tree is always reachable from the bench too.               |
| `xpScale` | `1.0`             | **The tuning dial.** Every perk cost is multiplied by this. `0.7` = 30% faster, `2.0` = twice as slow. Safe to change at any time. |

## The tree

Four branches. Tiers unlock strictly in order, and a tier's `value` is the **total** effect (Speed IV is 45% faster, not 5+15+30+45).

| Branch                 | Effect                 | Tiers: value (cost in Mastery XP)                                                                    |
| ---------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------- |
| **Crafting Speed**     | Crafts take less time  | I 5% (1,500) · II 15% (5,200) · III 30% (16,000) · IV 45% (44,000)                                   |
| **Table Maintenance**  | Repairs finish sooner  | I 5% (1,200) · II 15% (4,200) · III 30% (12,000) · IV 45% (30,000) · V 65% (68,000)                  |
| **Crafting Knowledge** | More Mastery XP earned | I 5% (1,200) · II 10% (3,600) · III 15% (9,000) · IV 20% (20,000) · V 30% (45,000) · VI 40% (95,000) |
| **Careful Handling**   | Less bench wear        | I 5% (1,400) · II 10% (4,800) · III 15% (14,000)                                                     |

Each tier looks like this in the file:

```lua
{ key = 'speed_1', label = 'mastery.speed_1', value = 0.05, cost = 1500 },
```

Edit `value` and `cost` freely. Keep the branch `effect` names (`craftSpeed`, `repairSpeed`, `xpGain`, `damageReduction`) as they are.

### Effect caps

A safety net in case a tier is edited to something extreme:

```lua
caps = {
    craftSpeed      = 0.60,
    repairSpeed     = 0.75,
    xpGain          = 0.50,
    damageReduction = 0.30,
},
```

## Perk slots

```lua
slots = {
    max = 2,
    bonuses = {
        { atLifetimeXp = 120000, slots = 1 },  -- ~7 months in: 3 slots
    },
    absoluteMax = 3,
},

equip = {
    cooldownSeconds  = 60,
    oneTierPerBranch = true,
},
```

| Option                   | Default                   | What it does                                                           |
| ------------------------ | ------------------------- | ---------------------------------------------------------------------- |
| `slots.max`              | `2`                       | Perks that can be equipped at once. The most important balance number. |
| `slots.bonuses`          | +1 at 120,000 lifetime XP | Extra slots at lifetime-XP milestones. Empty = hard cap at `max`.      |
| `slots.absoluteMax`      | `3`                       | Ceiling including bonuses.                                             |
| `equip.cooldownSeconds`  | `60`                      | Seconds between equip changes, per player.                             |
| `equip.oneTierPerBranch` | `true`                    | Equipping Speed III replaces Speed I instead of using a second slot.   |

## Earning Mastery XP

XP is awarded when a craft **finishes** on the server. A cancelled craft earns nothing.

```lua
xp = {
    perRecipeXp       = 0.35,
    fallbackPerCraft  = 4,
    quantityExponent  = 0.6,
    failureMultiplier = 0.35,
    maxPerCraft       = 120,
},
```

| Option              | Default | What it does                                                         |
| ------------------- | ------- | -------------------------------------------------------------------- |
| `perRecipeXp`       | `0.35`  | Mastery XP = the recipe's `xp` × this × the quantity factor.         |
| `fallbackPerCraft`  | `4`     | Used for recipes without their own XP.                               |
| `quantityExponent`  | `0.6`   | Batches pay less than linear. `1.0` = linear, `0` = ignore quantity. |
| `failureMultiplier` | `0.35`  | Failed units pay this fraction. `0` = nothing.                       |
| `maxPerCraft`       | `120`   | Cap for one finished craft, after every bonus.                       |

## Anti-farm

```lua
antiFarm = {
    enabled = true,

    minCraftSeconds      = 60,
    shortCraftMultiplier = 0.35,

    repetition = {
        enabled       = true,
        window        = 3 * 60 * 60,  -- 3 hours, rolling
        decay         = 0.82,
        minMultiplier = 0.20,
    },

    dailySoftCap = {
        enabled            = true,
        dailyXp            = 600,
        overflowMultiplier = 0.20,
        window             = 24 * 60 * 60,
    },

    eventRetention = 26 * 60 * 60,
},
```

| Rule               | What it does                                                                                                                                                                                                    |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Short crafts**   | Crafts shorter than `minCraftSeconds` pay `shortCraftMultiplier` (reduced, not zero).                                                                                                                           |
| **Repetition**     | The Nth craft of the **same** recipe within `window` pays `decay ^ (N-1)`, down to `minMultiplier`. With the defaults: 1st 100%, 2nd 82%, 3rd 67%, 5th 45%, 10th 20%. Crafting different things pays full rate. |
| **Daily soft cap** | After `dailyXp` in a rolling 24 h, XP keeps coming at `overflowMultiplier`. Not a wall.                                                                                                                         |
| `eventRetention`   | How long the anti-farm history is kept. Must be longer than the windows above.                                                                                                                                  |

## Pacing

With the defaults (600 XP/day soft cap, a player who crafts most days), the file estimates:

| Goal                  | Total XP | Roughly    |
| --------------------- | -------- | ---------- |
| Crafting Speed I      | 1,500    | 2-3 days   |
| Crafting Speed II     | 6,700    | 11 days    |
| Crafting Speed IV     | 66,700   | 3.5 months |
| Table Maintenance V   | 115,400  | 6.5 months |
| Crafting Knowledge VI | 173,800  | 9.5 months |
| Careful Handling III  | 20,200   | 5 weeks    |

Too slow for your server? Lower `xpScale` (for example `0.6`) instead of editing 18 costs by hand.

{% hint style="success" %}
Admin tools: `/crafting mastery <id>` shows a player's mastery, `/crafting mastery-xp <id> <amount>` grants XP, `/crafting mastery-reset <id>` wipes it, and `/crafting mastery-why <id> <recipe>` explains how much XP a recipe would give that player and why.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://visionstore.gitbook.io/visionstore-docs/scripts/crafting/configuration/mastery.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
