NeoOrigins 2.0 action_on_event Event Reference

neoorigins:action_on_event listens for one of the event keys below. When the event fires, the power’s entity_action (for action-style events) or modifier (for MOD_* events) runs with the event’s context in scope.

Source of truth for the key list: EventPowerIndex.Event. Every key in the enum has a live EventPowerIndex.dispatch(...) call site. Keys that earlier drafts exposed without a dispatch site have been removed rather than left as silent no-ops; see the Removed keys section at the bottom for the two that were dropped (and their replacements).

Event shape

{
  "type": "neoorigins:action_on_event",
  "event": "<KEY>",
  "condition": { ... },          // optional: entity-side gate (object, or array = all must pass)
  "entity_action": { ... },      // for action-style events
  "modifier": { ... },           // for MOD_* events (object or array); chains with other registered modifiers
  "block_condition": { ... },    // optional: block-side gate (block events only)
  "item_condition": { ... },     // optional: item gate (item-carrying events only)
  "hands": ["main_hand"],        // optional: hand gate (interaction events only); `hand` also accepted
  "cooldown_ticks": 0,           // optional: re-fire cooldown for the action, in ticks
  "effect": "...",               // effect_applied only (see that section)
  "effect_tag": "...",           // effect_applied only
  "immunity_ticks": 0,           // effect_applied only
  "power": "..."                 // power_activated only (see that section)
}

event is the enum name, matched case-insensitively (e.g. "kill", "mod_exhaustion"). If it is not an enum name, the compat spelling table is tried; an event that matches neither is a load error and the whole power is dropped.

condition is an EntityCondition evaluated against the player before the action / modifier runs. Use it for neoorigins:power_active, item-in-hand, fluid-in-eyes, and similar gates. entity_action and modifier may both be set on one power; the dispatcher only calls whichever matches the site’s call shape.

Action-path gates. The entity_action runs only when every configured gate passes, checked in this order: the effect / effect_tag filter (effect_applied), the power filter (power_activated), condition, hands, item_condition, block_condition, then cooldown_ticks. The modifier path consults only condition; block_condition, item_condition, hands and cooldown_ticks have no effect on modifier.

block_condition reads the block position out of the event context. That works for block_break and block_place (the NeoForge BlockEvent) and for block_use and bonemeal (BlockInteractContext). On any other event there is no position to read and the gate fails closed: the action never runs. The value is a block condition compiled by the same block-condition compiler Apoli-format packs use (and / or combinators, offset, block_state, height, adjacent, and a leaf matching a block / id / tag field), e.g. { "type": "neoorigins:block", "id": "minecraft:stone" }. An unsupported leaf matches everything and logs a warning. Use this instead of (or in addition to) condition when you want to filter by what was broken/placed/used:

{
  "type": "neoorigins:action_on_event",
  "event": "block_break",
  "block_condition": { "type": "neoorigins:block", "id": "minecraft:stone" },
  "entity_action": {
    "type": "neoorigins:drop_items",
    "items": [{ "item": "minecraft:emerald", "chance": 0.05 }]
  }
}

item_condition is an item condition (the same parser equipped_item uses) tested against the stack the event carries: the FoodContext stack on item_use, food_eaten, item_use_finish and food_finished, the item entity’s remaining stack on item_pickup (empty after a full pickup; see that section), and the stack in the interacting hand on block_use, entity_use and villager_interact. On an event with no item (or an empty stack) the gate fails closed.

hands (or hand) takes "main_hand" / "off_hand" (also "mainhand" / "offhand"), as a single string or an array. Only the block_use, entity_use and villager_interact contexts carry a hand; on every other event the gate fails closed. Unknown values are skipped with a warning.

cooldown_ticks (default 0, off) suppresses the action for that many ticks after it runs. The timer is per power and per player, stored in the player’s origin data and counted down by the power’s tick.

The event’s context is published to ActionContextHolder for the duration of the dispatch so context-aware action verbs (neoorigins:damage_attacker, neoorigins:cancel_event, neoorigins:food_item_in_tag, …) can read it without needing to be parameterised at JSON authoring time.

cancel_event support

