---
title: PMMO Settings
hide_meta: true
---

# PMMO Settings

`PmmoJS.settings` is the main way to register PMMO data for items, blocks, entities, biomes, and dimensions from `server_scripts/`.

Think of it as a replacement for editing PMMO's JSON config files by hand. You write JavaScript instead, and the data is applied cleanly through PMMO's API.

## Single targets

Use these when you need to configure one object at a time:

```js
PmmoJS.settings(event => {
  event
    .item('minecraft:diamond_sword')
    .override(true)
    .setRequirement(ReqType.WEAPON, 'combat', 10)
    .setXp(EventType.CRAFT, 'smithing', 100)

  event
    .block('minecraft:diamond_ore')
    .override(true)
    .setRequirement(ReqType.BREAK, 'mining', 30)
    .setXp(EventType.BLOCK_BREAK, 'mining', 200)

  event
    .entity('minecraft:zombie')
    .override(true)
    .setXp(EventType.DEATH, 'combat', 25)
})
```

Available target methods: `event.item(id)`, `event.block(id)`, `event.entity(id)`, `event.biome(id)`, `event.dimension(id)`, `event.generic(objectType, id)`.

You can pass either the registry object or a string ID. For items, blocks, and entities, both work.

## Batch targets

These apply the same configuration to many targets at once — much cleaner than repeating the same setup code:

```js
PmmoJS.settings(event => {
  event.items([
    'minecraft:diamond_sword',
    'minecraft:netherite_sword',
    'minecraft:trident'
  ], setting => {
    setting.override(true)
    setting.setRequirement(ReqType.WEAPON, 'combat', 20)
    setting.setXp(EventType.CRAFT, 'smithing', 150)
  })

  event.entities([
    'minecraft:villager',
    'minecraft:wandering_trader'
  ], setting => {
    setting.override(true)
    setting.setRequirement(ReqType.ENTITY_INTERACT, 'charisma', 8)
  })
})
```

Available batch methods: `event.items(targets, callback)`, `event.blocks(targets, callback)`, `event.entities(targets, callback)`, `event.biomes(targets, callback)`, `event.dimensions(targets, callback)`, `event.genericMany(objectType, targets, callback)`.

The `targets` parameter accepts a single ID string, a single registry object, a JS array, or any iterable.

## Common builder methods

All settings builders share these methods:

- `setRequirement(reqType, skill, level)` — require a skill level to use the object
- `requirement(reqType, map)` — set multiple requirements at once (e.g., `{combat: 10, mining: 5}`)
- `setXp(eventType, skill, amount)` — award XP for an action
- `xp(eventType, map)` — set multiple XP awards at once
- `override(boolean)` — when `true`, replace PMMO's default data instead of merging with it

## Authoring flow

Use `PmmoJS.settings(...)` for PMMO's object data. Object data is the normal place for stable pack rules:

1. Choose the target object: item, block, entity, biome, or dimension.
2. Decide whether you are replacing defaults with `override(true)` or layering onto them with `override(false)`.
3. Add normal requirements and XP for rules based only on the registry ID.
4. Add NBT logic only when the registry ID is not enough.
5. Add type-specific extras such as salvage, effects, bonuses, or vein data.

Runtime hooks like `PmmoJS.trigger(...)` should not be the first tool for requirements. If every diamond pickaxe needs level 20 mining, put that in `settings`. Use runtime hooks when the rule depends on live state such as stages, party state, temporary events, or custom context.

## NBT logic with globals

PMMO's NBT logic is for modular objects: one registry ID with different behavior stored in NBT. Examples include Tinkers' Construct, Tetra, Silent Gear, and other tools or armor that store material data in tags.

There are three NBT builder entry points:

| Method | Writes PMMO data for |
|---|---|
| `nbtRequirement(reqType)` | Skill requirements based on NBT |
| `nbtXp(eventType)` | XP awards based on NBT |
| `nbtBonus(modifierType)` | XP modifiers based on NBT |

Each `.done()` call writes one PMMO `LogicEntry`. Multiple entries for the same object can combine with `BehaviorToPrevious`.

