> For the complete documentation index, see [llms.txt](https://axiomemu.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://axiomemu.gitbook.io/docs/data/plugins/catchup.md).

# Catch-Up System

The Catch-Up System gives characters who are behind the server's leading progress a scaling EXP, zen, and item-drop bonus. The bonus grows with how far behind the character is and shrinks to nothing once they reach the front. It is free, always on, and drives an always-on HUD element that shows the current server leader. The math uses the Nth-place player as the anchor so a single mule cannot inflate everyone's rates.

## File Location

```
Data/Plugins/Characters/CatchUpSystem.xml
```

## How the Bonus Is Computed

Each character has a progress score:

```
score = GrandReset * GrandResetWeight + MasterReset * MasterResetWeight + Reset * MaxLevel + Level
```

`MaxLevel` is taken from the server's configured max level-up (falls back to 400).

The system finds the anchor score (the score of the Nth-place player set by `Anchor Rank`) and computes a gap ratio:

```
ratio = (anchorScore - myScore) / anchorScore     clamped to 0 .. RatioCap
```

Each bonus is then `ratio` raised to that bonus's shape exponent, times that bonus's cap:

```
expPct      = round( ratio ^ ExpShape   * MaxExpBonusPct )
dropPct(cat)= round( ratio ^ Shape[cat] * MaxPct[cat] )     (0 if the category is disabled)
```

A character at or above the anchor gets ratio 0 and no bonus. Item quality (luck, excellent options) is never boosted - only drop chance and amount.

## Shape (Curve Exponent)

`Shape` controls how the bonus scales with the gap. Each bonus has its own `Shape`.

| Shape            | Curve        | Effect                                                   |
| ---------------- | ------------ | -------------------------------------------------------- |
| 1.0              | Linear       | Bonus is proportional to how far behind the character is |
| Greater than 1.0 | Back-loaded  | Small until far behind, then ramps up                    |
| Less than 1.0    | Front-loaded | Large bonus even when only a little behind               |

## Configuration

```xml
<CatchUpSystem Enable="1">
  <Score GrandResetWeight="100000" MasterResetWeight="10000"/>
  <Anchor Rank="10" RatioCap="1.0"/>
  <Curve MaxExpBonusPct="1500" Shape="1.0"/>
  <Drop>
    <NormalItem Enable="1" MaxPct="300" Shape="1.0"/>
    <Zen        Enable="1" MaxPct="300" Shape="1.0"/>
    <RareTable  Enable="1" MaxPct="100" Shape="1.0"/>
    <ExcSet     Enable="1" MaxPct="100" Shape="1.0"/>
  </Drop>
  <Display Title="CATCH-UP EXP"/>
</CatchUpSystem>
```

### Root

| Attribute | Type      | Range | Default | Effect                                                                        |
| --------- | --------- | ----- | ------- | ----------------------------------------------------------------------------- |
| `Enable`  | int (0/1) | 0-1   | 1       | Master switch. Also drives HUD visibility. 0 disables all bonuses and the HUD |

### Score

Weights that convert progress into the comparison score.

| Attribute           | Type | Range | Default | Effect                                                                                                                          |
| ------------------- | ---- | ----- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `GrandResetWeight`  | int  | raw   | 100000  | Points per grand reset in the score. Should exceed one full reset's worth (`MaxLevel`) so a grand reset outranks stacked resets |
| `MasterResetWeight` | int  | raw   | 10000   | Points per master reset in the score                                                                                            |

### Anchor

Which ranked player the bonus is measured against, and the cap on the gap ratio.

| Attribute  | Type   | Range   | Default | Effect                                                                                                                                              |
| ---------- | ------ | ------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Rank`     | int    | 1-1000  | 10      | The ranked position whose score is the anchor. Values below 1 or above 1000 are clamped. The HUD still shows the #1 player regardless of this value |
| `RatioCap` | number | 0.0-1.0 | 1.0     | Upper clamp on the gap ratio. 1.0 = no cap (full bonus at maximum gap). A value at or below 0 is treated as 1.0; above 1.0 is clamped to 1.0        |

### Curve (EXP)

| Attribute        | Type   | Range   | Default | Effect                                                                                                     |
| ---------------- | ------ | ------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `MaxExpBonusPct` | int    | 0+      | 1500    | Maximum extra EXP percent at the full gap. 1500 = up to +1500% (16x) EXP. Negative values are clamped to 0 |
| `Shape`          | number | above 0 | 1.0     | EXP curve exponent. See Shape table. A value at or below 0 is treated as 1.0                               |

### Drop

Four independent drop categories, each with its own enable, cap, and curve. Category caps are in percent added to the base chance or amount.

| Category     | Default Enable | Default MaxPct | Boosts                                                               |
| ------------ | -------------- | -------------- | -------------------------------------------------------------------- |
| `NormalItem` | 1              | 300            | Base-game item drop chance                                           |
| `Zen`        | 1              | 300            | Zen amount dropped                                                   |
| `RareTable`  | 1              | 100            | Custom / rare drops from [ItemDrop.xml](/docs/data/item/itemdrop.md) |
| `ExcSet`     | 1              | 100            | Excellent and set-item drop chance                                   |

Per-category attributes:

| Attribute | Type      | Range   | Default   | Effect                                                                  |
| --------- | --------- | ------- | --------- | ----------------------------------------------------------------------- |
| `Enable`  | int (0/1) | 0-1     | 1         | 0 = this category gets no bonus (its percent is always 0)               |
| `MaxPct`  | int       | 0+      | see above | Maximum extra percent at the full gap. Negative values are clamped to 0 |
| `Shape`   | number    | above 0 | 1.0       | This category's curve exponent. A value at or below 0 is treated as 1.0 |

### Display

| Attribute | Type   | Range | Default | Effect                                                                                                                                                         |
| --------- | ------ | ----- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Title`   | string | -     | -       | HUD label text. Present in the shipped template for readability; the HUD title is rendered client-side and this attribute is not consumed by the server loader |

## Important Behavior

* The anchor drives the math; the HUD always shows the #1 player. Setting `Rank` higher than 1 lets everyone below the top group still earn a bonus without a single leader zeroing it out.
* The score uses live reset / master-reset / grand-reset / level values, so a character's bonus drops as they progress and rises again after each reset.
* Item quality is never affected. The drop categories change chance and amount only, not which options an item rolls.
* Disabling a drop category (`Enable="0"`) forces its bonus to 0 regardless of `MaxPct` or `Shape`.
* Changes take effect after a plugin reload or GameServer restart. Anchor recomputation and the HUD update as players enter the world, reset, or teleport.

## Examples

{% tabs %}
{% tab title="Default (EXP + all drops)" %}

```xml
<CatchUpSystem Enable="1">
  <Score GrandResetWeight="100000" MasterResetWeight="10000"/>
  <Anchor Rank="10" RatioCap="1.0"/>
  <Curve MaxExpBonusPct="1500" Shape="1.0"/>
  <Drop>
    <NormalItem Enable="1" MaxPct="300" Shape="1.0"/>
    <Zen        Enable="1" MaxPct="300" Shape="1.0"/>
    <RareTable  Enable="1" MaxPct="100" Shape="1.0"/>
    <ExcSet     Enable="1" MaxPct="100" Shape="1.0"/>
  </Drop>
  <Display Title="CATCH-UP EXP"/>
</CatchUpSystem>
```

{% endtab %}

{% tab title="EXP only, back-loaded" %}
Only badly-behind players get a large boost; drops are untouched.

```xml
<CatchUpSystem Enable="1">
  <Score GrandResetWeight="100000" MasterResetWeight="10000"/>
  <Anchor Rank="5" RatioCap="1.0"/>
  <Curve MaxExpBonusPct="800" Shape="2.0"/>
  <Drop>
    <NormalItem Enable="0" MaxPct="0"  Shape="1.0"/>
    <Zen        Enable="0" MaxPct="0"  Shape="1.0"/>
    <RareTable  Enable="0" MaxPct="0"  Shape="1.0"/>
    <ExcSet     Enable="0" MaxPct="0"  Shape="1.0"/>
  </Drop>
  <Display Title="CATCH-UP EXP"/>
</CatchUpSystem>
```

{% endtab %}
{% endtabs %}

## Common Issues

{% hint style="warning" %}
No bonus for anyone: if fewer players exist than `Anchor Rank`, or the anchor score is 0, the ratio is 0 and no bonus applies. Lower `Rank` on a small server.
{% endhint %}

{% hint style="warning" %}
Grand resets not outweighing resets: keep `GrandResetWeight` above `MaxLevel` so one grand reset scores higher than a stack of ordinary resets.
{% endhint %}

{% hint style="info" %}
HUD label wrong: the HUD title text is drawn by the client. The `Display Title` attribute in this file is for readability and does not change the client label.
{% endhint %}