neoorigins:cancel_event as the entity_action vetoes the underlying game event, but only where NeoForge exposes a cancellable event:

  • Cancellable: death (lethal blow undone; a player still at 0 HP is left at 1 HP, totem-style), kill (spares the victim, same 1-HP patch), hit_taken, attack, land (negates fall damage), projectile_hit, item_use, food_eaten, effect_applied, block_break, block_place, block_use, entity_use, villager_interact, breed, tame, bonemeal.
  • Not cancellable (post-hoc or uncancellable NeoForge event; cancel_event is a silent no-op): jump, item_use_finish, food_finished, item_pickup, craft_item, smelt_item, enchant_item, anvil_repair, trade_completed, advancement_earned, wake_up, respawn, dimension_change, climb, tick, gained, lost, chosen, power_activated, and all mod_* modifier events.

Action-style events

These run a side-effect action against the player actor when fired. Register via entity_action.

attack

Fires when the player attacks an entity (pre-damage).

Context: EntityInteractContext(target, event) when the target is a LivingEntity: bientity conditions resolve the target, and the wrapped AttackEntityEvent is what neoorigins:cancel_event vetoes. Non-living targets (boats, item frames) fall back to the raw AttackEntityEvent, so cancel_event still works there but bientity conditions have no target.

Dispatch site: CombatPowerEvents.onAttackEntity (hooks AttackEntityEvent).

Typical use: apply mining fatigue / slow to anything you hit, charge a rage meter, spawn a visual shockwave.


hit_taken

Fires when the player takes damage (post-cancel, before final apply).

Context: HitTakenContext(amount, source, event). The amount is the incoming damage after NeoOrigins’ own modify_damage (incoming) scaling; armour, enchantment and resistance reductions are applied later by vanilla. The DamageSource is the original source, and event is the cancellable LivingIncomingDamageEvent that makes neoorigins:cancel_event work (null at dispatch sites without cancel semantics). Action verbs like neoorigins:damage_attacker read amount for amount-ratio thorns-style retaliation.

Dispatch site: CombatPowerEvents.onLivingDamage (LivingIncomingDamage victim branch).

Typical use: thorns/counter-damage, defensive-cooldown triggers, hurt-noises, panic-mode buffs.


hit_dealt

Fires on the attacker when the player deals damage to a living entity: the attacker-side mirror of hit_taken. Unlike attack (which fires pre-damage), this fires from a LOW-priority LivingIncomingDamageEvent listener, so the amount already includes NeoOrigins’ own damage modifiers (which run at HIGH priority). Armour and resistance on the target are applied later by vanilla. Not dispatched if another listener cancelled the damage.

Context: HitDealtContext(amount, target, source). amount is the incoming damage as seen at LOW priority, target is the LivingEntity that was hit, and source is the DamageSource. The neoorigins:hit_dealt_amount condition gates on the most recent damage the player dealt.

Dispatch site: CombatPowerEvents.onPlayerDealDamage (LOW-priority LivingIncomingDamageEvent, attacker = ServerPlayer).

Typical use: lifesteal / blood-tithe healing scaled to damage dealt, combo counters, on-hit resource gain, big-hit screen shake.


kill

Fires when the player kills a living entity.

Context: KillContext(killed, event): the LivingEntity that just died plus the cancellable LivingDeathEvent, which is what lets neoorigins:cancel_event spare the victim. Bientity / entity-type conditions can filter on the killed entity.

Dispatch site: CombatPowerEvents.onLivingDeath (killer = ServerPlayer branch).

Typical use: bloodthirst healing, kill-streak counters, soul-capture mechanics.


death

Fires when the player themself dies.

Context: the cancellable LivingDeathEvent itself, so neoorigins:cancel_event can veto the death. After a veto a player still at 0 HP is patched to 1 HP (totem-style) so they don’t re-die next tick.

Dispatch site: CombatPowerEvents.onLivingDeath (dying-player branch, fires before the killer branch).

Typical use: revival sigils (paired with neoorigins:cancel_event), last-stand explosions, insurance payouts.


block_break

Fires when the player successfully breaks a block (post-cancel).

Context: the BlockEvent.BreakEvent itself, readable by neoorigins:cancel_event and any verb that reflects on the event object.

Dispatch site: WorldPowerEvents.onBlockBreak.

Typical use: XP from ores, mining-sound replacement, silk-touch emulation.


block_place

Fires when the player places a block. Cancellable via neoorigins:cancel_event (vetoes the placement).

Context: the BlockEvent.EntityPlaceEvent.

Dispatch site: WorldPowerEvents.onBlockPlace.

Typical use: place-and-enchant, build-mode dust particles, builder-class XP.


item_use

