NeoOrigins 2.0 API Reference
Single landing page for the NeoOrigins datapack API. Every power type, condition verb, action verb, and event key is listed below with a jump-link to the per-topic detail doc.
- Layer model
- Documents in this API
- Power types: 122 registered types plus the
multiplecontainer, and 29 retired ids - Condition verbs: 108 conditions
- Action verbs: 95 actions
- Event keys: 51 events
- Named keybinds
- Active theme datapack file
- Namespaces & prefixes
- JSON schemas
Layer model
A NeoOrigins pack is composed of four layers, each authored in JSON:
- Origin layers (
origins/origin_layers/*.json) control which origins show in the picker. Overrideneoorigins:originto add your origins to the main picker tab. - Origins (
origins/origins/*.json) define each selectable origin: name, description, icon, impact, and the list of powers it grants. - Powers (
origins/powers/*.json) are the mechanical units. Each has atype(see the power-type index below) plus the type-specific fields. - Composition DSL: most 2.0 power types accept a
condition(a predicate on the player) and either anentity_action(a side-effect) or aneventkey. Conditions and actions are themselves JSON objects with their owntypeand fields; they can be nested (neoorigins:and,neoorigins:not,neoorigins:or) to express arbitrary logic.
A tick-driven gate like “take damage in the Nether, unless wearing Frost Walker boots” is expressed as one power whose condition is an neoorigins:and of neoorigins:biome and neoorigins:not(origins:enchantment). The 2.0 design goal is that virtually any behaviour a pack wants is a composition of verbs that already exist, rather than a bespoke power type.
The upstream layer (for cross-mod pack compatibility) is handled by the compat loader: origins: and apace: types are translated into the 2.0 vocabulary by OriginsPowerTranslator / OriginsCompatPowerLoader, while apoli: and apugli: spellings are canonicalized to origins: first. LegacyPowerTypeAliases is a narrower remap table: retired neoorigins: ids plus a few cross-mod entries. See MIGRATION.md and the Namespaces table.
Documents in this API
| Doc | What it covers |
|---|---|
| POWER_TYPES.md | Full field table for every power type. Source of truth for allowable fields. |
| CONDITIONS.md | Every condition verb with fields and semantics. |
| ACTIONS.md | Every action verb with fields and semantics. |
| EVENTS.md | Every event key the action_on_event power can listen on. |
| MIGRATION.md | Legacy type → 2.0 type remap table, lossy translations, DSL gap catalog. |
| COOKBOOK.md | Recipe-oriented tutorial: a five-minute starter origin, then worked recipes for common patterns. |
| PACK_FORMAT.md | Directory layout, file-name conventions, JSON boilerplate. |
| CONTENT_CONFIG.md | Server content.toml toggles: global vision / resource-bar switches and per-origin / per-class enable flags. |
| CLIENT_CONFIG.md | Per-client client.toml options: UI theme, HUD layout, hotkey pool size. |
| GAMEPLAY_CONFIG.md | gameplay.toml options: Orb of Origins costs, random assignment, evolution kill counts, ocean-origin survival, sun damage, mount consent, friendly fire, armor classes. |
| ADMIN_CONFIG.md | admin.toml policy: command-power blacklist, dimension restrictions, compat origin filtering, taming exclusions, debug flags. |
| ARCHITECTURE.md | How powers are loaded, dispatched, cached. For debugging. |
| COMPATIBILITY.md | Out-of-the-box mod integrations (Origins/Apoli, Curios, Ars Nouveau, KubeJS, JEI/REI, etc.). |
If a prose doc disagrees with the code, the code wins. Source of truth paths are cross-linked in each detail doc.
Power types
The type field on a power file selects one of these. All use the neoorigins: namespace; see Namespaces for how legacy prefixes map.
Each row jumps to its section in POWER_TYPES.md.
Generic composable (use these for new powers)
| Type | Summary |
|---|---|
action_on_event | Run an action (or modify a float) when an event fires. Workhorse event-listener. |
action_on_hit | Run an action when the player deals damage. Filterable by target. |
active_ability | Skill-key-triggered ability running one or more actions. Cooldown + hunger cost. |
attribute_modifier | Add/multiply a player attribute. Optional tick-driven condition gate. |
condition_passive | Run an action on an interval while a condition holds. Workhorse passive. |
conditional | Gate another power on a static condition enum. |
edible_item | Make arbitrary items edible for this player. |
effect_over_time | Sustained aura pulsing an action on an interval. Passive (always on) or active (keybind + upkeep). |
modify_damage | Scale damage the player deals or takes. Direction + type/tag filter. |
multiple | Bundle several powers into one file. Sub-powers are flattened to their own ids at load. |
persistent_effect | Refresh a status effect every tick. Replaces legacy status_effect. |
prevent_action | Cancel a specific player action (FALL_DAMAGE, DROWN, FIRE, SWIM, etc.). |
resource | Named persistent value with a HUD bar. Regeneration, threshold actions, change_resource compatible. |
simple | Does nothing. Display-only marker, the equivalent of origins:simple. |
tick_action | Legacy no-op: it dispatches nothing. Use condition_passive, which takes the same interval. |
toggle | Boolean state cycled by the skill key, readable via neoorigins:power_active. |
variable | Hidden persistent integer counter. No bar, no regen: written only by actions. |
Movement & body
| Type | Summary |
|---|---|
bounce_on_land | Reflect fall impact back upward on landing, like a slime block. |
creative_flight | True hover flight as a toggle. Keeps collision and gravity when not flying. |
elytra_boost | Add forward thrust while elytra-flying. |
elytra_flight | Elytra-style fall-flight with no elytra equipped. Can draw wings while gliding. |
enhanced_vision | Permanent brightness boost applied client-side (no potion effect or HUD icon), switched with the player’s “Toggle Night Vision” key. The retired night_vision id remaps to persistent_effect, not to this. |
flight | Creative-style flight. |
modify_flight_speed | Scale creative and hover flight speed, but not elytra gliding. In-mod replacement for Pehkui. |
natural_glide | Glide by pressing jump while falling, with no elytra equipped. |
phantom_form | Mayfly + noPhysics + no-fall: walk through walls. |
size_scaling | Scale player dimensions. Optional reach-scaling + flat reach bonus. |
wall_climbing | Scale walls like a spider. |
walk_on_fluid | Walk on water, lava or both (default both), like a Strider. The surface stops being solid once you are submerged. |
water_breathing | Never loses air underwater. |
wraith_phase | Toggleable phasing through solid blocks: jump and sneak for vertical control. always_on makes it passive. |
cobweb_affinity | Web mobility + 10× cobweb break speed. |
burn | Set the player on fire at a configurable interval. |
ignore_water | Full land speed in water + no current pushing. |
ignore_fluid | Totally ignore named fluids (incl. modded): no buoyancy, drag, push, drowning, burn, fog or swim pose. |
lava_vision | Increase vision distance in lava. |
modify_lava_speed | Change movement speed while submerged in lava. |
overlay | Full-screen texture overlay with configurable opacity. |
model_color | RGBA tint on the player model. Not drawn on 26.1 or 26.2: the power still loads and syncs, but there is no tint render pass. |
entity_model | Replace the player’s model with another entity’s: a morph. Changes hitbox and voice with it. |
invisibility | Turn the player invisible, optionally hiding worn armour too. |
prevent_entity_render | Hide matching living entities from this player only; they still act and collide. |
pose | Hold the player’s body in a chosen pose (prone, sneak height, upright) while the power is on. |
particle | Emit vanilla particles on the player at a fixed cadence. Server-side. |
shader | Post-processing shader on the player’s view. |
Minions & entities
| Type | Summary |
|---|---|
summon_minion | Active ability that spawns a tracked mob with owner-aware AI. |
tame_mob | Active ability that rewrites a mob’s AI to follow and defend the owner. |
tamed_animal_boost | Buff vanilla tamed animals (HP / speed). |
tamed_potion_diffusal | Potions drunk near tamed animals apply to them too. |
entity_group | Mark the player as part of a built-in or datapack-defined entity group. Affects effect/enchant interactions and which mobs ignore, hunt, or flee you. |
entity_set | Named UUID set per power id. Pair with neoorigins:in_set / add_to_set / remove_from_set. |
mobs_ignore_player | Mobs don’t aggro. Retaliation window preserved. |
sneaky | Cut mob detection range via detection_multiplier (default 0.3): mobs only target the holder from much closer. |
stealth | Invisibility after sneaking continuously for a threshold, clearing when you stop. Toggleable, so it claims a skill key. |
mobs_target_player | The inverse: listed mobs, or every mob if none are listed, hunt the holder within range without needing line of sight. |
mob_behavior | Give a mob origin piglin-style aggression toward players or a named entity type. Vanilla AI stays intact. |
attract_mobs | Pull nearby mobs toward the holder, as though holding their favourite food. |
scare_entities | Listed entity types flee from the player. |
muffle_sound | Emit no game-event vibrations: sculk sensors and wardens stop noticing you. |
mount | Toggleable ability that seats the player on the entity they are looking at. Consent for player targets is server-config gated, and off by default. |
no_mob_spawns_nearby | Cancel natural spawns in a radius. |
twin_breeding | Chance for breeding to yield two babies. |
Combat
| Type | Summary |
|---|---|
invulnerability | Filter damage types the player is immune to. |
prevent_death | Cancel the lethal blow; condition / damage-type / cooldown gated. |
projectile_immunity | Filter projectile types the player is immune to. |
effect_immunity | Block specific status effects. |
dodge_chance | Percentage chance to dodge incoming damage. |
no_projectile_divergence | Perfect accuracy on projectiles the player shoots: no random spread. |
thorns_on_hit | Passive thorns: attacker takes damage back. |
light_level_effect | Apply effect at/below a light level. |
low_hp_threshold | Apply effects when HP drops below a threshold. |
ender_gaze_immunity | Endermen don’t aggro on eye contact. |
ground_slam | Radial AoE damage from falling. |
tidal_wave | Active cone-shape knockback. |
shadow_orb | Place a stationary orb emitting Darkness + Blindness. |
Mining, farming, crafting
| Type | Summary |
|---|---|
break_speed_modifier | Multiply block break speed with block/tool/condition filters. |
bare_hand_tool | Empty hand mines as a named tool, for both drop eligibility and speed. |
underwater_mining_speed | Remove underwater mining penalty. |
tree_felling | Chop connected logs in one swing. |
ultimine | Vein-mining via FTB Ultimine. Inert when that mod is absent. |
fortune_when_effect | Virtual Fortune level on a block tag (default #c:ores) while a named status effect is active. |
crop_growth_accelerator | Periodic tick boost to nearby crops. |
crop_harvest_bonus | +N drops per crop break. |
quality_equipment | Starting tool quality uplift. |
craft_amount_bonus | Extra output on crafted items. |
more_smoker_xp | Bonus XP from smoker. |
Inventory & items
| Type | Summary |
|---|---|
starting_equipment | Grant items on origin chosen. |
extra_inventory | Extra chest-style inventory on the skill key. size is in slots (9-54), persisted. |
keep_inventory | Slot/item filter for inventory kept across death. |
restrict_armor | Slot-scoped gate on wearable items. |
restrict_items | Gate equipping and using items: prevent_equip and prevent_use are separate opt-ins. Allow-list or blacklist, any slot or hand. |
prevent_item_damage | Matching items never lose durability, on every durability path. |
item_magnetism | Pull item entities to the player. |
hide_hud_bar | Hide the food or air bar. |
less_item_use_slowdown | Speed modifier while using an item (item_type: any / bow / shield / id substring). Still registered; hidden from the creator’s type picker. For new packs, attribute_modifier + the neoorigins:using_item condition covers the any case. |
Healing, hunger, survival
| Type | Summary |
|---|---|
horde_regen | Regen scales with nearby allied mob count. |
no_natural_regen | Kill food-driven regen; potion/beacon heals still work. |
exhaustion_filter | Selective hunger-drain modifier. |
modify_food_nutrition | Override the hunger value of matching food. Saturation scales with it. |
no_slowdown | Immune to specific slowdown sources. |
breath_in_fluid | Air supply drains in named fluids. |
breath_out_of_fluid | Air drains while out of a named fluid: a fish out of water. |
slime_moisture | Moisture bar draining over time, faster when dry or on fire. Threshold effects. |
slime_level_hp | Bonus max HP per XP level (default one per 10, capped), tracking your current level. |
Respawn & lifecycle
| Type | Summary |
|---|---|
modify_player_spawn | Per-power respawn override. Optional bed override. |
slime_death_save | Split instead of dying while moisture is high: teleport away at 2 hearts. |
Merchant & loot
| Type | Summary |
|---|---|
trade_availability | Extend villager trade offers. |
rare_wandering_loot | Bonus wandering-trader drops. |
kill_loot_drops | Extra drops on mobs the holder kills, through the real loot pipeline. |
loot_pool_grant | Active ability that rolls a loot table into the inventory. One-shot per grant_id, cleared by an origin reset. |
Command integration
| Type | Summary |
|---|---|
command_pack | Package of execute_command actions behind a single power id. |
Scripting
Power types whose behaviour is supplied by a KubeJS script. See KUBEJS.md.
| Type | Summary |
|---|---|
js_active | Keybind ability whose onUse runs JS. Returning false consumes nothing. |
js_custom | Passive power whose grant / revoke / tick hooks run JS. |
Mod compatibility
Hooks into another mod. Each is an inert marker when that mod is absent. See COMPATIBILITY.md.
| Type | Summary |
|---|---|
become_dragon | Dragon Survival: the holder is a dragon of the named species while the power is granted. |
xeno_passive | Aliens vs Predator: facehuggers stop treating the holder as a viable host. |
Active abilities (specialised)
| Type | Summary |
|---|---|
active_bolt | Fires a wind-charge projectile. Legacy; prefer active_ability + spawn_projectile. |
active_dash | Horizontal impulse. Legacy; see MIGRATION.md. |
active_fireball | Single small fireball. Legacy. |
active_phase | Toggle movement state. Legacy. |
active_place_block | Raycast and place. Legacy; no DSL verb yet. |
active_recall | Saved-position teleport. Legacy; stateful. |
active_swap | Swap positions with target. |
active_teleport | Look-direction blink. Legacy; no DSL verb yet. |
Deprecated & retired
Retired ids: no longer registered as types, but still load because LegacyPowerTypeAliases remaps them (with their fields) onto a live type and logs a one-time [2.0-legacy] warning. Existing packs keep working; prefer the replacement in new ones. See MIGRATION.md for the full remap table.
| Type | Replaced by |
|---|---|
action_on_hit_taken | action_on_event |
action_on_kill | action_on_event |
action_over_time | condition_passive |
active_aoe_effect | active_ability |
active_launch | active_ability |
better_bone_meal | action_on_event |
better_crafted_food | action_on_event |
better_enchanting | action_on_event |
biome_buff | condition_passive |
burn_at_health_threshold | condition_passive |
damage_in_biome | condition_passive |
damage_in_daylight | condition_passive |
damage_in_water | condition_passive |
efficient_repairs | action_on_event |
food_restriction | action_on_event |
glow | persistent_effect |
healing_mist | active_ability |
hunger_drain_modifier | action_on_event |
knockback_modifier | action_on_event |
longer_potions | action_on_event |
more_animal_loot | action_on_event |
natural_regen_modifier | action_on_event |
night_vision | persistent_effect (or enhanced_vision for a brightness floor) |
regen_in_fluid | condition_passive |
repulse | active_ability |
stacking_status_effects | persistent_effect |
status_effect | persistent_effect |
teleport_range_modifier | action_on_event |
thorns_aura | action_on_event |
Condition verbs
Used in condition fields. A bare verb name defaults to neoorigins:; any other namespace (origins:, apace:, apoli:, apugli:, …) is rewritten to neoorigins: with a one-time [2.0-legacy] warning. An unknown verb fails closed. Each entry jumps to CONDITIONS.md.
Alias spellings (dispatch to the same verb, not counted above): riding → passenger, fire → on_fire, food → food_level, name → damage_name, replaceable → replacable, resource_level → resource, covered_by_block → cover, block_in_radius → near_block, all_of → and, any_of → or.
Boolean combinators
neoorigins:and • neoorigins:or • neoorigins:not • neoorigins:constant • neoorigins:always_active
Environment
neoorigins:biome • neoorigins:dimension • neoorigins:in_tag • neoorigins:submerged_in • neoorigins:submerged_in_water • neoorigins:in_water • neoorigins:in_block • neoorigins:on_block • neoorigins:block • neoorigins:block_collision • neoorigins:on_ground • neoorigins:on_fire • neoorigins:in_rain • neoorigins:temperature • neoorigins:weather • neoorigins:brightness • neoorigins:light_level • neoorigins:exposed_to_sky • neoorigins:exposed_to_sun • neoorigins:daytime • neoorigins:time_of_day • neoorigins:moon_phase • neoorigins:height • neoorigins:fluid_height • neoorigins:distance • neoorigins:near_entity • neoorigins:nearby_entities • neoorigins:near_villager • neoorigins:near_block • neoorigins:in_block_anywhere • neoorigins:distance_from_coordinates • neoorigins:cover • neoorigins:hardness • neoorigins:replacable • neoorigins:night • neoorigins:thundering
Player state
neoorigins:health • neoorigins:relative_health • neoorigins:food_level • neoorigins:armor_value • neoorigins:xp_level • neoorigins:xp_points • neoorigins:fall_distance • neoorigins:fall_flying • neoorigins:sneaking • neoorigins:sprinting • neoorigins:swimming • neoorigins:invisible • neoorigins:creative_flying • neoorigins:moving • neoorigins:passenger • neoorigins:using_item • neoorigins:equipped_item • neoorigins:enchantment • neoorigins:resource • neoorigins:living • neoorigins:exists • neoorigins:ticking • neoorigins:advancement • neoorigins:air • neoorigins:body_temperature • neoorigins:climbing • neoorigins:climbing_gate • neoorigins:collided_horizontally • neoorigins:creative_mode • neoorigins:has_effect • neoorigins:status_effect • neoorigins:inventory • neoorigins:saturation_level • neoorigins:using_effective_tool • neoorigins:xp_levels
Food context
neoorigins:food_item_id • neoorigins:food_item_in_tag • neoorigins:food_item_in_config_list
Entity & damage
neoorigins:entity_type • neoorigins:target_type • neoorigins:target_group • neoorigins:can_see • neoorigins:damage_type • neoorigins:damage_tag • neoorigins:damage_name • neoorigins:from_fire • neoorigins:from_projectile • neoorigins:from_explosion • neoorigins:actor_condition • neoorigins:hit_dealt_amount • neoorigins:hit_taken_amount • neoorigins:out_of_combat
Power introspection
neoorigins:power_active • neoorigins:power_type • neoorigins:in_set • neoorigins:power • neoorigins:origin • neoorigins:cooldown • neoorigins:no_minions_alive
Advanced
neoorigins:nbt • neoorigins:scoreboard • neoorigins:statistic • neoorigins:command • neoorigins:predicate • neoorigins:amount • neoorigins:equal • neoorigins:config_flag
Action verbs
Used in entity_action fields. Namespace handling is the same as for conditions (bare name → neoorigins:; other namespaces rewritten with a one-time warning). Each entry jumps to ACTIONS.md.
Two caveats. In a bientity action slot, pair behaviour (actor/target wrappers, and, chance, invert, damage, mount, if_else) only exists for the literal origins: / apoli: / apace: spellings; any other type, including a neoorigins: one, is parsed as a plain entity action and runs on the actor, with the target published as context. And the entity-action neoorigins:invert is registered but is a no-op (it parses to EntityAction.noop()); only the bientity origins:invert swaps actor and target.
Alias spellings (dispatch to the same verb, not counted above): all_of → and, bonemeal → grow, modify_resource → change_resource, fire_projectile → spawn_projectile, command → execute_command, spawn_sword_rain → spawn_projectile_rain.
Combinators & control
neoorigins:and • neoorigins:chance • neoorigins:delay • neoorigins:if_else • neoorigins:if_else_list • neoorigins:nothing • neoorigins:choice • neoorigins:invert (no-op; see above) • neoorigins:cancel_event
Wrappers & targeting
neoorigins:actor_action • neoorigins:target_action • neoorigins:riding_action • neoorigins:passenger_action • neoorigins:equipped_item_action • neoorigins:block_action_at • neoorigins:block_target_action • neoorigins:selector_action • neoorigins:raycast • neoorigins:offset
Damage & healing
neoorigins:damage • neoorigins:heal • neoorigins:feed • neoorigins:exhaust • neoorigins:change_resource • neoorigins:damage_attacker • neoorigins:ignite_attacker • neoorigins:effect_on_attacker
Effects
neoorigins:apply_effect • neoorigins:clear_effect • neoorigins:spawn_effect_cloud • neoorigins:spawn_lingering_area • neoorigins:modify_temperature
Movement & position
neoorigins:add_velocity • neoorigins:launch • neoorigins:set_fall_distance • neoorigins:dismount • neoorigins:throw_target • neoorigins:dash • neoorigins:mount • neoorigins:random_teleport • neoorigins:swap_positions • neoorigins:swap_with_entity • neoorigins:teleport_target_to_self • neoorigins:teleport_to_marker • neoorigins:teleport_to_target
Items & inventory
neoorigins:give • neoorigins:modify_food • neoorigins:spawn_entity • neoorigins:spawn_projectile • neoorigins:drop_inventory • neoorigins:drop_items • neoorigins:force_drop • neoorigins:steal_item • neoorigins:modify_inventory • neoorigins:dye • neoorigins:shear • neoorigins:add_xp • neoorigins:crafting_table
World & environment
neoorigins:set_block • neoorigins:set_on_fire • neoorigins:extinguish • neoorigins:explode • neoorigins:gain_air • neoorigins:area_of_effect • neoorigins:grow • neoorigins:till • neoorigins:path • neoorigins:strip • neoorigins:transform_block • neoorigins:spawn_black_hole • neoorigins:spawn_tornado • neoorigins:spawn_projectile_rain • neoorigins:spawn_telegraph • neoorigins:spawn_particles
Power control
neoorigins:grant_power • neoorigins:revoke_power • neoorigins:trigger_cooldown • neoorigins:activate_power • neoorigins:toggle • neoorigins:set_resource • neoorigins:open_layer_picker
Entities & sets
neoorigins:tame_target • neoorigins:chain_to_nearest • neoorigins:pull_entities • neoorigins:add_to_set • neoorigins:remove_from_set • neoorigins:morph_entity_event • neoorigins:trigger_morph_animation
Integration
neoorigins:execute_command • neoorigins:play_sound • neoorigins:swing_hand • neoorigins:emit_game_event • neoorigins:kubejs_callback • neoorigins:cast_spell • neoorigins:cast_iron_spell
Event keys
Used in action_on_event’s event field. Case-insensitive. The compat spelling item_use_start also resolves (to ITEM_USE); see EVENTS.md. Each entry jumps to its section in EVENTS.md.
Core lifecycle & combat
ATTACK • HIT_TAKEN • HIT_DEALT • KILL • DEATH • BLOCK_BREAK • BLOCK_PLACE • ITEM_USE • RESPAWN • TICK • DIMENSION_CHANGE • JUMP • CLIMB • PROJECTILE_HIT • EFFECT_APPLIED
Interactions
BONEMEAL • FOOD_EATEN • FOOD_FINISHED • BLOCK_USE • ENTITY_USE • ITEM_PICKUP • ITEM_USE_FINISH • VILLAGER_INTERACT • TRADE_COMPLETED • BREED • TAME • CRAFT_ITEM • SMELT_ITEM • ENCHANT_ITEM • ANVIL_REPAIR • ADVANCEMENT_EARNED
Origin & power lifecycle
GAINED • LOST • CHOSEN • WAKE_UP • LAND • POWER_ACTIVATED
Modifiers (return a float, chain in registration order)
MOD_EXHAUSTION • MOD_NATURAL_REGEN • MOD_ENCHANT_LEVEL • MOD_HARVEST_DROPS • MOD_TELEPORT_RANGE • MOD_KNOCKBACK • MOD_POTION_DURATION • MOD_ANVIL_COST • MOD_CRAFTED_FOOD_SATURATION • MOD_BONEMEAL_EXTRA • MOD_FALL_DAMAGE • MOD_TRADE_PRICE • MOD_CRAFT_AMOUNT • MOD_FOOD_NUTRITION
See EVENTS.md for each event’s context record.
Named keybinds
By default, active powers consume one of the six hardcoded skill slots (key.neoorigins.skill_1 … key.neoorigins.skill_6). For packs that ship more than six active abilities, NeoOrigins exposes a named-keybind pool: the pack declares its own translation key on the power, and the client surfaces each declared key as a labelled hotkey in Controls → Key Binds → NeoOrigins (Hotkeys).
Declaring on a power
Add a key field to any active power: the native neoorigins:active_ability, or an Apoli-style origins:active_self / origins:toggle. The loader picks the field up and registers the binding:
{
"type": "origins:active_self",
"key": "examplepack.key.origins.1",
"cooldown": 80,
"entity_action": { "type": "neoorigins:add_velocity", "y": 1.5 },
"name": "Leap"
}
key can also be an object form that carries the continuous flag:
"key": { "key": "examplepack.key.origins.channel", "continuous": true }
keyis a free-form translation key string. Ship the human label as the matching entry in your pack’slang/en_us.json(e.g."examplepack.key.origins.1": "Phase Step").continuous: false(default) = the action fires once per press.true= the action fires every tick while the key is held, appropriate for hold-to-channel abilities; skip cooldowns for these.- Vanilla input keys (see Vanilla input keys below) are not routed through the pool; they bind directly to a real game control and fire from server-side input polling, so they never consume a named-hotkey or skill slot.
- The native
neoorigins:active_abilityuses the pool too. Give it the samekeyfield and it binds to a named hotkey and drops out of the skill-slot roster; leavekeyoff and it takes the next freeskill_1..skill_6slot as before. There is no need to rewrite it asorigins:active_self. It reads the same three forms as everything else here: the mod’s ownneoorigins:windwalker_cloud_stepsis a nativeactive_abilitycarrying"key": "key.jump", the vanilla-key form covered by the bullet above. - The native
neoorigins:toggleis the exception, because it is not an active power: it holds a boolean for other powers to read and has no activation to fire, so akeyon it is ignored. Put the key on anactive_abilitywhoseentity_actionflips the toggle.
Numbered slots (key: N)
Instead of a translation-key string, key may be a number. "key": 1 targets named-hotkey pool slot 1 directly; it is shorthand for the canonical translation key key.neoorigins.hotkey.1 (1-indexed). The slot already carries a built-in label (“Hotkey 01” … up to “Hotkey 64”), so you don’t need to ship a lang entry for it, and the modpack can pre-bind it via the slot_defaults client config.
{
"type": "origins:active_self",
"key": 1,
"cooldown": 80,
"entity_action": { "type": "neoorigins:add_velocity", "y": 1.5 },
"name": "Leap"
}
The object form accepts a number too, so a numbered slot can still be continuous: "key": { "key": 1, "continuous": true }.
- String vs. number. A string
keyfills the next free pool slot in sorted order: stable across relogs, but which physical “Hotkey N” row it lands on depends on what else the pack declares. A numerickey: Nis deterministic: it always pins to slot N, so the author controls exactly which row (and whichslot_defaultsdefault) a power gets. Reach for the number when you want a predictable layout; reach for the string when you just want “some free slot” and a custom label. - Slot
Nmust be withinpool_size(default 32). Akey: Nabove the pool size is logged and left dormant, same as string overflow. Raisepool_sizeto make room.
One key, several powers
Multiple powers may declare the same key, whether a shared string or the same key: N. They are not in conflict: the server keeps a list of bindings per key and fans a single press out to all of them (each still gated by its own condition and cooldown). This is how one keypress can drive several powers on an origin at once, e.g. "key": 1 on both a movement power and a particle power fires both from one button. A player binds that one “Hotkey N” row a single time in Controls and it triggers the whole group.
Source of truth: power/keybind/PowerKeybindRegistry.java (BY_KEY list + dispatch fan-out) and client/HotkeyAssignments.java (the two-pass slot assignment that pins numbered keys).
Vanilla input keys
Instead of a translation key, a power’s key field may name one of nine vanilla game controls. The power then activates whenever the player uses that control: no extra hotkey to bind, no pool slot consumed. This is ideal for abilities that should feel native to an existing input (a sneak-toggle stance, a jump-triggered dash, a use-key channel).
Supported keys:
| Key | Fires while… |
|---|---|
key.jump | the jump key is held |
key.sneak | the player is sneaking |
key.sprint | the player is sprinting |
key.use | the use / right-click key is held |
key.attack | the attack / left-click key is held (or the player is swinging) |
key.forward | pressing forward |
key.back | pressing back |
key.left | strafing left |
key.right | strafing right |
{
"type": "origins:active_self",
"key": "key.jump",
"cooldown": 30,
"condition": { "type": "origins:in_air" },
"entity_action": { "type": "neoorigins:add_velocity", "y": 0.8 },
"name": "Double Jump"
}
- The server polls the bound control’s state every tick and fires the power’s own action under its
conditiongate andcooldown. Non-continuous bindings are edge-detected: one activation per press, not once per tick. Set"key": { "key": "key.use", "continuous": true }for a hold-to-channel ability. key.use,key.attackandkey.jumpreport their true held state: the client sends the real key state each tick (VanillaKeyStatePayload) rather than inferring it from swing animations or interaction packets, so hold-and-release timing is accurate.- Because the activation runs through the power’s normal gate,
fail_actionand cooldowns behave exactly as they do for named hotkeys. - Works on
neoorigins:active_abilityas well as the Apoli-styleorigins:active_self/origins:togglepowers.
Source of truth: power/keybind/PowerKeybindRegistry.java (the case "key.*" switch and VANILLA_NATIVE poller).
Fail feedback (fail_action)
origins:active_self, origins:toggle, and origins:launch accept an optional fail_action (a NeoOrigins extension; plain Apoli ignores it). It runs when the player presses the power’s key but the condition gate fails, replacing the silent no-op with author-defined feedback:
{
"type": "origins:active_self",
"key": "examplepack.key.origins.1",
"cooldown": 80,
"condition": { "type": "origins:on_block" },
"entity_action": { "type": "neoorigins:add_velocity", "y": 1.5 },
"fail_action": {
"type": "neoorigins:execute_command",
"command": "tellraw @s {\"text\":\"You must be on the ground to leap.\",\"color\":\"red\"}"
},
"name": "Leap"
}
- Works on every activation path: skill slots, named hotkeys, and vanilla input keys.
- Fires once per press. Held continuous keys are edge-detected so the feedback doesn’t spam every tick.
- Only
conditionfailures trigger it; a press blocked by an active cooldown stays silent (the HUD already shows the cooldown), and a blocked attempt never consumes the cooldown. - The native
neoorigins:active_abilitytype supports the same field (see POWER_TYPES.md).
Hotkey-less actives (disable_hotkey)
origins:active_self accepts an optional boolean disable_hotkey (a NeoOrigins extension; plain Apoli ignores it). When true, the power stays a fully-fledged active ability (its condition, cooldown, and fail_action all still apply), but it claims no skill slot or named hotkey, so no key press can fire it. The only way to trigger it is the neoorigins:activate_power action from another power:
{
"type": "origins:active_self",
"disable_hotkey": true,
"cooldown": 200,
"entity_action": { "type": "neoorigins:add_velocity", "y": 2.0 },
"name": "Hidden Leap"
}
- Use this for abilities that should only ever be reached programmatically, e.g. a passive
condition_passivepower that firesneoorigins:activate_powerat the hotkey-less power when its own trigger conditions are met. - Omitting
keyon anorigins:active_selfnormally drops the power into the next freeskill_1..skill_6slot;disable_hotkey: trueopts out of that entirely, freeing the slot for other powers. - A
disable_hotkeypower with noentity_actiondoes nothing; there’s no hotkey and no action, so the power is inert. disable_hotkey: truetakes precedence even if you also declare akey: the key is ignored and no slot or hotkey is bound. You don’t have to removekeyto make an existing active power hotkey-less.
How the pool works
- At reload, the server collects every distinct
keyvalue from all loaded powers and broadcasts the sorted list to each client. Pool size is the client’s[hotkeys] pool_size(default 32, range 1-256;NeoOriginsClientConfig.HOTKEY_POOL_SIZE). Slots 1-64 ship a “Hotkey N” label; higher slots work but show the raw translation key. - Each declared key is assigned an anonymous
Hotkey 01…Hotkey Nslot in stable order; a player who relogs sees the same key in the same slot as long as the pack hasn’t changed. - The player rebinds each slot to a physical key in vanilla controls. Press routes via
ActivatePowerByKeyPayloadback to the server, which fires the bound power’s entity action under the original cooldown / condition gates. - If keybindjs is loaded and already registers a mapping with the same translation key, that mapping is used and no pool slot is spent on it.
Display labels
The hotkey list in the controls menu shows your translation key’s human label. Built-in skill_5 and skill_6 slots use the same key.neoorigins.skill_N naming as the original four; their labels are bundled in assets/neoorigins/lang/en_us.json.
Source of truth: power/keybind/PowerKeybindRegistry.java, client/HotkeyAssignments.java.
Active theme datapack file
The UI theme used by the origin selection / info screens is selectable per world via a datapack file. Drop the following into any pack:
data/<namespace>/neoorigins/active_theme.json
{ "theme": "examplepack:dark_woods" }
The server reads every active_theme.json on world load + each /reload and broadcasts the selection to every client at login. When multiple packs each declare an active_theme.json, the one loaded last wins and a warning is logged listing every contributor. A per-client override lives at config/neoorigins/client.toml ([ui] theme_override = "<ns>:<id>") and beats the datapack file when set to a loaded id.
For the theme JSON schema (assets/<ns>/ui_themes/<id>.json) and the authoring quickstart, see THEMING.md. A copy-and-edit pack skeleton lives at docs/theme-template/.
Namespaces & prefixes
NeoOrigins accepts legacy prefixes for cross-mod pack compat.
| Prefix | Meaning | How it’s resolved |
|---|---|---|
neoorigins:* | Canonical 2.0 namespace. Use this for new packs. | Direct registry lookup. |
origins:* | Upstream Apoli / vanilla Origins. | Translator in OriginsCompatPowerLoader maps to neoorigins:* or a DSL recipe. |
apace:* | Apace mod variant. | Same translator as origins:*. |
apoli:* | Upstream Apoli mod. | Canonicalized to origins:* and fed through the same translator; LegacyPowerTypeAliases covers only the odd cross-mod id (e.g. apoli:edible_item). |
apugli:* | Apugli mod. | Canonicalized to origins:* like apoli:* and fed through the same translator. LegacyPowerTypeAliases also covers apugli:edible_item, apugli:action_on_jump and apugli:action_on_target_death. |
A remapped type logs one [2.0-legacy] warning per old type id per boot, naming the replacement. The remap rewrites only the fields it knows about; the replacement type’s parser then reads the result, so a field neither the remap nor the new type reads has no effect.
JSON schemas
Machine-readable schemas live under schema/. Point your IDE / datapack validator at:
schema/power.schema.json: for files underdata/*/origins/powers/schema/origin.schema.json: for files underdata/*/origins/origins/schema/origin_layer.schema.json: for files underdata/*/origins/origin_layers/schema/mob_origin.schema.json: for files underdata/*/origins/mob_origins/schema/morph.schema.json: for files underdata/*/neoorigins/morphs/schema/condition.schema.json,schema/action.schema.json,schema/block_condition.schema.json,schema/item_condition.schema.json,schema/item_action.schema.json: the nested condition / action objects
Schemas are derived from the Java Config records and are authoritative against what the loader accepts. If the schema disagrees with a prose doc, the schema wins.
Capability system
Powers declare capability tags via capabilities(Config). These tags are synced to the client and used by client-predicted mixins (e.g. "wall_climb", "wall_phase", "no_physics", "flight").
A player-aware variant capabilities(ServerPlayer, Config) is available for capabilities that depend on runtime state (conditions, resource levels, etc.). Default delegates to the static variant. Used by model_color to conditionally emit the color capability based on a condition field.
Mod integration (Java)
For other mods that need to read or change a player’s origins programmatically.
Where origins live. A player’s per-layer selection is stored on the neoorigins:origin_data data attachment (PlayerOriginData, accessed via player.getData(OriginAttachments.originData())). It persists only the layer → origin map plus a little bookkeeping; a player’s powers are not stored. The active power set is derived at runtime from each assigned origin’s definition (ActiveOriginService), so writing the attachment NBT directly does not apply or remove any powers.
Changing origins cleanly. Because powers are derived, swapping an origin requires running the revoke/grant lifecycle (onRevoked / onGranted, attribute-modifier cleanup, event-handler teardown, client sync). Two entry points on com.cyberday1.neoorigins.service.ActiveOriginService:
applyOriginPowers(player, layerId, oldOriginId, newOriginId)transitions a single layer: revokesoldOriginId’s powers, grantsnewOriginId’s. Passnullfor either id to grant-only / revoke-only. This is what/neoorigins setuses.reapplyOrigins(player, Map<layerId, originId>)replaces a player’s entire origin selection in one clean call: tears down all current powers, overwrites the layer map, regrants, restores server-global powers, and syncs the client. Intended for profile / loadout mods (e.g. Switchy) that restore a saved origin set. Call this instead of writing the attachment NBT directly to avoid leftover powers from the previous profile. An empty map clears the player to no origins.
Both run the full lifecycle, so the client HUD, keybinds, and attribute state stay consistent. After either call you do not need a separate sync.
Source-of-truth paths
When docs drift, these are the code files that won:
- Power registrations:
src/main/java/com/cyberday1/neoorigins/power/registry/PowerTypes.java - Power Config records:
src/main/java/com/cyberday1/neoorigins/power/builtin/*.java - Condition verbs:
src/main/java/com/cyberday1/neoorigins/compat/condition/BuiltinConditions.java(registered descriptors;ConditionParser.javadispatches to them) - Action verbs:
src/main/java/com/cyberday1/neoorigins/compat/action/BuiltinActions.java(registered descriptors;ActionParser.javadispatches to them) - Event keys:
src/main/java/com/cyberday1/neoorigins/service/EventPowerIndex.java - Legacy aliases:
src/main/java/com/cyberday1/neoorigins/power/registry/LegacyPowerTypeAliases.java