---
title: Startup Registries
hide_meta: true
---

# Startup Registries

Startup events register structures that PMMO needs before gameplay begins. These belong in `startup_scripts/`, not `server_scripts/`.

## What goes where

**Put in `startup_scripts/`:**
- `PmmoJS.registerPredicate(...)` — custom requirement predicates
- `PmmoJS.registerPerk(...)` — new perk type definitions
- `PmmoHelper.registerRequirementData(...)` — direct PMMO data registration
- `PmmoHelper.registerXpAwardData(...)` — direct XP award registration
- `PmmoHelper.registerTriggerListener(...)` — direct trigger listener registration
- `ForgeEvents.onEvent(...)` — raw Forge event listeners

**Put in `server_scripts/`:**
- `PmmoJS.trigger(...)`, `PmmoJS.internal(...)` — runtime hooks
- All config events — `PmmoJS.skillsConfig(...)`, `PmmoJS.perksConfig(...)`, etc.
- `PmmoJS.settings(...)` — item/block/entity data
- `ProbeJSEvents.generateDoc(...)` — 自定义 ProbeJS 文档生成

## `PmmoJS.registerPredicate`

Registers custom predicates that PMMO evaluates during requirement checks. Three methods are available:

- `registerActionPredicate(resourceId, reqType, predicate)` — for item actions
- `registerBreakPredicate(resourceId, reqType, predicate)` — for block breaks
- `registerEntityPredicate(resourceId, reqType, predicate)` — for entity interactions

Each predicate receives the current `Player` and the relevant target object.

```js
PmmoJS.registerPredicate(event => {
  event.registerActionPredicate(
    PmmoHelper.id('minecraft:stick'),
    ReqType.WEAPON,
    (player, stack) => player.experienceLevel >= 5
  )
})
```

## `PmmoJS.registerPerk`

Defines new PMMO perk types. This is the heavyweight API for creating custom perks with lifecycle callbacks.

Custom perk registration uses a dedicated builder with lifecycle callbacks.

## Direct PMMO registration

`PmmoHelper` is available in `startup_scripts/` for registering data directly into PMMO's API. This is useful when you want precise control over what gets registered without going through the KubeJS event system.

Common helpers:

```js
// Register requirements
PmmoHelper.registerRequirementData(
  ObjectType.ITEM, 'minecraft:diamond_pickaxe', ReqType.TOOL,
  { mining: 10, endurance: 4 }, true
)

// Register XP awards
PmmoHelper.registerXpAwardData(
  ObjectType.ITEM, 'minecraft:diamond_pickaxe', EventType.BLOCK_BREAK,
  { mining: 8 }, true
)

// Register a trigger listener
PmmoHelper.registerTriggerListener('kubejs:example', EventType.BLOCK_BREAK,
  (forgeEvent, context) => {
    context.putInt('bonus_roll', 1)
    context.putBoolean('is_cancelled', false)
    return context
  }
)
```

For the direct data helpers above, the last parameter (`true`) tells PMMO to replace existing data rather than merging with it.

Raw trigger listeners must return a tag containing `is_cancelled`; PMMO uses that key to decide whether the listener output is valid. Use `PmmoJS.trigger(...)` for ordinary runtime scripts.

Full list of direct registration methods: `registerRequirementData`, `registerXpAwardData`, `registerDamageXpAwardData`, `registerBonusData`, `registerPositiveEffects`, `registerNegativeEffects`, `registerSalvageData`, `registerVeinData`, `registerMobModifierData`, `registerTriggerListener`, plus tooltip registration variants.

## Raw Forge events

On KubeJS for 1.20.1, `ForgeEvents.onEvent(...)` is a startup-script API:

```js
ForgeEvents.onEvent(
  'net.minecraftforge.event.entity.player.PlayerEvent$PlayerLoggedInEvent',
  event => {
    console.info(`[PmmoJS] ${event.getEntity().getScoreboardName()} logged in`)
  }
)
```

`ProbeJSEvents.generateDoc(...)` 是 server script API，不是 startup API。两套事件系统看起来相似，但生命周期不同。

PmmoJS 会自动注册自己的 ProbeJS 类型。`ProbeJSEvents.generateDoc(...)` 只用于整合包自己的额外代码片段或自定义文档。