Fires when the player right-clicks to use an item. Two kinds of item are covered:

  • Held-use items (food, potions, bows, shields, spyglasses, tridents; anything with a use duration): fires at use start, when the right-click hold begins.
  • Instant-use items (fireworks, ender pearls, snowballs, eggs, splash potions, fire charges; anything used in a single click): fires on the right-click itself, whether aimed at air or at a block.

Context: the held ItemStack, plus the cancellable interaction event, so neoorigins:cancel_event vetoes the use, and an item_condition can target a specific item (e.g. only minecraft:firework_rocket).

Dispatch site: CompatEventPowers.onItemUseStart (LivingEntityUseItemEvent.Start, held-use items), CompatEventPowers.onRightClickItem (RightClickItem, instant items in air), and CompatEventPowers.onRightClickBlockUse (RightClickBlock, instant items aimed at a block). All run after the prevent_item_use gate, only if not cancelled.

Typical use: rev-up animations, charging sounds, start cooldowns; or, with cancel_event, blocking an item outright (e.g. preventing firework use). On the block-aimed path (an instant-use item used while looking at a block), cancel_event cancels the whole RightClickBlock, so the block’s own interaction (opening a chest, flipping a lever) is blocked too. The prevent_item_use power is narrower there: it denies only the item’s use.

Note: instant-use coverage is broader than a held-use start. An item_use handler with no item_condition now also fires on snowballs, ender pearls, etc. Add an item_condition to scope it to the items you care about.

Accepted spelling: item_use_start also resolves here (see Compat spellings). For a shield, bow or food the two names denote the same instant; item_use merely covers instant-use items as well, which have no “start” distinct from their use.


respawn

Fires when the player respawns (after origin re-sync and modify_player_spawn teleport).

Context: none.

Dispatch site: PlayerLifecycleEvents.onPlayerRespawn.

Typical use: gift-on-respawn, status-effect restore, hunger top-up.


tick

Fires once per server tick for every online player.

Context: none.

Dispatch site: PlayerLifecycleEvents.onPlayerTick (PlayerTickEvent.Pre).

Typical use: anything that must react every tick. For periodic work, neoorigins:condition_passive with an interval (default 20 ticks) is cheaper. tick runs 20 times a second for every player.


dimension_change

Fires when the player changes dimension.

Context: none. If you need the dimension ID, query player.level().dimension() inside the action.

Dispatch site: PlayerLifecycleEvents.onPlayerChangedDimension.

Typical use: dimension-gated buffs, portal-sickness effects, re-equip starter gear on Nether entry.


climb

Fires once per server tick while the player is on a climbable block (ladder, vine, scaffolding, …).

Context: none. Query player state inside the action for finer detail.

Dispatch site: PlayerLifecycleEvents.onPlayerTick (gated on player.onClimbable(), fired right after the generic tick).

Typical use: spider-class climb-speed buffs, wall-cling stamina drain, fall-immunity-while-climbing. Like tick, this runs every tick the gate is met. Keep the action cheap and gate hard with condition.


jump

Fires when the player jumps.

Context: none.

Dispatch site: CombatPowerEvents.onLivingJump (LivingEvent.LivingJumpEvent filtered to ServerPlayer).

Typical use: double-jump priming, jump-boost particles, stamina drain.


projectile_hit

Fires when a projectile owned by the player hits something (entity or block).

Context: ProjectileHitContext(projectile, result, event): the projectile entity, the HitResult, and the cancellable ProjectileImpactEvent that neoorigins:cancel_event negates. Check result.getType() for ENTITY / BLOCK / MISS.

Dispatch site: CombatPowerEvents.onProjectileImpact.

Typical use: homing arrows, projectile-converts-to-lightning, ranged debuff application.


craft_item

Fires when the player crafts an item in a crafting grid (table or inventory).

Context: CraftContext(stack), the crafted result ItemStack.

Dispatch site: CraftingPowerEvents.onItemCrafted (PlayerEvent.ItemCraftedEvent).

Typical use: artisan-class craft XP, recipe-discovery rewards, craft-and-enchant.


smelt_item

Fires when the player removes a smelted item from a furnace / smoker / blast furnace output.

Context: CraftContext(stack), the smelted result ItemStack.

Dispatch site: CraftingPowerEvents.onItemSmelted (PlayerEvent.ItemSmeltedEvent).

Typical use: smelting XP bonus, auto-quench effects, cook-class progress.


enchant_item

Fires when the player applies enchantments at an enchanting table (post-apply).

Context: CraftContext(stack), the freshly-enchanted ItemStack.

Dispatch site: CraftingPowerEvents.onItemEnchanted (PlayerEnchantItemEvent).