`EventType`, `ReqType`, `ObjectType`, and `ModifierDataType` are PmmoJS globals. `BehaviorToPrevious` and `Operator` are PMMO NBT enums, so load them when you need the low-level enum directly. The convenience methods like `.equals(...)`, `.greaterThan(...)`, and `.exists(...)` do not require loading `Operator`.

```js
const BehaviorToPrevious = Java.loadClass('harmonised.pmmo.core.nbt.BehaviorToPrevious')

PmmoJS.globalsConfig(event => {
  event.addPath('head_material', 'tic_materials[0]')
  event.addPath('all_materials', 'tic_materials[]')
  event.addPath('damage', 'Damage')

  event.addConstant('iron', 'tconstruct:iron')
  event.addConstant('manyullyn', 'tconstruct:manyullyn')
})

PmmoJS.settings(event => {
  event
    .item('tconstruct:pickaxe')
    .override(true)
    .setRequirement(ReqType.TOOL, 'mining', 5)

    .nbtRequirement(ReqType.TOOL)
    .newCase('#head_material')
    .equals('#iron', 'mining', 10)
    .equals('#manyullyn', 'mining', 35)
    .done()

    .nbtRequirement(ReqType.TOOL)
    .behavior(BehaviorToPrevious.SUB_FROM)
    .newCase('#damage')
    .greaterThan(800, 'mining', 10)
    .done()
})
```

In this example:

- `setRequirement(...)` gives the item a base rule.
- `#head_material` expands through `globalsConfig` before PMMO reads NBT.
- `#iron` and `#manyullyn` expand through `globalsConfig` before PMMO compares values.
- `BehaviorToPrevious.SUB_FROM` subtracts the second NBT entry from the result built before it.

Use `.additive(true)` when one NBT path can return several values and each match should contribute:

```js
PmmoJS.settings(event => {
  event
    .item('tconstruct:pickaxe')
    .override(true)
    .nbtRequirement(ReqType.TOOL)
    .additive(true)
    .newCase('#all_materials')
    .equals('#iron', 'mining', 5)
    .equals('#manyullyn', 'mining', 20)
    .done()
})
```

Without `.additive(true)`, PMMO keeps the highest value for duplicate skills inside one logic entry. With it, matching cases add together.

See [Config Events](config#pmmojsglobalsconfig) for how globals work and [PMMO Authoring Workflow](../pmmo-workflow) for the full data flow.

## Type-specific features

Depending on the builder type, you also get access to:

- **Items:** salvage configuration, vein-mining settings, NBT-based requirements and XP
- **Entities:** damage-type XP registration, positive/negative mob effects
- **Blocks:** vein-mining data, NBT requirements
- **Locations:** mob modifiers for biomes and dimensions

Example — configuring vein mining on an item:

```js
PmmoJS.settings(event => {
  event
    .item('minecraft:diamond_pickaxe')
    .override(true)
    .veinChargeCap(128)
    .veinChargeRate(1.25)
    .veinConsumeAmount(2)
})
```

## Clearing default data

If you want to wipe PMMO's built-in data and start from scratch, use `config/pmmojs-common.toml`:

```toml
[disableDefaultSettings]
all = false
skills = false
perks = false
requirements = false
xpAwards = false
itemExtras = false
blockVeinData = false
```

The reset happens before your KubeJS scripts run, so your custom data always wins.

The settings event also has legacy helpers `clearVanillaItemSettings()`, `clearVanillaBlockSettings()`, and `clearVanillaEntitySettings()`. These only reset requirement data — they don't touch XP awards, bonuses, effects, salvage, or vein data. Use the common config for full resets.

## Enum naming

PMMO's enum names are case-sensitive and follow the PMMO source code exactly. Some values that trip people up:

- `ReqType.ENTITY_INTERACT` exists, `ReqType.ENTITY` does not
- `EventType.BLOCK_BREAK` exists, `EventType.BREAK` does not
- `EventType.DEATH` exists, `EventType.KILL` does not

安装 ProbeJS 后，类型补全会直接显示可用值。
