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 predicatesPmmoJS.registerPerk(...)— new perk type definitionsPmmoHelper.registerRequirementData(...)— direct PMMO data registrationPmmoHelper.registerXpAwardData(...)— direct XP award registrationPmmoHelper.registerTriggerListener(...)— direct trigger listener registrationForgeEvents.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 dataProbeJSEvents.generateDoc(...)— 自定义 ProbeJS 文档生成
PmmoJS.registerPredicate
Registers custom predicates that PMMO evaluates during requirement checks. Three methods are available:
registerActionPredicate(resourceId, reqType, predicate)— for item actionsregisterBreakPredicate(resourceId, reqType, predicate)— for block breaksregisterEntityPredicate(resourceId, reqType, predicate)— for entity interactions
Each predicate receives the current Player and the relevant target object.
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:
// Register requirementsPmmoHelper.registerRequirementData(ObjectType.ITEM, 'minecraft:diamond_pickaxe', ReqType.TOOL,{ mining: 10, endurance: 4 }, true)// Register XP awardsPmmoHelper.registerXpAwardData(ObjectType.ITEM, 'minecraft:diamond_pickaxe', EventType.BLOCK_BREAK,{ mining: 8 }, true)// Register a trigger listenerPmmoHelper.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:
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(...) 只用于整合包自己的额外代码片段或自定义文档。