Typical use: arcane-class enchant rituals, lapis refund, bonus-curse application. Distinct from mod_enchant_level, which changes the offered level before the player commits.


anvil_repair

Fires when the player takes the repaired / combined output from an anvil.

Context: CraftContext(stack), the finished ItemStack.

Dispatch site: CraftingPowerEvents.onAnvilRepair (AnvilCraftEvent.Post). In 26.1 the legacy AnvilRepairEvent was removed; the post-craft hook is now AnvilCraftEvent.Post, whose getOutput() carries the result.

Typical use: smith-class repair XP, durability bonus on repair, free-naming perks. Distinct from mod_anvil_cost, which only scales the XP cost preview.


food_eaten

Fires at item-use start for any stack carrying a vanilla FOOD data component. Cancellable via neoorigins:cancel_event.

Context: FoodContext(stack, event), the food ItemStack plus the underlying LivingEntityUseItemEvent.Start (so cancel_event can veto the eat). neoorigins:food_item_in_tag reads the stack.

Dispatch site: MovementPowerEvents.onItemUseStart (only dispatched when the stack has a FOOD component).

Typical use: vegetarian / carnivore restrictions, allergen damage, bonus-effect-on-eat.


food_finished

Fires when the player finishes eating a food item (post-eat). Not cancellable: the food has already been consumed. This is distinct from food_eaten, which fires at eat-start and can cancel the eat.

Also fired by InteractionPowerEvents.onEdibleUseFinish after a successful bite of an item made edible by the edible_item power, so custom edible items trigger the same post-eat hooks.

Context: FoodContext(stack), the consumed food ItemStack (no event is attached). Context-aware conditions like neoorigins:food_item_in_tag and neoorigins:food_item_id read the stack.

Dispatch sites: InteractionPowerEvents.onItemUseFinish (LivingEntityUseItemEvent.Finish, only when the stack has a FOOD component) and InteractionPowerEvents.onEdibleUseFinish (edible_item consumes).

Typical use: post-eat nutrition bonuses, food-specific buffs, bonus saturation for certain food types.


advancement_earned

Fires when the player earns an advancement.

Context: AdvancementContext(id), the advancement’s Identifier.

Dispatch site: PlayerLifecycleEvents.onAdvancementEarned (AdvancementEvent.AdvancementEarnEvent). Folded into the existing advancement handler, so it fires for every earned advancement. Gate with condition if you only care about specific ones.

Typical use: milestone rewards, achievement-gated power unlocks, progression-tied buffs.


trade_completed

Fires when the player completes a trade with a villager or wandering trader.

Context: TradeContext(offer), the MerchantOffer that was traded.

Dispatch site: InteractionPowerEvents.onTradeCompleted (TradeWithVillagerEvent).

Typical use: merchant-class trade XP, haggle-streak counters, trade-completion sound / particle.


gained

Fires when a power has just been granted to the player.

Context: the power’s Identifier ID (as a raw Object).

Dispatch site: ActiveOriginService.applyOriginPowers (after onGranted + PowerGrantedEvent).

Typical use: welcome-message broadcasts, one-shot starter equipment, origin-pick particle effect. Fires every origin change. Use condition to gate on a specific origin.


lost

Fires when a power has just been revoked from the player.

Context: the power’s Identifier ID.

Dispatch site: ActiveOriginService.applyOriginPowers (after onRevoked + PowerRevokedEvent).

Typical use: clean-up rituals, revoke-gained items, farewell message.


chosen

Fires when the player picks an origin from the selection screen (ChooseOriginPayload).

Context: the chosen origin’s Identifier.

Dispatch site: NeoOriginsNetwork.handleChooseOrigin. Timing depends on whether the player had already filled every layer:

  • First walkthrough: the per-pick dispatch is deferred. Once the last layer is filled, chosen fires once per layer, in layer order, with that layer’s origin as context.
  • Re-picks (every layer already filled, e.g. Orb of Origin or an admin re-selection): fires immediately for the picked origin.

Assigning an origin by command or random assignment does not go through this handler and does not fire chosen.

Typical use: first-choice welcome flow, origin-lock gates, server-wide announcement.


wake_up

Fires when the player wakes from sleeping.

Context: none.

Dispatch site: PlayerLifecycleEvents.onPlayerWakeUp.

Typical use: well-rested buff, dream-power cooldown reset.


land

Fires when the player lands after a fall, via NeoForge’s LivingFallEvent. That event is only raised when the player has accumulated fall distance, so landings in creative flight or slow descents do not fire land on this line.

Context: the cancellable LivingFallEvent itself, so neoorigins:cancel_event negates the fall damage.

Dispatch site: MovementPowerEvents.onLivingFall (runs after the prevent_action: FALL_DAMAGE gate).

Typical use: landing shockwave, impact-damage scaling, parkour streak reset.


block_use

Fires when the player right-clicks a block (every RightClickBlock event that reaches the listener; the listener does not receive events another handler already cancelled). Cancellable via neoorigins:cancel_event (vetoes the interaction).

Context: BlockInteractContext(pos, state, event), carries the underlying cancellable RightClickBlock event.

Dispatch site: InteractionPowerEvents.onBlockUse.

Typical use: right-click enchant, block-specific rituals, class-lock interactions.


entity_use

Fires when the player right-clicks a living entity. The narrower villager_interact alias fires immediately after, only when the target is a villager or wandering trader. Both are cancellable via neoorigins:cancel_event (vetoes the interaction, e.g. blocking villager trading for an origin).

Context: EntityInteractContext(target, event), carries the underlying cancellable PlayerInteractEvent.EntityInteract event. The breed, tame and bonemeal dispatches share this pattern and are likewise cancellable.

Dispatch site: InteractionPowerEvents.onEntityUse (filtered to LivingEntity targets).

Typical use: healing touch, taming-by-class, entity-hug particle, trade-lock origins (villager_interact + cancel_event).


villager_interact

Fires when the player right-clicks a villager or wandering trader (AbstractVillager covers both), a narrower alias of entity_use, fired immediately after it so a power can target either granularity. Cancellable via neoorigins:cancel_event (vetoes the interaction before the trade screen opens).

Context: EntityInteractContext(target, event), carries the underlying cancellable PlayerInteractEvent.EntityInteract event.

Dispatch site: InteractionPowerEvents.onEntityUse.

Typical use: trade-lock origins (pillager-friendly origins that villagers refuse to deal with), reputation hooks.


breed

Fires when the player causes a baby animal to spawn (feeding two parents). Fires regardless of any twin_breeding power. Cancellable via neoorigins:cancel_event (vetoes the baby spawn).

Context: EntityInteractContext(child, event). The target is the newborn AgeableMob; carries the underlying cancellable BabyEntitySpawnEvent.

Dispatch site: WorldPowerEvents.onBabyEntitySpawn (BabyEntitySpawnEvent, gated on a causing ServerPlayer). Dispatched before the twin_breeding gate, so a breed power and twin_breeding can coexist.

Typical use: shepherd-class bonuses on breeding, sterile-origin breeding bans (cancel_event).


tame

Fires when the player tames an animal (wolf, cat, horse, parrot, etc.; any AnimalTameEvent). Distinct from the tame_mob power, which tames via its own active-ability pipeline. Cancellable via neoorigins:cancel_event (the taming fails).

Context: EntityInteractContext(animal, event), carries the underlying cancellable AnimalTameEvent.

Dispatch site: WorldPowerEvents.onAnimalTame (AnimalTameEvent, gated on getTamer() instanceof ServerPlayer).

Typical use: beastmaster buffs on tame, feral origins that animals refuse to bond with (cancel_event).


bonemeal

Fires when the player applies bone meal to a block. Distinct from mod_bonemeal_extra, which only scales the extra-application count. Cancellable via neoorigins:cancel_event (the bone meal is not consumed and nothing grows). Cancelling wins over mod_bonemeal_extra: a granted extra never revives an interaction a power has refused.

Context: BlockInteractContext(pos, state, event), the bonemealed block; carries the underlying cancellable BonemealEvent. Supports block_condition like the other block events.

Dispatch site: CraftingPowerEvents.onBonemeal (BonemealEvent).

Typical use: druid growth side-effects, blighted origins that kill instead of grow (cancel_event + replacement action).


item_pickup

Fires when the player picks up an item entity off the ground.

Context: the item entity’s remaining stack after the pickup (getItemEntity().getItem(), a live reference), not a copy of what was picked up. When the player picks up the whole stack this is empty, so an item_condition fails closed and item-reading verbs see nothing; only a partial pickup (inventory full) leaves a non-empty remainder.

Dispatch site: InteractionPowerEvents.onItemPickup (ItemEntityPickupEvent.Post).

Typical use: coin-magnet XP, allergy damage, auto-sort hooks.


item_use_finish

Fires when the player finishes using an item (distinct from ITEM_USE which fires at use-start). Also synthetically fired by EdibleItemPower after a successful bite.

Context: FoodContext(stack) wrapping the finished ItemStack, so item_condition filters resolve here the same way they do on item_use.

Dispatch site: InteractionPowerEvents.onItemUseFinish (LivingEntityUseItemEvent.Finish) and InteractionPowerEvents.onEdibleUseFinish (for EdibleItemPower consumes).

Typical use: post-eat buffs, empty-bottle return, drink-finish sound.


power_activated

Fires when another power on the same player is successfully activated: an active power fired past its cooldown / hunger / resource gates, or a toggle power flipped (either direction; pair with a power_active condition on the toggled power if you only want one direction). Compat-layer (Route B) actives fire per dispatched attempt, since their gating lives inside the compat consumer and exposes no success signal.

Context: EventPowerIndex.PowerActivatedContext, carries the activated power’s id.

Dispatch sites: AbstractActivePower.onActivated (success branch), AbstractTogglePower.onActivated, CompatPower.onActivated, all via EventPowerIndex.dispatchPowerActivated.

Filter (power, optional): a single power id or an array of ids; the action only fires when the activated power’s id matches. Omit to fire on any activation.

Re-entrancy: if a power_activated listener’s action itself activates a power (e.g. via a command), that nested activation does not re-dispatch power_activated; A→B→A loops are cut at the first level. The nested activation itself still happens.

{
  "type": "neoorigins:action_on_event",
  "event": "power_activated",
  "power": "neoorigins:ground_slam",
  "entity_action": {
    "type": "neoorigins:execute_command",
    "command": "say Ground slam unleashed!"
  }
}

Typical use: announce ability use in chat, chain a secondary effect onto another ability, build combo systems (resource gain on each activation).


effect_applied

Fires when a MobEffect is about to be added to the player, after NeoOrigins’ EffectImmunityPower / EntityGroupPower immunity checks and any open immunity_ticks grace window but before the effect lands. Cancelling with neoorigins:cancel_event denies the application (calls setResult(DO_NOT_APPLY) on the underlying MobEffectEvent.Applicable).

Context: EventPowerIndex.EffectAppliedContext, carries the MobEffectInstance, its registry id, and the cancellable event.

Dispatch site: CombatPowerEvents.onMobEffectApplicable (MobEffectEvent.Applicable).

Filters: the action_on_event config accepts two optional pre-dispatch filters that work only on this event:

  • effect: a single registry id (e.g. spore:mycelium_ef)
  • effect_tag: a TagKey<MobEffect> (e.g. #minecraft:harmful; leading # optional)

If both are set they OR-match. If neither is set the action fires for every effect that reaches dispatch.

Post-cleanse grace (immunity_ticks, optional, default 0): when the action successfully cancels an EFFECT_APPLIED event AND immunity_ticks > 0, opens a per-effect-id grace window. Subsequent EFFECT_APPLIED dispatches for the same effect short-circuit to DO_NOT_APPLY until the window closes, skipping the user’s condition entirely. Lets pack authors smooth out probabilistic cancels: a successful 50% random_chance cleanse with immunity_ticks: 40 means the player is fully immune for 2 seconds before the next re-roll. The window max-merges across powers (multiple cleanses take the longest expiry, not the latest) and is cleared on logout.

Typical use: infection resistance (probabilistic cancel via random_chance + cancel_event + grace window); class-specific antidote behaviour; sound/particle reactions to incoming buffs.


Modifier-style events (return a float)

These chain modifiers on a vanilla float value. Base value enters, each modifier transforms, result goes back to vanilla. Register via modifier (or a list of them).

mod_exhaustion

Scales hunger exhaustion (which drives food drain).

Context: null. The base value is the unscaled exhaustion delta.

Dispatch site: FoodDataMixin.causeFoodExhaustion (movement, damage, mining, …) and FoodDataTickMixin.addExhaustion (regen-tick exhaustion). Both routes use the same event so a single MOD_EXHAUSTION power covers both.

Typical use: draconic 1.5× drain, feline 1.3× drain, avian 0.25× drain.


mod_natural_regen

Scales every heal the player receives. The dispatch listens to NeoForge’s LivingHealEvent, which fires for natural food regeneration and also for any other heal (Regeneration and Instant Health effects, heal actions, and so on). The event name notwithstanding, there is no source filter; gate with condition if you need one.

Context: null. Base value is event.getAmount() from LivingHealEvent. A non-finite result is clamped to Float.MAX_VALUE.

Dispatch site: WorldPowerEvents.onLivingHeal.

Typical use: fast/slow regen class modifiers, regen-on-sunlight, low- HP healing buff.


mod_trade_price

Per-player adjustment of a merchant offer’s cost-A count. The chained result is treated as the new absolute count (clamped to [1, maxStackSize]) and folded into vanilla’s specialPriceDiff channel (the same knob Hero of the Village and villager reputation use), so it stacks on top of natural discounts and shows correctly on both client and server.

Context: TradeContext(offer), the MerchantOffer. Base value is the currently-displayed cost-A count.

Dispatch site: AbstractVillagerTradePriceMixin (TAIL of AbstractVillager.setTradingPlayer, applied on trade-screen open). The mixin’s HEAD inject resets the prior contribution on close so the delta never compounds across repeated opens of the same wandering trader.

Typical use: charisma-class cheaper trades, cursed-class price hikes, faction-discount perks.


mod_craft_amount

Scales the count of the assembled crafting-grid result. The chained result is treated as the new count (clamped to [1, maxStackSize]) and written to the result slot in place, so vanilla’s later broadcastChanges syncs it to the client.

Context: the result ItemStack. Base value is the recipe’s natural output count.

Dispatch site: CraftingMenuCraftAmountMixin (RETURN of the static CraftingMenu.slotChangedCraftingGrid, which covers both the 3×3 table and the 2×2 inventory grid). Server-only in 26.1 (the method’s level parameter is a ServerLevel).

Typical use: artisan-class double-output, efficient-crafting perks, resource-multiplier classes.


mod_harvest_drops

Multiplies extra-drop count when the player kills an animal.

Context: the killed LivingEntity. Base value is 1.0f; final value is rounded and extraCopies = Math.max(0, Math.round(value) - 1).

Dispatch site: CombatPowerEvents.onLivingDrops (filtered to Animal victims).

Typical use: hunter class double-drops, butcher bonus wool/leather.


mod_knockback

Scales incoming knockback strength for the player as victim. A result ≤ 0 cancels the knockback entirely.

Context: null. Base value is event.getStrength().

Dispatch site: CombatPowerEvents.onLivingKnockBack.

Typical use: heavy-frame knockback resistance, stone-armour no-push, mid-air combat anti-knockback.


mod_potion_duration

Multiplies the duration of status effects newly added to the player. The new duration is (int)(duration * value), written into the incoming effect instance with MobEffectInstance.update, which only ever strengthens an effect. A result below 1.0 therefore has no effect: this event can lengthen effects but cannot shorten them.

Context: the MobEffectInstance being added (readable for effect-specific gating from conditions). Base value is 1.0f.

Dispatch site: CombatPowerEvents.onMobEffectAdded (MobEffectEvent.Added).

Typical use: longer potions, longer buffs for a potion-brewer class. It scales duration, not amplifier.


mod_bonemeal_extra

Adds extra bonemeal applications when the player uses bonemeal on a block. Base value is 0f (vanilla behaviour is one application total) and the final value is Math.round(result), clamped at zero.

A result above zero makes the handler take the interaction over rather than adding to it. It cancels the event, which suppresses vanilla’s own application, performs result + 1 applications so the suppressed one is still accounted for, consumes one bone meal itself and reports success. Half-participating is not an option here: growing the block from inside the event can turn vanilla’s own live-world validity check false, and NeoForge then discards every block change the handler made without ever telling the client.

The takeover is deliberately narrow, so vanilla is left completely alone unless all of the following hold:

  • the modifier chain resolved to at least one extra, and
  • the block was a valid bonemeal target when the event was constructed, that is before any power ran, and
  • no power cancelled the event, from either this dispatch or bonemeal.

The first of the applications keeps vanilla’s isBonemealSuccess roll, which is a random chance on crops, since it stands in for the vanilla growth. The extras do not consult that roll.

Context: the BonemealEvent itself.

Dispatch site: CraftingPowerEvents.onBonemeal.

Typical use: druid / forester class, 2× / 3× growth per bonemeal.


mod_enchant_level

Modifies the level shown on an enchanting-table slot. Note: the EnchantmentLevelSetEvent has no player reference, so NeoOrigins runs a spatial query for players within 8 blocks of the table and dispatches to each. First player whose modifier changes the level wins.

Context: the EnchantmentLevelSetEvent. Base value is the vanilla level as a float.

Dispatch site: CraftingPowerEvents.onEnchantmentLevelSet.

Typical use: arcane class +3 enchant levels, cursed class -2.


mod_crafted_food_saturation

Additive saturation bonus applied to any food item freshly crafted or smelted by the player. Base value is 0f. When the chained result is > 0, the item’s FOOD component is rebuilt with saturation + result and nutrition + 1 (a fixed +1 hunger point comes with any bonus). Results ≤ 0 leave the item untouched.

Context: the resulting ItemStack.

Dispatch site: CraftingPowerEvents.onItemCrafted and onItemSmelted (via boostFoodIfCook).

Typical use: chef class, crafted/smelted food gives +0.2 saturation.


mod_food_nutrition

Modifies the nutrition (hunger points) of any food the player actually eats. Base value is the item’s nutrition; the result is rounded and clamped at 0. Contrast mod_crafted_food_saturation, which fires at craft time and only touches saturation — this one fires at eat time and only touches nutrition, so the two never see the same moment.

Context: FoodContext(stack) — the food being eaten, so food_item_in_tag and food_item_id both work. No cancel wrapper: the dispatch site fires after the eat, leaving cancel_event nothing to veto.

Dispatch site: CompatEventPowers.onFoodEaten (LivingEntityUseItemEvent.Finish). Because that event fires after vanilla has credited the food, the difference is applied by correcting FoodData rather than by editing the stack.

Chaining: runs after the legacy origins:modify_food power, on whatever nutrition that power left behind, so a pack may use both. Neither requires the other to be present.

Typical use: a picky-eater origin halving nutrition from disliked food.


mod_anvil_cost

Multiplies the XP-level cost of an anvil repair / combine.

Context: the AnvilUpdateEvent. Base value is 1.0f; final cost is max(1, (int)(originalCost * value)).

Dispatch site: CraftingPowerEvents.onAnvilUpdate.

Typical use: artisan / smith class 0.5× anvil cost, cursed class 2×.


mod_teleport_range

Scales the range of built-in neoorigins:active_teleport (the replacement for the legacy teleport_range_modifier).

Context: null. Base value is the power config’s declared range.

Dispatch site: ActiveTeleportPower.execute.

Typical use: ender class, +4 blocks teleport distance, cursed class halved.

Note: only affects the built-in active-teleport power. Ender pearls and mod teleports are not routed through this event.


mod_fall_damage

Scales the fall-damage multiplier when the player lands. Chains on the event’s current multiplier so it stacks with feather-falling and similar effects. A result ≤ 0 (or non-finite) zeroes fall damage; the final value is clamped to ≥ 0.

Context: the LivingFallEvent. Base value is event.getDamageMultiplier().

Dispatch site: MovementPowerEvents.onLivingFall (runs after the land dispatch and the prevent_action: FALL_DAMAGE gate).

Typical use: acrobat-class reduced fall damage, heavy-class increased impact, partial fall mitigation that stacks with vanilla effects. For a full no-fall immunity, prefer prevent_action: FALL_DAMAGE.


Removed keys

Two keys that earlier drafts exposed were dropped because a better-fitting mechanism already covers them; exposing a second, redundant handler would only invite divergent behaviour:

  • mod_break_speed → use the break_speed_modifier power, which is applied through PlayerEvent.BreakSpeed on both the client and the server (BreakSpeedModifierEvents).
  • mod_xp_gain → use the origins:modify_xp_gain power type (aliases apace: / apoli: / apugli:), parsed by the Apoli compat layer in OriginsCompatPowerLoader.parseNumericModifier into the NumericModifierRegistry XP_GAIN path with full Apoli modifier math (addition + multiply_base / multiply_total). There is no native neoorigins: spelling for this one; the compat type is the supported route, and it is not deprecated.

Compat spellings

A handful of alternate event names are accepted and resolved to a canonical event. These exist because an unknown event is a hard load error, not a no-op: a pack that guessed a plausible name loses the entire power, silently as far as the game is concerned.

Spelling Resolves to Why it is safe
item_use_start item_use item_use already dispatches from LivingEntityUseItemEvent.Start, so for anything with a use duration the two names name the same instant.

An alias is only ever added when the target event already fires at the same moment. This is a spelling table, not a way to fake a capability: aiming a name at an event that fires at a different time buys a power that loads and then does the wrong thing, which is worse than the load error it replaced. Where no equivalent exists, a real event is added instead — that is what mod_food_nutrition is.

These spellings are published in the editor schema alongside the canonical names, so the editors never reject a pack the game loads happily.

Declared in CompatEventAliases.java.


Cross-reference