All Mods Resource Packs Data Packs Shaders Modpacks Plugins
Neo Origins

Neo Origins

by cyberday • Downloads: 0 • Followers: 0
Description
Gallery
Changelog
Versions

A modern, ground-up reimplementation of the Origins experience for NeoForge (MC 26.1).

Much of what it ships beyond the vanilla Origins set arrived as community suggestions, and some of those suggestions may have been shaped by addons that covered the same ground first. Where an origin here lines up with one of theirs, the idea is theirs:

If you maintain one of these and would like the wording changed, or your project removed from this list, open an issue and it will be handled.

Features 21 built-in origins — Human, Merling, Avian, Blazeling, Elytrian, Enderian, Arachnid, Shulk, Phantom, Feline, Golem, Caveborn, Draconic, Sylvan, Tiny, Revenant, Abyssal, Voidwalker, Stoneguard, Verdant, Umbral.

51 built-in power types — attribute modifiers, status effects, flight, wall climbing, damage modification, active abilities, biome effects, starting equipment, and more.

Hot-reload — /reload rebuilds all origins and powers without restarting the server.

Origins pack compatibility — drop existing Origins mod content packs into /config/originpacks/ and they load automatically.

Data-driven — all origins and powers defined in JSON; fully overridable via datapacks.

The original mod by Apace: https://modrinth.com/mod/origins

All Versions

+ Add Version
Name Game version Platforms Published Downloads Actions
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.2
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
26.1.x
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
1.21.1
Neoforge
1d ago 1
26.1.1
Neoforge
1d ago 1
26.1
Neoforge
1d ago 1
26.1.1
Neoforge
1d ago 1
26.1
Neoforge
1d ago 1
26.1
Neoforge
1d ago 1
26.1
Neoforge
1d ago 1
> A small release for the resource bar HUD and for pack commands. Resource bars now stack in a fixed, predictable order instead of one that followed an internal hash, with no empty slot left behind a bar that is hidden or dragged to its own position, and no bar's text printed over another bar's. The bars also get a new look: the built-in ones now draw in a framed style with value ticks, most with a scrolling fill themed to their origin, and packs can use the same eight styles, tint the plain one any colour, and run a bar from one colour into another. For pack authors, a command that does not parse is now written to the log along with the power that ran it, where before it failed in complete silence, and a valid execute ... run chain is no longer mistaken for a broken command by the legacy translation layer.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

### Changes

  • Resource bars stack in resource id order, lowest id nearest the hotbar.** The client kept its bars in a hash map, so the vertical order of the stack followed the resource keys' string hashes: stable for a given set of bars, but nothing a pack could predict, describe to a player, or control, and adding one resource dropped its bar wherever its hash happened to fall. A full sync now stores the bars sorted by resource key, which is the power id, and value updates leave each bar where it is. This rearranges existing stacks: any two or more bars sitting at their default positions, whose hash order differed from their id order, will have moved. Bars given a saved position in the HUD editor are unaffected. [POWER_TYPES.md](docs/POWER_TYPES.md) describes the order and which bars take a slot.

  • The built-in resource bars use the new bar styles.** Every origin that shows a resource bar now draws it in a framed style with value ticks: a scrolling themed fill where the origin has a clear element, such as fire for the Blazeling, water for the Kraken, void for the Enderian and sculk for the Warden, and otherwise the plain grey fill tinted to the bar's existing colour. The Frostborn bar is the one exception: it was orange and is now an ice gradient, blue at the empty end shading to frost white at the full end. Only the look changed: no resource values, regeneration or costs moved.

### Bug Fixes

  • A hidden or repositioned resource bar no longer leaves a gap in the stack.** The HUD advanced its stacking counter for every bar it knew about, whether or not that bar was drawn in the stack, so a bar hidden by hide when full, or one moved to a saved position in the HUD editor, still reserved its slot and the bars above it did not close up. The draw decision is now made for every bar first, and slots are handed only to the bars that will actually draw at a default position. The HUD editor assigns its slots the same way, so the gap that used to sit behind a dragged bar there is gone as well.

  • Stacked resource bars no longer print their text over each other.** Every bar draws its name above it and its value below it, but the stack climbed a fixed sixteen pixels per bar, which is less than a bar and its two lines of text need. Each bar's value landed on the name of the bar below it, so in a stack of several bars everything between the top name and the bottom value was an unreadable pile. Each slot is now as tall as what its bar actually draws: the bar, the name line, the value line and a small gap, which puts the built-in framed bars 29 pixels apart. A bar whose label is empty draws no name line and takes a shorter slot, though never shorter than the old sixteen. The HUD editor measures its bars the same way, so its default stack uses the same spacing as the HUD. [POWER_TYPES.md](docs/POWER_TYPES.md) describes the slot sizes.

  • A resource bar colour of the wrong length falls back to the default.** color, tint and tint_end in hud_render read any run of hex digits as a number, so the shorthand #FFF was read as #00000FFF rather than white, which draws an invisible fill or a blue tint, and a seven- or nine-digit typo gave some other wrong colour. Anything other than six or eight hex digits now falls back to #55AAFF, as a value that is not hex already did, and the log names the power and the value it rejected. An empty tint or tint_end counts as not set, as the field descriptions say, rather than as a bad value. A bar_fx preset whose track_color or level_color has the wrong length is skipped with a warning, the same as any other malformed preset.

### Pack Author Features

  • A pack command that does not parse is written to the log, naming the power that ran it.** Powers run their commands on a source with output suppressed, which is what keeps command spam out of chat. The game reports a command it cannot parse through that same suppressed channel, runs nothing, and raises no error doing so, so a typo such as tellraw @s {"Triggered"} produced no chat message, no log line and no effect: the power simply appeared to do nothing. Such a command is now logged once for each combination of power, site and command text, carrying the game's own reason for refusing it. Commands are still handed to the game exactly as before, so nothing that used to run stops running, and a legacy command the compatibility layer repairs on its way through is not reported. [ACTIONS.md](docs/ACTIONS.md) and [ADMIN_CONFIG.md](docs/ADMIN_CONFIG.md) both record what is logged.

  • Eight resource bar styles to choose from.** hud_render.animated now has built-in styles: neoorigins:fire, water, wind, earth, soul, void and sculk draw a scrolling themed fill inside a grey frame, and neoorigins:tinted draws a plain grey fill that does not move. Every style draws value ticks over the fill, a faint one every 5 points and a brighter one every 25, the same steps the old bar used, and ticks that would sit closer than 2 pixels apart are still left out. The scroll follows game time, so it moves smoothly between game ticks and stops while the game is paused. A player whose resource packs do not have the style sees the flat color fill instead, and a pack already using neoorigins:fire gets the new art and frame. Presets also gained frame (sized by frame_width and frame_height), loop_width, tint_from_color and a static mode, for packs that ship their own styles; a preset with no frame still draws the old box. [POWER_TYPES.md](docs/POWER_TYPES.md) lists the styles, [PACK_FORMAT.md](docs/PACK_FORMAT.md) describes the hud_render fields, and [animated_bar_artist_spec.md](docs/animated_bar_artist_spec.md) covers drawing the textures.

  • neoorigins:tinted takes any colour.** The fill is grey, and tint multiplies it channel by channel: its lightest pixels come out as the colour itself and its darker greys as deeper shades of it, so the fill keeps its shading, and a bright, saturated colour gives the clearest bar. When tint is not set the bar uses its color, so a bar that already has one only needs "animated": "neoorigins:tinted" added. tint takes #RRGGBB or #AARRGGBB, with the alpha ignored since the fill is always opaque. It works on the themed styles too, but those are drawn in colour already. [POWER_TYPES.md](docs/POWER_TYPES.md) has worked examples.

  • hud_render.tint_end shades a bar from one colour into another.** On a framed style that does not scroll, such as neoorigins:tinted, the fill runs from tint at the left end of the bar to tint_end at the right, starting from color instead when tint is not set and the style takes its colour, as neoorigins:tinted does. The gradient spans the whole bar rather than the filled part, so each point of the bar keeps its colour as the value rises and falls. Without tint_end the bar is one flat colour, as before. The Frostborn bar is built this way, and is the gradient example in [POWER_TYPES.md](docs/POWER_TYPES.md).

  • Both power editors know the new bar fields.** In the in-game creator, animated has a pick button listing the eight built-in styles and any style a loaded resource pack adds, and it still takes any id typed in. The web editor suggests the eight styles as you type and shows a preview of the bar above the hud_render fields, with its style, tint and gradient applied. Both editors now flag a color, tint or tint_end that is not six or eight hex digits, which the loader would replace with #55AAFF, and an animated id with no namespace, which can never match a style.

### Compatibility (Apoli / Origins)

  • A valid execute ... run command is no longer treated as unparseable by the legacy rewriter.** The check that decides whether a legacy pack's command may be rewritten asked whether the top level of the parse carried a command to run. A redirect such as execute as @s run does not: it leaves the top level empty and puts the command in a child context, so every valid execute chain in every pack read as broken. That was the reverse of what the check exists for, since an execute chain also matching a legacy pattern was handed to the rewriter even though the game would have run it exactly as written. The check now judges a parse the way the game itself does when it finishes parsing, taking the game's own parse error first, then asking whether the chain of contexts flattens into something runnable.

### Documentation

  • The commands page shows a text component.** Every example under neoorigins:execute_command used a command with no JSON payload, so the one thing most likely to go wrong in a pack command had no worked example on the page that documents pack commands: a text component is itself JSON, and its quotes have to be escaped inside the command string. The escaped tellraw form now sits beside the existing example, with {"Triggered"} named as the shape that does not parse and the reason it does not. The paragraph describing what a command that does not parse writes to the log now notes that up to 2.2.29 nothing was written at all, so a reader still on that version does not go hunting for a line that is not there. See [ACTIONS.md](docs/ACTIONS.md).
> A small release for the resource bar HUD and for pack commands. Resource bars now stack in a fixed, predictable order instead of one that followed an internal hash, with no empty slot left behind a bar that is hidden or dragged to its own position, and no bar's text printed over another bar's. The bars also get a new look: the built-in ones now draw in a framed style with value ticks, most with a scrolling fill themed to their origin, and packs can use the same eight styles, tint the plain one any colour, and run a bar from one colour into another. For pack authors, a command that does not parse is now written to the log along with the power that ran it, where before it failed in complete silence, and a valid execute ... run chain is no longer mistaken for a broken command by the legacy translation layer.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

### Changes

  • Resource bars stack in resource id order, lowest id nearest the hotbar.** The client kept its bars in a hash map, so the vertical order of the stack followed the resource keys' string hashes: stable for a given set of bars, but nothing a pack could predict, describe to a player, or control, and adding one resource dropped its bar wherever its hash happened to fall. A full sync now stores the bars sorted by resource key, which is the power id, and value updates leave each bar where it is. This rearranges existing stacks: any two or more bars sitting at their default positions, whose hash order differed from their id order, will have moved. Bars given a saved position in the HUD editor are unaffected. [POWER_TYPES.md](docs/POWER_TYPES.md) describes the order and which bars take a slot.

  • The built-in resource bars use the new bar styles.** Every origin that shows a resource bar now draws it in a framed style with value ticks: a scrolling themed fill where the origin has a clear element, such as fire for the Blazeling, water for the Kraken, void for the Enderian and sculk for the Warden, and otherwise the plain grey fill tinted to the bar's existing colour. The Frostborn bar is the one exception: it was orange and is now an ice gradient, blue at the empty end shading to frost white at the full end. Only the look changed: no resource values, regeneration or costs moved.

### Bug Fixes

  • A hidden or repositioned resource bar no longer leaves a gap in the stack.** The HUD advanced its stacking counter for every bar it knew about, whether or not that bar was drawn in the stack, so a bar hidden by hide when full, or one moved to a saved position in the HUD editor, still reserved its slot and the bars above it did not close up. The draw decision is now made for every bar first, and slots are handed only to the bars that will actually draw at a default position. The HUD editor assigns its slots the same way, so the gap that used to sit behind a dragged bar there is gone as well.

  • Stacked resource bars no longer print their text over each other.** Every bar draws its name above it and its value below it, but the stack climbed a fixed sixteen pixels per bar, which is less than a bar and its two lines of text need. Each bar's value landed on the name of the bar below it, so in a stack of several bars everything between the top name and the bottom value was an unreadable pile. Each slot is now as tall as what its bar actually draws: the bar, the name line, the value line and a small gap, which puts the built-in framed bars 29 pixels apart. A bar whose label is empty draws no name line and takes a shorter slot, though never shorter than the old sixteen. The HUD editor measures its bars the same way, so its default stack uses the same spacing as the HUD. [POWER_TYPES.md](docs/POWER_TYPES.md) describes the slot sizes.

  • A resource bar colour of the wrong length falls back to the default.** color, tint and tint_end in hud_render read any run of hex digits as a number, so the shorthand #FFF was read as #00000FFF rather than white, which draws an invisible fill or a blue tint, and a seven- or nine-digit typo gave some other wrong colour. Anything other than six or eight hex digits now falls back to #55AAFF, as a value that is not hex already did, and the log names the power and the value it rejected. An empty tint or tint_end counts as not set, as the field descriptions say, rather than as a bad value. A bar_fx preset whose track_color or level_color has the wrong length is skipped with a warning, the same as any other malformed preset.

### Pack Author Features

  • A pack command that does not parse is written to the log, naming the power that ran it.** Powers run their commands on a source with output suppressed, which is what keeps command spam out of chat. The game reports a command it cannot parse through that same suppressed channel, runs nothing, and raises no error doing so, so a typo such as tellraw @s {"Triggered"} produced no chat message, no log line and no effect: the power simply appeared to do nothing. Such a command is now logged once for each combination of power, site and command text, carrying the game's own reason for refusing it. Commands are still handed to the game exactly as before, so nothing that used to run stops running, and a legacy command the compatibility layer repairs on its way through is not reported. [ACTIONS.md](docs/ACTIONS.md) and [ADMIN_CONFIG.md](docs/ADMIN_CONFIG.md) both record what is logged.

  • Eight resource bar styles to choose from.** hud_render.animated now has built-in styles: neoorigins:fire, water, wind, earth, soul, void and sculk draw a scrolling themed fill inside a grey frame, and neoorigins:tinted draws a plain grey fill that does not move. Every style draws value ticks over the fill, a faint one every 5 points and a brighter one every 25, the same steps the old bar used, and ticks that would sit closer than 2 pixels apart are still left out. The scroll follows game time, so it moves smoothly between game ticks and stops while the game is paused. A player whose resource packs do not have the style sees the flat color fill instead, and a pack already using neoorigins:fire gets the new art and frame. Presets also gained frame (sized by frame_width and frame_height), loop_width, tint_from_color and a static mode, for packs that ship their own styles; a preset with no frame still draws the old box. [POWER_TYPES.md](docs/POWER_TYPES.md) lists the styles, [PACK_FORMAT.md](docs/PACK_FORMAT.md) describes the hud_render fields, and [animated_bar_artist_spec.md](docs/animated_bar_artist_spec.md) covers drawing the textures.

  • neoorigins:tinted takes any colour.** The fill is grey, and tint multiplies it channel by channel: its lightest pixels come out as the colour itself and its darker greys as deeper shades of it, so the fill keeps its shading, and a bright, saturated colour gives the clearest bar. When tint is not set the bar uses its color, so a bar that already has one only needs "animated": "neoorigins:tinted" added. tint takes #RRGGBB or #AARRGGBB, with the alpha ignored since the fill is always opaque. It works on the themed styles too, but those are drawn in colour already. [POWER_TYPES.md](docs/POWER_TYPES.md) has worked examples.

  • hud_render.tint_end shades a bar from one colour into another.** On a framed style that does not scroll, such as neoorigins:tinted, the fill runs from tint at the left end of the bar to tint_end at the right, starting from color instead when tint is not set and the style takes its colour, as neoorigins:tinted does. The gradient spans the whole bar rather than the filled part, so each point of the bar keeps its colour as the value rises and falls. Without tint_end the bar is one flat colour, as before. The Frostborn bar is built this way, and is the gradient example in [POWER_TYPES.md](docs/POWER_TYPES.md).

  • Both power editors know the new bar fields.** In the in-game creator, animated has a pick button listing the eight built-in styles and any style a loaded resource pack adds, and it still takes any id typed in. The web editor suggests the eight styles as you type and shows a preview of the bar above the hud_render fields, with its style, tint and gradient applied. Both editors now flag a color, tint or tint_end that is not six or eight hex digits, which the loader would replace with #55AAFF, and an animated id with no namespace, which can never match a style.

### Compatibility (Apoli / Origins)

  • A valid execute ... run command is no longer treated as unparseable by the legacy rewriter.** The check that decides whether a legacy pack's command may be rewritten asked whether the top level of the parse carried a command to run. A redirect such as execute as @s run does not: it leaves the top level empty and puts the command in a child context, so every valid execute chain in every pack read as broken. That was the reverse of what the check exists for, since an execute chain also matching a legacy pattern was handed to the rewriter even though the game would have run it exactly as written. The check now judges a parse the way the game itself does when it finishes parsing, taking the game's own parse error first, then asking whether the chain of contexts flattens into something runnable.

### Documentation

  • The commands page shows a text component.** Every example under neoorigins:execute_command used a command with no JSON payload, so the one thing most likely to go wrong in a pack command had no worked example on the page that documents pack commands: a text component is itself JSON, and its quotes have to be escaped inside the command string. The escaped tellraw form now sits beside the existing example, with {"Triggered"} named as the shape that does not parse and the reason it does not. The paragraph describing what a command that does not parse writes to the log now notes that up to 2.2.29 nothing was written at all, so a reader still on that version does not go hunting for a line that is not there. See [ACTIONS.md](docs/ACTIONS.md).
> A small release for the resource bar HUD and for pack commands. Resource bars now stack in a fixed, predictable order instead of one that followed an internal hash, with no empty slot left behind a bar that is hidden or dragged to its own position, and no bar's text printed over another bar's. The bars also get a new look: the built-in ones now draw in a framed style with value ticks, most with a scrolling fill themed to their origin, and packs can use the same eight styles, tint the plain one any colour, and run a bar from one colour into another. For pack authors, a command that does not parse is now written to the log along with the power that ran it, where before it failed in complete silence, and a valid execute ... run chain is no longer mistaken for a broken command by the legacy translation layer.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

### Changes

  • Resource bars stack in resource id order, lowest id nearest the hotbar.** The client kept its bars in a hash map, so the vertical order of the stack followed the resource keys' string hashes: stable for a given set of bars, but nothing a pack could predict, describe to a player, or control, and adding one resource dropped its bar wherever its hash happened to fall. A full sync now stores the bars sorted by resource key, which is the power id, and value updates leave each bar where it is. This rearranges existing stacks: any two or more bars sitting at their default positions, whose hash order differed from their id order, will have moved. Bars given a saved position in the HUD editor are unaffected. [POWER_TYPES.md](docs/POWER_TYPES.md) describes the order and which bars take a slot.

  • The built-in resource bars use the new bar styles.** Every origin that shows a resource bar now draws it in a framed style with value ticks: a scrolling themed fill where the origin has a clear element, such as fire for the Blazeling, water for the Kraken, void for the Enderian and sculk for the Warden, and otherwise the plain grey fill tinted to the bar's existing colour. The Frostborn bar is the one exception: it was orange and is now an ice gradient, blue at the empty end shading to frost white at the full end. Only the look changed: no resource values, regeneration or costs moved.

### Bug Fixes

  • A hidden or repositioned resource bar no longer leaves a gap in the stack.** The HUD advanced its stacking counter for every bar it knew about, whether or not that bar was drawn in the stack, so a bar hidden by hide when full, or one moved to a saved position in the HUD editor, still reserved its slot and the bars above it did not close up. The draw decision is now made for every bar first, and slots are handed only to the bars that will actually draw at a default position. The HUD editor assigns its slots the same way, so the gap that used to sit behind a dragged bar there is gone as well.

  • Stacked resource bars no longer print their text over each other.** Every bar draws its name above it and its value below it, but the stack climbed a fixed sixteen pixels per bar, which is less than a bar and its two lines of text need. Each bar's value landed on the name of the bar below it, so in a stack of several bars everything between the top name and the bottom value was an unreadable pile. Each slot is now as tall as what its bar actually draws: the bar, the name line, the value line and a small gap, which puts the built-in framed bars 29 pixels apart. A bar whose label is empty draws no name line and takes a shorter slot, though never shorter than the old sixteen. The HUD editor measures its bars the same way, so its default stack uses the same spacing as the HUD. [POWER_TYPES.md](docs/POWER_TYPES.md) describes the slot sizes.

  • A resource bar colour of the wrong length falls back to the default.** color, tint and tint_end in hud_render read any run of hex digits as a number, so the shorthand #FFF was read as #00000FFF rather than white, which draws an invisible fill or a blue tint, and a seven- or nine-digit typo gave some other wrong colour. Anything other than six or eight hex digits now falls back to #55AAFF, as a value that is not hex already did, and the log names the power and the value it rejected. An empty tint or tint_end counts as not set, as the field descriptions say, rather than as a bad value. A bar_fx preset whose track_color or level_color has the wrong length is skipped with a warning, the same as any other malformed preset.

### Pack Author Features

  • A pack command that does not parse is written to the log, naming the power that ran it.** Powers run their commands on a source with output suppressed, which is what keeps command spam out of chat. The game reports a command it cannot parse through that same suppressed channel, runs nothing, and raises no error doing so, so a typo such as tellraw @s {"Triggered"} produced no chat message, no log line and no effect: the power simply appeared to do nothing. Such a command is now logged once for each combination of power, site and command text, carrying the game's own reason for refusing it. Commands are still handed to the game exactly as before, so nothing that used to run stops running, and a legacy command the compatibility layer repairs on its way through is not reported. [ACTIONS.md](docs/ACTIONS.md) and [ADMIN_CONFIG.md](docs/ADMIN_CONFIG.md) both record what is logged.

  • Eight resource bar styles to choose from.** hud_render.animated now has built-in styles: neoorigins:fire, water, wind, earth, soul, void and sculk draw a scrolling themed fill inside a grey frame, and neoorigins:tinted draws a plain grey fill that does not move. Every style draws value ticks over the fill, a faint one every 5 points and a brighter one every 25, the same steps the old bar used, and ticks that would sit closer than 2 pixels apart are still left out. The scroll follows game time, so it moves smoothly between game ticks and stops while the game is paused. A player whose resource packs do not have the style sees the flat color fill instead, and a pack already using neoorigins:fire gets the new art and frame. Presets also gained frame (sized by frame_width and frame_height), loop_width, tint_from_color and a static mode, for packs that ship their own styles; a preset with no frame still draws the old box. [POWER_TYPES.md](docs/POWER_TYPES.md) lists the styles, [PACK_FORMAT.md](docs/PACK_FORMAT.md) describes the hud_render fields, and [animated_bar_artist_spec.md](docs/animated_bar_artist_spec.md) covers drawing the textures.

  • neoorigins:tinted takes any colour.** The fill is grey, and tint multiplies it channel by channel: its lightest pixels come out as the colour itself and its darker greys as deeper shades of it, so the fill keeps its shading, and a bright, saturated colour gives the clearest bar. When tint is not set the bar uses its color, so a bar that already has one only needs "animated": "neoorigins:tinted" added. tint takes #RRGGBB or #AARRGGBB, with the alpha ignored since the fill is always opaque. It works on the themed styles too, but those are drawn in colour already. [POWER_TYPES.md](docs/POWER_TYPES.md) has worked examples.

  • hud_render.tint_end shades a bar from one colour into another.** On a framed style that does not scroll, such as neoorigins:tinted, the fill runs from tint at the left end of the bar to tint_end at the right, starting from color instead when tint is not set and the style takes its colour, as neoorigins:tinted does. The gradient spans the whole bar rather than the filled part, so each point of the bar keeps its colour as the value rises and falls. Without tint_end the bar is one flat colour, as before. The Frostborn bar is built this way, and is the gradient example in [POWER_TYPES.md](docs/POWER_TYPES.md).

  • Both power editors know the new bar fields.** In the in-game creator, animated has a pick button listing the eight built-in styles and any style a loaded resource pack adds, and it still takes any id typed in. The web editor suggests the eight styles as you type and shows a preview of the bar above the hud_render fields, with its style, tint and gradient applied. Both editors now flag a color, tint or tint_end that is not six or eight hex digits, which the loader would replace with #55AAFF, and an animated id with no namespace, which can never match a style.

### Compatibility (Apoli / Origins)

  • A valid execute ... run command is no longer treated as unparseable by the legacy rewriter.** The check that decides whether a legacy pack's command may be rewritten asked whether the top level of the parse carried a command to run. A redirect such as execute as @s run does not: it leaves the top level empty and puts the command in a child context, so every valid execute chain in every pack read as broken. That was the reverse of what the check exists for, since an execute chain also matching a legacy pattern was handed to the rewriter even though the game would have run it exactly as written. The check now judges a parse the way the game itself does when it finishes parsing, taking the game's own parse error first, then asking whether the chain of contexts flattens into something runnable.

### Documentation

  • The commands page shows a text component.** Every example under neoorigins:execute_command used a command with no JSON payload, so the one thing most likely to go wrong in a pack command had no worked example on the page that documents pack commands: a text component is itself JSON, and its quotes have to be escaped inside the command string. The escaped tellraw form now sits beside the existing example, with {"Triggered"} named as the shape that does not parse and the reason it does not. The paragraph describing what a command that does not parse writes to the log now notes that up to 2.2.29 nothing was written at all, so a reader still on that version does not go hunting for a line that is not there. See [ACTIONS.md](docs/ACTIONS.md).
> A fixes release, mostly for the two origin editors, which could quietly lose data on save. Saving a power in the in-game creator deleted any detail its form could not display, loading a template and saving it dropped the origin's evolution tiers and custom spawn, one creator save could overwrite another origin's power files, and the web editor started new origins in the neoorigins namespace, where a name matching a shipped origin replaced it for the whole server. Outside the editors, an area_of_effect with a block action and no radius no longer runs that action across seventeen thousand blocks, one invalid origin id no longer empties an entire origin layer, and origin spawn searches start from the world spawn instead of the wrong end of the map. On 1.21.1 other players are drawn in their own model colour rather than yours.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • An area_of_effect with a block action no longer runs it across seventeen thousand blocks.** The block sweep borrowed the entity sweep's default radius of sixteen, so a block_action with no radius written ran at every block within sixteen of the centre: 17,077 positions per activation, and with explode as the block action the server stalled. The block sweep now defaults to two blocks, thirty-three positions, while the entity sweep keeps its sixteen, and a radius you do write is honoured as before up to the existing cap of sixteen. Separately, explode is limited to four per player per tick. They all go off at the player rather than the swept block, and hurt immunity after the first absorbs most of what the rest would deal, so the extras bought lag and nothing else. [ACTIONS.md](docs/ACTIONS.md) records both defaults and the cap.
  • One invalid origin id no longer empties a whole origin layer.** An id the game cannot parse, such as a web export named Wizard or wizard with a trailing space, threw while its layer was being read, and the loader's answer was to discard the entire layer. Since addon and exported packs add to the built-in neoorigins:origin and neoorigins:class layers, one bad id emptied the picker of every origin, or every class, for everyone on the server, with nothing on screen to say why. The bad entry is now skipped with a warning naming it, and the rest of the layer loads.
  • Origin spawn searches start from the world spawn, scaled into the searched dimension the way a portal scales it.** On 1.21.1 only the Nether was wrong: the search read the Overworld's spawn point without dividing by eight, so a world spawn at 8000, 0 sent a new Blazeling to Nether 8000, 0, sixty-four thousand blocks out in Overworld terms. On 26.1 and 26.2 every search started from 0, 0 in whatever dimension it searched, so all nine built-in origins with a spawn location ignored a moved world spawn. All three versions now start from the world spawn converted into the searched dimension, so an Overworld spawn at 8000, 0 centres a Nether search on 1000, 0, with the height kept inside build limits and the position inside the world border. [PACK_FORMAT.md](docs/PACK_FORMAT.md) covers spawn_location itself.
  • Every player is drawn in their own model colour instead of yours (1.21.1).** model_color tints were read from your own powers for every player on screen, so everyone around you wore your colour and nobody ever saw theirs. Each player's tint now comes from that player's own synced powers, clears when their effect ends, and is dropped when they log out or leave range. Minecraft 26.1 and 26.2 draw no model colours, since the 26.1 rendering rework removed the call the tint depends on.
  • Caveborn meal tints clear when the meal's effect wears off.** model_color kept one condition slot per player, so the six Caveborn diet tints overwrote each other every second: a tint that ran out only told the client if it happened to be checked last, and the others stayed on the model until a respawn, relog or dimension change forced a resync. The shared slot also flipped twice a second, sending a full power sync each time. Each power now keeps its own result. On 26.1 and 26.2, where tints are not drawn, what changes is that the needless syncs stop.

  • Saving a power in the in-game creator keeps everything its form cannot show.** Opening a power in the form and saving it rebuilt each field from what the form understands, so any detail a sub-form did not model was deleted even if you changed nothing: an "inverted": true on a condition vanished and flipped its meaning, a nested weapon_damage_scale disappeared, an action written as a list could be dropped outright, and a shorthand item condition with no type was read as empty. That last one is how a saved Riding the Sword would fly with anything in hand. A save now applies only what you changed, onto the JSON the form was opened on, at any depth and inside lists, and clearing a field still removes it. A list you wrote as [] is kept rather than dropped, since for some fields it means something different from leaving the key out. Every shipped power saves back unchanged now, apart from starting_equipment folding a single item into its stacks list, which the game reads the same way.
  • Load template followed by Save gives you back the origin you loaded.** Loading a template into the in-game creator and saving it wrote a different origin from the one on screen. Evolution tiers, spawn locations and upgrades were dropped, so of the seventy-eight shipped origins the fifty-eight with evolution tiers lost them and the nine with a spawn location lost that, along with any origin field the creator has no box for, such as unchoosable, special or the Figura model keys. Powers were copied under new ids without updating the references between them, so a saved Iron Monk's Palm Strike still checked the original stamina pool, read zero and never fired. A name or description written as a translation key came back as the raw key, and the identity boxes truncated at two hundred and fifty-six characters, cutting six built-in descriptions. All of that is kept or corrected now, and a power keeps its id once given, so later edits in the Powers tab no longer rename it out from under its references.
  • A creator save no longer overwrites another origin's power files.** Power files are named after the origin's path and the power's type, with anything that is not a letter, digit or underscore folded into _. So a mob origin and a player origin both called foo, or two origins called a/b and a_b, wrote to the same file, and the second save silently replaced the first origin's power. The creator now checks which origin already lists each power id, saves a clashing one under a free id, updates every reference to it, and logs the move.
  • The web editor starts new origins in neoorigins_custom, so they cannot replace shipped ones by accident.** New origin and mob origin drafts defaulted to neoorigins, the namespace the built-in content uses, so a name matching a shipped origin or power silently replaced it for everyone on the server. New drafts now default to neoorigins_custom, the namespace the in-game creator already writes to. Loading a template still keeps the shipped id, since overriding that origin is the point. Templates also keep their evolution tiers, which used to be stripped on load: fifty-eight of the seventy-eight web templates have them, and they are carried through and exported as they were, though still not editable here. An empty list you wrote survives export too.
  • Web exports refuse ids the game cannot load.** The check only caught blank and duplicate ids, so a path with a capital letter or a trailing space exported cleanly and then, through the layer fault above, emptied the origin picker. The origin's namespace and path, the layer id, power ids and upgrade ids are now all checked against the game's own id rules first, with a message naming the offending character, and a blank upgrade is refused instead of loading as a dead reference. The mob origin editor, which had no export check at all, now refuses the same ids, and any power id used twice.
  • Modded fish whitelisted in the config now count as meat.** ocean_origins.extra_fish_foods lets you name modded fish an ocean origin may eat without editing a datapack, but the carnivore and vegetarian diets read only the neoorigins:meat_foods tag, so a fish listed there fed a Merling and was invisible to origins:carnivore. Both diets now read the tag **or** that list, so a whitelisted fish feeds a carnivore and is refused to a vegetarian, the same way tagged fish already were.

> A fixes release, mostly for the two origin editors, which could quietly lose data on save. Saving a power in the in-game creator deleted any detail its form could not display, loading a template and saving it dropped the origin's evolution tiers and custom spawn, one creator save could overwrite another origin's power files, and the web editor started new origins in the neoorigins namespace, where a name matching a shipped origin replaced it for the whole server. Outside the editors, an area_of_effect with a block action and no radius no longer runs that action across seventeen thousand blocks, one invalid origin id no longer empties an entire origin layer, and origin spawn searches start from the world spawn instead of the wrong end of the map. On 1.21.1 other players are drawn in their own model colour rather than yours.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • An area_of_effect with a block action no longer runs it across seventeen thousand blocks.** The block sweep borrowed the entity sweep's default radius of sixteen, so a block_action with no radius written ran at every block within sixteen of the centre: 17,077 positions per activation, and with explode as the block action the server stalled. The block sweep now defaults to two blocks, thirty-three positions, while the entity sweep keeps its sixteen, and a radius you do write is honoured as before up to the existing cap of sixteen. Separately, explode is limited to four per player per tick. They all go off at the player rather than the swept block, and hurt immunity after the first absorbs most of what the rest would deal, so the extras bought lag and nothing else. [ACTIONS.md](docs/ACTIONS.md) records both defaults and the cap.
  • One invalid origin id no longer empties a whole origin layer.** An id the game cannot parse, such as a web export named Wizard or wizard with a trailing space, threw while its layer was being read, and the loader's answer was to discard the entire layer. Since addon and exported packs add to the built-in neoorigins:origin and neoorigins:class layers, one bad id emptied the picker of every origin, or every class, for everyone on the server, with nothing on screen to say why. The bad entry is now skipped with a warning naming it, and the rest of the layer loads.
  • Origin spawn searches start from the world spawn, scaled into the searched dimension the way a portal scales it.** On 1.21.1 only the Nether was wrong: the search read the Overworld's spawn point without dividing by eight, so a world spawn at 8000, 0 sent a new Blazeling to Nether 8000, 0, sixty-four thousand blocks out in Overworld terms. On 26.1 and 26.2 every search started from 0, 0 in whatever dimension it searched, so all nine built-in origins with a spawn location ignored a moved world spawn. All three versions now start from the world spawn converted into the searched dimension, so an Overworld spawn at 8000, 0 centres a Nether search on 1000, 0, with the height kept inside build limits and the position inside the world border. [PACK_FORMAT.md](docs/PACK_FORMAT.md) covers spawn_location itself.
  • Every player is drawn in their own model colour instead of yours (1.21.1).** model_color tints were read from your own powers for every player on screen, so everyone around you wore your colour and nobody ever saw theirs. Each player's tint now comes from that player's own synced powers, clears when their effect ends, and is dropped when they log out or leave range. Minecraft 26.1 and 26.2 draw no model colours, since the 26.1 rendering rework removed the call the tint depends on.
  • Caveborn meal tints clear when the meal's effect wears off.** model_color kept one condition slot per player, so the six Caveborn diet tints overwrote each other every second: a tint that ran out only told the client if it happened to be checked last, and the others stayed on the model until a respawn, relog or dimension change forced a resync. The shared slot also flipped twice a second, sending a full power sync each time. Each power now keeps its own result. On 26.1 and 26.2, where tints are not drawn, what changes is that the needless syncs stop.

  • Saving a power in the in-game creator keeps everything its form cannot show.** Opening a power in the form and saving it rebuilt each field from what the form understands, so any detail a sub-form did not model was deleted even if you changed nothing: an "inverted": true on a condition vanished and flipped its meaning, a nested weapon_damage_scale disappeared, an action written as a list could be dropped outright, and a shorthand item condition with no type was read as empty. That last one is how a saved Riding the Sword would fly with anything in hand. A save now applies only what you changed, onto the JSON the form was opened on, at any depth and inside lists, and clearing a field still removes it. A list you wrote as [] is kept rather than dropped, since for some fields it means something different from leaving the key out. Every shipped power saves back unchanged now, apart from starting_equipment folding a single item into its stacks list, which the game reads the same way.
  • Load template followed by Save gives you back the origin you loaded.** Loading a template into the in-game creator and saving it wrote a different origin from the one on screen. Evolution tiers, spawn locations and upgrades were dropped, so of the seventy-eight shipped origins the fifty-eight with evolution tiers lost them and the nine with a spawn location lost that, along with any origin field the creator has no box for, such as unchoosable, special or the Figura model keys. Powers were copied under new ids without updating the references between them, so a saved Iron Monk's Palm Strike still checked the original stamina pool, read zero and never fired. A name or description written as a translation key came back as the raw key, and the identity boxes truncated at two hundred and fifty-six characters, cutting six built-in descriptions. All of that is kept or corrected now, and a power keeps its id once given, so later edits in the Powers tab no longer rename it out from under its references.
  • A creator save no longer overwrites another origin's power files.** Power files are named after the origin's path and the power's type, with anything that is not a letter, digit or underscore folded into _. So a mob origin and a player origin both called foo, or two origins called a/b and a_b, wrote to the same file, and the second save silently replaced the first origin's power. The creator now checks which origin already lists each power id, saves a clashing one under a free id, updates every reference to it, and logs the move.
  • The web editor starts new origins in neoorigins_custom, so they cannot replace shipped ones by accident.** New origin and mob origin drafts defaulted to neoorigins, the namespace the built-in content uses, so a name matching a shipped origin or power silently replaced it for everyone on the server. New drafts now default to neoorigins_custom, the namespace the in-game creator already writes to. Loading a template still keeps the shipped id, since overriding that origin is the point. Templates also keep their evolution tiers, which used to be stripped on load: fifty-eight of the seventy-eight web templates have them, and they are carried through and exported as they were, though still not editable here. An empty list you wrote survives export too.
  • Web exports refuse ids the game cannot load.** The check only caught blank and duplicate ids, so a path with a capital letter or a trailing space exported cleanly and then, through the layer fault above, emptied the origin picker. The origin's namespace and path, the layer id, power ids and upgrade ids are now all checked against the game's own id rules first, with a message naming the offending character, and a blank upgrade is refused instead of loading as a dead reference. The mob origin editor, which had no export check at all, now refuses the same ids, and any power id used twice.
  • Modded fish whitelisted in the config now count as meat.** ocean_origins.extra_fish_foods lets you name modded fish an ocean origin may eat without editing a datapack, but the carnivore and vegetarian diets read only the neoorigins:meat_foods tag, so a fish listed there fed a Merling and was invisible to origins:carnivore. Both diets now read the tag **or** that list, so a whitelisted fish feeds a carnivore and is refused to a vegetarian, the same way tagged fish already were.

> A fixes release, mostly for the two origin editors, which could quietly lose data on save. Saving a power in the in-game creator deleted any detail its form could not display, loading a template and saving it dropped the origin's evolution tiers and custom spawn, one creator save could overwrite another origin's power files, and the web editor started new origins in the neoorigins namespace, where a name matching a shipped origin replaced it for the whole server. Outside the editors, an area_of_effect with a block action and no radius no longer runs that action across seventeen thousand blocks, one invalid origin id no longer empties an entire origin layer, and origin spawn searches start from the world spawn instead of the wrong end of the map. On 1.21.1 other players are drawn in their own model colour rather than yours.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • An area_of_effect with a block action no longer runs it across seventeen thousand blocks.** The block sweep borrowed the entity sweep's default radius of sixteen, so a block_action with no radius written ran at every block within sixteen of the centre: 17,077 positions per activation, and with explode as the block action the server stalled. The block sweep now defaults to two blocks, thirty-three positions, while the entity sweep keeps its sixteen, and a radius you do write is honoured as before up to the existing cap of sixteen. Separately, explode is limited to four per player per tick. They all go off at the player rather than the swept block, and hurt immunity after the first absorbs most of what the rest would deal, so the extras bought lag and nothing else. [ACTIONS.md](docs/ACTIONS.md) records both defaults and the cap.
  • One invalid origin id no longer empties a whole origin layer.** An id the game cannot parse, such as a web export named Wizard or wizard with a trailing space, threw while its layer was being read, and the loader's answer was to discard the entire layer. Since addon and exported packs add to the built-in neoorigins:origin and neoorigins:class layers, one bad id emptied the picker of every origin, or every class, for everyone on the server, with nothing on screen to say why. The bad entry is now skipped with a warning naming it, and the rest of the layer loads.
  • Origin spawn searches start from the world spawn, scaled into the searched dimension the way a portal scales it.** On 1.21.1 only the Nether was wrong: the search read the Overworld's spawn point without dividing by eight, so a world spawn at 8000, 0 sent a new Blazeling to Nether 8000, 0, sixty-four thousand blocks out in Overworld terms. On 26.1 and 26.2 every search started from 0, 0 in whatever dimension it searched, so all nine built-in origins with a spawn location ignored a moved world spawn. All three versions now start from the world spawn converted into the searched dimension, so an Overworld spawn at 8000, 0 centres a Nether search on 1000, 0, with the height kept inside build limits and the position inside the world border. [PACK_FORMAT.md](docs/PACK_FORMAT.md) covers spawn_location itself.
  • Every player is drawn in their own model colour instead of yours (1.21.1).** model_color tints were read from your own powers for every player on screen, so everyone around you wore your colour and nobody ever saw theirs. Each player's tint now comes from that player's own synced powers, clears when their effect ends, and is dropped when they log out or leave range. Minecraft 26.1 and 26.2 draw no model colours, since the 26.1 rendering rework removed the call the tint depends on.
  • Caveborn meal tints clear when the meal's effect wears off.** model_color kept one condition slot per player, so the six Caveborn diet tints overwrote each other every second: a tint that ran out only told the client if it happened to be checked last, and the others stayed on the model until a respawn, relog or dimension change forced a resync. The shared slot also flipped twice a second, sending a full power sync each time. Each power now keeps its own result. On 26.1 and 26.2, where tints are not drawn, what changes is that the needless syncs stop.

  • Saving a power in the in-game creator keeps everything its form cannot show.** Opening a power in the form and saving it rebuilt each field from what the form understands, so any detail a sub-form did not model was deleted even if you changed nothing: an "inverted": true on a condition vanished and flipped its meaning, a nested weapon_damage_scale disappeared, an action written as a list could be dropped outright, and a shorthand item condition with no type was read as empty. That last one is how a saved Riding the Sword would fly with anything in hand. A save now applies only what you changed, onto the JSON the form was opened on, at any depth and inside lists, and clearing a field still removes it. A list you wrote as [] is kept rather than dropped, since for some fields it means something different from leaving the key out. Every shipped power saves back unchanged now, apart from starting_equipment folding a single item into its stacks list, which the game reads the same way.
  • Load template followed by Save gives you back the origin you loaded.** Loading a template into the in-game creator and saving it wrote a different origin from the one on screen. Evolution tiers, spawn locations and upgrades were dropped, so of the seventy-eight shipped origins the fifty-eight with evolution tiers lost them and the nine with a spawn location lost that, along with any origin field the creator has no box for, such as unchoosable, special or the Figura model keys. Powers were copied under new ids without updating the references between them, so a saved Iron Monk's Palm Strike still checked the original stamina pool, read zero and never fired. A name or description written as a translation key came back as the raw key, and the identity boxes truncated at two hundred and fifty-six characters, cutting six built-in descriptions. All of that is kept or corrected now, and a power keeps its id once given, so later edits in the Powers tab no longer rename it out from under its references.
  • A creator save no longer overwrites another origin's power files.** Power files are named after the origin's path and the power's type, with anything that is not a letter, digit or underscore folded into _. So a mob origin and a player origin both called foo, or two origins called a/b and a_b, wrote to the same file, and the second save silently replaced the first origin's power. The creator now checks which origin already lists each power id, saves a clashing one under a free id, updates every reference to it, and logs the move.
  • The web editor starts new origins in neoorigins_custom, so they cannot replace shipped ones by accident.** New origin and mob origin drafts defaulted to neoorigins, the namespace the built-in content uses, so a name matching a shipped origin or power silently replaced it for everyone on the server. New drafts now default to neoorigins_custom, the namespace the in-game creator already writes to. Loading a template still keeps the shipped id, since overriding that origin is the point. Templates also keep their evolution tiers, which used to be stripped on load: fifty-eight of the seventy-eight web templates have them, and they are carried through and exported as they were, though still not editable here. An empty list you wrote survives export too.
  • Web exports refuse ids the game cannot load.** The check only caught blank and duplicate ids, so a path with a capital letter or a trailing space exported cleanly and then, through the layer fault above, emptied the origin picker. The origin's namespace and path, the layer id, power ids and upgrade ids are now all checked against the game's own id rules first, with a message naming the offending character, and a blank upgrade is refused instead of loading as a dead reference. The mob origin editor, which had no export check at all, now refuses the same ids, and any power id used twice.
  • Modded fish whitelisted in the config now count as meat.** ocean_origins.extra_fish_foods lets you name modded fish an ocean origin may eat without editing a datapack, but the carnivore and vegetarian diets read only the neoorigins:meat_foods tag, so a fish listed there fed a Merling and was invisible to origins:carnivore. Both diets now read the tag **or** that list, so a whitelisted fish feeds a carnivore and is refused to a vegetarian, the same way tagged fish already were.

> A large fixes release, and one of them is a crash. On 1.21.1, installing a resource pack built from our own theme template could kill the client at boot, or stop a server loading its datapacks, and the template shipped in a state that triggered both. All three are fixed, and a theme whose panel texture is missing now falls back to the parchment panel instead of stretching the missing-texture checkerboard across the origin screen. Elytrian now wears its wings folded on its back instead of showing them only mid-glide (#130), through a new third setting on render_elytra that every editor offers as a dropdown, and on 26.1 and 26.2 a chestplate no longer hides power-granted wings. The Rogue's one Class Skill key now goes to Step Assist, so the switch the Rogue gained in 2.2.26 can finally be pressed, and sneaking stops a step-assisted player at a ledge again (#134). The slime's bounce keeps a running player's speed, and a jump or a short drop no longer sets it off (#133). Resource bars stay on screen until you spend the resource for the first time (#105), come back by themselves after a /reload, and one player losing a resource power no longer takes every other holder's bar with it. The wraith's client and server now read its blocked-block list the same way (#109). Several fixes change what players feel without any visible change to the origin: power modifiers stopped adding another copy of themselves on every death and relog, the Sporeling's Fungal Contact heals only on mushroom blocks and mycelium as its description says, the Slime's tier-2 Sticky Aura slows things for the first time, and two powers that could never fire now do, one of them a Piglin downside. The Lumberjack pays its bonus planks for every wood rather than only oak. The three Dragon Survival origins can be picked at all now, and a random roll will not turn you into one. The in-game creator stops offering an operation that its own maths reads as an addition, the web editor's block view stops quietly rewriting the powers it loads, and both editors gained fields they could never author. Fish counts as meat for the Origins-compatible carnivore and vegetarian diets. Every config option and every entity has an English name, where the config screen had been drawing raw keys for a couple of hundred of them. The One Probe works on 26.1 and 26.2 for the first time, FTB Quests tag-marker rewards grant again on 26.1, and KubeJS scripts can read a player's resource values on 1.21.1 and 26.1.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Elytrian keeps its wings on its back (#130).** Wings drawn by a flight power appeared only while the player was gliding, so an origin whose whole body plan is wings looked wingless the moment it landed. Elytrian now shows them folded on its back whenever its flight power is active, and spreads them in a glide as it always has. The other flying origins are unchanged: Phantom, Hiveling and Draconic still show wings only while gliding, and Windwalker still shows none. The setting behind this is described under Pack Author Features.

  • The Rogue's Class Skill key goes to Step Assist.** A class gets exactly one Class Skill key, and it goes to the first power in the class that can be activated. The Rogue listed Stealth ahead of the Step Assist switch it gained in 2.2.26, so Stealth took the key and Step Assist could not be switched at all. Step Assist is now first. Stealth is still granted and works as before (sneak for ten seconds and you turn invisible), but it no longer has a key, so it stays on.

  • A toggle no key can reach is switched back on when you log in.** A Rogue who switched Stealth off before this release would otherwise be left with it off and no way to turn it back on short of changing class. At every login, any NeoOrigins toggle power whose switch is not bound to a key has its off state cleared, which returns it to on. Origins-format origins:toggle powers keep their state separately and are not included. That includes toggles set to start off with default_off, since without a key there is no way to switch those on either. A power counts as bound when it holds one of the six Skill slots, the Class Skill slot, or a named hotkey of its own. Two cases are left alone. Nothing is changed while Suppression is in effect, because Suppression switches toggles off on purpose, and a toggle that does have a key keeps whatever you last set it to.

  • Stealth and the Rogue are described by what they actually do.** Stealth's description promised that attacking from behind deals double damage, and the Rogue's promised devastating backstab damage. Neither was ever true: Stealth turns you invisible after ten seconds of sneaking and stops a mob picking you as a new target while you are invisible, and the separate Backstab power is a flat +2 attack damage while sneaking, whichever way you are facing. Both strings now say that. Nothing about combat changes. The two corrected strings are English for now, and the other eleven languages fall back to the English text rather than showing a stale promise.

  • The slime's bounce leaves jumps and short drops alone (#133).** The bounce triggered on an ordinary jump, and on a drop of a single block. It now needs the impact of a fall of four blocks or more: a jump and a drop of up to three blocks land normally, and anything from four blocks up still bounces. A jump off a ledge counts from the top of the jump, so jumping off a drop of more than two blocks still bounces. The threshold is min_velocity on neoorigins:bounce_on_land, and its default moved from 0.3 to 0.63.

  • A resource bar stays on screen until you have spent it once (#105).** Bars hide while they are full, so a bar that starts full was invisible from the moment the origin was picked, and a new player had no way to know the resource existed. A full bar now stays on screen until that resource drops below full for the first time, and from then on it hides when full as before. The reminder starts over each time your origins are re-sent to you, which includes joining, respawning and picking an origin. Bars set to always_render are unaffected.

  • Fish counts as meat for the carnivore and vegetarian diets.** The Origins-compatible origins:carnivore and origins:vegetarian diets both decide what is meat from the neoorigins:meat_foods tag, and that tag held no fish, so a carnivore origin from an Origins pack could not eat cod while a vegetarian one could. The meat tag now includes neoorigins:fish_foods, so fish is food for the carnivore and refused by the vegetarian. None of the built-in origins use either diet.

  • The ocean origins eat modded fish that sit outside the common tags.** Alex's Mobs raw and cooked catfish, blobfish, flying fish and cosmic cod, and Ocean's Delight's fugu slice, are fish that sit outside the fish tags this mod reads, so the ocean origins' fish-only diet refused them. They are now listed in neoorigins:fish_foods directly, which makes them food for Abyssal, Kraken, Merling and Siren, and, through the change above, for a carnivore.

  • An installed theme could crash the 1.21.1 client at boot.** A font file that points at another font, which is how a theme reuses the mod's parchment typeface, puts one TrueType provider into two fonts and so hands one FreeType face to two threads: the font manager finishes each font on its own worker. On 1.21.1 nothing guarded that face, and the client died during loading with a FreeType error, a native heap corruption, or an access violation in freetype.dll, differing from run to run. A client mixin now locks the face around both glyph reads, which is what 26.1 and 26.2 already do in vanilla. The theme template, which shipped exactly such a font file and therefore crashed the client the moment it was installed unmodified, no longer sets a font at all: it keeps Newsreader as before, and the recipe for shipping your own TTF moved to a placeholder file alongside it.

  • A theme pack could stop a 1.21.1 server loading its datapacks.** Both theme managers built their instance during class initialisation and handed the reload listener a parser that had not been created yet, so the listener's parser was null and the first JSON file it touched threw. A datapack carrying data/<namespace>/neoorigins/active_theme.json failed the whole server load with "Failed to load datapacks", and a resource pack carrying assets/<namespace>/ui_themes/*.json broke the client's resource reload. The theme template triggered both. Both managers now build their own parser. 26.1 and 26.2 read theme files a different way and never had this fault.

  • A theme with a missing panel texture draws the parchment panel instead of a checkerboard.** A theme whose panel_background names a file that no loaded pack ships used to bind the missing-texture checkerboard and stretch it across the entire origin screen panel, which is what the template did out of the box because it ships a placeholder where panel.png goes. The theme now keeps the parchment panel and its 9-slice geometry while keeping its own colours and font, and logs a single [theming] warning naming the path it could not find. Flat themes never draw a texture and are untouched.

  • Sneaking stops a step-assisted player at a ledge again (#134).** The game decides whether sneaking should hold you at an edge by looking for floor as far below your feet as your step height reaches. A step height that clears a full block therefore found the floor beneath a one-block drop, concluded there was no ledge, and let you walk off it. While you are sneaking, that one check now looks only as deep as your unmodified step height, and only for players whose step height one of our powers has changed. You still step up as high as the power allows, and Step Assist can stay on.

  • The slime's bounce stops killing a running player's speed (#133).** Every bounce set the player's sideways speed to zero, because the server was reading a movement value that the client never sends it and that is always zero on the server. A running slime stopped dead on every landing, which is also why a chain of bounces ended up happening on the spot. The bounce now carries the sideways speed you landed with.

  • The Slime's Sticky Aura slows what is near it.** The tier-2 aura wrote its effect as loose effect, amplifier, duration and exclude_self fields directly on the area_of_effect action, which reads none of them. With no entity, bientity or block action to run, the action compiled to nothing and the aura had never slowed anything. It now writes the effect the way the other built-in auras do: every second, everything within three blocks other than the Slime itself gets Slowness I for two seconds. It was the only shipped power written in that shape.

  • Power modifiers stop stacking on every death and relog.** Four kinds of modifier added a fresh copy of themselves each time a player respawned or logged back in, without removing the one already there: the native modify_lava_speed, and the Origins-compatible modify_lava_speed, modify_xp_gain and modify_food. On 26.1 and 26.2 modify_xp_gain had no effect at all before this release (see Compatibility), so there it never grew. A power balanced for one copy therefore got stronger with every death. Each one now replaces its own entry. A pack that was tuned against the grown value will find its powers back at the strength its file actually says.

  • A /reload no longer takes every online player's resource bars away.** A reload clears the registered resource information and rebuilds it from the datapack, but the native neoorigins:resource only registered itself when a power was granted or a player logged in, and the Origins-compatible origins:resource registered its backing only on grant. Every player already online therefore lost the bar until someone relogged: a plain resource dropped off the HUD entirely and a mana-backed one read as unbacked. Stored values were never affected. The sync that follows a reload now re-registers each online player's resources and re-sends their bars, and the compatible form registers its backing as it is parsed, so the reload itself restores it.

  • One player losing a resource power no longer takes it from everybody.** Resource information, mana backing and cooldown durations are keyed by the power rather than by the player, and are shared by everyone who holds it, but revoking the power from one player deleted the shared entry. Every other holder lost their bar at the same moment: a mana-backed bar vanished from the HUD and an Apoli resource lost its bounds, until the next relog or reload. A revoke now clears only that player's own state. Separately, the HUD sync was sending every mana-backed bar to every player because it walked the shared table; it now sends a bar only to players who hold the power. The value shown was always the player's own mana.

  • The Lumberjack's bonus planks cover every wood, not just oak.** The power set an item_id field that craft_amount_bonus never reads, so it fell back to the default output of oak planks and every other plank recipe paid nothing. The Lumberjack now names the #minecraft:planks tag and the bonus copies whatever you crafted, modded planks in that tag included.

  • The wraith's client and server agree about blocked blocks (#109).** A wraith that phases into a block it is barred from, such as obsidian or bedrock, is meant to be pushed back out by ordinary collision. The server stopped the phasing while the player was inside such a block, but the client kept phasing, so the two sides disagreed about whether the player was being pushed out at all. Both sides now use one rule for that decision and one reading of the blocked list.

  • Fungal Contact heals only on mushroom blocks and mycelium.** The Sporeling's healing power wrote its block list under a field the condition never reads, and a condition with no block list matches any block, so it healed 1 health every second everywhere. It now heals while you stand on, or have your feet inside, a red or brown mushroom block, a mushroom stem or mycelium, which is what its description has always said.

  • Mushroom Symbiosis and Soul Dread now work.** Both named a biome tag that does not exist, so neither could ever fire. Mushroom Symbiosis asked for minecraft:is_mushroom, and the mushroom biome tag is c:is_mushroom, so the Sporeling now gets its Regeneration in mushroom fields. Soul Dread asked for a tag called minecraft:soul_sand_valley, which is the name of a biome, and it now names the biome. Soul Dread is a Piglin downside, so this fix makes the Piglin weaker: Piglins now take the 0.5 damage a second in a Soul Sand Valley that the description promised.

  • The three Dragon Survival origins can be picked.** Cave Dragon, Forest Dragon and Sea Dragon shipped in no layer file at all. The picker builds its rows from the layer's own origin list and the server refuses a choice the layer does not offer, so none of the three could be chosen even with Dragon Survival installed, and only /neoorigins set reached them. They now sit in neoorigins:origin. Without Dragon Survival their required_mods gate keeps them unloaded and nothing changes for packs that do not have the mod.

  • A random origin will not turn you into a dragon.** With the dragons now listed in a layer that also allows random, rolling for an origin could land on one. Layers read exclude_random (described under Pack Author Features) and the shipped layer excludes the three dragons, which stay directly pickable. The same change made the Random button and the server's own random assignment draw from one pool: server assignment now honours layer conditions, content toggles and unchoosable, all of which it ignored before.

  • Power-granted wings show under a chestplate on 26.1 and 26.2 (#130).** So that it never draws a second pair on top of a real elytra, the wing layer steps aside when the chest slot holds one. On the 26.x lines its test for an elytra matched any armour worn in that slot, so wearing a chestplate hid the wings completely. It now steps aside only for an actual elytra, which is what 1.21.1 has always done.

  • on_block honours inverted.** An on_block whose block condition was a single block, a tag, or an and/or group ignored the inverted flag on that node, so a condition written as "not standing on stone" still matched stone. Every node now honours it, at the top and at any depth, the same way in_block already did. You still have to be on the ground for on_block to match, whether or not the block is inverted. One smaller change comes with it: an or group containing a block condition that cannot be read now fails as a whole, where it used to ignore that one entry.

  • An inline block condition applies inverted once instead of twice.** A condition written as a single node with the block and the flag together, {"type": "block", "block": "stone", "inverted": true}, was negated by the parser and then negated again by the compiler, so it matched stone. It now negates once. The wrapper form, where an outer node holds a nested block condition, was always correct: those are two separate nodes and each flag still applies to its own.

  • The block entity condition reads a root-level tag.** The condition documents a tag written at the top of the node, and packs write it that way, but the shared compiler only looked for one nested under in_tag. Such a node compiled to nothing, which made the entity condition permanently false and made a nested block condition match no block at all. The tag is now read where the documentation says to put it.

  • The in-game creator stops offering speed operations that turn into additions.** On modify_lava_speed and modify_flight_speed, the operation dropdown listed the attribute operations add_value, add_multiplied_base and add_multiplied_total. Those powers only understand addition, multiply_base and multiply_total, and read anything else as an addition, so picking the obvious multiplier silently produced an addition. The dropdown now offers the three the power reads. If you saved one of these powers from the in-game creator, check its operation: a file that already says add_multiplied_base or add_multiplied_total is still read as an addition. The same fix means the change_resource action and Cold Sweat's modify_temperature now offer set alongside add, and the equipped_item condition's slot now offers accessory.

  • The web editor's block view stops rewriting the powers it loads.** The block view rebuilds the powers it holds whenever the canvas changes, and anything a block had no widget for was dropped on the way. Loading the built-in powers and making no edit at all was enough to change some of them: the nested inverted flag came off Windwalker's Cloud Steps, the Qi Cultivator's Dantian Expansion and the Iron Monk's Stamina, and the bare "tag": "minecraft:swords" item condition came off Sword Immortal powers, so those no longer required a sword. Each block now keeps what it cannot display and writes it back unchanged, including a value its dropdown has no entry for, until you change that field yourself.

  • The web editor's built-in powers and origin templates match the mod again.** Both had fallen behind what the mod ships. The power catalogue still gave Elytrian's flight as true, and the origin templates were older still, with the Caveborn diets missing their tiers and the Rogue's Parkour missing the Step Assist toggle that now gates it. Both are regenerated, and a new check in the editor's tooling fails when either falls out of step with the mod.

  • The web editor says when a power type has no form.** Many of the power types the editor offers have no form of their own, so the form shows only the common fields. The note meant to explain this could never appear, and it pointed at the JSON Preview, which is read-only. It now appears for every such type and says what is true: the mod accepts the type, only the common fields can be set in the editor, fields already in an imported file are kept, and anything else has to be written in the power's JSON and imported.

  • The origin picker shows which unique origins are already taken (1.21.1).** When a pack marks an origin as unique, the server tracks who has claimed it and sent that list to the client, but nothing on the client read it. The picker offered a claimed origin anyway, let you confirm it, and the server's refusal arrived as a line of chat, leaving you on an empty layer with no picker to try again. Claimed origins are now shown as claimed, with the name of the player holding them; Confirm is disabled on them and the Random button skips them. The server remains the authority, and a refusal now resyncs you and reopens the picker rather than stranding you. Claims reach every online player as they change and on login, instead of only when a picker opens, so an open picker updates while you are looking at it. This one is on the 1.21.1 line only for 2.2.28; the client that reads the claims does not exist on 26.1 or 26.2 yet.

  • Every config option and every entity has an English name.** The in-game config screen looks a label up by the option's own name rather than by its full path, and 91 entries in the English file were written with the full path, so the screen never read them and drew the raw key instead. Together with options that had no entry at all, that left 234 labels unnamed on 1.21.1, 229 on 26.1 and 228 on 26.2: thirteen section titles including Hotkeys, HUD and Compatibility, the content toggles for nine origins, around 110 power-override sections and the 76 shared field names beneath them, and every client, gameplay and admin option that had been added without one. Nine entities, the black hole, tornado and thrown sword among them, had no name on any line and showed their registry id wherever the game named them. All of them are named now.

  • render_elytra takes "never", "flying" or "always" (#130).** The field on elytra_flight, natural_glide and flight was a plain true or false: wings during a glide, or no wings. "always" draws the wings, folded, whenever the power is active, and spreads them in a glide. "never" and "flying" are the word forms of false and true, and both booleans keep their exact meaning, so existing packs and Origins imports are untouched. Defaults are unchanged: "flying" on elytra_flight, "never" on natural_glide and flight. The in-game creator and both web editor views offer the three as a dropdown, and a file written with true or false opens on the matching entry, with the creator's tooltip naming the real default. Saving writes the word. NeoOrigins 2.2.27 and earlier read only a boolean here, so a pack that has to load on an older version should keep true or false.

  • Layers take exclude_random.** This is the Origins-format list of origin ids that a random roll never lands on, while leaving them directly pickable. A layer file added on top of another adds to the list rather than replacing it. The shipped origin layer uses it for the three Dragon Survival origins.

  • craft_amount_bonus takes a #tag as its output_item.** The bonus then copies whatever was crafted rather than always producing the one named item, which is what a "more planks from logs" power needs in a world with more than one kind of wood. The default is still oak planks, and naming a single item behaves exactly as before.

  • Every block condition can be inverted in the editors.** With on_block fixed, in_block, on_block and the compatibility loader's block compiler all honour inverted, so each block-condition type in the schema now carries it as an optional flag, default false. The in-game creator and both web editor views can set it on any node.

  • spawn_projectile_rain offers telegraph_ticks in both editors.** The action has read the field since it shipped, and the documented example sets it, but no editor declared it, so the lead-in before the first projectile lands could only be authored by hand. It is now an integer field carrying the parser's own default of 14.

  • persistent_effect offers its root-level shorthand in both editors.** The power accepts a single effect written at the root as a one-entry list, with ambient, show_particles and show_icon beside it as defaults for every entry, and 36 shipped powers use that form, but only the root amplifier was ever declared. All four are now authorable, with the decode's defaults. The status_effect alias inherits them instead of carrying its own copies, and stacking_status_effects gains them too.

  • The bundled example packs and the theme template load on 26.1 and 26.2.** The packs in the repository that an author copies from all declared 1.21.1's pack formats, so on the 26.x lines they loaded as too old, and slime-morph-example declared a resource-pack format without the bounds the data-pack parser requires above 81, so it failed to load at all. Each now declares the format of the line it sits on, with example-pack and the theme template, which are both resource and data packs, declaring the full supported span. These sit in the repository rather than inside the jar, so nothing about a player's install changes.

  • Five power types stop being rewritten out of their own behaviour.** A salvage step meant for misspelled types was rewriting neoorigins:action_on_kill, action_over_time, food_restriction, night_vision and status_effect into their Origins-compatible forms before the alias table, which handles all five correctly, ever got the chance. The compatible readers ignore the fields those types document: an action_on_kill written exactly as the docs show it never fired at all, and an action_over_time lost else_action, toggleable, default_off and its enabled switch. Salvage now leaves alone any type the alias table already knows. Shipped content is unchanged: the 22 night_vision and 3 food_restriction powers load to exactly what they did before.

  • origins-classes:more_planks_from_logs covers every wood.** It translated to a bonus with no output named, which meant the default of oak planks, so every other plank recipe paid nothing. It now names the #minecraft:planks tag and pays in whatever you crafted. The bonus count is unchanged.

  • The compatibility loader reads four block condition fields it used to ignore.** fluid, light_level, exposed_to_sky and movement_blocking have compiled correctly in in_block and on_block since 2.2.24, but the Origins-compatible loader has its own block compiler, and there all four fell through to a branch that matches every block. That compiler serves action_on_event block filters, prevent_block_use, prevent_sleep, block_collision and the area_of_effect block filter, so a condition using any of the four was silently always true in all five. No shipped power writes any of them.

  • origins:modify_xp_gain changes the XP a player gains (26.1 and 26.2).** The power loaded on these lines, but nothing read it, so it never changed any XP. It now applies, as it always has on 1.21.1.

  • Config power_overrides reach the water-damage and slow-regeneration powers (26.1 and 26.2).** The overrides ran after the alias table had already read and removed the fields they target, so a server owner's multiplier, damage_per_second or include_rain for those powers was silently ignored. They now run first, as they always have on 1.21.1. A server that set one of these will see it take effect.

  • /reload does not restore some powers for players already online.** A reload clears the per-player tables behind modify_lava_speed (native and Origins-compatible) and the Origins-compatible modify_xp_gain, modify_food, modify_crafting, prevent_item_use, prevent_block_use, prevent_entity_use, prevent_sleep and restrict_armor, and nothing refills them until the player dies, relogs or is granted the power again. Among the built-in origins this affects the Draconic's Molten Stride, which stops speeding up lava swimming until the next death or relog. This is unchanged in 2.2.28.

  • The One Probe is supported on 26.1 and 26.2.** The integration was 1.21.1 only because The One Probe published no 26.x build. It now does, and the API and the handshake are unchanged, so the same provider runs on all three lines. EMI still has no 26.x build, so that integration stays on 1.21.1.

  • FTB Quests tag-marker grants work again on 26.1.** FTB Quests 26.1.2.x dropped the event and the Architectury layer our hook bound to, so with it installed the mod warned at every boot that tag-marker rewards were inert, and a quest tagged neoorigins_loot_pool_grant:<table> granted nothing at all. A typed listener now handles the quest-progress event that 26.1 posts on the NeoForge bus, loaded only when FTB Quests is present, and the older hook stays as the fallback. The 1.21.1 and 26.2 lines are unchanged.

  • KubeJS scripts can read a player's resource values (1.21.1 and 26.1).** NeoOrigins.getResource(player, id) returns the current value, or null when the player does not have that resource, so a missing resource never reads as an empty one. NeoOrigins.hasResource(player, id) says whether they have it. The id is the resource power's full id, the same one /resource get takes. A bar backed by Iron's Spells mana reports that player's live mana. Both are read-only. The 26.2 build does not bundle KubeJS support, so neither is available there. See [KUBEJS.md](docs/KUBEJS.md).

> A large fixes release, and one of them is a crash. On 1.21.1, installing a resource pack built from our own theme template could kill the client at boot, or stop a server loading its datapacks, and the template shipped in a state that triggered both. All three are fixed, and a theme whose panel texture is missing now falls back to the parchment panel instead of stretching the missing-texture checkerboard across the origin screen. Elytrian now wears its wings folded on its back instead of showing them only mid-glide (#130), through a new third setting on render_elytra that every editor offers as a dropdown, and on 26.1 and 26.2 a chestplate no longer hides power-granted wings. The Rogue's one Class Skill key now goes to Step Assist, so the switch the Rogue gained in 2.2.26 can finally be pressed, and sneaking stops a step-assisted player at a ledge again (#134). The slime's bounce keeps a running player's speed, and a jump or a short drop no longer sets it off (#133). Resource bars stay on screen until you spend the resource for the first time (#105), come back by themselves after a /reload, and one player losing a resource power no longer takes every other holder's bar with it. The wraith's client and server now read its blocked-block list the same way (#109). Several fixes change what players feel without any visible change to the origin: power modifiers stopped adding another copy of themselves on every death and relog, the Sporeling's Fungal Contact heals only on mushroom blocks and mycelium as its description says, the Slime's tier-2 Sticky Aura slows things for the first time, and two powers that could never fire now do, one of them a Piglin downside. The Lumberjack pays its bonus planks for every wood rather than only oak. The three Dragon Survival origins can be picked at all now, and a random roll will not turn you into one. The in-game creator stops offering an operation that its own maths reads as an addition, the web editor's block view stops quietly rewriting the powers it loads, and both editors gained fields they could never author. Fish counts as meat for the Origins-compatible carnivore and vegetarian diets. Every config option and every entity has an English name, where the config screen had been drawing raw keys for a couple of hundred of them. The One Probe works on 26.1 and 26.2 for the first time, FTB Quests tag-marker rewards grant again on 26.1, and KubeJS scripts can read a player's resource values on 1.21.1 and 26.1.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Elytrian keeps its wings on its back (#130).** Wings drawn by a flight power appeared only while the player was gliding, so an origin whose whole body plan is wings looked wingless the moment it landed. Elytrian now shows them folded on its back whenever its flight power is active, and spreads them in a glide as it always has. The other flying origins are unchanged: Phantom, Hiveling and Draconic still show wings only while gliding, and Windwalker still shows none. The setting behind this is described under Pack Author Features.

  • The Rogue's Class Skill key goes to Step Assist.** A class gets exactly one Class Skill key, and it goes to the first power in the class that can be activated. The Rogue listed Stealth ahead of the Step Assist switch it gained in 2.2.26, so Stealth took the key and Step Assist could not be switched at all. Step Assist is now first. Stealth is still granted and works as before (sneak for ten seconds and you turn invisible), but it no longer has a key, so it stays on.

  • A toggle no key can reach is switched back on when you log in.** A Rogue who switched Stealth off before this release would otherwise be left with it off and no way to turn it back on short of changing class. At every login, any NeoOrigins toggle power whose switch is not bound to a key has its off state cleared, which returns it to on. Origins-format origins:toggle powers keep their state separately and are not included. That includes toggles set to start off with default_off, since without a key there is no way to switch those on either. A power counts as bound when it holds one of the six Skill slots, the Class Skill slot, or a named hotkey of its own. Two cases are left alone. Nothing is changed while Suppression is in effect, because Suppression switches toggles off on purpose, and a toggle that does have a key keeps whatever you last set it to.

  • Stealth and the Rogue are described by what they actually do.** Stealth's description promised that attacking from behind deals double damage, and the Rogue's promised devastating backstab damage. Neither was ever true: Stealth turns you invisible after ten seconds of sneaking and stops a mob picking you as a new target while you are invisible, and the separate Backstab power is a flat +2 attack damage while sneaking, whichever way you are facing. Both strings now say that. Nothing about combat changes. The two corrected strings are English for now, and the other eleven languages fall back to the English text rather than showing a stale promise.

  • The slime's bounce leaves jumps and short drops alone (#133).** The bounce triggered on an ordinary jump, and on a drop of a single block. It now needs the impact of a fall of four blocks or more: a jump and a drop of up to three blocks land normally, and anything from four blocks up still bounces. A jump off a ledge counts from the top of the jump, so jumping off a drop of more than two blocks still bounces. The threshold is min_velocity on neoorigins:bounce_on_land, and its default moved from 0.3 to 0.63.

  • A resource bar stays on screen until you have spent it once (#105).** Bars hide while they are full, so a bar that starts full was invisible from the moment the origin was picked, and a new player had no way to know the resource existed. A full bar now stays on screen until that resource drops below full for the first time, and from then on it hides when full as before. The reminder starts over each time your origins are re-sent to you, which includes joining, respawning and picking an origin. Bars set to always_render are unaffected.

  • Fish counts as meat for the carnivore and vegetarian diets.** The Origins-compatible origins:carnivore and origins:vegetarian diets both decide what is meat from the neoorigins:meat_foods tag, and that tag held no fish, so a carnivore origin from an Origins pack could not eat cod while a vegetarian one could. The meat tag now includes neoorigins:fish_foods, so fish is food for the carnivore and refused by the vegetarian. None of the built-in origins use either diet.

  • The ocean origins eat modded fish that sit outside the common tags.** Alex's Mobs raw and cooked catfish, blobfish, flying fish and cosmic cod, and Ocean's Delight's fugu slice, are fish that sit outside the fish tags this mod reads, so the ocean origins' fish-only diet refused them. They are now listed in neoorigins:fish_foods directly, which makes them food for Abyssal, Kraken, Merling and Siren, and, through the change above, for a carnivore.

  • An installed theme could crash the 1.21.1 client at boot.** A font file that points at another font, which is how a theme reuses the mod's parchment typeface, puts one TrueType provider into two fonts and so hands one FreeType face to two threads: the font manager finishes each font on its own worker. On 1.21.1 nothing guarded that face, and the client died during loading with a FreeType error, a native heap corruption, or an access violation in freetype.dll, differing from run to run. A client mixin now locks the face around both glyph reads, which is what 26.1 and 26.2 already do in vanilla. The theme template, which shipped exactly such a font file and therefore crashed the client the moment it was installed unmodified, no longer sets a font at all: it keeps Newsreader as before, and the recipe for shipping your own TTF moved to a placeholder file alongside it.

  • A theme pack could stop a 1.21.1 server loading its datapacks.** Both theme managers built their instance during class initialisation and handed the reload listener a parser that had not been created yet, so the listener's parser was null and the first JSON file it touched threw. A datapack carrying data/<namespace>/neoorigins/active_theme.json failed the whole server load with "Failed to load datapacks", and a resource pack carrying assets/<namespace>/ui_themes/*.json broke the client's resource reload. The theme template triggered both. Both managers now build their own parser. 26.1 and 26.2 read theme files a different way and never had this fault.

  • A theme with a missing panel texture draws the parchment panel instead of a checkerboard.** A theme whose panel_background names a file that no loaded pack ships used to bind the missing-texture checkerboard and stretch it across the entire origin screen panel, which is what the template did out of the box because it ships a placeholder where panel.png goes. The theme now keeps the parchment panel and its 9-slice geometry while keeping its own colours and font, and logs a single [theming] warning naming the path it could not find. Flat themes never draw a texture and are untouched.

  • Sneaking stops a step-assisted player at a ledge again (#134).** The game decides whether sneaking should hold you at an edge by looking for floor as far below your feet as your step height reaches. A step height that clears a full block therefore found the floor beneath a one-block drop, concluded there was no ledge, and let you walk off it. While you are sneaking, that one check now looks only as deep as your unmodified step height, and only for players whose step height one of our powers has changed. You still step up as high as the power allows, and Step Assist can stay on.

  • The slime's bounce stops killing a running player's speed (#133).** Every bounce set the player's sideways speed to zero, because the server was reading a movement value that the client never sends it and that is always zero on the server. A running slime stopped dead on every landing, which is also why a chain of bounces ended up happening on the spot. The bounce now carries the sideways speed you landed with.

  • The Slime's Sticky Aura slows what is near it.** The tier-2 aura wrote its effect as loose effect, amplifier, duration and exclude_self fields directly on the area_of_effect action, which reads none of them. With no entity, bientity or block action to run, the action compiled to nothing and the aura had never slowed anything. It now writes the effect the way the other built-in auras do: every second, everything within three blocks other than the Slime itself gets Slowness I for two seconds. It was the only shipped power written in that shape.

  • Power modifiers stop stacking on every death and relog.** Four kinds of modifier added a fresh copy of themselves each time a player respawned or logged back in, without removing the one already there: the native modify_lava_speed, and the Origins-compatible modify_lava_speed, modify_xp_gain and modify_food. On 26.1 and 26.2 modify_xp_gain had no effect at all before this release (see Compatibility), so there it never grew. A power balanced for one copy therefore got stronger with every death. Each one now replaces its own entry. A pack that was tuned against the grown value will find its powers back at the strength its file actually says.

  • A /reload no longer takes every online player's resource bars away.** A reload clears the registered resource information and rebuilds it from the datapack, but the native neoorigins:resource only registered itself when a power was granted or a player logged in, and the Origins-compatible origins:resource registered its backing only on grant. Every player already online therefore lost the bar until someone relogged: a plain resource dropped off the HUD entirely and a mana-backed one read as unbacked. Stored values were never affected. The sync that follows a reload now re-registers each online player's resources and re-sends their bars, and the compatible form registers its backing as it is parsed, so the reload itself restores it.

  • One player losing a resource power no longer takes it from everybody.** Resource information, mana backing and cooldown durations are keyed by the power rather than by the player, and are shared by everyone who holds it, but revoking the power from one player deleted the shared entry. Every other holder lost their bar at the same moment: a mana-backed bar vanished from the HUD and an Apoli resource lost its bounds, until the next relog or reload. A revoke now clears only that player's own state. Separately, the HUD sync was sending every mana-backed bar to every player because it walked the shared table; it now sends a bar only to players who hold the power. The value shown was always the player's own mana.

  • The Lumberjack's bonus planks cover every wood, not just oak.** The power set an item_id field that craft_amount_bonus never reads, so it fell back to the default output of oak planks and every other plank recipe paid nothing. The Lumberjack now names the #minecraft:planks tag and the bonus copies whatever you crafted, modded planks in that tag included.

  • The wraith's client and server agree about blocked blocks (#109).** A wraith that phases into a block it is barred from, such as obsidian or bedrock, is meant to be pushed back out by ordinary collision. The server stopped the phasing while the player was inside such a block, but the client kept phasing, so the two sides disagreed about whether the player was being pushed out at all. Both sides now use one rule for that decision and one reading of the blocked list.

  • Fungal Contact heals only on mushroom blocks and mycelium.** The Sporeling's healing power wrote its block list under a field the condition never reads, and a condition with no block list matches any block, so it healed 1 health every second everywhere. It now heals while you stand on, or have your feet inside, a red or brown mushroom block, a mushroom stem or mycelium, which is what its description has always said.

  • Mushroom Symbiosis and Soul Dread now work.** Both named a biome tag that does not exist, so neither could ever fire. Mushroom Symbiosis asked for minecraft:is_mushroom, and the mushroom biome tag is c:is_mushroom, so the Sporeling now gets its Regeneration in mushroom fields. Soul Dread asked for a tag called minecraft:soul_sand_valley, which is the name of a biome, and it now names the biome. Soul Dread is a Piglin downside, so this fix makes the Piglin weaker: Piglins now take the 0.5 damage a second in a Soul Sand Valley that the description promised.

  • The three Dragon Survival origins can be picked.** Cave Dragon, Forest Dragon and Sea Dragon shipped in no layer file at all. The picker builds its rows from the layer's own origin list and the server refuses a choice the layer does not offer, so none of the three could be chosen even with Dragon Survival installed, and only /neoorigins set reached them. They now sit in neoorigins:origin. Without Dragon Survival their required_mods gate keeps them unloaded and nothing changes for packs that do not have the mod.

  • A random origin will not turn you into a dragon.** With the dragons now listed in a layer that also allows random, rolling for an origin could land on one. Layers read exclude_random (described under Pack Author Features) and the shipped layer excludes the three dragons, which stay directly pickable. The same change made the Random button and the server's own random assignment draw from one pool: server assignment now honours layer conditions, content toggles and unchoosable, all of which it ignored before.

  • Power-granted wings show under a chestplate on 26.1 and 26.2 (#130).** So that it never draws a second pair on top of a real elytra, the wing layer steps aside when the chest slot holds one. On the 26.x lines its test for an elytra matched any armour worn in that slot, so wearing a chestplate hid the wings completely. It now steps aside only for an actual elytra, which is what 1.21.1 has always done.

  • on_block honours inverted.** An on_block whose block condition was a single block, a tag, or an and/or group ignored the inverted flag on that node, so a condition written as "not standing on stone" still matched stone. Every node now honours it, at the top and at any depth, the same way in_block already did. You still have to be on the ground for on_block to match, whether or not the block is inverted. One smaller change comes with it: an or group containing a block condition that cannot be read now fails as a whole, where it used to ignore that one entry.

  • An inline block condition applies inverted once instead of twice.** A condition written as a single node with the block and the flag together, {"type": "block", "block": "stone", "inverted": true}, was negated by the parser and then negated again by the compiler, so it matched stone. It now negates once. The wrapper form, where an outer node holds a nested block condition, was always correct: those are two separate nodes and each flag still applies to its own.

  • The block entity condition reads a root-level tag.** The condition documents a tag written at the top of the node, and packs write it that way, but the shared compiler only looked for one nested under in_tag. Such a node compiled to nothing, which made the entity condition permanently false and made a nested block condition match no block at all. The tag is now read where the documentation says to put it.

  • The in-game creator stops offering speed operations that turn into additions.** On modify_lava_speed and modify_flight_speed, the operation dropdown listed the attribute operations add_value, add_multiplied_base and add_multiplied_total. Those powers only understand addition, multiply_base and multiply_total, and read anything else as an addition, so picking the obvious multiplier silently produced an addition. The dropdown now offers the three the power reads. If you saved one of these powers from the in-game creator, check its operation: a file that already says add_multiplied_base or add_multiplied_total is still read as an addition. The same fix means the change_resource action and Cold Sweat's modify_temperature now offer set alongside add, and the equipped_item condition's slot now offers accessory.

  • The web editor's block view stops rewriting the powers it loads.** The block view rebuilds the powers it holds whenever the canvas changes, and anything a block had no widget for was dropped on the way. Loading the built-in powers and making no edit at all was enough to change some of them: the nested inverted flag came off Windwalker's Cloud Steps, the Qi Cultivator's Dantian Expansion and the Iron Monk's Stamina, and the bare "tag": "minecraft:swords" item condition came off Sword Immortal powers, so those no longer required a sword. Each block now keeps what it cannot display and writes it back unchanged, including a value its dropdown has no entry for, until you change that field yourself.

  • The web editor's built-in powers and origin templates match the mod again.** Both had fallen behind what the mod ships. The power catalogue still gave Elytrian's flight as true, and the origin templates were older still, with the Caveborn diets missing their tiers and the Rogue's Parkour missing the Step Assist toggle that now gates it. Both are regenerated, and a new check in the editor's tooling fails when either falls out of step with the mod.

  • The web editor says when a power type has no form.** Many of the power types the editor offers have no form of their own, so the form shows only the common fields. The note meant to explain this could never appear, and it pointed at the JSON Preview, which is read-only. It now appears for every such type and says what is true: the mod accepts the type, only the common fields can be set in the editor, fields already in an imported file are kept, and anything else has to be written in the power's JSON and imported.

  • The origin picker shows which unique origins are already taken (1.21.1).** When a pack marks an origin as unique, the server tracks who has claimed it and sent that list to the client, but nothing on the client read it. The picker offered a claimed origin anyway, let you confirm it, and the server's refusal arrived as a line of chat, leaving you on an empty layer with no picker to try again. Claimed origins are now shown as claimed, with the name of the player holding them; Confirm is disabled on them and the Random button skips them. The server remains the authority, and a refusal now resyncs you and reopens the picker rather than stranding you. Claims reach every online player as they change and on login, instead of only when a picker opens, so an open picker updates while you are looking at it. This one is on the 1.21.1 line only for 2.2.28; the client that reads the claims does not exist on 26.1 or 26.2 yet.

  • Every config option and every entity has an English name.** The in-game config screen looks a label up by the option's own name rather than by its full path, and 91 entries in the English file were written with the full path, so the screen never read them and drew the raw key instead. Together with options that had no entry at all, that left 234 labels unnamed on 1.21.1, 229 on 26.1 and 228 on 26.2: thirteen section titles including Hotkeys, HUD and Compatibility, the content toggles for nine origins, around 110 power-override sections and the 76 shared field names beneath them, and every client, gameplay and admin option that had been added without one. Nine entities, the black hole, tornado and thrown sword among them, had no name on any line and showed their registry id wherever the game named them. All of them are named now.

  • render_elytra takes "never", "flying" or "always" (#130).** The field on elytra_flight, natural_glide and flight was a plain true or false: wings during a glide, or no wings. "always" draws the wings, folded, whenever the power is active, and spreads them in a glide. "never" and "flying" are the word forms of false and true, and both booleans keep their exact meaning, so existing packs and Origins imports are untouched. Defaults are unchanged: "flying" on elytra_flight, "never" on natural_glide and flight. The in-game creator and both web editor views offer the three as a dropdown, and a file written with true or false opens on the matching entry, with the creator's tooltip naming the real default. Saving writes the word. NeoOrigins 2.2.27 and earlier read only a boolean here, so a pack that has to load on an older version should keep true or false.

  • Layers take exclude_random.** This is the Origins-format list of origin ids that a random roll never lands on, while leaving them directly pickable. A layer file added on top of another adds to the list rather than replacing it. The shipped origin layer uses it for the three Dragon Survival origins.

  • craft_amount_bonus takes a #tag as its output_item.** The bonus then copies whatever was crafted rather than always producing the one named item, which is what a "more planks from logs" power needs in a world with more than one kind of wood. The default is still oak planks, and naming a single item behaves exactly as before.

  • Every block condition can be inverted in the editors.** With on_block fixed, in_block, on_block and the compatibility loader's block compiler all honour inverted, so each block-condition type in the schema now carries it as an optional flag, default false. The in-game creator and both web editor views can set it on any node.

  • spawn_projectile_rain offers telegraph_ticks in both editors.** The action has read the field since it shipped, and the documented example sets it, but no editor declared it, so the lead-in before the first projectile lands could only be authored by hand. It is now an integer field carrying the parser's own default of 14.

  • persistent_effect offers its root-level shorthand in both editors.** The power accepts a single effect written at the root as a one-entry list, with ambient, show_particles and show_icon beside it as defaults for every entry, and 36 shipped powers use that form, but only the root amplifier was ever declared. All four are now authorable, with the decode's defaults. The status_effect alias inherits them instead of carrying its own copies, and stacking_status_effects gains them too.

  • The bundled example packs and the theme template load on 26.1 and 26.2.** The packs in the repository that an author copies from all declared 1.21.1's pack formats, so on the 26.x lines they loaded as too old, and slime-morph-example declared a resource-pack format without the bounds the data-pack parser requires above 81, so it failed to load at all. Each now declares the format of the line it sits on, with example-pack and the theme template, which are both resource and data packs, declaring the full supported span. These sit in the repository rather than inside the jar, so nothing about a player's install changes.

  • Five power types stop being rewritten out of their own behaviour.** A salvage step meant for misspelled types was rewriting neoorigins:action_on_kill, action_over_time, food_restriction, night_vision and status_effect into their Origins-compatible forms before the alias table, which handles all five correctly, ever got the chance. The compatible readers ignore the fields those types document: an action_on_kill written exactly as the docs show it never fired at all, and an action_over_time lost else_action, toggleable, default_off and its enabled switch. Salvage now leaves alone any type the alias table already knows. Shipped content is unchanged: the 22 night_vision and 3 food_restriction powers load to exactly what they did before.

  • origins-classes:more_planks_from_logs covers every wood.** It translated to a bonus with no output named, which meant the default of oak planks, so every other plank recipe paid nothing. It now names the #minecraft:planks tag and pays in whatever you crafted. The bonus count is unchanged.

  • The compatibility loader reads four block condition fields it used to ignore.** fluid, light_level, exposed_to_sky and movement_blocking have compiled correctly in in_block and on_block since 2.2.24, but the Origins-compatible loader has its own block compiler, and there all four fell through to a branch that matches every block. That compiler serves action_on_event block filters, prevent_block_use, prevent_sleep, block_collision and the area_of_effect block filter, so a condition using any of the four was silently always true in all five. No shipped power writes any of them.

  • origins:modify_xp_gain changes the XP a player gains (26.1 and 26.2).** The power loaded on these lines, but nothing read it, so it never changed any XP. It now applies, as it always has on 1.21.1.

  • Config power_overrides reach the water-damage and slow-regeneration powers (26.1 and 26.2).** The overrides ran after the alias table had already read and removed the fields they target, so a server owner's multiplier, damage_per_second or include_rain for those powers was silently ignored. They now run first, as they always have on 1.21.1. A server that set one of these will see it take effect.

  • /reload does not restore some powers for players already online.** A reload clears the per-player tables behind modify_lava_speed (native and Origins-compatible) and the Origins-compatible modify_xp_gain, modify_food, modify_crafting, prevent_item_use, prevent_block_use, prevent_entity_use, prevent_sleep and restrict_armor, and nothing refills them until the player dies, relogs or is granted the power again. Among the built-in origins this affects the Draconic's Molten Stride, which stops speeding up lava swimming until the next death or relog. This is unchanged in 2.2.28.

  • The One Probe is supported on 26.1 and 26.2.** The integration was 1.21.1 only because The One Probe published no 26.x build. It now does, and the API and the handshake are unchanged, so the same provider runs on all three lines. EMI still has no 26.x build, so that integration stays on 1.21.1.

  • FTB Quests tag-marker grants work again on 26.1.** FTB Quests 26.1.2.x dropped the event and the Architectury layer our hook bound to, so with it installed the mod warned at every boot that tag-marker rewards were inert, and a quest tagged neoorigins_loot_pool_grant:<table> granted nothing at all. A typed listener now handles the quest-progress event that 26.1 posts on the NeoForge bus, loaded only when FTB Quests is present, and the older hook stays as the fallback. The 1.21.1 and 26.2 lines are unchanged.

  • KubeJS scripts can read a player's resource values (1.21.1 and 26.1).** NeoOrigins.getResource(player, id) returns the current value, or null when the player does not have that resource, so a missing resource never reads as an empty one. NeoOrigins.hasResource(player, id) says whether they have it. The id is the resource power's full id, the same one /resource get takes. A bar backed by Iron's Spells mana reports that player's live mana. Both are read-only. The 26.2 build does not bundle KubeJS support, so neither is available there. See [KUBEJS.md](docs/KUBEJS.md).

> A large fixes release, and one of them is a crash. On 1.21.1, installing a resource pack built from our own theme template could kill the client at boot, or stop a server loading its datapacks, and the template shipped in a state that triggered both. All three are fixed, and a theme whose panel texture is missing now falls back to the parchment panel instead of stretching the missing-texture checkerboard across the origin screen. Elytrian now wears its wings folded on its back instead of showing them only mid-glide (#130), through a new third setting on render_elytra that every editor offers as a dropdown, and on 26.1 and 26.2 a chestplate no longer hides power-granted wings. The Rogue's one Class Skill key now goes to Step Assist, so the switch the Rogue gained in 2.2.26 can finally be pressed, and sneaking stops a step-assisted player at a ledge again (#134). The slime's bounce keeps a running player's speed, and a jump or a short drop no longer sets it off (#133). Resource bars stay on screen until you spend the resource for the first time (#105), come back by themselves after a /reload, and one player losing a resource power no longer takes every other holder's bar with it. The wraith's client and server now read its blocked-block list the same way (#109). Several fixes change what players feel without any visible change to the origin: power modifiers stopped adding another copy of themselves on every death and relog, the Sporeling's Fungal Contact heals only on mushroom blocks and mycelium as its description says, the Slime's tier-2 Sticky Aura slows things for the first time, and two powers that could never fire now do, one of them a Piglin downside. The Lumberjack pays its bonus planks for every wood rather than only oak. The three Dragon Survival origins can be picked at all now, and a random roll will not turn you into one. The in-game creator stops offering an operation that its own maths reads as an addition, the web editor's block view stops quietly rewriting the powers it loads, and both editors gained fields they could never author. Fish counts as meat for the Origins-compatible carnivore and vegetarian diets. Every config option and every entity has an English name, where the config screen had been drawing raw keys for a couple of hundred of them. The One Probe works on 26.1 and 26.2 for the first time, FTB Quests tag-marker rewards grant again on 26.1, and KubeJS scripts can read a player's resource values on 1.21.1 and 26.1.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Elytrian keeps its wings on its back (#130).** Wings drawn by a flight power appeared only while the player was gliding, so an origin whose whole body plan is wings looked wingless the moment it landed. Elytrian now shows them folded on its back whenever its flight power is active, and spreads them in a glide as it always has. The other flying origins are unchanged: Phantom, Hiveling and Draconic still show wings only while gliding, and Windwalker still shows none. The setting behind this is described under Pack Author Features.

  • The Rogue's Class Skill key goes to Step Assist.** A class gets exactly one Class Skill key, and it goes to the first power in the class that can be activated. The Rogue listed Stealth ahead of the Step Assist switch it gained in 2.2.26, so Stealth took the key and Step Assist could not be switched at all. Step Assist is now first. Stealth is still granted and works as before (sneak for ten seconds and you turn invisible), but it no longer has a key, so it stays on.

  • A toggle no key can reach is switched back on when you log in.** A Rogue who switched Stealth off before this release would otherwise be left with it off and no way to turn it back on short of changing class. At every login, any NeoOrigins toggle power whose switch is not bound to a key has its off state cleared, which returns it to on. Origins-format origins:toggle powers keep their state separately and are not included. That includes toggles set to start off with default_off, since without a key there is no way to switch those on either. A power counts as bound when it holds one of the six Skill slots, the Class Skill slot, or a named hotkey of its own. Two cases are left alone. Nothing is changed while Suppression is in effect, because Suppression switches toggles off on purpose, and a toggle that does have a key keeps whatever you last set it to.

  • Stealth and the Rogue are described by what they actually do.** Stealth's description promised that attacking from behind deals double damage, and the Rogue's promised devastating backstab damage. Neither was ever true: Stealth turns you invisible after ten seconds of sneaking and stops a mob picking you as a new target while you are invisible, and the separate Backstab power is a flat +2 attack damage while sneaking, whichever way you are facing. Both strings now say that. Nothing about combat changes. The two corrected strings are English for now, and the other eleven languages fall back to the English text rather than showing a stale promise.

  • The slime's bounce leaves jumps and short drops alone (#133).** The bounce triggered on an ordinary jump, and on a drop of a single block. It now needs the impact of a fall of four blocks or more: a jump and a drop of up to three blocks land normally, and anything from four blocks up still bounces. A jump off a ledge counts from the top of the jump, so jumping off a drop of more than two blocks still bounces. The threshold is min_velocity on neoorigins:bounce_on_land, and its default moved from 0.3 to 0.63.

  • A resource bar stays on screen until you have spent it once (#105).** Bars hide while they are full, so a bar that starts full was invisible from the moment the origin was picked, and a new player had no way to know the resource existed. A full bar now stays on screen until that resource drops below full for the first time, and from then on it hides when full as before. The reminder starts over each time your origins are re-sent to you, which includes joining, respawning and picking an origin. Bars set to always_render are unaffected.

  • Fish counts as meat for the carnivore and vegetarian diets.** The Origins-compatible origins:carnivore and origins:vegetarian diets both decide what is meat from the neoorigins:meat_foods tag, and that tag held no fish, so a carnivore origin from an Origins pack could not eat cod while a vegetarian one could. The meat tag now includes neoorigins:fish_foods, so fish is food for the carnivore and refused by the vegetarian. None of the built-in origins use either diet.

  • The ocean origins eat modded fish that sit outside the common tags.** Alex's Mobs raw and cooked catfish, blobfish, flying fish and cosmic cod, and Ocean's Delight's fugu slice, are fish that sit outside the fish tags this mod reads, so the ocean origins' fish-only diet refused them. They are now listed in neoorigins:fish_foods directly, which makes them food for Abyssal, Kraken, Merling and Siren, and, through the change above, for a carnivore.

  • An installed theme could crash the 1.21.1 client at boot.** A font file that points at another font, which is how a theme reuses the mod's parchment typeface, puts one TrueType provider into two fonts and so hands one FreeType face to two threads: the font manager finishes each font on its own worker. On 1.21.1 nothing guarded that face, and the client died during loading with a FreeType error, a native heap corruption, or an access violation in freetype.dll, differing from run to run. A client mixin now locks the face around both glyph reads, which is what 26.1 and 26.2 already do in vanilla. The theme template, which shipped exactly such a font file and therefore crashed the client the moment it was installed unmodified, no longer sets a font at all: it keeps Newsreader as before, and the recipe for shipping your own TTF moved to a placeholder file alongside it.

  • A theme pack could stop a 1.21.1 server loading its datapacks.** Both theme managers built their instance during class initialisation and handed the reload listener a parser that had not been created yet, so the listener's parser was null and the first JSON file it touched threw. A datapack carrying data/<namespace>/neoorigins/active_theme.json failed the whole server load with "Failed to load datapacks", and a resource pack carrying assets/<namespace>/ui_themes/*.json broke the client's resource reload. The theme template triggered both. Both managers now build their own parser. 26.1 and 26.2 read theme files a different way and never had this fault.

  • A theme with a missing panel texture draws the parchment panel instead of a checkerboard.** A theme whose panel_background names a file that no loaded pack ships used to bind the missing-texture checkerboard and stretch it across the entire origin screen panel, which is what the template did out of the box because it ships a placeholder where panel.png goes. The theme now keeps the parchment panel and its 9-slice geometry while keeping its own colours and font, and logs a single [theming] warning naming the path it could not find. Flat themes never draw a texture and are untouched.

  • Sneaking stops a step-assisted player at a ledge again (#134).** The game decides whether sneaking should hold you at an edge by looking for floor as far below your feet as your step height reaches. A step height that clears a full block therefore found the floor beneath a one-block drop, concluded there was no ledge, and let you walk off it. While you are sneaking, that one check now looks only as deep as your unmodified step height, and only for players whose step height one of our powers has changed. You still step up as high as the power allows, and Step Assist can stay on.

  • The slime's bounce stops killing a running player's speed (#133).** Every bounce set the player's sideways speed to zero, because the server was reading a movement value that the client never sends it and that is always zero on the server. A running slime stopped dead on every landing, which is also why a chain of bounces ended up happening on the spot. The bounce now carries the sideways speed you landed with.

  • The Slime's Sticky Aura slows what is near it.** The tier-2 aura wrote its effect as loose effect, amplifier, duration and exclude_self fields directly on the area_of_effect action, which reads none of them. With no entity, bientity or block action to run, the action compiled to nothing and the aura had never slowed anything. It now writes the effect the way the other built-in auras do: every second, everything within three blocks other than the Slime itself gets Slowness I for two seconds. It was the only shipped power written in that shape.

  • Power modifiers stop stacking on every death and relog.** Four kinds of modifier added a fresh copy of themselves each time a player respawned or logged back in, without removing the one already there: the native modify_lava_speed, and the Origins-compatible modify_lava_speed, modify_xp_gain and modify_food. On 26.1 and 26.2 modify_xp_gain had no effect at all before this release (see Compatibility), so there it never grew. A power balanced for one copy therefore got stronger with every death. Each one now replaces its own entry. A pack that was tuned against the grown value will find its powers back at the strength its file actually says.

  • A /reload no longer takes every online player's resource bars away.** A reload clears the registered resource information and rebuilds it from the datapack, but the native neoorigins:resource only registered itself when a power was granted or a player logged in, and the Origins-compatible origins:resource registered its backing only on grant. Every player already online therefore lost the bar until someone relogged: a plain resource dropped off the HUD entirely and a mana-backed one read as unbacked. Stored values were never affected. The sync that follows a reload now re-registers each online player's resources and re-sends their bars, and the compatible form registers its backing as it is parsed, so the reload itself restores it.

  • One player losing a resource power no longer takes it from everybody.** Resource information, mana backing and cooldown durations are keyed by the power rather than by the player, and are shared by everyone who holds it, but revoking the power from one player deleted the shared entry. Every other holder lost their bar at the same moment: a mana-backed bar vanished from the HUD and an Apoli resource lost its bounds, until the next relog or reload. A revoke now clears only that player's own state. Separately, the HUD sync was sending every mana-backed bar to every player because it walked the shared table; it now sends a bar only to players who hold the power. The value shown was always the player's own mana.

  • The Lumberjack's bonus planks cover every wood, not just oak.** The power set an item_id field that craft_amount_bonus never reads, so it fell back to the default output of oak planks and every other plank recipe paid nothing. The Lumberjack now names the #minecraft:planks tag and the bonus copies whatever you crafted, modded planks in that tag included.

  • The wraith's client and server agree about blocked blocks (#109).** A wraith that phases into a block it is barred from, such as obsidian or bedrock, is meant to be pushed back out by ordinary collision. The server stopped the phasing while the player was inside such a block, but the client kept phasing, so the two sides disagreed about whether the player was being pushed out at all. Both sides now use one rule for that decision and one reading of the blocked list.

  • Fungal Contact heals only on mushroom blocks and mycelium.** The Sporeling's healing power wrote its block list under a field the condition never reads, and a condition with no block list matches any block, so it healed 1 health every second everywhere. It now heals while you stand on, or have your feet inside, a red or brown mushroom block, a mushroom stem or mycelium, which is what its description has always said.

  • Mushroom Symbiosis and Soul Dread now work.** Both named a biome tag that does not exist, so neither could ever fire. Mushroom Symbiosis asked for minecraft:is_mushroom, and the mushroom biome tag is c:is_mushroom, so the Sporeling now gets its Regeneration in mushroom fields. Soul Dread asked for a tag called minecraft:soul_sand_valley, which is the name of a biome, and it now names the biome. Soul Dread is a Piglin downside, so this fix makes the Piglin weaker: Piglins now take the 0.5 damage a second in a Soul Sand Valley that the description promised.

  • The three Dragon Survival origins can be picked.** Cave Dragon, Forest Dragon and Sea Dragon shipped in no layer file at all. The picker builds its rows from the layer's own origin list and the server refuses a choice the layer does not offer, so none of the three could be chosen even with Dragon Survival installed, and only /neoorigins set reached them. They now sit in neoorigins:origin. Without Dragon Survival their required_mods gate keeps them unloaded and nothing changes for packs that do not have the mod.

  • A random origin will not turn you into a dragon.** With the dragons now listed in a layer that also allows random, rolling for an origin could land on one. Layers read exclude_random (described under Pack Author Features) and the shipped layer excludes the three dragons, which stay directly pickable. The same change made the Random button and the server's own random assignment draw from one pool: server assignment now honours layer conditions, content toggles and unchoosable, all of which it ignored before.

  • Power-granted wings show under a chestplate on 26.1 and 26.2 (#130).** So that it never draws a second pair on top of a real elytra, the wing layer steps aside when the chest slot holds one. On the 26.x lines its test for an elytra matched any armour worn in that slot, so wearing a chestplate hid the wings completely. It now steps aside only for an actual elytra, which is what 1.21.1 has always done.

  • on_block honours inverted.** An on_block whose block condition was a single block, a tag, or an and/or group ignored the inverted flag on that node, so a condition written as "not standing on stone" still matched stone. Every node now honours it, at the top and at any depth, the same way in_block already did. You still have to be on the ground for on_block to match, whether or not the block is inverted. One smaller change comes with it: an or group containing a block condition that cannot be read now fails as a whole, where it used to ignore that one entry.

  • An inline block condition applies inverted once instead of twice.** A condition written as a single node with the block and the flag together, {"type": "block", "block": "stone", "inverted": true}, was negated by the parser and then negated again by the compiler, so it matched stone. It now negates once. The wrapper form, where an outer node holds a nested block condition, was always correct: those are two separate nodes and each flag still applies to its own.

  • The block entity condition reads a root-level tag.** The condition documents a tag written at the top of the node, and packs write it that way, but the shared compiler only looked for one nested under in_tag. Such a node compiled to nothing, which made the entity condition permanently false and made a nested block condition match no block at all. The tag is now read where the documentation says to put it.

  • The in-game creator stops offering speed operations that turn into additions.** On modify_lava_speed and modify_flight_speed, the operation dropdown listed the attribute operations add_value, add_multiplied_base and add_multiplied_total. Those powers only understand addition, multiply_base and multiply_total, and read anything else as an addition, so picking the obvious multiplier silently produced an addition. The dropdown now offers the three the power reads. If you saved one of these powers from the in-game creator, check its operation: a file that already says add_multiplied_base or add_multiplied_total is still read as an addition. The same fix means the change_resource action and Cold Sweat's modify_temperature now offer set alongside add, and the equipped_item condition's slot now offers accessory.

  • The web editor's block view stops rewriting the powers it loads.** The block view rebuilds the powers it holds whenever the canvas changes, and anything a block had no widget for was dropped on the way. Loading the built-in powers and making no edit at all was enough to change some of them: the nested inverted flag came off Windwalker's Cloud Steps, the Qi Cultivator's Dantian Expansion and the Iron Monk's Stamina, and the bare "tag": "minecraft:swords" item condition came off Sword Immortal powers, so those no longer required a sword. Each block now keeps what it cannot display and writes it back unchanged, including a value its dropdown has no entry for, until you change that field yourself.

  • The web editor's built-in powers and origin templates match the mod again.** Both had fallen behind what the mod ships. The power catalogue still gave Elytrian's flight as true, and the origin templates were older still, with the Caveborn diets missing their tiers and the Rogue's Parkour missing the Step Assist toggle that now gates it. Both are regenerated, and a new check in the editor's tooling fails when either falls out of step with the mod.

  • The web editor says when a power type has no form.** Many of the power types the editor offers have no form of their own, so the form shows only the common fields. The note meant to explain this could never appear, and it pointed at the JSON Preview, which is read-only. It now appears for every such type and says what is true: the mod accepts the type, only the common fields can be set in the editor, fields already in an imported file are kept, and anything else has to be written in the power's JSON and imported.

  • The origin picker shows which unique origins are already taken (1.21.1).** When a pack marks an origin as unique, the server tracks who has claimed it and sent that list to the client, but nothing on the client read it. The picker offered a claimed origin anyway, let you confirm it, and the server's refusal arrived as a line of chat, leaving you on an empty layer with no picker to try again. Claimed origins are now shown as claimed, with the name of the player holding them; Confirm is disabled on them and the Random button skips them. The server remains the authority, and a refusal now resyncs you and reopens the picker rather than stranding you. Claims reach every online player as they change and on login, instead of only when a picker opens, so an open picker updates while you are looking at it. This one is on the 1.21.1 line only for 2.2.28; the client that reads the claims does not exist on 26.1 or 26.2 yet.

  • Every config option and every entity has an English name.** The in-game config screen looks a label up by the option's own name rather than by its full path, and 91 entries in the English file were written with the full path, so the screen never read them and drew the raw key instead. Together with options that had no entry at all, that left 234 labels unnamed on 1.21.1, 229 on 26.1 and 228 on 26.2: thirteen section titles including Hotkeys, HUD and Compatibility, the content toggles for nine origins, around 110 power-override sections and the 76 shared field names beneath them, and every client, gameplay and admin option that had been added without one. Nine entities, the black hole, tornado and thrown sword among them, had no name on any line and showed their registry id wherever the game named them. All of them are named now.

  • render_elytra takes "never", "flying" or "always" (#130).** The field on elytra_flight, natural_glide and flight was a plain true or false: wings during a glide, or no wings. "always" draws the wings, folded, whenever the power is active, and spreads them in a glide. "never" and "flying" are the word forms of false and true, and both booleans keep their exact meaning, so existing packs and Origins imports are untouched. Defaults are unchanged: "flying" on elytra_flight, "never" on natural_glide and flight. The in-game creator and both web editor views offer the three as a dropdown, and a file written with true or false opens on the matching entry, with the creator's tooltip naming the real default. Saving writes the word. NeoOrigins 2.2.27 and earlier read only a boolean here, so a pack that has to load on an older version should keep true or false.

  • Layers take exclude_random.** This is the Origins-format list of origin ids that a random roll never lands on, while leaving them directly pickable. A layer file added on top of another adds to the list rather than replacing it. The shipped origin layer uses it for the three Dragon Survival origins.

  • craft_amount_bonus takes a #tag as its output_item.** The bonus then copies whatever was crafted rather than always producing the one named item, which is what a "more planks from logs" power needs in a world with more than one kind of wood. The default is still oak planks, and naming a single item behaves exactly as before.

  • Every block condition can be inverted in the editors.** With on_block fixed, in_block, on_block and the compatibility loader's block compiler all honour inverted, so each block-condition type in the schema now carries it as an optional flag, default false. The in-game creator and both web editor views can set it on any node.

  • spawn_projectile_rain offers telegraph_ticks in both editors.** The action has read the field since it shipped, and the documented example sets it, but no editor declared it, so the lead-in before the first projectile lands could only be authored by hand. It is now an integer field carrying the parser's own default of 14.

  • persistent_effect offers its root-level shorthand in both editors.** The power accepts a single effect written at the root as a one-entry list, with ambient, show_particles and show_icon beside it as defaults for every entry, and 36 shipped powers use that form, but only the root amplifier was ever declared. All four are now authorable, with the decode's defaults. The status_effect alias inherits them instead of carrying its own copies, and stacking_status_effects gains them too.

  • The bundled example packs and the theme template load on 26.1 and 26.2.** The packs in the repository that an author copies from all declared 1.21.1's pack formats, so on the 26.x lines they loaded as too old, and slime-morph-example declared a resource-pack format without the bounds the data-pack parser requires above 81, so it failed to load at all. Each now declares the format of the line it sits on, with example-pack and the theme template, which are both resource and data packs, declaring the full supported span. These sit in the repository rather than inside the jar, so nothing about a player's install changes.

  • Five power types stop being rewritten out of their own behaviour.** A salvage step meant for misspelled types was rewriting neoorigins:action_on_kill, action_over_time, food_restriction, night_vision and status_effect into their Origins-compatible forms before the alias table, which handles all five correctly, ever got the chance. The compatible readers ignore the fields those types document: an action_on_kill written exactly as the docs show it never fired at all, and an action_over_time lost else_action, toggleable, default_off and its enabled switch. Salvage now leaves alone any type the alias table already knows. Shipped content is unchanged: the 22 night_vision and 3 food_restriction powers load to exactly what they did before.

  • origins-classes:more_planks_from_logs covers every wood.** It translated to a bonus with no output named, which meant the default of oak planks, so every other plank recipe paid nothing. It now names the #minecraft:planks tag and pays in whatever you crafted. The bonus count is unchanged.

  • The compatibility loader reads four block condition fields it used to ignore.** fluid, light_level, exposed_to_sky and movement_blocking have compiled correctly in in_block and on_block since 2.2.24, but the Origins-compatible loader has its own block compiler, and there all four fell through to a branch that matches every block. That compiler serves action_on_event block filters, prevent_block_use, prevent_sleep, block_collision and the area_of_effect block filter, so a condition using any of the four was silently always true in all five. No shipped power writes any of them.

  • origins:modify_xp_gain changes the XP a player gains (26.1 and 26.2).** The power loaded on these lines, but nothing read it, so it never changed any XP. It now applies, as it always has on 1.21.1.

  • Config power_overrides reach the water-damage and slow-regeneration powers (26.1 and 26.2).** The overrides ran after the alias table had already read and removed the fields they target, so a server owner's multiplier, damage_per_second or include_rain for those powers was silently ignored. They now run first, as they always have on 1.21.1. A server that set one of these will see it take effect.

  • /reload does not restore some powers for players already online.** A reload clears the per-player tables behind modify_lava_speed (native and Origins-compatible) and the Origins-compatible modify_xp_gain, modify_food, modify_crafting, prevent_item_use, prevent_block_use, prevent_entity_use, prevent_sleep and restrict_armor, and nothing refills them until the player dies, relogs or is granted the power again. Among the built-in origins this affects the Draconic's Molten Stride, which stops speeding up lava swimming until the next death or relog. This is unchanged in 2.2.28.

  • The One Probe is supported on 26.1 and 26.2.** The integration was 1.21.1 only because The One Probe published no 26.x build. It now does, and the API and the handshake are unchanged, so the same provider runs on all three lines. EMI still has no 26.x build, so that integration stays on 1.21.1.

  • FTB Quests tag-marker grants work again on 26.1.** FTB Quests 26.1.2.x dropped the event and the Architectury layer our hook bound to, so with it installed the mod warned at every boot that tag-marker rewards were inert, and a quest tagged neoorigins_loot_pool_grant:<table> granted nothing at all. A typed listener now handles the quest-progress event that 26.1 posts on the NeoForge bus, loaded only when FTB Quests is present, and the older hook stays as the fallback. The 1.21.1 and 26.2 lines are unchanged.

  • KubeJS scripts can read a player's resource values (1.21.1 and 26.1).** NeoOrigins.getResource(player, id) returns the current value, or null when the player does not have that resource, so a missing resource never reads as an empty one. NeoOrigins.hasResource(player, id) says whether they have it. The id is the resource power's full id, the same one /resource get takes. A bar backed by Iron's Spells mana reports that player's live mana. Both are read-only. The 26.2 build does not bundle KubeJS support, so neither is available there. See [KUBEJS.md](docs/KUBEJS.md).

> A hotfix for a startup crash on 26.1 and 26.2. A recent NeoForge update moved the code that our ignore_fluid power attaches itself to. When that attachment point isn't where the mod expects it, the game refuses to start rather than carry on without the power, so servers on a current NeoForge failed during boot with an error that gave no hint of the real cause (#131). Both 26.x jars are fixed. It isn't a 2.2.26 regression: the same code shipped in 2.2.25 and earlier, and every one of those builds fails the same way on a current NeoForge. Minecraft 1.21.1 was never in reach of it, and is republished unchanged so the three versions stay on one number.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • 26.1 and 26.2 servers start again on current NeoForge (#131).** At NeoForge 26.2.0.69, backported to 26.1.2.100, the block scan our ignore_fluid power wraps moved out of EntityFluidInteraction.update(Entity, boolean) and into a new overload beside it. The old signature stayed, so nothing looked missing, but the attachment point had gone with the body, and startup failed with a "Scanned 0 target(s)" line. The power now attaches to whichever of the two overloads holds the scan, so one build works on both sides of the change; what it does once attached is unchanged. Supported-NeoForge floors are deliberately left where they were. Confirmed against a stock dedicated server at the newest NeoForge on each line.

  • The in-game creators' numeric fields survive current NeoForge (26.2).** NeoForge removed a text-field helper at 26.2.0.52 that the origin and mob creators used on every field taking a number, so on anything newer, opening a tab with one on it would have thrown. Those fields filter their own input now. Minecraft 26.1 never lost the method and is unchanged.
> A hotfix for a startup crash on 26.1 and 26.2. A recent NeoForge update moved the code that our ignore_fluid power attaches itself to. When that attachment point isn't where the mod expects it, the game refuses to start rather than carry on without the power, so servers on a current NeoForge failed during boot with an error that gave no hint of the real cause (#131). Both 26.x jars are fixed. It isn't a 2.2.26 regression: the same code shipped in 2.2.25 and earlier, and every one of those builds fails the same way on a current NeoForge. Minecraft 1.21.1 was never in reach of it, and is republished unchanged so the three versions stay on one number.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • 26.1 and 26.2 servers start again on current NeoForge (#131).** At NeoForge 26.2.0.69, backported to 26.1.2.100, the block scan our ignore_fluid power wraps moved out of EntityFluidInteraction.update(Entity, boolean) and into a new overload beside it. The old signature stayed, so nothing looked missing, but the attachment point had gone with the body, and startup failed with a "Scanned 0 target(s)" line. The power now attaches to whichever of the two overloads holds the scan, so one build works on both sides of the change; what it does once attached is unchanged. Supported-NeoForge floors are deliberately left where they were. Confirmed against a stock dedicated server at the newest NeoForge on each line.

  • The in-game creators' numeric fields survive current NeoForge (26.2).** NeoForge removed a text-field helper at 26.2.0.52 that the origin and mob creators used on every field taking a number, so on anything newer, opening a tab with one on it would have thrown. Those fields filter their own input now. Minecraft 26.1 never lost the method and is unchanged.
> A hotfix for a startup crash on 26.1 and 26.2. A recent NeoForge update moved the code that our ignore_fluid power attaches itself to. When that attachment point isn't where the mod expects it, the game refuses to start rather than carry on without the power, so servers on a current NeoForge failed during boot with an error that gave no hint of the real cause (#131). Both 26.x jars are fixed. It isn't a 2.2.26 regression: the same code shipped in 2.2.25 and earlier, and every one of those builds fails the same way on a current NeoForge. Minecraft 1.21.1 was never in reach of it, and is republished unchanged so the three versions stay on one number.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • 26.1 and 26.2 servers start again on current NeoForge (#131).** At NeoForge 26.2.0.69, backported to 26.1.2.100, the block scan our ignore_fluid power wraps moved out of EntityFluidInteraction.update(Entity, boolean) and into a new overload beside it. The old signature stayed, so nothing looked missing, but the attachment point had gone with the body, and startup failed with a "Scanned 0 target(s)" line. The power now attaches to whichever of the two overloads holds the scan, so one build works on both sides of the change; what it does once attached is unchanged. Supported-NeoForge floors are deliberately left where they were. Confirmed against a stock dedicated server at the newest NeoForge on each line.

  • The in-game creators' numeric fields survive current NeoForge (26.2).** NeoForge removed a text-field helper at 26.2.0.52 that the origin and mob creators used on every field taking a number, so on anything newer, opening a tab with one on it would have thrown. Those fields filter their own input now. Minecraft 26.1 never lost the method and is unchanged.
> A compatibility and origin-content release, led by a startup failure. Installing The One Probe alongside NeoOrigins was enough to be refused at launch, over a version bound that compared our lower bound against the wrong part of TOP's version string. It had never protected anything, and it is gone. Six new pack-author capabilities follow, most of them out of getting one legacy Origins pack to run untouched: a morph can play one of the mob's own animations, or run one of the entity events the game uses to make a mob swing, sparkle or shake; pose holds the player prone, crouched or upright, which is what a crawling or a serpentine origin needs; prevent_entity_render hides entities from a single player; using_effective_tool asks whether the swing a player is making is a productive one; and mod_food_nutrition changes what a meal is worth as it goes down. The origin picker gains two more shapes for the two things people kept asking for (#127): a carousel for anyone who preferred the original mod's chooser, and a grid of cards for anyone who wanted a whole layer visible at once, with the two-panel screen unchanged as the default. Dragon Survival no longer fights it for the screen at join either: whichever mod loses that race now has its screen held and reopened instead of dropped. The Caveborn get copper and emerald diets filling the two gaps in the ore ladder, water breathing and fire resistance to go with them, a wash of the ore's own colour for as long as its effect runs, and descriptions that finally admit the diets refuse on a full stomach. All seven of their diets are rebuilt on common tags, so a modded metal or stone is food without a pack touching anything, and what you eat is now worth what it is: a block feeds twice what an ingot does and holds its effect three times as long, a nugget is worth almost nothing, and ore goes down in creative mode the way bread always has. A pack written for 1.19 or 1.20 gets four more of its breakages repaired as the file is read, with no edit to the zip, and four legacy power mappings that dropped their power silently now land, with the rest walked end to end so none of them can. Alongside those: declining an evolution keeps it declined, fire-immune origins stop burning on campfires and blazes (#129), a fire-resistant helmet shades without wearing out, a slime rehydrates from a water cauldron and from a water bottle, the step-up ability gained an off switch for everyone it kept walking up the block they meant to step down from (#123), the web editor's form view stops refusing to switch off a setting that defaults to on while its block canvas stops writing back fields nobody ever set, an event name a pack guessed at costs it a hook rather than the whole power, a legacy repeating action that names no interval paces itself at Apoli's once a second instead of every tick, the in-game creator checks its ids as strictly as the web editor always has, and the reference has been re-read against the loader in the places it had drifted, gaining pages for the two config files that never had one.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • The origin picker comes in three shapes now (#127).** It had one: a scrolling list on the left, details on the right. Players who came from the original Origins mod kept asking for its one-at-a-time chooser back, and others wanted a whole layer visible at once. Both are choices rather than replacements. The client setting ui.picker_layout takes TWO_PANEL, the default and unchanged; CAROUSEL, one origin at a time with arrows to step through them; and GRID, a wall of origin cards that fits as many as your window allows and pages the rest. A card carries the icon, name and impact dots but has no room for a description, so clicking one opens the same full detail read the other layouts use, and Back returns you to the wall. The search box filters the wall as you type, and the arrow keys page it unless the box has focus. The carousel is a NeoOrigins screen shaped like the original rather than a copy of it, so it keeps whatever theme you are running instead of the old dirt-background window, and browsing in it *is* selecting: Confirm always applies to whatever is on screen. Layout and skin are independent. theme_override and classic_picker_style still control colour and font, and any skin works with any layout. See [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • A fire-resistant helmet shades you without wearing out.** Origins that burn in daylight wear down the helmet protecting them, which is right for an ordinary hat and wrong for one that already survives lava. Netherite helmets now shade for free, the way unbreakable ones always did. It keys off the item's own fire-resistant property rather than a list of names, so a modded helmet that grants itself the same property is covered without us naming it.

  • Declining an evolution keeps it declined.** The prompt to evolve was re-offered on every kill after the requirement was met, so refusing it bought a few seconds of quiet and nothing more, and a player near their next tier spent the rest of the session being asked. A decline is now remembered against the tier it was made at, and nothing re-offers that tier: not more kills, not a relog. It stays quiet until you ask for it yourself with /neoorigins evolve accept, an operator sets your tier, or you spend an Orb of Origin, which resets the ladder to zero outright. The tier is not lost by declining it, only muted, and accepting clears the record so the tier above it prompts normally once its own threshold is reached. See [EVOLUTION.md](docs/EVOLUTION.md).

  • The Caveborn's diets say they will not go down on a full stomach.** All eight of them (the Caveborn's seven ores and the Nether origin's fungal diet) refuse when the hunger bar is already full, which is deliberate and matches ordinary food. Nothing said so, and the refusal is completely silent: no message, no eating animation, no sound, so a player at full hunger reads it as the power being broken rather than as being full. Every one of those descriptions now ends by saying it, in all twelve languages the mod ships. The stone diet's list also gained cobbled deepslate, which it has always eaten and never mentioned.

  • The Caveborn eats copper, and copper lets them breathe.** The diet ladder jumped straight from stone to iron, skipping the ore a player turns up more of than any other on the way down. Copper now feeds for 3 hunger and 0.6 saturation, which places it neatly between stone and iron, and eating it grants Water Breathing I for a minute. The effect is picked for the gap it fills rather than for the flavour: a Caveborn sees in the dark, ignores the drop and mines bare-handed, but a flooded ravine or a drowned mineshaft stopped them the same as anybody, and copper is what they are already picking up on the way to one. Ingots, raw copper, both ores and both kinds of copper block all count. Like the other six diets it is a tag, neoorigins:caveborn_eat_copper, so a pack adds a modded copper to it without replacing the power.

  • The Caveborn takes on the colour of the ore they ate.** Six of the seven diets grant an effect, and while one was running there was nothing about the player that showed which one, least of all to anybody looking at them from the other end of the shaft. The model is now washed in that ore's own colour for as long as its effect lasts, sampled from the item rather than picked by hand: copper orange, iron pale grey, gold yellow, diamond cyan, emerald green, netherite a dark brown. Eat two and the colours average. Nothing about the buffs changes, and each of the six is its own switch in power_overrides.toml, from caveborn_copper_tint through caveborn_netherite_tint, so a server that wants the diets without the colour can turn off as many of them as it likes. Stone has no tint, having no effect to signal. See [ORIGINS.md](docs/ORIGINS.md).

  • Emerald is the seventh diet, and it buys a trip to the surface.** The Caveborn's one real cost is that daylight burns them, and nothing in the origin ever answered it: you either stayed under or you took the damage. Emerald now feeds for 7 hunger and 1.4 saturation, filling the gap the ladder had left between diamond and netherite, and eating one grants Fire Resistance for five minutes. The sunlight damage was always dealt as fire, so this cancels it outright rather than blunting it, and it covers lava on the way back down, which is the other thing that kills miners. Emeralds, both emerald ores and blocks of emerald all count, through neoorigins:caveborn_eat_emerald. You will still catch fire: Fire Resistance cancels the damage but does not put the flames out, and the sunlight power re-lights you every second you are exposed, so those five minutes above ground are spent visibly alight and entirely unharmed. Step into shade or water and the burn runs out on its own. Emerald is the one Caveborn diet with a renewable supply, since a villager will trade for it.

  • A block of ore feeds a Caveborn like a block, and a nugget like a nugget.** Every form of a material was worth the same meal, so a raw iron block and a single ingot both restored 4 hunger, and the block was worth eating only if you had nothing else to hand. The nugget was the inverse and the worse half of it: nine nuggets restored 36 hunger where the ingot they make restored 4, and nether gold ore drops nuggets rather than ingots, so the least valuable form of gold in the game was by a wide margin the most efficient food in the origin. What you eat is now worth what it is. A block feeds twice what an ingot or gem does and holds its effect three times as long; a nugget feeds 1 hunger with no saturation and buys fifteen seconds. A block is deliberately not worth the nine that a crafting recipe would suggest, because hunger caps at 20 and most of that food would be discarded the moment it was granted, so the duration is where the value went instead. The arithmetic that matters is that an ingot at 4 hunger and 6.4 saturation now stays ahead of the nine nuggets you could split it into, which is the comparison the old numbers had backwards. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • The step-up ability has an off switch (#123).** An origin or class that steps a full block does it whether you want it to or not, and holding shift does not suppress it, so edging up to a drop or lowering yourself onto a ledge walks you straight up the block you were working around. The game offers no way to ask for a step height that yields to sneaking, so the answer is a switch rather than a rule. The Explorer's *Climber's Step*, the Rogue's *Parkour* and the Scout's *Tracker's Stride* now share a *Step Assist* ability that turns the step height off and back on, with a low note for off and a high one for on. It defaults to on, so nothing changes for anyone who never presses it, and the state is saved with the rest of your toggles rather than springing back on at the next login. With it off you climb blocks by jumping, the same as everybody else.

  • Fire-immune origins stop burning on campfires and blazes.** (#129) The immunity checked four damage types by name (standing in fire, being on fire, lava and magma blocks), which left out campfires and both kinds of fireball, so an origin that is supposed to be unburnable took full damage from a blaze and cooked on a campfire like anyone else. It now asks the game's own minecraft:is_fire tag instead of a hand-written list, which covers those cases, agrees with the matching condition that was already using the tag, and picks up fire damage added by other mods without further work.

  • The web editor's form view can turn a default-on setting off.** Any boolean whose default is true could not be set to false from the form view: the row drew itself unchecked while the power actually behaved as switched on, and ticking the box and clearing it again wrote nothing at all, so the setting looked changed and was not. An unset field now seeds from the schema's declared default rather than a flat false. This affected 68 default-true booleans across the shipped power, action and condition schemas.

  • The block editor stops writing fields you never set.** A block widget has to display something, so an optional field the power does not carry gets drawn with a stand-in, and the canvas was writing every one of those back when it saved. One drag of an unrelated block was enough to turn a damage-halving power into total immunity, because modify_damage came back carrying set_total: 0, a field whose own reference entry says to leave it out if you want the multiplied value kept. Nothing on screen looked any different. A leaf still equal to the stand-in the widget had to show is now left out on the way back, and the fields the loaded file genuinely carried are tracked alongside it, so an author who deliberately means a zero keeps it. Powers the canvas cannot draw are put back at their original position rather than at the end, since the order powers are written in is authored data too.

  • An area_of_effect inside a lingering cloud stays with the cloud (#125).** The interval action a lingering area runs is executed as the caster, which is right for kill credit and for anything that spends a resource, but it also meant an area effect nested inside it measured its radius from wherever the caster was standing at that moment. Walk away from your own cloud and the damage walked with you, leaving the cloud drawing particles over nothing. The action still runs as the caster; an area_of_effect inside it now centres on the cloud.

  • The Merchant's restocked trades stop showing as sold out.** The class refills nearby villagers' trades on a timer, but it refilled them server-side only. A trade's sold-out cross is drawn from the copy of the offers the client was handed when the screen opened, so a trade that had just been refilled kept its cross, and the only way to clear it was to close the villager and open it again. The refill now resends the offers to whoever has that villager open, which is what vanilla's own restock does. It sends nothing when nothing was actually refilled, so an open trading screen no longer takes a packet every couple of seconds for the life of the interaction.

  • Ore goes down in creative mode, the way bread always has.** A Caveborn in creative could not eat any of their seven diets, while every vanilla food in the game ate normally, and because the refusal is silent it read as the power being broken rather than as a rule. Our gate asked whether the hunger bar had room, and creative mode is precisely the case where it never does. It now asks the game's own question instead, which is invulnerable or always-edible or genuinely hungry, at both places that had to know, so the two can no longer drift apart. Fixing that surfaced the other half of the same problem: the meal took one from the stack unconditionally, where vanilla food leaves a creative player's stack alone. It now spends the item through the same call vanilla uses, which declines to spend anything for a player with infinite materials. Both halves apply to every edible_item power, not only to the Caveborn's.

  • A slime rehydrates from a water cauldron and from a water bottle.** The moisture bar refilled from water, rain and bubble columns, which is the game's own in-water test, and a water cauldron does not answer to it: a cauldron is a block carrying a level, not a body of water. A slime standing in a full cauldron therefore dried out at exactly the rate of one standing on bare stone, which is the opposite of what anyone builds a cauldron for. Standing in one now refills at the same rate open water does. Drinking a water bottle tops the bar up as well, by half its length, which gives a drying slime something it can carry rather than a source it has to reach. Neither of these is new ground, and that is the point: breath_out_of_fluid has handled the cauldron and the bottle for aquatic origins for some time, and the moisture bar simply never got the same treatment. The bottle amount is water_bottle_refill on the power, so a pack can retune it or set it to 0 to leave water bottles out of it entirely. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:pose holds the player prone, crouched or upright.** A forced pose is the missing piece for a crawling origin, a serpent that never stands, or a form that cannot fit through a full-height door: "pose": "swimming" puts the player flat, which carries the one-block hitbox and the crawl animation everywhere, not only in water. It is a power rather than an action because the pose has to be held and then released, and it takes the usual condition, plus toggleable and default_off and a HUD icon, so a pack can hand the switch to the player. Clearance is deliberately not checked: a forced crawl fits through gaps the player otherwise could not, and whether that is too strong is the pack's call. Releasing it hands the player back to the game, which does check, so nobody ends up standing inside a ceiling. Sleeping, gliding and spin-attack are not offered: those poses carry behaviour a pose alone cannot deliver. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:prevent_entity_render hides entities from the player who has it.** Every living entity matching entity_condition stops being drawn for that player alone; everyone else sees it normally and the entity itself is untouched, so it still moves, still attacks and still blocks the way. Pair it with something that applies glowing for an origin that sees only what it has marked. The condition is evaluated on the server, which is what lets it use status_effect and nbt: a client is never told another entity's effects, so a client-side check would have quietly matched nothing. The hidden set refreshes every five ticks over living entities within view distance, capped at 1024 per player. origins:prevent_entity_render maps onto it, so a legacy pack using it works now rather than loading it as an unsupported no-op.

  • A morph can play the mob's own animations.** neoorigins:trigger_morph_animation names a triggerable animation on the GeckoLib model a player is morphed into, and it plays for everyone who can see them. It needs no dependency and no packet: GeckoLib's own trigger call already routes a client-side entity straight into its animation manager, and the morph is a real client-side entity rather than a static model, so it takes that path for free. One hard limit worth knowing before you plan around it: the only reachable names are the ones the mob's author explicitly registered as triggerable; an unregistered name does nothing at all and logs nothing; and there is no way to discover the list from JSON. Vanilla mobs are not GeckoLib models and do nothing here. AzureLib is shaped the same way and could follow; Citadel is not. See [ACTIONS.md](docs/ACTIONS.md).

  • A morph can run the mob's entity events.** neoorigins:morph_entity_event fires the hook the server normally uses to tell clients a mob just did something, whether that is an iron golem's attack swing, a villager's angry particles or a wolf shaking off water, so a morph reacts like the mob instead of only sharing its silhouette. The names come from Minecraft's own table rather than a hand-copied list, so they track the game version, and a raw id byte is there for modded mobs with events of their own. Three limits are documented rather than papered over: events whose sound plays through the entity itself are silent on a morph, events that set a countdown for the mob's own tick to drain hold that pose instead of playing through it, and particle events that read the mob's movement draw their particles streaking in from the world origin instead. The death byte is refused outright, because on a morph it would fire a client-side death for an entity that was never in the world.

  • set_block places where you aimed.** It was an entity action only, and it placed at the target's feet, so a right-click power aimed at a block changed the ground the player was standing on instead of the block they clicked. It now resolves the position from whatever context it runs in (a block or bonemeal interaction, a projectile or raycast hit, a block_action_at or offset wrapper), and falls back to the actor's own position when there is no block context, which is what it always did. It is also a block-target verb now, so it can be named directly inside block_target_action alongside strip, till, path, grow and transform_block. The keep field, which places only into air, was never documented.

  • item_condition gates right-click powers instead of being dropped.** Apoli's action_on_block_use and action_on_entity_use both take an item_condition meaning "only with this in hand", and the translator never copied it, so a power that was supposed to fire only while holding a specific item fired for whatever the player happened to be carrying. It is carried across now, along with Apoli's newer held_item_condition spelling, and the gate reads the stack out of the interaction rather than only out of a food context. Copying the field alone would have made every one of those powers fail instead, since the gate fails closed and had nothing to read. action_on_block_break, wake_up and bonemeal carry no item gate across. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:using_effective_tool asks whether the swing you are making is a productive one.** It matches Apoli's condition of the same name and takes no fields. It answers two things at once, and the first is the half that is easy to get wrong: it is true only while the player is part-way through breaking a block *and* holding a tool that will actually yield its drops. It is false whenever the player is not mid-break, so it cannot be used to ask "am I holding a pickaxe". A power gated on it fires during mining and at no other time, which makes it the right gate for a mining-flavoured effect and the wrong one for an equipment check. See [CONDITIONS.md](docs/CONDITIONS.md).

  • edible_item can pay a different amount for one part of its set.** The type read a list of items and tags and paid one number for all of them, so anything whose worth varies by form (an ore against its block, an ingot against its nugget) needed a second power, a second tag and a second copy of every field it shared with the first. The new tiers list puts those bands inside the one power. Each entry carries its own items or tags and its own nutrition, with saturation optional and inherited from the power when it is left out. First match wins, so write the narrow bands first, and anything matching none of them falls back to the power's own values. Bands match alongside the top-level lists rather than within them, so a tier can introduce items the power never otherwise mentions. One thing to know before you tune one: saturation is restored as nutrition times the modifier times two, so a band that doubles both grants four times the saturation, which is almost never what was meant. Leaving saturation off is the right default. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • All seven Caveborn diet tags are built out of common tags.** The stone diet listed its ten blocks inside the power, so it was the one diet a pack could not extend without replacing the whole file, and the other six listed vanilla item ids, so a modded metal was not food until somebody added it by hand. Every one of them is a tag now, and every one is a union of NeoForge's c: tags: the six materials take their ingots/, nuggets/, gems/, raw_materials/, ores/ and storage_blocks/ entries, and stone takes #c:stones and #c:cobblestones alongside basalt and blackstone. A modded metal or stone that registers itself where mods normally do is edible with no pack work at all. netherite_scrap is the one literal id left in the set, since NeoForge publishes no common tag for that item. The rebuild closed a gap nobody had reported as such: the refined storage blocks were in none of the old lists, only the raw ones, so a Caveborn could eat a raw iron block and not an iron block. Adding your own item to a tag works exactly as before, and it lands in the matching value band if there is one. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • mod_food_nutrition changes what a meal is worth as it is eaten.** Nutrition could be retuned only through the legacy origins:modify_food power, so a pack working in the native vocabulary had no way to reach it and no event to hang a condition on. action_on_event now carries a mod_food_nutrition event that fires for any food actually eaten, with the item itself in context, so food_item_in_tag and food_item_id both gate it. It runs after modify_food and on whatever that left behind, so a pack can use either or both and neither needs the other to be present. The result is rounded and floored at zero. See [EVENTS.md](docs/EVENTS.md).

  • The in-game creator checks your ids the way the web editor does.** The generated schemas have always carried a pattern for each id-shaped string field, and only the web editor read them: the in-game creator's text rows took anything and left the mistake to surface at load, far from the field that caused it. Each text row now checks its value against the schema's own pattern as you type and shows the same inline complaint the web editor would. It advises rather than blocks, deliberately: the loader is more forgiving than the patterns in a few places (a particle or dimension written without its minecraft: prefix loads fine), and an editor that refuses what the game accepts is the failure shape 2.2.26 already removed once. Nothing you can load is ever locked out of saving.

  • model_color stacks, and can be switched off from the config.** Two tints active at once resolved to whichever one the capability set happened to hand over first, which is not something a pack can predict or arrange around, so an origin with more than one conditional tint had a colour nobody could design. Overlapping tints now average their channels: two produce their midpoint, three their mean, and every client watching sees the same thing. The type also honours the shared enabled flag, so a server owner can drop a single tint from power_overrides.toml while leaving the power that carries it in place.

  • Four legacy power mappings that never landed now do.** origins:aquatic, origins:conduit_power_on_land and origins:nether_spawn were each mapped onto a NeoOrigins type that does not exist, so a legacy pack using any of them had the power silently dropped: nothing failed, nothing was logged, the origin simply came up missing an ability. origins:creative_flight was worse in a quieter way. It named a type that does exist, just the wrong one, and had done so for five months. All four are retargeted, and every remaining legacy mapping has been walked end to end on both sides rather than only on the name a pack writes, so the mappings that ship are the ones that resolve.

  • An action_on_event that names an event which does not exist no longer costs the whole power.** An unrecognised event fails the power's decode outright, so a pack that guessed a plausible spelling did not end up with a hook that misbehaved, it ended up with nothing, the ability simply missing from the origin with no sign of why. item_use_start is the common guess, and it now resolves to item_use, which already fires at exactly that moment for anything with a use duration: a shield going up, a bow drawn, food raised. The accepted spellings are offered by both editors as well, so a pack the game loads is never marked invalid on the way in. A name matching nothing at all still fails loudly rather than being quietly swallowed. Only a spelling whose target already fires at the same instant is ever added this way, since a name pointed at a different moment would load and then do the wrong thing, which is worse than the refusal it replaced. See [EVENTS.md](docs/EVENTS.md).

  • A pack that writes neoorigins: where it meant origins: is salvaged rather than dropped.** The compatibility power types answer to origins: and apace: and nothing else, so an author writing neoorigins:action_on_item_use got the power dropped outright, with no line in the log explaining why. It is an easy mistake to make, since the mod is called NeoOrigins and every other type they write really does start with neoorigins:. Such a type is now rewritten back to origins:, but only when the name is one the compatibility layer actually handles and there is no native type of that name, so the 34 names that exist in both vocabularies keep resolving natively. The "unknown power type" warning is more useful too: powers, actions and conditions share a namespace and a naming style, so it now tells you which of the three an unrecognised id actually belongs to.

  • The loot function 1.20.5 deleted no longer takes the whole table down with it.** minecraft:set_nbt is gone, and a loot table naming it fails to parse outright, which cascades into every function and advancement that referenced the table, so items a legacy pack was supposed to hand out simply never arrived, with the failure logged somewhere far from the cause. It is retargeted to minecraft:set_custom_data, which takes the identical field, as the file is read. It is not an NBT-to-components converter and does not pretend to be: a blob carrying a key that became a real data component is left exactly as it was and reported, so the table still fails, but it fails loudly instead of quietly handing out an item with its enchantments missing.

  • A legacy starting_equipment written with a singular stack grants it.** Packs in the wild are written with both spellings; NeoOrigins read only the plural, so a power using the singular was skipped and gave the player nothing, without an error. Both spellings are read now, with the plural winning where a pack has somehow written both. See [COMPATIBILITY.md](docs/COMPATIBILITY.md).

  • Item NBT paths that step through the deleted tag field are repointed.** 1.20.5 removed tag from item stacks, and this is the worst shape of breakage a pack can carry: a path like SelectedItem.tag.Foo still parses and still runs; it just resolves to nothing, so neither the command parser nor a load-time check can see anything wrong and the pack fails silently in game. Both spellings are repaired (the dot path, including subscripts, and the brace form inside a selector), and this one runs unconditionally rather than behind a parse check, because on 1.21 no item stack carries a tag field in any context, so there is no valid path of that shape to break. Quoted text is skipped and the commands whose payload is free text are excluded, so a tellraw that happens to mention one is left alone.

  • set_block reaches legacy packs that used it as a block action.** In Apoli it is a block action and places at the block the power was aimed at. Because the translator flattens a block action into an entity action, adding the block-side verb alone would not have reached these packs at all; the fix is the context resolution above, which is what makes the flattened form land in the right place.

  • A legacy repeating action that names no interval fires once a second, not twenty times.** Apoli's action_over_time defaults its interval to 20 ticks, and packs lean on that: leaving the field out is normal upstream. Our compatibility layer defaulted it to 1, so such a power ran its action on every tick, which is twenty heals, twenty particle bursts or twenty command executions a second, and a pack tuned around the upstream pace ran twenty times hot with nothing in its file to show why. The default is now 20, matching Apoli and matching our own condition_passive, which has said 20 all along. A power that writes its own interval is untouched.

  • The compat layer's night-vision and diet mappings outlive the alias table.** Five well-known Origins powers (night_vision, cat_vision, water_vision, carnivore, vegetarian) were compiled into two retired NeoOrigins type names that only still load because the legacy remap catches them on the way in, and that remap is scheduled to go. They now emit the canonical forms directly: an ambient, particle-free persistent_effect for the visions, and an event-cancelling action_on_event diet gate for the two food rules, each byte-matching what the remap produced. Nothing changes in game, which is the point: when the aliases retire, these five keep working instead of being the surprise.

  • Two condition ids that never existed stop being claimed as supported.** neoorigins:lava and neoorigins:water sat in the compat condition catalogue with no implementation behind them, put there by a build-time audit that misread the fluid ids inside submerged_in and fluid_height as condition types. A pack writing one was told nothing, since the id was "known", and the condition then failed anyway. Both are gone, the audit no longer manufactures them, and writing one now earns the ordinary unknown-type warning that points you at in_water, in_lava and submerged_in, which are the conditions that exist.

  • The game starts again if you have The One Probe installed.** This one blocked the mod outright rather than degrading it, and it took no unusual setup to hit: installing TOP alongside NeoOrigins was enough. TOP publishes its version as 1.21_neo-12.0.8, and NeoForge compares version ranges piece by piece from the left, so our lower bound of 12 was tested against the leading 1 of the Minecraft version and failed every time. The 12.0.8 was never reached. The message named the right numbers and still made no sense to read: "only supports theoneprobe 12 or above. Currently, theoneprobe is 1.21_neo-12.0.8". NeoForge enforces a range even on an optional dependency, so this was a hard stop at startup. The bound is gone, and it was never doing anything: the integration is already behind a check for whether TOP is loaded, with every TOP-specific reference confined to its own package, so an old or missing TOP cannot reach the code either way.

  • Dragon Survival and the origin picker stop knocking each other off the screen.** Both mods open a screen when you join, Dragon Survival when its species-choice setting is on and NeoOrigins because the server asked for a pick, and whichever arrived second replaced the first. That is how players were being thrown out of the origin picker, and because it was a race, which screen you lost was not even consistent between joins. The old setting was a plain on/off switch whose two positions were "leave the race alone" and "cancel Dragon Survival's screen outright", so neither of them was what most people wanted. It is now compat.dragon_species_screens, with three positions: DEFER, the new default, holds Dragon Survival's screen back and opens it the moment the origin picker is finished, so neither mod loses its screen; SUPPRESS cancels species screens, as the old "on" did; ALLOW never interferes, as the old "off" did. The interception runs both ways, so it does not matter which mod wins the race. Under DEFER and ALLOW, a species screen you opened yourself (from an altar, the inventory button or a command) is left alone; only one that would trample the picker is caught. Dragon Survival's appearance editor, skins, abilities and inventory are never touched under any setting. It is a client setting, so nothing changes on the server or in Dragon Survival's own config. See [COMPATIBILITY.md](docs/COMPATIBILITY.md).

  • Three client-config defaults were documented as their opposites.** hud_ability_display defaults to COOLDOWNS_AND_TOGGLES and was written as ALL_ACTIVE_ABILITIES, default_sort defaults to MANUAL and was written as CLASS, and always_show_icon was described as having no effect under the default mode when the default mode is exactly where it matters. All three are the shape of error that costs nothing at load and shows up as a HUD or a picker that does not look the way the page said it would. See [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • Origin layers merge additively, not by replacement.** The cookbook told authors that a second pack's layer file replaces the origins array and that they should therefore copy the full list across, which is both wrong and the opposite of the sentence immediately before it in the same paragraph. Layers merge by appending, deduplicated by id, with "replace": true as the opt-out. Copying the full list was at best redundant and at worst a maintenance trap, since the copy goes stale the moment the original pack adds an origin. The ordering rule is spelled out alongside it: display order comes from each origin's own order field, not from position in the array. See [COOKBOOK.md](docs/COOKBOOK.md).

  • The legacy-pack repairs are written down.** [COMPATIBILITY.md](docs/COMPATIBILITY.md) gains a section covering every syntax-level repair applied while a 1.19/1.20 pack is read, what each one does, and what is deliberately not covered. That last part is the one that matters when a pack still misbehaves. SkullOwner is called out by name: it became the profile component, it is not in the mapped set, and a legacy pack handing out a named player head gets a blank one with no warning.

  • starting_equipment's plural form is documented.** The type has taken a stacks array for some time and the reference described only the single-item shape, so multi-item kits were being written as several powers. The two shapes do not combine, since a non-empty stacks ignores the root item entirely, and one grant_id seals the whole bundle, so a single bad item id is worth planning around. Both are now spelled out with a worked example. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • prevent_entity_render and the evolution prompt describe what the code does.** The former hides living entities only, so boats, minecarts, item frames and dropped items were never candidates despite the page saying every entity was. The latter had no written description of when the prompt appears or what declining does; [EVOLUTION.md](docs/EVOLUTION.md) now has one, and [KUBEJS.md](docs/KUBEJS.md) lists the evolutionDeclined event beside it with the conditions under which it fires.

  • An Orb of Origin does reset your evolution, whatever the page said.** [EVOLUTION.md](docs/EVOLUTION.md) claimed the orb left essence kills, tier and a declined tier untouched, and that only two things could clear a decline. Spending an orb clears all three fields, so three things clear a decline, not two. This is worth calling out rather than quietly fixing, because the cookbook had it right on the same page-set: the two documents contradicted each other, and if you planned around the wrong one, an orb has been resetting more than you expected all along.

  • A native active_ability can use a named hotkey, whatever the reference said.** [POWER_TYPES.md](docs/POWER_TYPES.md) and [API.md](docs/API.md) both stated it could not, and sent authors off to rewrite the power as an Apoli-style origins:active_self to get one. It was never true: key is not on the codec, but the loader reads it out of the power's own JSON for every active power, native ones included, and binds it like any other. Both denials are gone and key now has a row in the active_ability table. neoorigins:toggle went the other way and has lost the field: it declared key, so both editors offered it and the schema accepted it, but a toggle is not an active power and a keypress had nothing to run even once it arrived. The toggle section says so now, and points at the active_ability that flips it.

  • The power reference's field tables were re-read against the codecs.** Four sections listed fields the codec never reads or carried no table at all, and three types had no section anywhere: apugli:action_on_jump, apugli:action_on_target_death and action_over_time. Eleven fields were marked required that are not, and each now says what actually happens instead, which is rarely nothing: a modifier seam given neither modifier nor modifiers is not refused by the schema, but the loader drops the whole power rather than leaving the multiplier sitting at 1.0. Two entries were simply false. biome_buff with no biome_tag does not apply everywhere, it applies nowhere, the default being an empty tag that matches no biome; and the root amplifier on the persistent_effect family overrides the first effects entry alone rather than cascading onto all of them, winning even over one that entry sets for itself. enabled, the per-power kill switch, is written up on the six types that take it. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • The rest of the reference was re-read against the code, not against the older prose.** Four more claims did not survive it. The Caveborn's diet section listed five eating powers when there are seven. The copper tint was described as green-orange; it is orange. The burning-under-Emerald-Reprieve note explained itself with a rule about fire immunity that is not how the game works: Fire Resistance cancels fire damage and never puts the fire out, and it is the sunlight power re-lighting you each second that keeps you alight. And the compatibility page promised that a Dragon Survival species screen you opened yourself always behaves as it would without NeoOrigins installed, which holds under DEFER and ALLOW but not under SUPPRESS. Two sentences describing what Apoli itself declares have been rewritten to describe only what NeoOrigins does, since we cannot verify the first kind and that is exactly how the others got in.

  • gameplay.toml and admin.toml have reference pages at last.** Two of the four config files had none, so the options between them (the Orb's XP cost formula, random assignment, the evolution kill thresholds, ocean-origin survival tuning, the command-power blacklist, dimension restrictions) were configurable and written down nowhere but the file's own comments. [GAMEPLAY_CONFIG.md](docs/GAMEPLAY_CONFIG.md) and [ADMIN_CONFIG.md](docs/ADMIN_CONFIG.md) now cover every section, key, default and range. [CONTENT_CONFIG.md](docs/CONTENT_CONFIG.md) also stops calling all four files server configs, because only content.toml is one: it alone is synced to clients and overridable per world, while the other three load early, apply to the whole install, and enforce server-side. The distinction decides where you edit and whether a per-world copy will be honoured, which is exactly the thing to get right on a page about config files.

  • The event contexts say what a handler is actually handed.** Eight of them had drifted: hit_taken, kill and projectile_hit all carry the live, cancellable event in their context and the page did not say so; death's context *is* the event; land has a second dispatch site (a per-tick ground-contact detector for landings the fall path never sees) where the context is empty and cancel_event deliberately does nothing; and the paragraph on mod_break_speed described a removed event as though it still fired. Alongside them, add_velocity gains its missing space row with all eight Apoli reference frames, dash its set_velocity, and spawn_projectile's count admits it defaults to 1 for a plain projectile and 2 for an orb trail. See [EVENTS.md](docs/EVENTS.md) and [ACTIONS.md](docs/ACTIONS.md).

  • The API index is exhaustive again, and now provably.** [API.md](docs/API.md) promises a complete list of everything registered, and it had fallen to roughly two thirds on conditions and actions: 21 conditions, 17 actions and 17 events were registered, working and listed nowhere, so a reader took the absence as the feature not existing, which is the same failure 2.2.25 fixed for power types. All four lists were regenerated from the registries (122 power types, 108 conditions, 95 actions, 51 events, with the 26.2 build counting two types and one action fewer, the KubeJS-backed ids it does not ship) and verified by script in both directions, so an id in the code is on the page and an id on the page is in the code, with zero exceptions either way. The page's description of how legacy packs are translated was corrected in the same pass: origins: and apace: go through the translator, apoli: and apugli: are canonicalized to origins: first, and the legacy alias table covers only the odd cross-mod id rather than being the pipeline itself.
> A compatibility and origin-content release, led by a startup failure. Installing The One Probe alongside NeoOrigins was enough to be refused at launch, over a version bound that compared our lower bound against the wrong part of TOP's version string. It had never protected anything, and it is gone. Six new pack-author capabilities follow, most of them out of getting one legacy Origins pack to run untouched: a morph can play one of the mob's own animations, or run one of the entity events the game uses to make a mob swing, sparkle or shake; pose holds the player prone, crouched or upright, which is what a crawling or a serpentine origin needs; prevent_entity_render hides entities from a single player; using_effective_tool asks whether the swing a player is making is a productive one; and mod_food_nutrition changes what a meal is worth as it goes down. The origin picker gains two more shapes for the two things people kept asking for (#127): a carousel for anyone who preferred the original mod's chooser, and a grid of cards for anyone who wanted a whole layer visible at once, with the two-panel screen unchanged as the default. Dragon Survival no longer fights it for the screen at join either: whichever mod loses that race now has its screen held and reopened instead of dropped. The Caveborn get copper and emerald diets filling the two gaps in the ore ladder, water breathing and fire resistance to go with them, a wash of the ore's own colour for as long as its effect runs, and descriptions that finally admit the diets refuse on a full stomach. All seven of their diets are rebuilt on common tags, so a modded metal or stone is food without a pack touching anything, and what you eat is now worth what it is: a block feeds twice what an ingot does and holds its effect three times as long, a nugget is worth almost nothing, and ore goes down in creative mode the way bread always has. A pack written for 1.19 or 1.20 gets four more of its breakages repaired as the file is read, with no edit to the zip, and four legacy power mappings that dropped their power silently now land, with the rest walked end to end so none of them can. Alongside those: declining an evolution keeps it declined, fire-immune origins stop burning on campfires and blazes (#129), a fire-resistant helmet shades without wearing out, a slime rehydrates from a water cauldron and from a water bottle, the step-up ability gained an off switch for everyone it kept walking up the block they meant to step down from (#123), the web editor's form view stops refusing to switch off a setting that defaults to on while its block canvas stops writing back fields nobody ever set, an event name a pack guessed at costs it a hook rather than the whole power, a legacy repeating action that names no interval paces itself at Apoli's once a second instead of every tick, the in-game creator checks its ids as strictly as the web editor always has, and the reference has been re-read against the loader in the places it had drifted, gaining pages for the two config files that never had one.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • The origin picker comes in three shapes now (#127).** It had one: a scrolling list on the left, details on the right. Players who came from the original Origins mod kept asking for its one-at-a-time chooser back, and others wanted a whole layer visible at once. Both are choices rather than replacements. The client setting ui.picker_layout takes TWO_PANEL, the default and unchanged; CAROUSEL, one origin at a time with arrows to step through them; and GRID, a wall of origin cards that fits as many as your window allows and pages the rest. A card carries the icon, name and impact dots but has no room for a description, so clicking one opens the same full detail read the other layouts use, and Back returns you to the wall. The search box filters the wall as you type, and the arrow keys page it unless the box has focus. The carousel is a NeoOrigins screen shaped like the original rather than a copy of it, so it keeps whatever theme you are running instead of the old dirt-background window, and browsing in it *is* selecting: Confirm always applies to whatever is on screen. Layout and skin are independent. theme_override and classic_picker_style still control colour and font, and any skin works with any layout. See [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • A fire-resistant helmet shades you without wearing out.** Origins that burn in daylight wear down the helmet protecting them, which is right for an ordinary hat and wrong for one that already survives lava. Netherite helmets now shade for free, the way unbreakable ones always did. It keys off the item's own fire-resistant property rather than a list of names, so a modded helmet that grants itself the same property is covered without us naming it.

  • Declining an evolution keeps it declined.** The prompt to evolve was re-offered on every kill after the requirement was met, so refusing it bought a few seconds of quiet and nothing more, and a player near their next tier spent the rest of the session being asked. A decline is now remembered against the tier it was made at, and nothing re-offers that tier: not more kills, not a relog. It stays quiet until you ask for it yourself with /neoorigins evolve accept, an operator sets your tier, or you spend an Orb of Origin, which resets the ladder to zero outright. The tier is not lost by declining it, only muted, and accepting clears the record so the tier above it prompts normally once its own threshold is reached. See [EVOLUTION.md](docs/EVOLUTION.md).

  • The Caveborn's diets say they will not go down on a full stomach.** All eight of them (the Caveborn's seven ores and the Nether origin's fungal diet) refuse when the hunger bar is already full, which is deliberate and matches ordinary food. Nothing said so, and the refusal is completely silent: no message, no eating animation, no sound, so a player at full hunger reads it as the power being broken rather than as being full. Every one of those descriptions now ends by saying it, in all twelve languages the mod ships. The stone diet's list also gained cobbled deepslate, which it has always eaten and never mentioned.

  • The Caveborn eats copper, and copper lets them breathe.** The diet ladder jumped straight from stone to iron, skipping the ore a player turns up more of than any other on the way down. Copper now feeds for 3 hunger and 0.6 saturation, which places it neatly between stone and iron, and eating it grants Water Breathing I for a minute. The effect is picked for the gap it fills rather than for the flavour: a Caveborn sees in the dark, ignores the drop and mines bare-handed, but a flooded ravine or a drowned mineshaft stopped them the same as anybody, and copper is what they are already picking up on the way to one. Ingots, raw copper, both ores and both kinds of copper block all count. Like the other six diets it is a tag, neoorigins:caveborn_eat_copper, so a pack adds a modded copper to it without replacing the power.

  • The Caveborn takes on the colour of the ore they ate.** Six of the seven diets grant an effect, and while one was running there was nothing about the player that showed which one, least of all to anybody looking at them from the other end of the shaft. The model is now washed in that ore's own colour for as long as its effect lasts, sampled from the item rather than picked by hand: copper orange, iron pale grey, gold yellow, diamond cyan, emerald green, netherite a dark brown. Eat two and the colours average. Nothing about the buffs changes, and each of the six is its own switch in power_overrides.toml, from caveborn_copper_tint through caveborn_netherite_tint, so a server that wants the diets without the colour can turn off as many of them as it likes. Stone has no tint, having no effect to signal. See [ORIGINS.md](docs/ORIGINS.md).

  • Emerald is the seventh diet, and it buys a trip to the surface.** The Caveborn's one real cost is that daylight burns them, and nothing in the origin ever answered it: you either stayed under or you took the damage. Emerald now feeds for 7 hunger and 1.4 saturation, filling the gap the ladder had left between diamond and netherite, and eating one grants Fire Resistance for five minutes. The sunlight damage was always dealt as fire, so this cancels it outright rather than blunting it, and it covers lava on the way back down, which is the other thing that kills miners. Emeralds, both emerald ores and blocks of emerald all count, through neoorigins:caveborn_eat_emerald. You will still catch fire: Fire Resistance cancels the damage but does not put the flames out, and the sunlight power re-lights you every second you are exposed, so those five minutes above ground are spent visibly alight and entirely unharmed. Step into shade or water and the burn runs out on its own. Emerald is the one Caveborn diet with a renewable supply, since a villager will trade for it.

  • A block of ore feeds a Caveborn like a block, and a nugget like a nugget.** Every form of a material was worth the same meal, so a raw iron block and a single ingot both restored 4 hunger, and the block was worth eating only if you had nothing else to hand. The nugget was the inverse and the worse half of it: nine nuggets restored 36 hunger where the ingot they make restored 4, and nether gold ore drops nuggets rather than ingots, so the least valuable form of gold in the game was by a wide margin the most efficient food in the origin. What you eat is now worth what it is. A block feeds twice what an ingot or gem does and holds its effect three times as long; a nugget feeds 1 hunger with no saturation and buys fifteen seconds. A block is deliberately not worth the nine that a crafting recipe would suggest, because hunger caps at 20 and most of that food would be discarded the moment it was granted, so the duration is where the value went instead. The arithmetic that matters is that an ingot at 4 hunger and 6.4 saturation now stays ahead of the nine nuggets you could split it into, which is the comparison the old numbers had backwards. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • The step-up ability has an off switch (#123).** An origin or class that steps a full block does it whether you want it to or not, and holding shift does not suppress it, so edging up to a drop or lowering yourself onto a ledge walks you straight up the block you were working around. The game offers no way to ask for a step height that yields to sneaking, so the answer is a switch rather than a rule. The Explorer's *Climber's Step*, the Rogue's *Parkour* and the Scout's *Tracker's Stride* now share a *Step Assist* ability that turns the step height off and back on, with a low note for off and a high one for on. It defaults to on, so nothing changes for anyone who never presses it, and the state is saved with the rest of your toggles rather than springing back on at the next login. With it off you climb blocks by jumping, the same as everybody else.

  • Fire-immune origins stop burning on campfires and blazes.** (#129) The immunity checked four damage types by name (standing in fire, being on fire, lava and magma blocks), which left out campfires and both kinds of fireball, so an origin that is supposed to be unburnable took full damage from a blaze and cooked on a campfire like anyone else. It now asks the game's own minecraft:is_fire tag instead of a hand-written list, which covers those cases, agrees with the matching condition that was already using the tag, and picks up fire damage added by other mods without further work.

  • The web editor's form view can turn a default-on setting off.** Any boolean whose default is true could not be set to false from the form view: the row drew itself unchecked while the power actually behaved as switched on, and ticking the box and clearing it again wrote nothing at all, so the setting looked changed and was not. An unset field now seeds from the schema's declared default rather than a flat false. This affected 68 default-true booleans across the shipped power, action and condition schemas.

  • The block editor stops writing fields you never set.** A block widget has to display something, so an optional field the power does not carry gets drawn with a stand-in, and the canvas was writing every one of those back when it saved. One drag of an unrelated block was enough to turn a damage-halving power into total immunity, because modify_damage came back carrying set_total: 0, a field whose own reference entry says to leave it out if you want the multiplied value kept. Nothing on screen looked any different. A leaf still equal to the stand-in the widget had to show is now left out on the way back, and the fields the loaded file genuinely carried are tracked alongside it, so an author who deliberately means a zero keeps it. Powers the canvas cannot draw are put back at their original position rather than at the end, since the order powers are written in is authored data too.

  • An area_of_effect inside a lingering cloud stays with the cloud (#125).** The interval action a lingering area runs is executed as the caster, which is right for kill credit and for anything that spends a resource, but it also meant an area effect nested inside it measured its radius from wherever the caster was standing at that moment. Walk away from your own cloud and the damage walked with you, leaving the cloud drawing particles over nothing. The action still runs as the caster; an area_of_effect inside it now centres on the cloud.

  • The Merchant's restocked trades stop showing as sold out.** The class refills nearby villagers' trades on a timer, but it refilled them server-side only. A trade's sold-out cross is drawn from the copy of the offers the client was handed when the screen opened, so a trade that had just been refilled kept its cross, and the only way to clear it was to close the villager and open it again. The refill now resends the offers to whoever has that villager open, which is what vanilla's own restock does. It sends nothing when nothing was actually refilled, so an open trading screen no longer takes a packet every couple of seconds for the life of the interaction.

  • Ore goes down in creative mode, the way bread always has.** A Caveborn in creative could not eat any of their seven diets, while every vanilla food in the game ate normally, and because the refusal is silent it read as the power being broken rather than as a rule. Our gate asked whether the hunger bar had room, and creative mode is precisely the case where it never does. It now asks the game's own question instead, which is invulnerable or always-edible or genuinely hungry, at both places that had to know, so the two can no longer drift apart. Fixing that surfaced the other half of the same problem: the meal took one from the stack unconditionally, where vanilla food leaves a creative player's stack alone. It now spends the item through the same call vanilla uses, which declines to spend anything for a player with infinite materials. Both halves apply to every edible_item power, not only to the Caveborn's.

  • A slime rehydrates from a water cauldron and from a water bottle.** The moisture bar refilled from water, rain and bubble columns, which is the game's own in-water test, and a water cauldron does not answer to it: a cauldron is a block carrying a level, not a body of water. A slime standing in a full cauldron therefore dried out at exactly the rate of one standing on bare stone, which is the opposite of what anyone builds a cauldron for. Standing in one now refills at the same rate open water does. Drinking a water bottle tops the bar up as well, by half its length, which gives a drying slime something it can carry rather than a source it has to reach. Neither of these is new ground, and that is the point: breath_out_of_fluid has handled the cauldron and the bottle for aquatic origins for some time, and the moisture bar simply never got the same treatment. The bottle amount is water_bottle_refill on the power, so a pack can retune it or set it to 0 to leave water bottles out of it entirely. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:pose holds the player prone, crouched or upright.** A forced pose is the missing piece for a crawling origin, a serpent that never stands, or a form that cannot fit through a full-height door: "pose": "swimming" puts the player flat, which carries the one-block hitbox and the crawl animation everywhere, not only in water. It is a power rather than an action because the pose has to be held and then released, and it takes the usual condition, plus toggleable and default_off and a HUD icon, so a pack can hand the switch to the player. Clearance is deliberately not checked: a forced crawl fits through gaps the player otherwise could not, and whether that is too strong is the pack's call. Releasing it hands the player back to the game, which does check, so nobody ends up standing inside a ceiling. Sleeping, gliding and spin-attack are not offered: those poses carry behaviour a pose alone cannot deliver. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:prevent_entity_render hides entities from the player who has it.** Every living entity matching entity_condition stops being drawn for that player alone; everyone else sees it normally and the entity itself is untouched, so it still moves, still attacks and still blocks the way. Pair it with something that applies glowing for an origin that sees only what it has marked. The condition is evaluated on the server, which is what lets it use status_effect and nbt: a client is never told another entity's effects, so a client-side check would have quietly matched nothing. The hidden set refreshes every five ticks over living entities within view distance, capped at 1024 per player. origins:prevent_entity_render maps onto it, so a legacy pack using it works now rather than loading it as an unsupported no-op.

  • A morph can play the mob's own animations.** neoorigins:trigger_morph_animation names a triggerable animation on the GeckoLib model a player is morphed into, and it plays for everyone who can see them. It needs no dependency and no packet: GeckoLib's own trigger call already routes a client-side entity straight into its animation manager, and the morph is a real client-side entity rather than a static model, so it takes that path for free. One hard limit worth knowing before you plan around it: the only reachable names are the ones the mob's author explicitly registered as triggerable; an unregistered name does nothing at all and logs nothing; and there is no way to discover the list from JSON. Vanilla mobs are not GeckoLib models and do nothing here. AzureLib is shaped the same way and could follow; Citadel is not. See [ACTIONS.md](docs/ACTIONS.md).

  • A morph can run the mob's entity events.** neoorigins:morph_entity_event fires the hook the server normally uses to tell clients a mob just did something, whether that is an iron golem's attack swing, a villager's angry particles or a wolf shaking off water, so a morph reacts like the mob instead of only sharing its silhouette. The names come from Minecraft's own table rather than a hand-copied list, so they track the game version, and a raw id byte is there for modded mobs with events of their own. Three limits are documented rather than papered over: events whose sound plays through the entity itself are silent on a morph, events that set a countdown for the mob's own tick to drain hold that pose instead of playing through it, and particle events that read the mob's movement draw their particles streaking in from the world origin instead. The death byte is refused outright, because on a morph it would fire a client-side death for an entity that was never in the world.

  • set_block places where you aimed.** It was an entity action only, and it placed at the target's feet, so a right-click power aimed at a block changed the ground the player was standing on instead of the block they clicked. It now resolves the position from whatever context it runs in (a block or bonemeal interaction, a projectile or raycast hit, a block_action_at or offset wrapper), and falls back to the actor's own position when there is no block context, which is what it always did. It is also a block-target verb now, so it can be named directly inside block_target_action alongside strip, till, path, grow and transform_block. The keep field, which places only into air, was never documented.

  • item_condition gates right-click powers instead of being dropped.** Apoli's action_on_block_use and action_on_entity_use both take an item_condition meaning "only with this in hand", and the translator never copied it, so a power that was supposed to fire only while holding a specific item fired for whatever the player happened to be carrying. It is carried across now, along with Apoli's newer held_item_condition spelling, and the gate reads the stack out of the interaction rather than only out of a food context. Copying the field alone would have made every one of those powers fail instead, since the gate fails closed and had nothing to read. action_on_block_break, wake_up and bonemeal carry no item gate across. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:using_effective_tool asks whether the swing you are making is a productive one.** It matches Apoli's condition of the same name and takes no fields. It answers two things at once, and the first is the half that is easy to get wrong: it is true only while the player is part-way through breaking a block *and* holding a tool that will actually yield its drops. It is false whenever the player is not mid-break, so it cannot be used to ask "am I holding a pickaxe". A power gated on it fires during mining and at no other time, which makes it the right gate for a mining-flavoured effect and the wrong one for an equipment check. See [CONDITIONS.md](docs/CONDITIONS.md).

  • edible_item can pay a different amount for one part of its set.** The type read a list of items and tags and paid one number for all of them, so anything whose worth varies by form (an ore against its block, an ingot against its nugget) needed a second power, a second tag and a second copy of every field it shared with the first. The new tiers list puts those bands inside the one power. Each entry carries its own items or tags and its own nutrition, with saturation optional and inherited from the power when it is left out. First match wins, so write the narrow bands first, and anything matching none of them falls back to the power's own values. Bands match alongside the top-level lists rather than within them, so a tier can introduce items the power never otherwise mentions. One thing to know before you tune one: saturation is restored as nutrition times the modifier times two, so a band that doubles both grants four times the saturation, which is almost never what was meant. Leaving saturation off is the right default. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • All seven Caveborn diet tags are built out of common tags.** The stone diet listed its ten blocks inside the power, so it was the one diet a pack could not extend without replacing the whole file, and the other six listed vanilla item ids, so a modded metal was not food until somebody added it by hand. Every one of them is a tag now, and every one is a union of NeoForge's c: tags: the six materials take their ingots/, nuggets/, gems/, raw_materials/, ores/ and storage_blocks/ entries, and stone takes #c:stones and #c:cobblestones alongside basalt and blackstone. A modded metal or stone that registers itself where mods normally do is edible with no pack work at all. netherite_scrap is the one literal id left in the set, since NeoForge publishes no common tag for that item. The rebuild closed a gap nobody had reported as such: the refined storage blocks were in none of the old lists, only the raw ones, so a Caveborn could eat a raw iron block and not an iron block. Adding your own item to a tag works exactly as before, and it lands in the matching value band if there is one. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • mod_food_nutrition changes what a meal is worth as it is eaten.** Nutrition could be retuned only through the legacy origins:modify_food power, so a pack working in the native vocabulary had no way to reach it and no event to hang a condition on. action_on_event now carries a mod_food_nutrition event that fires for any food actually eaten, with the item itself in context, so food_item_in_tag and food_item_id both gate it. It runs after modify_food and on whatever that left behind, so a pack can use either or both and neither needs the other to be present. The result is rounded and floored at zero. See [EVENTS.md](docs/EVENTS.md).

  • The in-game creator checks your ids the way the web editor does.** The generated schemas have always carried a pattern for each id-shaped string field, and only the web editor read them: the in-game creator's text rows took anything and left the mistake to surface at load, far from the field that caused it. Each text row now checks its value against the schema's own pattern as you type and shows the same inline complaint the web editor would. It advises rather than blocks, deliberately: the loader is more forgiving than the patterns in a few places (a particle or dimension written without its minecraft: prefix loads fine), and an editor that refuses what the game accepts is the failure shape 2.2.26 already removed once. Nothing you can load is ever locked out of saving.

  • model_color stacks, and can be switched off from the config.** Two tints active at once resolved to whichever one the capability set happened to hand over first, which is not something a pack can predict or arrange around, so an origin with more than one conditional tint had a colour nobody could design. Overlapping tints now average their channels: two produce their midpoint, three their mean, and every client watching sees the same thing. The type also honours the shared enabled flag, so a server owner can drop a single tint from power_overrides.toml while leaving the power that carries it in place.

  • Four legacy power mappings that never landed now do.** origins:aquatic, origins:conduit_power_on_land and origins:nether_spawn were each mapped onto a NeoOrigins type that does not exist, so a legacy pack using any of them had the power silently dropped: nothing failed, nothing was logged, the origin simply came up missing an ability. origins:creative_flight was worse in a quieter way. It named a type that does exist, just the wrong one, and had done so for five months. All four are retargeted, and every remaining legacy mapping has been walked end to end on both sides rather than only on the name a pack writes, so the mappings that ship are the ones that resolve.

  • An action_on_event that names an event which does not exist no longer costs the whole power.** An unrecognised event fails the power's decode outright, so a pack that guessed a plausible spelling did not end up with a hook that misbehaved, it ended up with nothing, the ability simply missing from the origin with no sign of why. item_use_start is the common guess, and it now resolves to item_use, which already fires at exactly that moment for anything with a use duration: a shield going up, a bow drawn, food raised. The accepted spellings are offered by both editors as well, so a pack the game loads is never marked invalid on the way in. A name matching nothing at all still fails loudly rather than being quietly swallowed. Only a spelling whose target already fires at the same instant is ever added this way, since a name pointed at a different moment would load and then do the wrong thing, which is worse than the refusal it replaced. See [EVENTS.md](docs/EVENTS.md).

  • A pack that writes neoorigins: where it meant origins: is salvaged rather than dropped.** The compatibility power types answer to origins: and apace: and nothing else, so an author writing neoorigins:action_on_item_use got the power dropped outright, with no line in the log explaining why. It is an easy mistake to make, since the mod is called NeoOrigins and every other type they write really does start with neoorigins:. Such a type is now rewritten back to origins:, but only when the name is one the compatibility layer actually handles and there is no native type of that name, so the 34 names that exist in both vocabularies keep resolving natively. The "unknown power type" warning is more useful too: powers, actions and conditions share a namespace and a naming style, so it now tells you which of the three an unrecognised id actually belongs to.

  • The loot function 1.20.5 deleted no longer takes the whole table down with it.** minecraft:set_nbt is gone, and a loot table naming it fails to parse outright, which cascades into every function and advancement that referenced the table, so items a legacy pack was supposed to hand out simply never arrived, with the failure logged somewhere far from the cause. It is retargeted to minecraft:set_custom_data, which takes the identical field, as the file is read. It is not an NBT-to-components converter and does not pretend to be: a blob carrying a key that became a real data component is left exactly as it was and reported, so the table still fails, but it fails loudly instead of quietly handing out an item with its enchantments missing.

  • A legacy starting_equipment written with a singular stack grants it.** Packs in the wild are written with both spellings; NeoOrigins read only the plural, so a power using the singular was skipped and gave the player nothing, without an error. Both spellings are read now, with the plural winning where a pack has somehow written both. See [COMPATIBILITY.md](docs/COMPATIBILITY.md).

  • Item NBT paths that step through the deleted tag field are repointed.** 1.20.5 removed tag from item stacks, and this is the worst shape of breakage a pack can carry: a path like SelectedItem.tag.Foo still parses and still runs; it just resolves to nothing, so neither the command parser nor a load-time check can see anything wrong and the pack fails silently in game. Both spellings are repaired (the dot path, including subscripts, and the brace form inside a selector), and this one runs unconditionally rather than behind a parse check, because on 1.21 no item stack carries a tag field in any context, so there is no valid path of that shape to break. Quoted text is skipped and the commands whose payload is free text are excluded, so a tellraw that happens to mention one is left alone.

  • set_block reaches legacy packs that used it as a block action.** In Apoli it is a block action and places at the block the power was aimed at. Because the translator flattens a block action into an entity action, adding the block-side verb alone would not have reached these packs at all; the fix is the context resolution above, which is what makes the flattened form land in the right place.

  • A legacy repeating action that names no interval fires once a second, not twenty times.** Apoli's action_over_time defaults its interval to 20 ticks, and packs lean on that: leaving the field out is normal upstream. Our compatibility layer defaulted it to 1, so such a power ran its action on every tick, which is twenty heals, twenty particle bursts or twenty command executions a second, and a pack tuned around the upstream pace ran twenty times hot with nothing in its file to show why. The default is now 20, matching Apoli and matching our own condition_passive, which has said 20 all along. A power that writes its own interval is untouched.

  • The compat layer's night-vision and diet mappings outlive the alias table.** Five well-known Origins powers (night_vision, cat_vision, water_vision, carnivore, vegetarian) were compiled into two retired NeoOrigins type names that only still load because the legacy remap catches them on the way in, and that remap is scheduled to go. They now emit the canonical forms directly: an ambient, particle-free persistent_effect for the visions, and an event-cancelling action_on_event diet gate for the two food rules, each byte-matching what the remap produced. Nothing changes in game, which is the point: when the aliases retire, these five keep working instead of being the surprise.

  • Two condition ids that never existed stop being claimed as supported.** neoorigins:lava and neoorigins:water sat in the compat condition catalogue with no implementation behind them, put there by a build-time audit that misread the fluid ids inside submerged_in and fluid_height as condition types. A pack writing one was told nothing, since the id was "known", and the condition then failed anyway. Both are gone, the audit no longer manufactures them, and writing one now earns the ordinary unknown-type warning that points you at in_water, in_lava and submerged_in, which are the conditions that exist.

  • The game starts again if you have The One Probe installed.** This one blocked the mod outright rather than degrading it, and it took no unusual setup to hit: installing TOP alongside NeoOrigins was enough. TOP publishes its version as 1.21_neo-12.0.8, and NeoForge compares version ranges piece by piece from the left, so our lower bound of 12 was tested against the leading 1 of the Minecraft version and failed every time. The 12.0.8 was never reached. The message named the right numbers and still made no sense to read: "only supports theoneprobe 12 or above. Currently, theoneprobe is 1.21_neo-12.0.8". NeoForge enforces a range even on an optional dependency, so this was a hard stop at startup. The bound is gone, and it was never doing anything: the integration is already behind a check for whether TOP is loaded, with every TOP-specific reference confined to its own package, so an old or missing TOP cannot reach the code either way.

  • Dragon Survival and the origin picker stop knocking each other off the screen.** Both mods open a screen when you join, Dragon Survival when its species-choice setting is on and NeoOrigins because the server asked for a pick, and whichever arrived second replaced the first. That is how players were being thrown out of the origin picker, and because it was a race, which screen you lost was not even consistent between joins. The old setting was a plain on/off switch whose two positions were "leave the race alone" and "cancel Dragon Survival's screen outright", so neither of them was what most people wanted. It is now compat.dragon_species_screens, with three positions: DEFER, the new default, holds Dragon Survival's screen back and opens it the moment the origin picker is finished, so neither mod loses its screen; SUPPRESS cancels species screens, as the old "on" did; ALLOW never interferes, as the old "off" did. The interception runs both ways, so it does not matter which mod wins the race. Under DEFER and ALLOW, a species screen you opened yourself (from an altar, the inventory button or a command) is left alone; only one that would trample the picker is caught. Dragon Survival's appearance editor, skins, abilities and inventory are never touched under any setting. It is a client setting, so nothing changes on the server or in Dragon Survival's own config. See [COMPATIBILITY.md](docs/COMPATIBILITY.md).

  • Three client-config defaults were documented as their opposites.** hud_ability_display defaults to COOLDOWNS_AND_TOGGLES and was written as ALL_ACTIVE_ABILITIES, default_sort defaults to MANUAL and was written as CLASS, and always_show_icon was described as having no effect under the default mode when the default mode is exactly where it matters. All three are the shape of error that costs nothing at load and shows up as a HUD or a picker that does not look the way the page said it would. See [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • Origin layers merge additively, not by replacement.** The cookbook told authors that a second pack's layer file replaces the origins array and that they should therefore copy the full list across, which is both wrong and the opposite of the sentence immediately before it in the same paragraph. Layers merge by appending, deduplicated by id, with "replace": true as the opt-out. Copying the full list was at best redundant and at worst a maintenance trap, since the copy goes stale the moment the original pack adds an origin. The ordering rule is spelled out alongside it: display order comes from each origin's own order field, not from position in the array. See [COOKBOOK.md](docs/COOKBOOK.md).

  • The legacy-pack repairs are written down.** [COMPATIBILITY.md](docs/COMPATIBILITY.md) gains a section covering every syntax-level repair applied while a 1.19/1.20 pack is read, what each one does, and what is deliberately not covered. That last part is the one that matters when a pack still misbehaves. SkullOwner is called out by name: it became the profile component, it is not in the mapped set, and a legacy pack handing out a named player head gets a blank one with no warning.

  • starting_equipment's plural form is documented.** The type has taken a stacks array for some time and the reference described only the single-item shape, so multi-item kits were being written as several powers. The two shapes do not combine, since a non-empty stacks ignores the root item entirely, and one grant_id seals the whole bundle, so a single bad item id is worth planning around. Both are now spelled out with a worked example. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • prevent_entity_render and the evolution prompt describe what the code does.** The former hides living entities only, so boats, minecarts, item frames and dropped items were never candidates despite the page saying every entity was. The latter had no written description of when the prompt appears or what declining does; [EVOLUTION.md](docs/EVOLUTION.md) now has one, and [KUBEJS.md](docs/KUBEJS.md) lists the evolutionDeclined event beside it with the conditions under which it fires.

  • An Orb of Origin does reset your evolution, whatever the page said.** [EVOLUTION.md](docs/EVOLUTION.md) claimed the orb left essence kills, tier and a declined tier untouched, and that only two things could clear a decline. Spending an orb clears all three fields, so three things clear a decline, not two. This is worth calling out rather than quietly fixing, because the cookbook had it right on the same page-set: the two documents contradicted each other, and if you planned around the wrong one, an orb has been resetting more than you expected all along.

  • A native active_ability can use a named hotkey, whatever the reference said.** [POWER_TYPES.md](docs/POWER_TYPES.md) and [API.md](docs/API.md) both stated it could not, and sent authors off to rewrite the power as an Apoli-style origins:active_self to get one. It was never true: key is not on the codec, but the loader reads it out of the power's own JSON for every active power, native ones included, and binds it like any other. Both denials are gone and key now has a row in the active_ability table. neoorigins:toggle went the other way and has lost the field: it declared key, so both editors offered it and the schema accepted it, but a toggle is not an active power and a keypress had nothing to run even once it arrived. The toggle section says so now, and points at the active_ability that flips it.

  • The power reference's field tables were re-read against the codecs.** Four sections listed fields the codec never reads or carried no table at all, and three types had no section anywhere: apugli:action_on_jump, apugli:action_on_target_death and action_over_time. Eleven fields were marked required that are not, and each now says what actually happens instead, which is rarely nothing: a modifier seam given neither modifier nor modifiers is not refused by the schema, but the loader drops the whole power rather than leaving the multiplier sitting at 1.0. Two entries were simply false. biome_buff with no biome_tag does not apply everywhere, it applies nowhere, the default being an empty tag that matches no biome; and the root amplifier on the persistent_effect family overrides the first effects entry alone rather than cascading onto all of them, winning even over one that entry sets for itself. enabled, the per-power kill switch, is written up on the six types that take it. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • The rest of the reference was re-read against the code, not against the older prose.** Four more claims did not survive it. The Caveborn's diet section listed five eating powers when there are seven. The copper tint was described as green-orange; it is orange. The burning-under-Emerald-Reprieve note explained itself with a rule about fire immunity that is not how the game works: Fire Resistance cancels fire damage and never puts the fire out, and it is the sunlight power re-lighting you each second that keeps you alight. And the compatibility page promised that a Dragon Survival species screen you opened yourself always behaves as it would without NeoOrigins installed, which holds under DEFER and ALLOW but not under SUPPRESS. Two sentences describing what Apoli itself declares have been rewritten to describe only what NeoOrigins does, since we cannot verify the first kind and that is exactly how the others got in.

  • gameplay.toml and admin.toml have reference pages at last.** Two of the four config files had none, so the options between them (the Orb's XP cost formula, random assignment, the evolution kill thresholds, ocean-origin survival tuning, the command-power blacklist, dimension restrictions) were configurable and written down nowhere but the file's own comments. [GAMEPLAY_CONFIG.md](docs/GAMEPLAY_CONFIG.md) and [ADMIN_CONFIG.md](docs/ADMIN_CONFIG.md) now cover every section, key, default and range. [CONTENT_CONFIG.md](docs/CONTENT_CONFIG.md) also stops calling all four files server configs, because only content.toml is one: it alone is synced to clients and overridable per world, while the other three load early, apply to the whole install, and enforce server-side. The distinction decides where you edit and whether a per-world copy will be honoured, which is exactly the thing to get right on a page about config files.

  • The event contexts say what a handler is actually handed.** Eight of them had drifted: hit_taken, kill and projectile_hit all carry the live, cancellable event in their context and the page did not say so; death's context *is* the event; land has a second dispatch site (a per-tick ground-contact detector for landings the fall path never sees) where the context is empty and cancel_event deliberately does nothing; and the paragraph on mod_break_speed described a removed event as though it still fired. Alongside them, add_velocity gains its missing space row with all eight Apoli reference frames, dash its set_velocity, and spawn_projectile's count admits it defaults to 1 for a plain projectile and 2 for an orb trail. See [EVENTS.md](docs/EVENTS.md) and [ACTIONS.md](docs/ACTIONS.md).

  • The API index is exhaustive again, and now provably.** [API.md](docs/API.md) promises a complete list of everything registered, and it had fallen to roughly two thirds on conditions and actions: 21 conditions, 17 actions and 17 events were registered, working and listed nowhere, so a reader took the absence as the feature not existing, which is the same failure 2.2.25 fixed for power types. All four lists were regenerated from the registries (122 power types, 108 conditions, 95 actions, 51 events, with the 26.2 build counting two types and one action fewer, the KubeJS-backed ids it does not ship) and verified by script in both directions, so an id in the code is on the page and an id on the page is in the code, with zero exceptions either way. The page's description of how legacy packs are translated was corrected in the same pass: origins: and apace: go through the translator, apoli: and apugli: are canonicalized to origins: first, and the legacy alias table covers only the odd cross-mod id rather than being the pipeline itself.
> A compatibility and origin-content release, led by a startup failure. Installing The One Probe alongside NeoOrigins was enough to be refused at launch, over a version bound that compared our lower bound against the wrong part of TOP's version string. It had never protected anything, and it is gone. Six new pack-author capabilities follow, most of them out of getting one legacy Origins pack to run untouched: a morph can play one of the mob's own animations, or run one of the entity events the game uses to make a mob swing, sparkle or shake; pose holds the player prone, crouched or upright, which is what a crawling or a serpentine origin needs; prevent_entity_render hides entities from a single player; using_effective_tool asks whether the swing a player is making is a productive one; and mod_food_nutrition changes what a meal is worth as it goes down. The origin picker gains two more shapes for the two things people kept asking for (#127): a carousel for anyone who preferred the original mod's chooser, and a grid of cards for anyone who wanted a whole layer visible at once, with the two-panel screen unchanged as the default. Dragon Survival no longer fights it for the screen at join either: whichever mod loses that race now has its screen held and reopened instead of dropped. The Caveborn get copper and emerald diets filling the two gaps in the ore ladder, water breathing and fire resistance to go with them, a wash of the ore's own colour for as long as its effect runs, and descriptions that finally admit the diets refuse on a full stomach. All seven of their diets are rebuilt on common tags, so a modded metal or stone is food without a pack touching anything, and what you eat is now worth what it is: a block feeds twice what an ingot does and holds its effect three times as long, a nugget is worth almost nothing, and ore goes down in creative mode the way bread always has. A pack written for 1.19 or 1.20 gets four more of its breakages repaired as the file is read, with no edit to the zip, and four legacy power mappings that dropped their power silently now land, with the rest walked end to end so none of them can. Alongside those: declining an evolution keeps it declined, fire-immune origins stop burning on campfires and blazes (#129), a fire-resistant helmet shades without wearing out, a slime rehydrates from a water cauldron and from a water bottle, the step-up ability gained an off switch for everyone it kept walking up the block they meant to step down from (#123), the web editor's form view stops refusing to switch off a setting that defaults to on while its block canvas stops writing back fields nobody ever set, an event name a pack guessed at costs it a hook rather than the whole power, a legacy repeating action that names no interval paces itself at Apoli's once a second instead of every tick, the in-game creator checks its ids as strictly as the web editor always has, and the reference has been re-read against the loader in the places it had drifted, gaining pages for the two config files that never had one.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • The origin picker comes in three shapes now (#127).** It had one: a scrolling list on the left, details on the right. Players who came from the original Origins mod kept asking for its one-at-a-time chooser back, and others wanted a whole layer visible at once. Both are choices rather than replacements. The client setting ui.picker_layout takes TWO_PANEL, the default and unchanged; CAROUSEL, one origin at a time with arrows to step through them; and GRID, a wall of origin cards that fits as many as your window allows and pages the rest. A card carries the icon, name and impact dots but has no room for a description, so clicking one opens the same full detail read the other layouts use, and Back returns you to the wall. The search box filters the wall as you type, and the arrow keys page it unless the box has focus. The carousel is a NeoOrigins screen shaped like the original rather than a copy of it, so it keeps whatever theme you are running instead of the old dirt-background window, and browsing in it *is* selecting: Confirm always applies to whatever is on screen. Layout and skin are independent. theme_override and classic_picker_style still control colour and font, and any skin works with any layout. See [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • A fire-resistant helmet shades you without wearing out.** Origins that burn in daylight wear down the helmet protecting them, which is right for an ordinary hat and wrong for one that already survives lava. Netherite helmets now shade for free, the way unbreakable ones always did. It keys off the item's own fire-resistant property rather than a list of names, so a modded helmet that grants itself the same property is covered without us naming it.

  • Declining an evolution keeps it declined.** The prompt to evolve was re-offered on every kill after the requirement was met, so refusing it bought a few seconds of quiet and nothing more, and a player near their next tier spent the rest of the session being asked. A decline is now remembered against the tier it was made at, and nothing re-offers that tier: not more kills, not a relog. It stays quiet until you ask for it yourself with /neoorigins evolve accept, an operator sets your tier, or you spend an Orb of Origin, which resets the ladder to zero outright. The tier is not lost by declining it, only muted, and accepting clears the record so the tier above it prompts normally once its own threshold is reached. See [EVOLUTION.md](docs/EVOLUTION.md).

  • The Caveborn's diets say they will not go down on a full stomach.** All eight of them (the Caveborn's seven ores and the Nether origin's fungal diet) refuse when the hunger bar is already full, which is deliberate and matches ordinary food. Nothing said so, and the refusal is completely silent: no message, no eating animation, no sound, so a player at full hunger reads it as the power being broken rather than as being full. Every one of those descriptions now ends by saying it, in all twelve languages the mod ships. The stone diet's list also gained cobbled deepslate, which it has always eaten and never mentioned.

  • The Caveborn eats copper, and copper lets them breathe.** The diet ladder jumped straight from stone to iron, skipping the ore a player turns up more of than any other on the way down. Copper now feeds for 3 hunger and 0.6 saturation, which places it neatly between stone and iron, and eating it grants Water Breathing I for a minute. The effect is picked for the gap it fills rather than for the flavour: a Caveborn sees in the dark, ignores the drop and mines bare-handed, but a flooded ravine or a drowned mineshaft stopped them the same as anybody, and copper is what they are already picking up on the way to one. Ingots, raw copper, both ores and both kinds of copper block all count. Like the other six diets it is a tag, neoorigins:caveborn_eat_copper, so a pack adds a modded copper to it without replacing the power.

  • The Caveborn takes on the colour of the ore they ate.** Six of the seven diets grant an effect, and while one was running there was nothing about the player that showed which one, least of all to anybody looking at them from the other end of the shaft. The model is now washed in that ore's own colour for as long as its effect lasts, sampled from the item rather than picked by hand: copper orange, iron pale grey, gold yellow, diamond cyan, emerald green, netherite a dark brown. Eat two and the colours average. Nothing about the buffs changes, and each of the six is its own switch in power_overrides.toml, from caveborn_copper_tint through caveborn_netherite_tint, so a server that wants the diets without the colour can turn off as many of them as it likes. Stone has no tint, having no effect to signal. See [ORIGINS.md](docs/ORIGINS.md).

  • Emerald is the seventh diet, and it buys a trip to the surface.** The Caveborn's one real cost is that daylight burns them, and nothing in the origin ever answered it: you either stayed under or you took the damage. Emerald now feeds for 7 hunger and 1.4 saturation, filling the gap the ladder had left between diamond and netherite, and eating one grants Fire Resistance for five minutes. The sunlight damage was always dealt as fire, so this cancels it outright rather than blunting it, and it covers lava on the way back down, which is the other thing that kills miners. Emeralds, both emerald ores and blocks of emerald all count, through neoorigins:caveborn_eat_emerald. You will still catch fire: Fire Resistance cancels the damage but does not put the flames out, and the sunlight power re-lights you every second you are exposed, so those five minutes above ground are spent visibly alight and entirely unharmed. Step into shade or water and the burn runs out on its own. Emerald is the one Caveborn diet with a renewable supply, since a villager will trade for it.

  • A block of ore feeds a Caveborn like a block, and a nugget like a nugget.** Every form of a material was worth the same meal, so a raw iron block and a single ingot both restored 4 hunger, and the block was worth eating only if you had nothing else to hand. The nugget was the inverse and the worse half of it: nine nuggets restored 36 hunger where the ingot they make restored 4, and nether gold ore drops nuggets rather than ingots, so the least valuable form of gold in the game was by a wide margin the most efficient food in the origin. What you eat is now worth what it is. A block feeds twice what an ingot or gem does and holds its effect three times as long; a nugget feeds 1 hunger with no saturation and buys fifteen seconds. A block is deliberately not worth the nine that a crafting recipe would suggest, because hunger caps at 20 and most of that food would be discarded the moment it was granted, so the duration is where the value went instead. The arithmetic that matters is that an ingot at 4 hunger and 6.4 saturation now stays ahead of the nine nuggets you could split it into, which is the comparison the old numbers had backwards. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • The step-up ability has an off switch (#123).** An origin or class that steps a full block does it whether you want it to or not, and holding shift does not suppress it, so edging up to a drop or lowering yourself onto a ledge walks you straight up the block you were working around. The game offers no way to ask for a step height that yields to sneaking, so the answer is a switch rather than a rule. The Explorer's *Climber's Step*, the Rogue's *Parkour* and the Scout's *Tracker's Stride* now share a *Step Assist* ability that turns the step height off and back on, with a low note for off and a high one for on. It defaults to on, so nothing changes for anyone who never presses it, and the state is saved with the rest of your toggles rather than springing back on at the next login. With it off you climb blocks by jumping, the same as everybody else.

  • Fire-immune origins stop burning on campfires and blazes.** (#129) The immunity checked four damage types by name (standing in fire, being on fire, lava and magma blocks), which left out campfires and both kinds of fireball, so an origin that is supposed to be unburnable took full damage from a blaze and cooked on a campfire like anyone else. It now asks the game's own minecraft:is_fire tag instead of a hand-written list, which covers those cases, agrees with the matching condition that was already using the tag, and picks up fire damage added by other mods without further work.

  • The web editor's form view can turn a default-on setting off.** Any boolean whose default is true could not be set to false from the form view: the row drew itself unchecked while the power actually behaved as switched on, and ticking the box and clearing it again wrote nothing at all, so the setting looked changed and was not. An unset field now seeds from the schema's declared default rather than a flat false. This affected 68 default-true booleans across the shipped power, action and condition schemas.

  • The block editor stops writing fields you never set.** A block widget has to display something, so an optional field the power does not carry gets drawn with a stand-in, and the canvas was writing every one of those back when it saved. One drag of an unrelated block was enough to turn a damage-halving power into total immunity, because modify_damage came back carrying set_total: 0, a field whose own reference entry says to leave it out if you want the multiplied value kept. Nothing on screen looked any different. A leaf still equal to the stand-in the widget had to show is now left out on the way back, and the fields the loaded file genuinely carried are tracked alongside it, so an author who deliberately means a zero keeps it. Powers the canvas cannot draw are put back at their original position rather than at the end, since the order powers are written in is authored data too.

  • An area_of_effect inside a lingering cloud stays with the cloud (#125).** The interval action a lingering area runs is executed as the caster, which is right for kill credit and for anything that spends a resource, but it also meant an area effect nested inside it measured its radius from wherever the caster was standing at that moment. Walk away from your own cloud and the damage walked with you, leaving the cloud drawing particles over nothing. The action still runs as the caster; an area_of_effect inside it now centres on the cloud.

  • The Merchant's restocked trades stop showing as sold out.** The class refills nearby villagers' trades on a timer, but it refilled them server-side only. A trade's sold-out cross is drawn from the copy of the offers the client was handed when the screen opened, so a trade that had just been refilled kept its cross, and the only way to clear it was to close the villager and open it again. The refill now resends the offers to whoever has that villager open, which is what vanilla's own restock does. It sends nothing when nothing was actually refilled, so an open trading screen no longer takes a packet every couple of seconds for the life of the interaction.

  • Ore goes down in creative mode, the way bread always has.** A Caveborn in creative could not eat any of their seven diets, while every vanilla food in the game ate normally, and because the refusal is silent it read as the power being broken rather than as a rule. Our gate asked whether the hunger bar had room, and creative mode is precisely the case where it never does. It now asks the game's own question instead, which is invulnerable or always-edible or genuinely hungry, at both places that had to know, so the two can no longer drift apart. Fixing that surfaced the other half of the same problem: the meal took one from the stack unconditionally, where vanilla food leaves a creative player's stack alone. It now spends the item through the same call vanilla uses, which declines to spend anything for a player with infinite materials. Both halves apply to every edible_item power, not only to the Caveborn's.

  • A slime rehydrates from a water cauldron and from a water bottle.** The moisture bar refilled from water, rain and bubble columns, which is the game's own in-water test, and a water cauldron does not answer to it: a cauldron is a block carrying a level, not a body of water. A slime standing in a full cauldron therefore dried out at exactly the rate of one standing on bare stone, which is the opposite of what anyone builds a cauldron for. Standing in one now refills at the same rate open water does. Drinking a water bottle tops the bar up as well, by half its length, which gives a drying slime something it can carry rather than a source it has to reach. Neither of these is new ground, and that is the point: breath_out_of_fluid has handled the cauldron and the bottle for aquatic origins for some time, and the moisture bar simply never got the same treatment. The bottle amount is water_bottle_refill on the power, so a pack can retune it or set it to 0 to leave water bottles out of it entirely. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:pose holds the player prone, crouched or upright.** A forced pose is the missing piece for a crawling origin, a serpent that never stands, or a form that cannot fit through a full-height door: "pose": "swimming" puts the player flat, which carries the one-block hitbox and the crawl animation everywhere, not only in water. It is a power rather than an action because the pose has to be held and then released, and it takes the usual condition, plus toggleable and default_off and a HUD icon, so a pack can hand the switch to the player. Clearance is deliberately not checked: a forced crawl fits through gaps the player otherwise could not, and whether that is too strong is the pack's call. Releasing it hands the player back to the game, which does check, so nobody ends up standing inside a ceiling. Sleeping, gliding and spin-attack are not offered: those poses carry behaviour a pose alone cannot deliver. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:prevent_entity_render hides entities from the player who has it.** Every living entity matching entity_condition stops being drawn for that player alone; everyone else sees it normally and the entity itself is untouched, so it still moves, still attacks and still blocks the way. Pair it with something that applies glowing for an origin that sees only what it has marked. The condition is evaluated on the server, which is what lets it use status_effect and nbt: a client is never told another entity's effects, so a client-side check would have quietly matched nothing. The hidden set refreshes every five ticks over living entities within view distance, capped at 1024 per player. origins:prevent_entity_render maps onto it, so a legacy pack using it works now rather than loading it as an unsupported no-op.

  • A morph can play the mob's own animations.** neoorigins:trigger_morph_animation names a triggerable animation on the GeckoLib model a player is morphed into, and it plays for everyone who can see them. It needs no dependency and no packet: GeckoLib's own trigger call already routes a client-side entity straight into its animation manager, and the morph is a real client-side entity rather than a static model, so it takes that path for free. One hard limit worth knowing before you plan around it: the only reachable names are the ones the mob's author explicitly registered as triggerable; an unregistered name does nothing at all and logs nothing; and there is no way to discover the list from JSON. Vanilla mobs are not GeckoLib models and do nothing here. AzureLib is shaped the same way and could follow; Citadel is not. See [ACTIONS.md](docs/ACTIONS.md).

  • A morph can run the mob's entity events.** neoorigins:morph_entity_event fires the hook the server normally uses to tell clients a mob just did something, whether that is an iron golem's attack swing, a villager's angry particles or a wolf shaking off water, so a morph reacts like the mob instead of only sharing its silhouette. The names come from Minecraft's own table rather than a hand-copied list, so they track the game version, and a raw id byte is there for modded mobs with events of their own. Three limits are documented rather than papered over: events whose sound plays through the entity itself are silent on a morph, events that set a countdown for the mob's own tick to drain hold that pose instead of playing through it, and particle events that read the mob's movement draw their particles streaking in from the world origin instead. The death byte is refused outright, because on a morph it would fire a client-side death for an entity that was never in the world.

  • set_block places where you aimed.** It was an entity action only, and it placed at the target's feet, so a right-click power aimed at a block changed the ground the player was standing on instead of the block they clicked. It now resolves the position from whatever context it runs in (a block or bonemeal interaction, a projectile or raycast hit, a block_action_at or offset wrapper), and falls back to the actor's own position when there is no block context, which is what it always did. It is also a block-target verb now, so it can be named directly inside block_target_action alongside strip, till, path, grow and transform_block. The keep field, which places only into air, was never documented.

  • item_condition gates right-click powers instead of being dropped.** Apoli's action_on_block_use and action_on_entity_use both take an item_condition meaning "only with this in hand", and the translator never copied it, so a power that was supposed to fire only while holding a specific item fired for whatever the player happened to be carrying. It is carried across now, along with Apoli's newer held_item_condition spelling, and the gate reads the stack out of the interaction rather than only out of a food context. Copying the field alone would have made every one of those powers fail instead, since the gate fails closed and had nothing to read. action_on_block_break, wake_up and bonemeal carry no item gate across. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • neoorigins:using_effective_tool asks whether the swing you are making is a productive one.** It matches Apoli's condition of the same name and takes no fields. It answers two things at once, and the first is the half that is easy to get wrong: it is true only while the player is part-way through breaking a block *and* holding a tool that will actually yield its drops. It is false whenever the player is not mid-break, so it cannot be used to ask "am I holding a pickaxe". A power gated on it fires during mining and at no other time, which makes it the right gate for a mining-flavoured effect and the wrong one for an equipment check. See [CONDITIONS.md](docs/CONDITIONS.md).

  • edible_item can pay a different amount for one part of its set.** The type read a list of items and tags and paid one number for all of them, so anything whose worth varies by form (an ore against its block, an ingot against its nugget) needed a second power, a second tag and a second copy of every field it shared with the first. The new tiers list puts those bands inside the one power. Each entry carries its own items or tags and its own nutrition, with saturation optional and inherited from the power when it is left out. First match wins, so write the narrow bands first, and anything matching none of them falls back to the power's own values. Bands match alongside the top-level lists rather than within them, so a tier can introduce items the power never otherwise mentions. One thing to know before you tune one: saturation is restored as nutrition times the modifier times two, so a band that doubles both grants four times the saturation, which is almost never what was meant. Leaving saturation off is the right default. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • All seven Caveborn diet tags are built out of common tags.** The stone diet listed its ten blocks inside the power, so it was the one diet a pack could not extend without replacing the whole file, and the other six listed vanilla item ids, so a modded metal was not food until somebody added it by hand. Every one of them is a tag now, and every one is a union of NeoForge's c: tags: the six materials take their ingots/, nuggets/, gems/, raw_materials/, ores/ and storage_blocks/ entries, and stone takes #c:stones and #c:cobblestones alongside basalt and blackstone. A modded metal or stone that registers itself where mods normally do is edible with no pack work at all. netherite_scrap is the one literal id left in the set, since NeoForge publishes no common tag for that item. The rebuild closed a gap nobody had reported as such: the refined storage blocks were in none of the old lists, only the raw ones, so a Caveborn could eat a raw iron block and not an iron block. Adding your own item to a tag works exactly as before, and it lands in the matching value band if there is one. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • mod_food_nutrition changes what a meal is worth as it is eaten.** Nutrition could be retuned only through the legacy origins:modify_food power, so a pack working in the native vocabulary had no way to reach it and no event to hang a condition on. action_on_event now carries a mod_food_nutrition event that fires for any food actually eaten, with the item itself in context, so food_item_in_tag and food_item_id both gate it. It runs after modify_food and on whatever that left behind, so a pack can use either or both and neither needs the other to be present. The result is rounded and floored at zero. See [EVENTS.md](docs/EVENTS.md).

  • The in-game creator checks your ids the way the web editor does.** The generated schemas have always carried a pattern for each id-shaped string field, and only the web editor read them: the in-game creator's text rows took anything and left the mistake to surface at load, far from the field that caused it. Each text row now checks its value against the schema's own pattern as you type and shows the same inline complaint the web editor would. It advises rather than blocks, deliberately: the loader is more forgiving than the patterns in a few places (a particle or dimension written without its minecraft: prefix loads fine), and an editor that refuses what the game accepts is the failure shape 2.2.26 already removed once. Nothing you can load is ever locked out of saving.

  • model_color stacks, and can be switched off from the config.** Two tints active at once resolved to whichever one the capability set happened to hand over first, which is not something a pack can predict or arrange around, so an origin with more than one conditional tint had a colour nobody could design. Overlapping tints now average their channels: two produce their midpoint, three their mean, and every client watching sees the same thing. The type also honours the shared enabled flag, so a server owner can drop a single tint from power_overrides.toml while leaving the power that carries it in place.

  • Four legacy power mappings that never landed now do.** origins:aquatic, origins:conduit_power_on_land and origins:nether_spawn were each mapped onto a NeoOrigins type that does not exist, so a legacy pack using any of them had the power silently dropped: nothing failed, nothing was logged, the origin simply came up missing an ability. origins:creative_flight was worse in a quieter way. It named a type that does exist, just the wrong one, and had done so for five months. All four are retargeted, and every remaining legacy mapping has been walked end to end on both sides rather than only on the name a pack writes, so the mappings that ship are the ones that resolve.

  • An action_on_event that names an event which does not exist no longer costs the whole power.** An unrecognised event fails the power's decode outright, so a pack that guessed a plausible spelling did not end up with a hook that misbehaved, it ended up with nothing, the ability simply missing from the origin with no sign of why. item_use_start is the common guess, and it now resolves to item_use, which already fires at exactly that moment for anything with a use duration: a shield going up, a bow drawn, food raised. The accepted spellings are offered by both editors as well, so a pack the game loads is never marked invalid on the way in. A name matching nothing at all still fails loudly rather than being quietly swallowed. Only a spelling whose target already fires at the same instant is ever added this way, since a name pointed at a different moment would load and then do the wrong thing, which is worse than the refusal it replaced. See [EVENTS.md](docs/EVENTS.md).

  • A pack that writes neoorigins: where it meant origins: is salvaged rather than dropped.** The compatibility power types answer to origins: and apace: and nothing else, so an author writing neoorigins:action_on_item_use got the power dropped outright, with no line in the log explaining why. It is an easy mistake to make, since the mod is called NeoOrigins and every other type they write really does start with neoorigins:. Such a type is now rewritten back to origins:, but only when the name is one the compatibility layer actually handles and there is no native type of that name, so the 34 names that exist in both vocabularies keep resolving natively. The "unknown power type" warning is more useful too: powers, actions and conditions share a namespace and a naming style, so it now tells you which of the three an unrecognised id actually belongs to.

  • The loot function 1.20.5 deleted no longer takes the whole table down with it.** minecraft:set_nbt is gone, and a loot table naming it fails to parse outright, which cascades into every function and advancement that referenced the table, so items a legacy pack was supposed to hand out simply never arrived, with the failure logged somewhere far from the cause. It is retargeted to minecraft:set_custom_data, which takes the identical field, as the file is read. It is not an NBT-to-components converter and does not pretend to be: a blob carrying a key that became a real data component is left exactly as it was and reported, so the table still fails, but it fails loudly instead of quietly handing out an item with its enchantments missing.

  • A legacy starting_equipment written with a singular stack grants it.** Packs in the wild are written with both spellings; NeoOrigins read only the plural, so a power using the singular was skipped and gave the player nothing, without an error. Both spellings are read now, with the plural winning where a pack has somehow written both. See [COMPATIBILITY.md](docs/COMPATIBILITY.md).

  • Item NBT paths that step through the deleted tag field are repointed.** 1.20.5 removed tag from item stacks, and this is the worst shape of breakage a pack can carry: a path like SelectedItem.tag.Foo still parses and still runs; it just resolves to nothing, so neither the command parser nor a load-time check can see anything wrong and the pack fails silently in game. Both spellings are repaired (the dot path, including subscripts, and the brace form inside a selector), and this one runs unconditionally rather than behind a parse check, because on 1.21 no item stack carries a tag field in any context, so there is no valid path of that shape to break. Quoted text is skipped and the commands whose payload is free text are excluded, so a tellraw that happens to mention one is left alone.

  • set_block reaches legacy packs that used it as a block action.** In Apoli it is a block action and places at the block the power was aimed at. Because the translator flattens a block action into an entity action, adding the block-side verb alone would not have reached these packs at all; the fix is the context resolution above, which is what makes the flattened form land in the right place.

  • A legacy repeating action that names no interval fires once a second, not twenty times.** Apoli's action_over_time defaults its interval to 20 ticks, and packs lean on that: leaving the field out is normal upstream. Our compatibility layer defaulted it to 1, so such a power ran its action on every tick, which is twenty heals, twenty particle bursts or twenty command executions a second, and a pack tuned around the upstream pace ran twenty times hot with nothing in its file to show why. The default is now 20, matching Apoli and matching our own condition_passive, which has said 20 all along. A power that writes its own interval is untouched.

  • The compat layer's night-vision and diet mappings outlive the alias table.** Five well-known Origins powers (night_vision, cat_vision, water_vision, carnivore, vegetarian) were compiled into two retired NeoOrigins type names that only still load because the legacy remap catches them on the way in, and that remap is scheduled to go. They now emit the canonical forms directly: an ambient, particle-free persistent_effect for the visions, and an event-cancelling action_on_event diet gate for the two food rules, each byte-matching what the remap produced. Nothing changes in game, which is the point: when the aliases retire, these five keep working instead of being the surprise.

  • Two condition ids that never existed stop being claimed as supported.** neoorigins:lava and neoorigins:water sat in the compat condition catalogue with no implementation behind them, put there by a build-time audit that misread the fluid ids inside submerged_in and fluid_height as condition types. A pack writing one was told nothing, since the id was "known", and the condition then failed anyway. Both are gone, the audit no longer manufactures them, and writing one now earns the ordinary unknown-type warning that points you at in_water, in_lava and submerged_in, which are the conditions that exist.

  • The game starts again if you have The One Probe installed.** This one blocked the mod outright rather than degrading it, and it took no unusual setup to hit: installing TOP alongside NeoOrigins was enough. TOP publishes its version as 1.21_neo-12.0.8, and NeoForge compares version ranges piece by piece from the left, so our lower bound of 12 was tested against the leading 1 of the Minecraft version and failed every time. The 12.0.8 was never reached. The message named the right numbers and still made no sense to read: "only supports theoneprobe 12 or above. Currently, theoneprobe is 1.21_neo-12.0.8". NeoForge enforces a range even on an optional dependency, so this was a hard stop at startup. The bound is gone, and it was never doing anything: the integration is already behind a check for whether TOP is loaded, with every TOP-specific reference confined to its own package, so an old or missing TOP cannot reach the code either way.

  • Dragon Survival and the origin picker stop knocking each other off the screen.** Both mods open a screen when you join, Dragon Survival when its species-choice setting is on and NeoOrigins because the server asked for a pick, and whichever arrived second replaced the first. That is how players were being thrown out of the origin picker, and because it was a race, which screen you lost was not even consistent between joins. The old setting was a plain on/off switch whose two positions were "leave the race alone" and "cancel Dragon Survival's screen outright", so neither of them was what most people wanted. It is now compat.dragon_species_screens, with three positions: DEFER, the new default, holds Dragon Survival's screen back and opens it the moment the origin picker is finished, so neither mod loses its screen; SUPPRESS cancels species screens, as the old "on" did; ALLOW never interferes, as the old "off" did. The interception runs both ways, so it does not matter which mod wins the race. Under DEFER and ALLOW, a species screen you opened yourself (from an altar, the inventory button or a command) is left alone; only one that would trample the picker is caught. Dragon Survival's appearance editor, skins, abilities and inventory are never touched under any setting. It is a client setting, so nothing changes on the server or in Dragon Survival's own config. See [COMPATIBILITY.md](docs/COMPATIBILITY.md).

  • Three client-config defaults were documented as their opposites.** hud_ability_display defaults to COOLDOWNS_AND_TOGGLES and was written as ALL_ACTIVE_ABILITIES, default_sort defaults to MANUAL and was written as CLASS, and always_show_icon was described as having no effect under the default mode when the default mode is exactly where it matters. All three are the shape of error that costs nothing at load and shows up as a HUD or a picker that does not look the way the page said it would. See [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • Origin layers merge additively, not by replacement.** The cookbook told authors that a second pack's layer file replaces the origins array and that they should therefore copy the full list across, which is both wrong and the opposite of the sentence immediately before it in the same paragraph. Layers merge by appending, deduplicated by id, with "replace": true as the opt-out. Copying the full list was at best redundant and at worst a maintenance trap, since the copy goes stale the moment the original pack adds an origin. The ordering rule is spelled out alongside it: display order comes from each origin's own order field, not from position in the array. See [COOKBOOK.md](docs/COOKBOOK.md).

  • The legacy-pack repairs are written down.** [COMPATIBILITY.md](docs/COMPATIBILITY.md) gains a section covering every syntax-level repair applied while a 1.19/1.20 pack is read, what each one does, and what is deliberately not covered. That last part is the one that matters when a pack still misbehaves. SkullOwner is called out by name: it became the profile component, it is not in the mapped set, and a legacy pack handing out a named player head gets a blank one with no warning.

  • starting_equipment's plural form is documented.** The type has taken a stacks array for some time and the reference described only the single-item shape, so multi-item kits were being written as several powers. The two shapes do not combine, since a non-empty stacks ignores the root item entirely, and one grant_id seals the whole bundle, so a single bad item id is worth planning around. Both are now spelled out with a worked example. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • prevent_entity_render and the evolution prompt describe what the code does.** The former hides living entities only, so boats, minecarts, item frames and dropped items were never candidates despite the page saying every entity was. The latter had no written description of when the prompt appears or what declining does; [EVOLUTION.md](docs/EVOLUTION.md) now has one, and [KUBEJS.md](docs/KUBEJS.md) lists the evolutionDeclined event beside it with the conditions under which it fires.

  • An Orb of Origin does reset your evolution, whatever the page said.** [EVOLUTION.md](docs/EVOLUTION.md) claimed the orb left essence kills, tier and a declined tier untouched, and that only two things could clear a decline. Spending an orb clears all three fields, so three things clear a decline, not two. This is worth calling out rather than quietly fixing, because the cookbook had it right on the same page-set: the two documents contradicted each other, and if you planned around the wrong one, an orb has been resetting more than you expected all along.

  • A native active_ability can use a named hotkey, whatever the reference said.** [POWER_TYPES.md](docs/POWER_TYPES.md) and [API.md](docs/API.md) both stated it could not, and sent authors off to rewrite the power as an Apoli-style origins:active_self to get one. It was never true: key is not on the codec, but the loader reads it out of the power's own JSON for every active power, native ones included, and binds it like any other. Both denials are gone and key now has a row in the active_ability table. neoorigins:toggle went the other way and has lost the field: it declared key, so both editors offered it and the schema accepted it, but a toggle is not an active power and a keypress had nothing to run even once it arrived. The toggle section says so now, and points at the active_ability that flips it.

  • The power reference's field tables were re-read against the codecs.** Four sections listed fields the codec never reads or carried no table at all, and three types had no section anywhere: apugli:action_on_jump, apugli:action_on_target_death and action_over_time. Eleven fields were marked required that are not, and each now says what actually happens instead, which is rarely nothing: a modifier seam given neither modifier nor modifiers is not refused by the schema, but the loader drops the whole power rather than leaving the multiplier sitting at 1.0. Two entries were simply false. biome_buff with no biome_tag does not apply everywhere, it applies nowhere, the default being an empty tag that matches no biome; and the root amplifier on the persistent_effect family overrides the first effects entry alone rather than cascading onto all of them, winning even over one that entry sets for itself. enabled, the per-power kill switch, is written up on the six types that take it. See [POWER_TYPES.md](docs/POWER_TYPES.md).

  • The rest of the reference was re-read against the code, not against the older prose.** Four more claims did not survive it. The Caveborn's diet section listed five eating powers when there are seven. The copper tint was described as green-orange; it is orange. The burning-under-Emerald-Reprieve note explained itself with a rule about fire immunity that is not how the game works: Fire Resistance cancels fire damage and never puts the fire out, and it is the sunlight power re-lighting you each second that keeps you alight. And the compatibility page promised that a Dragon Survival species screen you opened yourself always behaves as it would without NeoOrigins installed, which holds under DEFER and ALLOW but not under SUPPRESS. Two sentences describing what Apoli itself declares have been rewritten to describe only what NeoOrigins does, since we cannot verify the first kind and that is exactly how the others got in.

  • gameplay.toml and admin.toml have reference pages at last.** Two of the four config files had none, so the options between them (the Orb's XP cost formula, random assignment, the evolution kill thresholds, ocean-origin survival tuning, the command-power blacklist, dimension restrictions) were configurable and written down nowhere but the file's own comments. [GAMEPLAY_CONFIG.md](docs/GAMEPLAY_CONFIG.md) and [ADMIN_CONFIG.md](docs/ADMIN_CONFIG.md) now cover every section, key, default and range. [CONTENT_CONFIG.md](docs/CONTENT_CONFIG.md) also stops calling all four files server configs, because only content.toml is one: it alone is synced to clients and overridable per world, while the other three load early, apply to the whole install, and enforce server-side. The distinction decides where you edit and whether a per-world copy will be honoured, which is exactly the thing to get right on a page about config files.

  • The event contexts say what a handler is actually handed.** Eight of them had drifted: hit_taken, kill and projectile_hit all carry the live, cancellable event in their context and the page did not say so; death's context *is* the event; land has a second dispatch site (a per-tick ground-contact detector for landings the fall path never sees) where the context is empty and cancel_event deliberately does nothing; and the paragraph on mod_break_speed described a removed event as though it still fired. Alongside them, add_velocity gains its missing space row with all eight Apoli reference frames, dash its set_velocity, and spawn_projectile's count admits it defaults to 1 for a plain projectile and 2 for an orb trail. See [EVENTS.md](docs/EVENTS.md) and [ACTIONS.md](docs/ACTIONS.md).

  • The API index is exhaustive again, and now provably.** [API.md](docs/API.md) promises a complete list of everything registered, and it had fallen to roughly two thirds on conditions and actions: 21 conditions, 17 actions and 17 events were registered, working and listed nowhere, so a reader took the absence as the feature not existing, which is the same failure 2.2.25 fixed for power types. All four lists were regenerated from the registries (122 power types, 108 conditions, 95 actions, 51 events, with the 26.2 build counting two types and one action fewer, the KubeJS-backed ids it does not ship) and verified by script in both directions, so an id in the code is on the page and an id on the page is in the code, with zero exceptions either way. The page's description of how legacy packs are translated was corrected in the same pass: origins: and apace: go through the translator, apoli: and apugli: are canonicalized to origins: first, and the legacy alias table covers only the odd cross-mod id rather than being the pipeline itself.
## v2.2.25

> A documentation release, with a run of server-reported fixes riding along. The API reference index linked barely half of its power types. entity_model, restrict_items and creative_flight were documented in full and reachable from nowhere, so a reader who looked one up found nothing and reasonably concluded the feature did not exist. Every type has a row now. The verification pass that followed went back over the reference against the code rather than against the older prose, and it turned into the larger half of the release: fifteen summaries were wrong or misleading about what their class does, five documented fields do not exist under those names, six defaults were wrong, and one power type advertised three verbs that all silently teleport the player somewhere random. The fixes are unrelated to each other and all came from live servers. An invisibility power with a condition on it hid the body and left the armor and held item floating — the unconditional ones always worked, which is why it survived so long. A misconfigured attribute_modifier could fill an operator's log for as long as a player held the power, several lines a second, with a message that never said what was wrong. An origin with an empty slot in its power list did not load at all. And a keep-inventory origin dropped the armor it had just promised to keep, but only once your inventory was full, which is what made it look random. A second pass over the older reports found three of them worse than described: a grounded player wearing wings was cutting the elytra sound off for everyone gliding past, the clamp that keeps a phasing origin out of the few blocks it is barred from was collided against every block in range instead, and a player being ridden was the one person in the world who could not see their own rider. Two editor corrections close gaps left open in 2.2.24, and on the compatibility side an Artifacts umbrella finally keeps the sun and the rain off.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

### Changes

  • Ore counts as food for the Caveborn.** The four tags listing what a Caveborn can eat besides stone held ingots, nuggets, gems, raw metal and netherite scrap, and no ore at all, so a Caveborn standing at a freshly exposed vein had nothing in front of it that it could eat. Iron, gold and diamond ore now qualify, along with their deepslate forms, and so do nether gold ore, ancient debris and the raw iron and raw gold blocks. One thing worth knowing: ore is a placeable block. Aiming at a surface places it, as it always did, so eating one means aiming where it cannot be placed. That is the same rule the Caveborn's stone diet has always followed. [ORIGINS.md](docs/ORIGINS.md) lists the tags.
  • The four aquatic origins say what keeps them from drying out.** Dries Out told you two things — air ticks down while you are out of water, and staying too long suffocates you — so every way of stopping the drain was something you had to be told about or stumble into. The description now names them — rain, standing in a water cauldron, Water Breathing, and an active conduit nearby. Abyssal, Kraken, Merling and Siren all read the same, in every language the mod ships. [POWER_TYPES.md](docs/POWER_TYPES.md) says the same beside the type.

### Bug Fixes

  • An invisibility power with a condition hides armor and held items, not only the body.** Powers that turn invisibility on unconditionally were always fine, which is what kept this hidden. The armor-hiding flag was read from the condition-gated capability set, and it only reached the client when something else triggered a power sync — never at the moment the condition itself flipped. So a conditioned power froze the flag at whatever it was worth at the last sync: the body vanished on cue, and the boots and the sword stayed. The flag now comes from the power itself rather than from its live condition state, which is what it always meant ("hide the armor *when* invisible"), and the client already re-checks whether you are actually invisible before hiding anything. Invisibility itself is unchanged. Cosmetic elytra wings and morph state are left alone on purpose: nothing on the client re-checks those, so treating them the same way would draw wings on a player whose condition is not met.
  • A misconfigured attribute_modifier reports once instead of every few ticks.** The power re-tries the attachment whenever it should be active and is not. That is the right behaviour while the attachment can still succeed, and a permanent log flood once it cannot. Naming something that is not an attribute is the common way to get there, and the old message never said so. It does now. If the id is a mob effect — haste, night_vision and friends are the usual ones — it can never resolve as an attribute, and what the effect actually wants is an apply_effect action. The warning also names the prefixes that were tried, and repeats for the same id are suppressed.
  • An origin with an empty entry in its power list loads instead of vanishing.** A single null in powers failed the whole origin, so it never reached the picker, and all you got was one line repeating "not a string" once per empty slot, naming the origin but neither the field nor the position that caused it. The empty entries are now dropped and the origin loads with every power actually named in it, with one warning giving the origin id and how many were skipped. upgrades and the add / remove lists inside tier_powers are covered the same way. A trailing comma or a deleted line in a hand-edited file is the usual cause, so it is still worth fixing the file rather than leaving it to the warning.
  • The creator keybinds stop writing a server warning on every press.** Player X requested the mob creator without permission was a keybind collision, not something to act on. The open-creator keys ship unbound, the client sends a packet per press, and the server logged each refusal at warning level — so a player whose key overlapped something they use in normal play filled the operator's log just by playing. Both open paths log at debug now. Refusing a save or an apply still warns, on purpose: those are only reachable from inside the creator screen, so a refusal there is worth an operator's attention.
  • The elytra loop stops when you land, rather than starting again twenty times a second.** True of every origin that flies without an elytra in its chest slot. The guard that ends a flight ran its whole body on every tick the player was on the ground, in water or riding, instead of only on the tick the flight actually ended. On your own client that meant the fall-flying flag going on and straight back off once per tick, and the client starts a fresh elytra sound on the rising edge, so the loops stacked and got louder the longer you stood still. The server side reached further than the player it belonged to: it was broadcasting a stop-sound to every player within 64 blocks, twenty times a second, so standing on the ground with wings silenced the elytra of anyone genuinely gliding past. Both halves now fire once, when flight ends.
  • A phasing origin stops sticking inside ordinary blocks.** Phasing powers carry a short list of blocks they are *not* allowed through, and the clamp that enforces it asked the game's general-purpose collision routine to check the player against that list. That routine always adds the surrounding world to whatever list it is handed, so the clamp collided the player against every block within reach — the exact opposite of a blacklist — and a Wraith that strayed near one blocked block froze solid in stone it was entitled to walk through. The clamp now checks the listed blocks and nothing else. The Wraith's own description has been corrected alongside it: it said the Wraith cannot pass obsidian at all, where the apex form is stopped only by bedrock.
  • A player being ridden can see who is riding them.** Everyone else could. A player is never in their own tracking list, so the update naming their passengers was the one packet that never reached them, and their own client went on drawing an empty back until something unrelated forced a refresh. Consent-based mounts already worked around this by resending it by hand, but that is not the only way to end up ridden: the Apoli-compatible mount action, the built-in one, the mount power and summoned minions all take a seat directly, and none had that workaround. The resend now happens where a passenger is seated, so every route is covered.
  • Keep-inventory puts everything back where it was, instead of dropping your armor once your bag is full.** Reported from a live server, and the fullness is the whole of it. Everything kept at death went back through the routine that adds an item to your inventory, and that routine only fills the main thirty-six slots. With the wildcard * covering every slot you have, the first thirty-six kept stacks refilled the main inventory, and the four armor pieces and the offhand item had nowhere left to go, so the power dropped them on the floor — the one outcome it exists to prevent, and it only happened to players carrying enough to trigger it, which is why it looked arbitrary. Even with room to spare it was never quite right, since armor came back loose in the bag rather than worn. Kept items now return to the exact slot they were taken from, which is empty by construction, because dying is what emptied it. Armor comes back on, the hotbar keeps its layout, and a full inventory can no longer push anything onto the ground.
  • An origin that cannot find its spawn dimension says which one it wanted.** A spawn_location naming a dimension that no loaded world provides gave up without a word, which in game reads as picking the origin and simply not being moved, and in the log reads as nothing at all. The warning now names the dimension and the player, so a typo or a missing mod is the first thing you see rather than something to go hunting for.
  • An active conduit keeps an aquatic origin from drying out on land.** The exemption had been in place for months and could never once have fired. The game only hands Conduit Power to a player who is already in water or rain, so an Abyssal, Kraken, Merling or Siren standing on dry ground beside a conduit was never given the effect the exemption goes looking for. The one case that appeared to work was walking ashore near one: the effect carried out of the water, lasted about thirteen seconds, then lapsed with nothing to renew it. That is why it read as working sometimes rather than never. A conduit now reaches a drying-out player anywhere inside the radius it already uses for everything else, and the bubble row refills while you stand in it instead of holding at whatever it had drained down to. Pack authors get the same reprieve in attribute_modifier's on_land condition, which was written to stand down under Conduit Power and never once had the occasion to. It does now — for a player whose origin also carries a drying-out power, since that is who a conduit reaches on dry land. An origin without one is unchanged. See [POWER_TYPES.md](docs/POWER_TYPES.md).

### Pack Author Features

  • Block conditions written as all_of and any_of stop being marked invalid.** Both are the Apoli 2.9+ spellings of and and or, and the loader has always read them. The block condition catalogue behind the editors, and the generated schema, listed only the short pair, producing the one failure shape an author cannot debug from inside the game: the file works, and the editor says it does not. 2.2.24 documented the workaround of writing and and or there instead, which you no longer need. Both spellings are now in the catalogue, the schema and the editor pickers, and nothing you have already written changes behaviour. See [CONDITIONS.md](docs/CONDITIONS.md).
  • status_effect's ambient and show_particles advertise the loader's real defaults.** They were declared the wrong way round — ambient as defaulting to false and show_particles to true, where the loader does the opposite. A form field or a generated schema told you the inverse of what omitting the key would do. These two are exactly the pair where a wrong default costs nothing at load and shows up only as particles you did not expect, once you are already in game. The reference tables were right all along and are unchanged.
  • The example pack drops a tick_action power that never fired.** The Specter's Dimensional Escape declared action_type: teleport_on_damage on a type that dispatches nothing, so the origin advertised a teleport that could not happen, and it was the only worked example of the type an author had to copy. It is removed rather than rewritten, since condition_passive is what to copy for anything that runs on an interval. The Specter's other nine powers are unchanged. [MIGRATION.md](docs/MIGRATION.md) says what to write instead.

### Compatibility (Mod Integrations)

  • An Artifacts umbrella keeps the sun and the rain off.** Origins that burn in daylight and origins that take rain damage both look for an umbrella before they hurt you, but only Vampires Need Umbrellas ever counted as one, so an Artifacts umbrella held in plain sight did nothing. It works now, held in either hand or worn in a trinket slot, and one umbrella covers both weaknesses rather than only the one it was carried for. What counts as an umbrella is a new neoorigins:umbrellas item tag, so a pack can add any other mod's umbrella to it without touching code. [COMPATIBILITY.md](docs/COMPATIBILITY.md) documents the tag.
  • Keep-inventory covers trinket slots, and a kept trinket waits for its slot rather than being dumped in your bag.** On 26.1 and 26.2 the coverage is new: slots took only the vanilla categories there, so a Curios ring matched nothing and dropped on death like anything else. All three versions now read curio, accessory or trinket as meaning every trinket slot, or a specific slot id such as ring or necklace, and the wildcard * includes them. A kept trinket goes back into the slot it died in. Those mods rebuild their slot counts on their own schedule after a respawn, so a slot that is not writable the instant you land is usually a matter of timing rather than a slot that is genuinely gone: the trinket is held and retried for three seconds instead of being given up on, and only after that does it fall back to your inventory, and to the ground only if that is full as well. Logging out part-way through settles it the same way rather than losing it. Curios is read on every supported version; Accessories on 1.21.1 only, as it has no 26.1 or 26.2 build. [POWER_TYPES.md](docs/POWER_TYPES.md) documents the slot names.
  • equipped_item with equipment_slot: accessory reads your trinkets on 26.1 and 26.2.** 1.21.1 already did. A slot name the mapper does not recognise falls through to the mainhand, so on those two versions the condition quietly answered about whatever the player happened to be holding. It never errored and never logged, which is the hardest kind of wrong condition to find: the file looks correct, and the power simply behaves as though you had asked about the held item. It now inspects equipped trinkets, with an optional slot_type to narrow to a single named slot. [CONDITIONS.md](docs/CONDITIONS.md) documents both fields.

### Documentation

  • The API reference index lists every power type.** It listed barely half of them, so a reader looking up entity_model, restrict_items or creative_flight found no row and no link. Every documented type has one now, including a new group for the mod-compatibility types. Four rows were wrong rather than missing: sneaky, stealth, no_projectile_divergence and tick_action sat under retired aliases, but none is an alias: all four are registered types with their own implementations. They move to their live categories, and night_vision's replacement is named correctly as persistent_effect. See [API.md](docs/API.md).
  • Fifteen power-type summaries corrected against the code.** Each was re-read against its implementation class rather than against the older prose. The ones that change what you would write: tick_action dispatches nothing at all, so "run an action on a repeating interval" described a feature that is not there; no_projectile_divergence pointed at minecraft:projectile_accuracy, an attribute that does not exist, so the suggested modifier could never resolve; wraith_phase never grants flight; mount needs no consent unless the server config asks for it; and loot_pool_grant fires once per grant_id. The rest tighten wording that was true and misleading — modify_flight_speed leaves elytra gliding alone, mob_behavior adds goals rather than replacing the vanilla AI, restrict_items has two independent opt-ins, extra_inventory sizes in slots rather than rows, and slime_level_hp tracks the current level rather than resetting on death. [POWER_TYPES.md](docs/POWER_TYPES.md) carries all fifteen.
  • Field tables and examples the loader does not match.** Five documented fields do not exist under the names given: knockback_modifier's direction, thorns_aura's reflect_ratio (the real key is return_ratio), action_on_hit_taken's amount, persistent_effect's refresh_interval, and the enchantment item condition's min_level (the real keys are comparison and compare_to). Worse, action_on_hit_taken advertised restore_health, restore_hunger and grant_effect, none of which has an implementation: all three fall through to the default and teleport the player somewhere random — and the worked example asked for grant_effect, so it did the one thing its own title said it would not. Six defaults were wrong, and explode's destruction_type was documented backwards: absent means no blocks break, not the reverse. The action_on_event example used slot and item on an equipped-item condition, which reads equipment_slot and item_condition, so it matched any mainhand item rather than the wooden sword it claimed to test. The corrections span [POWER_TYPES.md](docs/POWER_TYPES.md), [CONDITIONS.md](docs/CONDITIONS.md) and [ACTIONS.md](docs/ACTIONS.md).
  • The pack folder layout shows every folder a pack can carry.** It listed three, so morphs, entity groups, mob origins and global powers were invisible to anyone reading the pack reference, and the morph feature was documented in full and reachable from nowhere else. The layout now shows all of them, each pointing at its own doc, with a note that the original Origins mod layout still loads unchanged. A hand-written morph.schema.json comes with it, so the editors read morph files like every other type. See [PACK_FORMAT.md](docs/PACK_FORMAT.md).
  • action_over_time and tick_action point somewhere useful.** action_over_time was a registered alias mentioned nowhere at all — not in the reference, not in the retired table, not in the migration guide. It loaded and ran exactly as written, and an author who inherited one had nothing to read about it. It has a migration entry now, alongside the other types that fold into condition_passive. tick_action pointed at action_on_event, where condition_passive is the closer replacement and takes the same interval field. See [MIGRATION.md](docs/MIGRATION.md).
  • Four reference links that never resolved.** The links to condition_passive, block_target_action and the cookbook's toggleable-abilities recipe all landed at the top of the page instead of at the section, with the cookbook link broken in two different files. All four now land on the section they name.
  • What holds off a dry-out, said the same way everywhere it is written down.** The origin list had *Dries Out* as damage out of water in hot biomes, where the power is not biome-gated at all: air drains anywhere on land, and you suffocate when it empties. The power type reference named Water Breathing and Conduit Power without ever saying that rain, a bubble column or standing in a water cauldron counts as being in the water — and it read as though those reprieves applied to fluid: lava as well, which is the bare check with none of them. The cookbook's moisture note gains Water Breathing and Create's backtank beside the rest. [ORIGINS.md](docs/ORIGINS.md), [POWER_TYPES.md](docs/POWER_TYPES.md) and [COOKBOOK.md](docs/COOKBOOK.md) now agree.
  • The mob origin schema is published alongside the other four.** mob_origin.schema.json sits in the schema folder, in the README's table and in its IDE-validator mapping, and in the API reference's validator list, so an editor pointed at data/*/origins/mob_origins/*.json now checks the file the way it already checked origins, layers, powers and morphs. See [schema/README.md](docs/schema/README.md).
  • Attribution for the bundled spectral sword travels with the mod.** The blades spawn_sword_rain summons are a third-party model under Creative Commons Attribution 4.0, and that licence asks for credit to travel with the file. A CREDITS.md at the root names the author, the source and the licence it is used under, and points at the bundled font licensing beside it.
> A documentation release with a handful of server-reported fixes and one compatibility addition riding along. The API reference index linked barely half of its power types, so entity_model, restrict_items and creative_flight were fully documented and reachable from nowhere: a reader who looked one up found nothing and reasonably concluded the feature did not exist. Every type has a row now. A verification pass then went back over the reference against the code rather than against the older prose, and the result is the larger half of this release: fifteen summaries were wrong or misleading about what their class does, five documented fields do not exist under those names, six defaults were wrong, and one power type advertised three verbs that all silently teleport the player somewhere random instead.
>
> The fixes are unrelated to each other and all came from live servers. An invisibility power with a condition on it hid the body and left the armor and held item floating, which is why it survived so long: the unconditional ones always worked. A misconfigured attribute_modifier could fill an operator's log for as long as a player held the power, several lines a second, with a message that never said what was actually wrong. And an origin with an empty slot in its power list did not load at all: absent from the picker, with the log naming neither the origin's fields nor the slot. A keep-inventory origin dropped the armor it had just promised to keep, though only once the player's inventory was full, which is what made it read as random.
>
> A second pass over the older reports found three of them worse than described. A grounded player wearing wings was not only hearing the elytra loop restart under their own feet, they were cutting the sound off for everyone gliding past them. The clamp that keeps a phasing origin out of the few blocks it is not allowed through was collided against every block in range instead, so a Wraith near one blocked block stuck fast in ordinary stone. And a player being ridden was the one person in the world who could not see their own rider.
>
> Two editor corrections close gaps left open in 2.2.24. Block conditions written as all_of / any_of no longer get marked invalid by an editor when the game reads them perfectly well, and status_effect's two particle fields stop advertising the opposite of the loader's real defaults.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Ore counts as food for the Caveborn.** The four tags listing what a Caveborn can eat besides stone held ingots, nuggets, gems, raw metal and netherite scrap, and no ore whatsoever, so a Caveborn standing at a freshly exposed vein had nothing in front of it that it could eat. Iron, gold and diamond ore now qualify along with their deepslate forms, and so do nether gold ore, ancient debris and the raw iron and raw gold blocks. Worth knowing: ore is a placeable block, so aiming at a surface places it as it always did, and eating one means aiming where it cannot be placed. That is the same rule the Caveborn's stone diet has always followed.
  • An Artifacts umbrella keeps the sun and the rain off.** Origins that burn in daylight and origins that take rain damage both look for an umbrella before they hurt you, but only Vampires Need Umbrellas ever counted as one, so an Artifacts umbrella held in plain sight did nothing to help. It works now, held in either hand or worn in a trinket slot, and one umbrella covers both weaknesses rather than only the one it was carried for. What counts as an umbrella is a new neoorigins:umbrellas item tag, so a pack can add any other mod's umbrella to it without touching code.
  • The four aquatic origins say what keeps them from drying out.** Dries Out told you only that air ticks down while you are out of water and that staying too long suffocates you, so every way of stopping the drain was something you had to be told about or stumble into. The description now names them: rain, standing in a water cauldron, Water Breathing, and an active conduit nearby. Abyssal, Kraken, Merling and Siren all read the same, in every language the mod ships.

  • An invisibility power with a condition hides armor and held items, not only the body.** Powers that turn invisibility on unconditionally were always fine, which is what kept this hidden. The armor-hiding flag was read from the condition-gated capability set and only sent to the client when something else triggered a power sync, never at the moment the condition itself flipped, so a conditioned power froze the flag at whatever it was worth at the last sync: the body vanished on cue and the boots and the sword stayed. The flag now comes from the power itself rather than from its live condition state, which is what it always meant ("hide the armor *when* invisible"), and the client already re-checks whether you are actually invisible before hiding anything. Invisibility itself is unchanged. Cosmetic elytra wings and morph state are deliberately left as they were: nothing on the client re-checks those, so treating them the same way would draw wings on a player whose condition is not met.
  • A misconfigured attribute_modifier reports once instead of every few ticks.** The power re-tries the attachment whenever it should be active and is not. That is the right behaviour while the attachment can still succeed, and a permanent log flood once it cannot. Naming something that is not an attribute is the common way to reach that state, and the old message did not say so. It does now: if the id is a mob effect (haste, night_vision and friends are the usual ones), it can never resolve as an attribute, and the effect wants an apply_effect action instead. The warning also names the prefixes that were tried, and repeats for the same id are suppressed.
  • An origin with an empty entry in its power list loads instead of vanishing.** A single null in powers failed the whole origin, so it never reached the picker, leaving a single line that repeated "not a string" once per empty slot, naming the origin but neither the field nor the position that caused it. The empty entries are now dropped and the origin loads with every power actually named in it, with one warning giving the origin id and how many were skipped. upgrades and the add / remove lists inside tier_powers are covered the same way. A trailing comma or a deleted line in a hand-edited file is the usual cause, so it is still worth fixing the file rather than leaving it to the warning.
  • The creator keybinds stop writing a server warning on every press.** Player X requested the mob creator without permission was a keybind collision rather than anything to act on: the open-creator keys ship unbound, the client sends a packet per press, and the server logged each refusal at warning level, so a player whose key overlapped something they use in normal play filled the operator's log by playing normally. Both open paths log at debug now. Refusing a save or an apply still warns, on purpose: those are only reachable from inside the creator screen, so a refusal there is worth an operator's attention.
  • The elytra loop stops when you land, rather than starting again twenty times a second.** True of every origin that flies without an elytra in its chest slot. The guard that ends a flight ran its whole body on every tick the player was on the ground, in water or riding, instead of only on the tick the flight actually ended. On your own client that meant the fall-flying flag being switched on and straight back off once per tick, and the client starts a fresh elytra sound on the rising edge, so the loops stacked and got louder the longer you stood still. The server side reached further than the player it belonged to: it was broadcasting a stop-sound to every player within 64 blocks, twenty times a second, so standing on the ground with wings silenced the elytra of anyone genuinely gliding past. Both halves now fire once, when flight ends.
  • A phasing origin stops sticking inside ordinary blocks.** Phasing powers carry a short list of blocks they are *not* allowed through, and the clamp that enforces it was asking the game's general-purpose collision routine to check the player against that list. That routine always adds the surrounding world to whatever list it is handed, so the clamp collided the player against every block within reach, which is the exact opposite of a blacklist, and a Wraith that strayed near one blocked block froze solid in stone it was entitled to walk through. The clamp now checks the listed blocks and nothing else. The Wraith's own description has been corrected alongside it: it said the Wraith cannot pass obsidian at all, where the apex form is stopped only by bedrock.
  • A player being ridden can see who is riding them.** Everyone else could. A player is never in their own tracking list, so the update naming their passengers was the one packet that never reached them, and their own client went on drawing an empty back until something unrelated forced a refresh. Consent-based mounts already worked around this by resending it by hand, but that is not the only way to end up ridden: the Apoli-compatible mount action, the built-in one, the mount power and summoned minions all take a seat directly and had no such workaround. The resend now happens where a passenger is seated, so every route is covered.
  • Keep-inventory puts everything back where it was, instead of dropping your armor once your bag is full.** Reported from a live server, and the fullness is the whole of it: everything kept at death went back through the routine that adds an item to your inventory, and that routine only fills the main thirty-six slots. With the wildcard * covering every slot you have, the first thirty-six kept stacks refilled the main inventory, and the four armor pieces and the offhand item had nowhere left to go, so the power dropped them on the floor. That is the one outcome it exists to prevent, and it only happened to players carrying enough to trigger it, which is why it looked arbitrary. Even with room to spare it was never quite right, since armor came back loose in the bag rather than worn. Kept items now return to the exact slot they were taken from, which is empty by construction because dying is what emptied it: armor comes back on, the hotbar keeps its layout, and a full inventory can no longer push anything onto the ground.
  • Keep-inventory covers trinket slots, and a kept trinket waits for its slot rather than being dumped in your bag.** On 26.1 and 26.2 the coverage is new: slots took only the vanilla categories there, so a Curios ring matched nothing and dropped on death like anything else. All three versions now read curio, accessory or trinket as meaning every trinket slot, or a specific slot id such as ring or necklace, and the wildcard * includes them. A kept trinket goes back into the slot it died in. Those mods rebuild their slot counts on their own schedule after a respawn, so a slot that is not writable the instant you land is usually a matter of timing rather than a slot that is genuinely gone: the trinket is held and retried for three seconds instead of being given up on, and only after that does it fall back to your inventory, and to the ground only if that is full as well. Logging out part-way through settles it the same way rather than losing it. Curios is read on every supported version; Accessories on 1.21.1 only, as it has no 26.1 or 26.2 build.
  • An origin that cannot find its spawn dimension says which one it wanted.** A spawn_location naming a dimension that no loaded world provides gave up without a word, which reads in game as picking the origin and simply not being moved, and reads in the log as nothing at all. The warning now names the dimension and the player, so a typo or a missing mod is the first thing you see rather than something to go hunting for.
  • An active conduit keeps an aquatic origin from drying out on land.** The exemption had been in place for months and could never once have fired: the game only hands Conduit Power to a player who is already in water or rain, so an Abyssal, Kraken, Merling or Siren standing on dry ground beside a conduit was never given the effect the exemption goes looking for. The one case that appeared to work was walking ashore near one, where the effect carried out of the water lasted about thirteen seconds and then lapsed with nothing to renew it, which is why it read as working sometimes rather than never. A conduit now reaches a drying-out player anywhere inside the radius it already uses for everything else, and the bubble row refills while you stand in it instead of holding at whatever it had drained down to. Pack authors see the same reprieve in attribute_modifier's on_land condition, which was written to stand down under Conduit Power and never once had the occasion to: it now does, for a player whose origin also carries a drying-out power, since that is who a conduit reaches on dry land. An origin without one is unchanged.

  • Block conditions written as all_of and any_of stop being marked invalid.** Both are the Apoli 2.9+ spellings of and and or, and the loader has always read them; the block condition catalogue behind the editors and the generated schema listed only the short pair. The effect was the one failure shape an author cannot debug from inside the game: the file works, and the editor says it does not. 2.2.24 documented the workaround of writing and and or there instead, which is no longer necessary. Both spellings are now in the catalogue, the schema and the editor pickers, and nothing you have already written changes behaviour.
  • status_effect's ambient and show_particles advertise the loader's real defaults.** They were declared the wrong way round, ambient as defaulting to false and show_particles to true where the loader does the opposite, so a form field or a generated schema told you the inverse of what omitting the key would do. These two are exactly the pair where a wrong default costs nothing at load and shows up only as particles you did not expect once you are in game. The reference tables were already right and are unchanged.
  • equipped_item with equipment_slot: accessory reads your trinkets on 26.1 and 26.2.** 1.21.1 already did. A slot name the mapper does not recognise falls through to the mainhand, so on those two versions the condition quietly answered about whatever the player happened to be holding. It never errored and never logged, which is the hardest kind of wrong condition to find: the file looks correct and the power simply behaves as though you had asked about the held item. It now inspects equipped trinkets, with an optional slot_type to narrow to a single named slot.
  • The example pack drops a tick_action power that never fired.** The Specter's Dimensional Escape declared action_type: teleport_on_damage on a type that dispatches nothing, so the origin advertised a teleport that could not happen, and it was the only worked example of the type an author had to copy. It is removed rather than rewritten, since condition_passive is what to copy for anything that runs on an interval. The Specter's other nine powers are unchanged.

  • The API reference index lists every power type.** It listed barely half of them, so a reader looking up entity_model, restrict_items or creative_flight found no row and no link. Every documented type has one now, including a new group for the mod-compatibility types. Four rows were wrong rather than missing: sneaky, stealth, no_projectile_divergence and tick_action sat under retired aliases, but none is an alias and all four are registered types with their own implementations. They move to their live categories, and night_vision's replacement is named correctly as persistent_effect.
  • Fifteen power-type summaries corrected against the code.** Each was re-read against its implementation class rather than against the older prose. The ones that change what you would write: tick_action dispatches nothing at all, so "run an action on a repeating interval" described a feature that is not there; no_projectile_divergence pointed at minecraft:projectile_accuracy, an attribute that does not exist, so the suggested modifier could never resolve; wraith_phase never grants flight; mount needs no consent unless the server config asks for it; and loot_pool_grant fires once per grant_id. The rest tighten wording that was true and misleading: modify_flight_speed leaves elytra gliding alone, mob_behavior adds goals rather than replacing the vanilla AI, restrict_items has two independent opt-ins, extra_inventory sizes in slots rather than rows, and slime_level_hp tracks the current level rather than resetting on death.
  • Field tables and examples the loader does not match.** Five documented fields do not exist under the names given: knockback_modifier's direction, thorns_aura's reflect_ratio (the real key is return_ratio), action_on_hit_taken's amount, persistent_effect's refresh_interval, and the enchantment item condition's min_level (the real keys are comparison and compare_to). Worse, action_on_hit_taken advertised restore_health, restore_hunger and grant_effect, none of which has an implementation: all three fall through to the default and teleport the player somewhere random, and the worked example asked for grant_effect, so it did the one thing its own title said it would not. Six defaults were wrong, and explode's destruction_type was documented backwards: absent means no blocks break, not the reverse. The action_on_event example used slot and item on an equipped-item condition, which reads equipment_slot and item_condition, so it matched any mainhand item rather than the wooden sword it claimed to test.
  • The pack folder layout shows every folder a pack can carry.** It listed three, so morphs, entity groups, mob origins and global powers were invisible to anyone reading the pack reference: the morph feature was documented in full and reachable from nowhere else. The layout now shows all of them, each pointing at its own doc, with a note that the original Origins mod layout still loads unchanged. A hand-written morph.schema.json comes with it, so the editors read morph files like every other type.
  • action_over_time and tick_action point somewhere useful.** action_over_time was a registered alias mentioned nowhere at all, not in the reference, not in the retired table, not in the migration guide: it loaded and ran exactly as written, and an author who inherited one had nothing to read about it. It has a migration entry now, alongside the other types that fold into condition_passive. tick_action pointed at action_on_event, where condition_passive is the closer replacement and takes the same interval field.
  • Four reference links that never resolved.** The links to condition_passive, block_target_action and the cookbook's toggleable-abilities recipe all landed at the top of the page instead of at the section, with the cookbook link broken in two different files.
  • What holds off a dry-out, said the same way everywhere it is written down.** The origin list had *Dries Out* as damage out of water in hot biomes, where the power is not biome-gated at all: air drains anywhere on land and you suffocate when it empties. The power type reference named Water Breathing and Conduit Power without ever saying that rain, a bubble column or standing in a water cauldron counts as being in the water, and it read as though those reprieves applied to fluid: lava as well, which is the bare check with none of them. The cookbook's moisture note gains Water Breathing and Create's backtank beside the rest.
  • The mob origin schema is published alongside the other four.** mob_origin.schema.json sits in the schema folder, in the README's table and in its IDE-validator mapping, and in the API reference's validator list, so an editor pointed at data/*/origins/mob_origins/*.json checks the file the way it already checked origins, layers, powers and morphs.
  • Attribution for the bundled spectral sword travels with the mod.** The blades spawn_sword_rain summons are a third-party model under Creative Commons Attribution 4.0, and that licence asks for credit to travel with the file. A CREDITS.md at the root names the author, the source and the licence it is used under, and points at the bundled font licensing beside it.
> A documentation release with a handful of server-reported fixes and one compatibility addition riding along. The API reference index linked barely half of its power types, so entity_model, restrict_items and creative_flight were fully documented and reachable from nowhere: a reader who looked one up found nothing and reasonably concluded the feature did not exist. Every type has a row now. A verification pass then went back over the reference against the code rather than against the older prose, and the result is the larger half of this release: fifteen summaries were wrong or misleading about what their class does, five documented fields do not exist under those names, six defaults were wrong, and one power type advertised three verbs that all silently teleport the player somewhere random instead.
>
> The fixes are unrelated to each other and all came from live servers. An invisibility power with a condition on it hid the body and left the armor and held item floating, which is why it survived so long: the unconditional ones always worked. A misconfigured attribute_modifier could fill an operator's log for as long as a player held the power, several lines a second, with a message that never said what was actually wrong. And an origin with an empty slot in its power list did not load at all: absent from the picker, with the log naming neither the origin's fields nor the slot. A keep-inventory origin dropped the armor it had just promised to keep, though only once the player's inventory was full, which is what made it read as random.
>
> A second pass over the older reports found three of them worse than described. A grounded player wearing wings was not only hearing the elytra loop restart under their own feet, they were cutting the sound off for everyone gliding past them. The clamp that keeps a phasing origin out of the few blocks it is not allowed through was collided against every block in range instead, so a Wraith near one blocked block stuck fast in ordinary stone. And a player being ridden was the one person in the world who could not see their own rider.
>
> Two editor corrections close gaps left open in 2.2.24. Block conditions written as all_of / any_of no longer get marked invalid by an editor when the game reads them perfectly well, and status_effect's two particle fields stop advertising the opposite of the loader's real defaults.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Ore counts as food for the Caveborn.** The four tags listing what a Caveborn can eat besides stone held ingots, nuggets, gems, raw metal and netherite scrap, and no ore whatsoever, so a Caveborn standing at a freshly exposed vein had nothing in front of it that it could eat. Iron, gold and diamond ore now qualify along with their deepslate forms, and so do nether gold ore, ancient debris and the raw iron and raw gold blocks. Worth knowing: ore is a placeable block, so aiming at a surface places it as it always did, and eating one means aiming where it cannot be placed. That is the same rule the Caveborn's stone diet has always followed.
  • An Artifacts umbrella keeps the sun and the rain off.** Origins that burn in daylight and origins that take rain damage both look for an umbrella before they hurt you, but only Vampires Need Umbrellas ever counted as one, so an Artifacts umbrella held in plain sight did nothing to help. It works now, held in either hand or worn in a trinket slot, and one umbrella covers both weaknesses rather than only the one it was carried for. What counts as an umbrella is a new neoorigins:umbrellas item tag, so a pack can add any other mod's umbrella to it without touching code.
  • The four aquatic origins say what keeps them from drying out.** Dries Out told you only that air ticks down while you are out of water and that staying too long suffocates you, so every way of stopping the drain was something you had to be told about or stumble into. The description now names them: rain, standing in a water cauldron, Water Breathing, and an active conduit nearby. Abyssal, Kraken, Merling and Siren all read the same, in every language the mod ships.

  • An invisibility power with a condition hides armor and held items, not only the body.** Powers that turn invisibility on unconditionally were always fine, which is what kept this hidden. The armor-hiding flag was read from the condition-gated capability set and only sent to the client when something else triggered a power sync, never at the moment the condition itself flipped, so a conditioned power froze the flag at whatever it was worth at the last sync: the body vanished on cue and the boots and the sword stayed. The flag now comes from the power itself rather than from its live condition state, which is what it always meant ("hide the armor *when* invisible"), and the client already re-checks whether you are actually invisible before hiding anything. Invisibility itself is unchanged. Cosmetic elytra wings and morph state are deliberately left as they were: nothing on the client re-checks those, so treating them the same way would draw wings on a player whose condition is not met.
  • A misconfigured attribute_modifier reports once instead of every few ticks.** The power re-tries the attachment whenever it should be active and is not. That is the right behaviour while the attachment can still succeed, and a permanent log flood once it cannot. Naming something that is not an attribute is the common way to reach that state, and the old message did not say so. It does now: if the id is a mob effect (haste, night_vision and friends are the usual ones), it can never resolve as an attribute, and the effect wants an apply_effect action instead. The warning also names the prefixes that were tried, and repeats for the same id are suppressed.
  • An origin with an empty entry in its power list loads instead of vanishing.** A single null in powers failed the whole origin, so it never reached the picker, leaving a single line that repeated "not a string" once per empty slot, naming the origin but neither the field nor the position that caused it. The empty entries are now dropped and the origin loads with every power actually named in it, with one warning giving the origin id and how many were skipped. upgrades and the add / remove lists inside tier_powers are covered the same way. A trailing comma or a deleted line in a hand-edited file is the usual cause, so it is still worth fixing the file rather than leaving it to the warning.
  • The creator keybinds stop writing a server warning on every press.** Player X requested the mob creator without permission was a keybind collision rather than anything to act on: the open-creator keys ship unbound, the client sends a packet per press, and the server logged each refusal at warning level, so a player whose key overlapped something they use in normal play filled the operator's log by playing normally. Both open paths log at debug now. Refusing a save or an apply still warns, on purpose: those are only reachable from inside the creator screen, so a refusal there is worth an operator's attention.
  • The elytra loop stops when you land, rather than starting again twenty times a second.** True of every origin that flies without an elytra in its chest slot. The guard that ends a flight ran its whole body on every tick the player was on the ground, in water or riding, instead of only on the tick the flight actually ended. On your own client that meant the fall-flying flag being switched on and straight back off once per tick, and the client starts a fresh elytra sound on the rising edge, so the loops stacked and got louder the longer you stood still. The server side reached further than the player it belonged to: it was broadcasting a stop-sound to every player within 64 blocks, twenty times a second, so standing on the ground with wings silenced the elytra of anyone genuinely gliding past. Both halves now fire once, when flight ends.
  • A phasing origin stops sticking inside ordinary blocks.** Phasing powers carry a short list of blocks they are *not* allowed through, and the clamp that enforces it was asking the game's general-purpose collision routine to check the player against that list. That routine always adds the surrounding world to whatever list it is handed, so the clamp collided the player against every block within reach, which is the exact opposite of a blacklist, and a Wraith that strayed near one blocked block froze solid in stone it was entitled to walk through. The clamp now checks the listed blocks and nothing else. The Wraith's own description has been corrected alongside it: it said the Wraith cannot pass obsidian at all, where the apex form is stopped only by bedrock.
  • A player being ridden can see who is riding them.** Everyone else could. A player is never in their own tracking list, so the update naming their passengers was the one packet that never reached them, and their own client went on drawing an empty back until something unrelated forced a refresh. Consent-based mounts already worked around this by resending it by hand, but that is not the only way to end up ridden: the Apoli-compatible mount action, the built-in one, the mount power and summoned minions all take a seat directly and had no such workaround. The resend now happens where a passenger is seated, so every route is covered.
  • Keep-inventory puts everything back where it was, instead of dropping your armor once your bag is full.** Reported from a live server, and the fullness is the whole of it: everything kept at death went back through the routine that adds an item to your inventory, and that routine only fills the main thirty-six slots. With the wildcard * covering every slot you have, the first thirty-six kept stacks refilled the main inventory, and the four armor pieces and the offhand item had nowhere left to go, so the power dropped them on the floor. That is the one outcome it exists to prevent, and it only happened to players carrying enough to trigger it, which is why it looked arbitrary. Even with room to spare it was never quite right, since armor came back loose in the bag rather than worn. Kept items now return to the exact slot they were taken from, which is empty by construction because dying is what emptied it: armor comes back on, the hotbar keeps its layout, and a full inventory can no longer push anything onto the ground.
  • Keep-inventory covers trinket slots, and a kept trinket waits for its slot rather than being dumped in your bag.** On 26.1 and 26.2 the coverage is new: slots took only the vanilla categories there, so a Curios ring matched nothing and dropped on death like anything else. All three versions now read curio, accessory or trinket as meaning every trinket slot, or a specific slot id such as ring or necklace, and the wildcard * includes them. A kept trinket goes back into the slot it died in. Those mods rebuild their slot counts on their own schedule after a respawn, so a slot that is not writable the instant you land is usually a matter of timing rather than a slot that is genuinely gone: the trinket is held and retried for three seconds instead of being given up on, and only after that does it fall back to your inventory, and to the ground only if that is full as well. Logging out part-way through settles it the same way rather than losing it. Curios is read on every supported version; Accessories on 1.21.1 only, as it has no 26.1 or 26.2 build.
  • An origin that cannot find its spawn dimension says which one it wanted.** A spawn_location naming a dimension that no loaded world provides gave up without a word, which reads in game as picking the origin and simply not being moved, and reads in the log as nothing at all. The warning now names the dimension and the player, so a typo or a missing mod is the first thing you see rather than something to go hunting for.
  • An active conduit keeps an aquatic origin from drying out on land.** The exemption had been in place for months and could never once have fired: the game only hands Conduit Power to a player who is already in water or rain, so an Abyssal, Kraken, Merling or Siren standing on dry ground beside a conduit was never given the effect the exemption goes looking for. The one case that appeared to work was walking ashore near one, where the effect carried out of the water lasted about thirteen seconds and then lapsed with nothing to renew it, which is why it read as working sometimes rather than never. A conduit now reaches a drying-out player anywhere inside the radius it already uses for everything else, and the bubble row refills while you stand in it instead of holding at whatever it had drained down to. Pack authors see the same reprieve in attribute_modifier's on_land condition, which was written to stand down under Conduit Power and never once had the occasion to: it now does, for a player whose origin also carries a drying-out power, since that is who a conduit reaches on dry land. An origin without one is unchanged.

  • Block conditions written as all_of and any_of stop being marked invalid.** Both are the Apoli 2.9+ spellings of and and or, and the loader has always read them; the block condition catalogue behind the editors and the generated schema listed only the short pair. The effect was the one failure shape an author cannot debug from inside the game: the file works, and the editor says it does not. 2.2.24 documented the workaround of writing and and or there instead, which is no longer necessary. Both spellings are now in the catalogue, the schema and the editor pickers, and nothing you have already written changes behaviour.
  • status_effect's ambient and show_particles advertise the loader's real defaults.** They were declared the wrong way round, ambient as defaulting to false and show_particles to true where the loader does the opposite, so a form field or a generated schema told you the inverse of what omitting the key would do. These two are exactly the pair where a wrong default costs nothing at load and shows up only as particles you did not expect once you are in game. The reference tables were already right and are unchanged.
  • equipped_item with equipment_slot: accessory reads your trinkets on 26.1 and 26.2.** 1.21.1 already did. A slot name the mapper does not recognise falls through to the mainhand, so on those two versions the condition quietly answered about whatever the player happened to be holding. It never errored and never logged, which is the hardest kind of wrong condition to find: the file looks correct and the power simply behaves as though you had asked about the held item. It now inspects equipped trinkets, with an optional slot_type to narrow to a single named slot.
  • The example pack drops a tick_action power that never fired.** The Specter's Dimensional Escape declared action_type: teleport_on_damage on a type that dispatches nothing, so the origin advertised a teleport that could not happen, and it was the only worked example of the type an author had to copy. It is removed rather than rewritten, since condition_passive is what to copy for anything that runs on an interval. The Specter's other nine powers are unchanged.

  • The API reference index lists every power type.** It listed barely half of them, so a reader looking up entity_model, restrict_items or creative_flight found no row and no link. Every documented type has one now, including a new group for the mod-compatibility types. Four rows were wrong rather than missing: sneaky, stealth, no_projectile_divergence and tick_action sat under retired aliases, but none is an alias and all four are registered types with their own implementations. They move to their live categories, and night_vision's replacement is named correctly as persistent_effect.
  • Fifteen power-type summaries corrected against the code.** Each was re-read against its implementation class rather than against the older prose. The ones that change what you would write: tick_action dispatches nothing at all, so "run an action on a repeating interval" described a feature that is not there; no_projectile_divergence pointed at minecraft:projectile_accuracy, an attribute that does not exist, so the suggested modifier could never resolve; wraith_phase never grants flight; mount needs no consent unless the server config asks for it; and loot_pool_grant fires once per grant_id. The rest tighten wording that was true and misleading: modify_flight_speed leaves elytra gliding alone, mob_behavior adds goals rather than replacing the vanilla AI, restrict_items has two independent opt-ins, extra_inventory sizes in slots rather than rows, and slime_level_hp tracks the current level rather than resetting on death.
  • Field tables and examples the loader does not match.** Five documented fields do not exist under the names given: knockback_modifier's direction, thorns_aura's reflect_ratio (the real key is return_ratio), action_on_hit_taken's amount, persistent_effect's refresh_interval, and the enchantment item condition's min_level (the real keys are comparison and compare_to). Worse, action_on_hit_taken advertised restore_health, restore_hunger and grant_effect, none of which has an implementation: all three fall through to the default and teleport the player somewhere random, and the worked example asked for grant_effect, so it did the one thing its own title said it would not. Six defaults were wrong, and explode's destruction_type was documented backwards: absent means no blocks break, not the reverse. The action_on_event example used slot and item on an equipped-item condition, which reads equipment_slot and item_condition, so it matched any mainhand item rather than the wooden sword it claimed to test.
  • The pack folder layout shows every folder a pack can carry.** It listed three, so morphs, entity groups, mob origins and global powers were invisible to anyone reading the pack reference: the morph feature was documented in full and reachable from nowhere else. The layout now shows all of them, each pointing at its own doc, with a note that the original Origins mod layout still loads unchanged. A hand-written morph.schema.json comes with it, so the editors read morph files like every other type.
  • action_over_time and tick_action point somewhere useful.** action_over_time was a registered alias mentioned nowhere at all, not in the reference, not in the retired table, not in the migration guide: it loaded and ran exactly as written, and an author who inherited one had nothing to read about it. It has a migration entry now, alongside the other types that fold into condition_passive. tick_action pointed at action_on_event, where condition_passive is the closer replacement and takes the same interval field.
  • Four reference links that never resolved.** The links to condition_passive, block_target_action and the cookbook's toggleable-abilities recipe all landed at the top of the page instead of at the section, with the cookbook link broken in two different files.
  • What holds off a dry-out, said the same way everywhere it is written down.** The origin list had *Dries Out* as damage out of water in hot biomes, where the power is not biome-gated at all: air drains anywhere on land and you suffocate when it empties. The power type reference named Water Breathing and Conduit Power without ever saying that rain, a bubble column or standing in a water cauldron counts as being in the water, and it read as though those reprieves applied to fluid: lava as well, which is the bare check with none of them. The cookbook's moisture note gains Water Breathing and Create's backtank beside the rest.
  • The mob origin schema is published alongside the other four.** mob_origin.schema.json sits in the schema folder, in the README's table and in its IDE-validator mapping, and in the API reference's validator list, so an editor pointed at data/*/origins/mob_origins/*.json checks the file the way it already checked origins, layers, powers and morphs.
  • Attribution for the bundled spectral sword travels with the mod.** The blades spawn_sword_rain summons are a third-party model under Creative Commons Attribution 4.0, and that licence asks for credit to travel with the file. A CREDITS.md at the root names the author, the source and the licence it is used under, and points at the bundled font licensing beside it.
> A corrective release. The ocean origins hold their depth instead of sinking the moment they stop swimming, four flying origins that glided bare-backed get wings, Sword Immortal can no longer fly empty-handed, and night-vision powers finally say which key toggles them. Most of the rest were failing quietly rather than visibly, which is why none had been reported: the Herbalist's bone meal growth never reached the client and never spent the bone meal, AppleSkin previewed vanilla's food values on every diet origin, two powers of one type shared a single toggle, ten tier night-vision powers each held an ability slot they had no business holding, and origins:remove_enchantment had never been implemented at all. On the compatibility side, two opposite failure shapes are closed: biome conditions that failed closed and could never fire anywhere, and item and block conditions that failed open and matched everything handed to them. Legacy packs load with their origins unchanged. KubeJS scripting also reaches the Minecraft 26.1 build, with scripts moving across unchanged.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Ocean origins hold their depth instead of sinking when they stop swimming.** Holding station used to mean swimming to hold it. A new shared power, *Neutral Buoyancy*, goes to Merling, Siren, Kraken and Abyssal: -0.08 on minecraft:gravity as an add_value, conditioned on being fully submerged. That lands the attribute on exactly 0.0, and vanilla skips its in-water descent entirely at zero base gravity, so depth holds cleanly rather than trading a sink for a slow float up. Swimming down is unaffected, and puddles and shallows do not trigger it. Conditioned modifiers re-evaluate every five ticks, so expect up to a quarter-second lag at the surface. See [COOKBOOK.md](docs/COOKBOOK.md).
  • Night-vision powers say how to switch them off.** Night vision deliberately has no entry in the HUD ability cluster, because it is not one of the six numbered skills, so nothing in game ever pointed at the key that toggles it and players reasonably concluded there was no toggle at all. Twenty-two power descriptions now end with "Toggle with the Night Vision key (default K)." — worded for the binding rather than the letter, since it is rebindable. Worth knowing alongside it: the setting is remembered per player rather than per origin, so switching it off on one origin and later picking another that has night vision starts you with it already off.

  • Ten tier night-vision powers stop taking up a numbered ability slot.** persistent_effect defaults toggleable to true, and these ten never declared it, so each claimed one of the six skill slots and answered to a stray skill-key press — the exact failure the base night-vision powers force toggleable: false to avoid, and one that reads to a player as night vision switching itself off for no reason. One tier power each on Wraith, Arachnid, Caveborn, Darkness Mage, Feline, Necromancer, Sculkborn, Sporeling, Sylvan and Umbral now sets it explicitly, matching the four conduit powers that always had. They are passive tier buffs, and the Night Vision key remains their off-switch.
  • Elytrian, Phantom, Hiveling and Draconic fly with visible wings.** True of every built-in origin that flies without an elytra in its chest slot. The renderer was never at fault: neoorigins:natural_glide and neoorigins:flight simply had no way to ask for wings. Both now take the same render_elytra and texture_location pair elytra_flight already carried, so a pack can put wings on either and point them at its own texture. They default to false rather than elytra_flight's true, deliberately — these types have shipped wingless their whole life, and defaulting them on would put an elytra on the back of every existing pack that uses them. Windwalker's Sky Dancer stays bare on purpose. [POWER_TYPES.md](docs/POWER_TYPES.md) documents both.
  • The Herbalist's extra bone meal growth shows up straight away instead of after a rejoin.** Bone mealing grass placed one plant and the rest appeared only after a relog. The handler grew the blocks and let vanilla carry on, but vanilla re-checked the target against the live world, found the space filled and returned PASS — and NeoForge replays an item's block changes only on success, so the blocks were there the whole time with no client told. That same PASS also skipped the bone meal being spent, giving a Herbalist unlimited bone meal on grass. The handler now cancels the event, does the work and claims success, keeping vanilla's success roll so the power is exactly as strong as before.
  • Two powers of the same type on one origin stop sharing a single toggle.** Pressing either keybind switched both on. Toggle state was keyed off the power's config rather than the power itself, so two powers that happened to agree collapsed into one flag. The reach was wider than the report: condition_passive keyed the same way, persistent_effect keyed off its effect ids so two tiers of one buff collided, and seven more types including stealth, flight and phantom_form keyed off the class name alone and so collided unconditionally. Keys are now the power's own resource id. Flags already saved in a world are still read, so a power you had switched off stays off.
  • A gameplay.toml written before 2.2.22 has its air drain rate corrected on the next start.** [ocean_origins] drain_rate_ticks shipped as 10 up to 2.2.21 and became 1 in 2.2.22, but the config system only rewrites a key that is missing or out of range, and 10 sits well inside the declared 1 to 1200 — so every install that had ever run 2.2.21 kept it. The correction reasons from the file rather than the value, since 10 is a legitimate setting. gameplay.toml now carries a config_version, and an unstamped file holding exactly 10 is moved to 1, stamped and logged. Any other value survives, and once stamped the setting is yours again: put it back to 10 and it stays.
  • AppleSkin previews a diet origin's real food values rather than vanilla's.** True of every origin that changes what food is worth. modify_food_nutrition never rewrites the item's food data — it corrects hunger and saturation server-side at the moment of eating — so there was nothing on the stack for AppleSkin to read, and an aquatic origin holding a cod was shown vanilla's 2 and 0.4. A new bridge answers AppleSkin's event with the origin-adjusted values, leaving the vanilla figure in place for its usual struck-through comparison. The nutrition-to-saturation scaling now lives in one place called by both the real eat and the preview, so the number shown and the number received cannot drift apart. AppleSkin remains optional.
  • Sword Immortal's flight and Flickering Slash need the sword in hand.** A Sword Immortal could fly empty-handed, which the origin's own description rules out. Seven of its ten powers already carried the requirement, and Immortal Body carries none precisely because it is the fall-immune mortal left when you are disarmed; the other two could not, because neoorigins:creative_flight and neoorigins:active_dash had no condition field for one to go in. Both take one now. On the flight it is re-checked every tick rather than at takeoff, so sheathing mid-air strips the ability there and then and the drop is real — pair a conditional flight with fall-damage immunity if it should be survivable. A blocked dash spends no cooldown. Defaults to absent, so existing powers of both types are unchanged. [POWER_TYPES.md](docs/POWER_TYPES.md) documents the field on both.

  • The in-game editor gives list fields a row of real entry boxes instead of a single raw JSON box.** Adding one entity type meant typing the brackets and quotes yourself. Thirty-four fields were affected across the schema-driven forms: a power's items, tags, entity_types, damage_types, slots and hands, plus the id lists on actions, conditions and item actions. The add-and-remove widget was already in the mod but unreachable, because the layer that reads schemas into the editor's field model never carried across the element pattern the check looks for. The model now carries it, reaching all thirty-four at once. The origin creator is hand-built and the web editor reads the schema directly, so neither was ever affected.
  • The schemas stop advertising fewer verbs than the parsers accept.** Working verbs looked unsupported unless you already knew they existed. Block conditions accept ten where the list named four, gaining adjacent, block_state, height and offset; item conditions accept thirteen where the list named seven, gaining all_of, amount, any_of, custom_data, food and name. All of them already worked if you wrote them, so nothing you have written changes behaviour. Both the list and its validating pattern now come from the editors' own catalogue rather than being maintained by hand beside it. One gap stays open, better said here than found in an editor: the block condition catalogue does not carry all_of and any_of, so a block condition written that way works in game while the editors mark the file invalid — write and and or there instead.

  • origins:remove_enchantment works, so a legacy Remove Curse power removes curses.** The verb had never been implemented, so the item action parser fell through to its no-op default and the power loaded, gated and ticked while doing nothing, with no error to say so. Both field shapes are accepted, since the docs describe a singular enchantment string while real packs commonly write a plural enchantments array and both are valid upstream. reset_repair_cost is read either on the action or on the enclosing equipped_item_action, true in either position winning. An unregistered id matches nothing, and a malformed one warns and is skipped rather than taking the power down. Enchanted books go through vanilla's own dispatch.
  • levels weakens an enchantment instead of stripping it outright.** The first implementation covered three of upstream's four fields and dropped the fourth silently, which is worse than not supporting the verb at all: a pack asking to knock one level off Sharpness V got the whole enchantment torn off while everything looked correct from the pack side. levels now reduces each named enchantment by that many and deletes it only at zero or below, matching upstream. Omitting the field still removes outright, since that is what older packs rely on. Nothing is clamped — 0 subtracts nothing and a negative raises the level, both of which are what upstream's plain subtraction does.
  • A biome-gated power fires in the biome it names.** origins:biome accepts a nested condition with its own small grammar, where in_tag means the biome is in a biome tag rather than anything about entity types. Only temperature had ever been implemented, so every other verb failed closed and a power written that way never activated in any biome at all, in_tag being much the most common of them. Now parsed: in_tag, precipitation, high_humidity, constant, not, a nested biome form for or-lists of exact ids, and all_of / any_of as the Apoli 2.9 spellings of and / or, each honouring inverted. Two details if you write them: precipitation answers for your block rather than the biome as a whole, and high_humidity keeps Apoli's 0.85 verbatim. An unknown sub-type still fails closed, which stays right here.
  • Five item conditions that were passing every stack instead of checking it.** An unimplemented item condition returned true — it accepted every stack rather than refusing it — so a herbivore restriction written against a verb we lack permitted meat while the power loaded, gated and ticked in apparent good order. That is the quieter failure of the two, and why these went unreported for so long. armor_value, meat, constant, harvest_level and durability are all implemented now. Two are worth knowing precisely: armor_value is what one stack confers rather than the wearer's total, and meat resolves through the NeoForge common food tags, so modded meats count. The honest limit: a verb still outside the list goes on passing, since flipping that default would make every unimplemented condition block everything across packs that work today.
  • Four block conditions that were matching every block, and the fallback that hid them.** An unimplemented verb compiled to nothing, which in_block, in_block_anywhere and the narrow neoorigins:block check all read as "match anything", while on_block discarded the filter outright and turned "standing on X" into "standing on anything". inverted was no protection, since inversion applies only to a condition that compiled, and it logged at debug with no warning — so a pack reload came back clean while light_level, exposed_to_sky, movement_blocking and fluid sat silently always-true: a sun-sensitive origin's slowness and blindness fired in the dark exactly as in the sun. All four verbs are implemented, since closing the fail-open alone would have swung those powers from always on to never on, and an unknown verb now matches nothing. The docs also stop calling in_block_anywhere an alias of in_block: the first samples one block, the second counts every position the hitbox overlaps. See [CONDITIONS.md](docs/CONDITIONS.md).

  • KubeJS scripting reaches the Minecraft 26.1 build.** It was 1.21.1 only because KubeJS had published nothing for 26.1, not because anything was tied to that version. The whole surface is on both builds now: the NeoOrigins and NeoOriginsEvents globals, all fifteen events, registerCallback with the neoorigins:kubejs_callback action behind it, and the two JavaScript-backed power types neoorigins:js_custom and neoorigins:js_active. Scripts move across without porting. Two install notes that are KubeJS's requirements rather than ours: the 26.1 build wants NeoForge 26.1.2.84 or newer before KubeJS will load at all, and on 1.21.1 registerPower needs Rhino 2101.2.8-build.91 or newer. **The 26.2 build does not get this and cannot yet**, since KubeJS has published nothing past Minecraft 26.1.2 to build against — and an unrecognised power type is dropped whole, so a js_custom power copied into a 26.2 pack never appears on the origin and nothing in game says why. [KUBEJS.md](docs/KUBEJS.md) documents the whole surface.

  • Air drain is counted per air point, not per bubble.** drain_rate_ticks is ticks per single air point, and the HUD draws 300 air as 10 bubbles, so one bubble is 30 points: at 1 a bubble lasts 1.5 seconds and the full bar 15; at 10, 15 seconds and 150. Reading it as ticks per bubble puts you out by a factor of thirty, which is where both reports came from. If your bar genuinely empties slower than the table says, an install predating 2.2.22 still holds the old default of 10, which this release moves for you on the next start. [POWER_TYPES.md](docs/POWER_TYPES.md) carries the arithmetic beside the table.
> A corrective release. The ocean origins hold their depth instead of sinking the moment they stop swimming, four flying origins that glided bare-backed get wings, Sword Immortal can no longer fly empty-handed, and night-vision powers finally say which key toggles them. Most of the rest were failing quietly rather than visibly, which is why none had been reported: the Herbalist's bone meal growth never reached the client and never spent the bone meal, AppleSkin previewed vanilla's food values on every diet origin, two powers of one type shared a single toggle, ten tier night-vision powers each held an ability slot they had no business holding, and origins:remove_enchantment had never been implemented at all. On the compatibility side, two opposite failure shapes are closed: biome conditions that failed closed and could never fire anywhere, and item and block conditions that failed open and matched everything handed to them. Legacy packs load with their origins unchanged. KubeJS scripting also reaches the Minecraft 26.1 build, with scripts moving across unchanged.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Ocean origins hold their depth instead of sinking when they stop swimming.** Holding station used to mean swimming to hold it. A new shared power, *Neutral Buoyancy*, goes to Merling, Siren, Kraken and Abyssal: -0.08 on minecraft:gravity as an add_value, conditioned on being fully submerged. That lands the attribute on exactly 0.0, and vanilla skips its in-water descent entirely at zero base gravity, so depth holds cleanly rather than trading a sink for a slow float up. Swimming down is unaffected, and puddles and shallows do not trigger it. Conditioned modifiers re-evaluate every five ticks, so expect up to a quarter-second lag at the surface. See [COOKBOOK.md](docs/COOKBOOK.md).
  • Night-vision powers say how to switch them off.** Night vision deliberately has no entry in the HUD ability cluster, because it is not one of the six numbered skills, so nothing in game ever pointed at the key that toggles it and players reasonably concluded there was no toggle at all. Twenty-two power descriptions now end with "Toggle with the Night Vision key (default K)." — worded for the binding rather than the letter, since it is rebindable. Worth knowing alongside it: the setting is remembered per player rather than per origin, so switching it off on one origin and later picking another that has night vision starts you with it already off.

  • Ten tier night-vision powers stop taking up a numbered ability slot.** persistent_effect defaults toggleable to true, and these ten never declared it, so each claimed one of the six skill slots and answered to a stray skill-key press — the exact failure the base night-vision powers force toggleable: false to avoid, and one that reads to a player as night vision switching itself off for no reason. One tier power each on Wraith, Arachnid, Caveborn, Darkness Mage, Feline, Necromancer, Sculkborn, Sporeling, Sylvan and Umbral now sets it explicitly, matching the four conduit powers that always had. They are passive tier buffs, and the Night Vision key remains their off-switch.
  • Elytrian, Phantom, Hiveling and Draconic fly with visible wings.** True of every built-in origin that flies without an elytra in its chest slot. The renderer was never at fault: neoorigins:natural_glide and neoorigins:flight simply had no way to ask for wings. Both now take the same render_elytra and texture_location pair elytra_flight already carried, so a pack can put wings on either and point them at its own texture. They default to false rather than elytra_flight's true, deliberately — these types have shipped wingless their whole life, and defaulting them on would put an elytra on the back of every existing pack that uses them. Windwalker's Sky Dancer stays bare on purpose. [POWER_TYPES.md](docs/POWER_TYPES.md) documents both.
  • The Herbalist's extra bone meal growth shows up straight away instead of after a rejoin.** Bone mealing grass placed one plant and the rest appeared only after a relog. The handler grew the blocks and let vanilla carry on, but vanilla re-checked the target against the live world, found the space filled and returned PASS — and NeoForge replays an item's block changes only on success, so the blocks were there the whole time with no client told. That same PASS also skipped the bone meal being spent, giving a Herbalist unlimited bone meal on grass. The handler now cancels the event, does the work and claims success, keeping vanilla's success roll so the power is exactly as strong as before.
  • Two powers of the same type on one origin stop sharing a single toggle.** Pressing either keybind switched both on. Toggle state was keyed off the power's config rather than the power itself, so two powers that happened to agree collapsed into one flag. The reach was wider than the report: condition_passive keyed the same way, persistent_effect keyed off its effect ids so two tiers of one buff collided, and seven more types including stealth, flight and phantom_form keyed off the class name alone and so collided unconditionally. Keys are now the power's own resource id. Flags already saved in a world are still read, so a power you had switched off stays off.
  • A gameplay.toml written before 2.2.22 has its air drain rate corrected on the next start.** [ocean_origins] drain_rate_ticks shipped as 10 up to 2.2.21 and became 1 in 2.2.22, but the config system only rewrites a key that is missing or out of range, and 10 sits well inside the declared 1 to 1200 — so every install that had ever run 2.2.21 kept it. The correction reasons from the file rather than the value, since 10 is a legitimate setting. gameplay.toml now carries a config_version, and an unstamped file holding exactly 10 is moved to 1, stamped and logged. Any other value survives, and once stamped the setting is yours again: put it back to 10 and it stays.
  • AppleSkin previews a diet origin's real food values rather than vanilla's.** True of every origin that changes what food is worth. modify_food_nutrition never rewrites the item's food data — it corrects hunger and saturation server-side at the moment of eating — so there was nothing on the stack for AppleSkin to read, and an aquatic origin holding a cod was shown vanilla's 2 and 0.4. A new bridge answers AppleSkin's event with the origin-adjusted values, leaving the vanilla figure in place for its usual struck-through comparison. The nutrition-to-saturation scaling now lives in one place called by both the real eat and the preview, so the number shown and the number received cannot drift apart. AppleSkin remains optional.
  • Sword Immortal's flight and Flickering Slash need the sword in hand.** A Sword Immortal could fly empty-handed, which the origin's own description rules out. Seven of its ten powers already carried the requirement, and Immortal Body carries none precisely because it is the fall-immune mortal left when you are disarmed; the other two could not, because neoorigins:creative_flight and neoorigins:active_dash had no condition field for one to go in. Both take one now. On the flight it is re-checked every tick rather than at takeoff, so sheathing mid-air strips the ability there and then and the drop is real — pair a conditional flight with fall-damage immunity if it should be survivable. A blocked dash spends no cooldown. Defaults to absent, so existing powers of both types are unchanged. [POWER_TYPES.md](docs/POWER_TYPES.md) documents the field on both.

  • The in-game editor gives list fields a row of real entry boxes instead of a single raw JSON box.** Adding one entity type meant typing the brackets and quotes yourself. Thirty-four fields were affected across the schema-driven forms: a power's items, tags, entity_types, damage_types, slots and hands, plus the id lists on actions, conditions and item actions. The add-and-remove widget was already in the mod but unreachable, because the layer that reads schemas into the editor's field model never carried across the element pattern the check looks for. The model now carries it, reaching all thirty-four at once. The origin creator is hand-built and the web editor reads the schema directly, so neither was ever affected.
  • The schemas stop advertising fewer verbs than the parsers accept.** Working verbs looked unsupported unless you already knew they existed. Block conditions accept ten where the list named four, gaining adjacent, block_state, height and offset; item conditions accept thirteen where the list named seven, gaining all_of, amount, any_of, custom_data, food and name. All of them already worked if you wrote them, so nothing you have written changes behaviour. Both the list and its validating pattern now come from the editors' own catalogue rather than being maintained by hand beside it. One gap stays open, better said here than found in an editor: the block condition catalogue does not carry all_of and any_of, so a block condition written that way works in game while the editors mark the file invalid — write and and or there instead.

  • origins:remove_enchantment works, so a legacy Remove Curse power removes curses.** The verb had never been implemented, so the item action parser fell through to its no-op default and the power loaded, gated and ticked while doing nothing, with no error to say so. Both field shapes are accepted, since the docs describe a singular enchantment string while real packs commonly write a plural enchantments array and both are valid upstream. reset_repair_cost is read either on the action or on the enclosing equipped_item_action, true in either position winning. An unregistered id matches nothing, and a malformed one warns and is skipped rather than taking the power down. Enchanted books go through vanilla's own dispatch.
  • levels weakens an enchantment instead of stripping it outright.** The first implementation covered three of upstream's four fields and dropped the fourth silently, which is worse than not supporting the verb at all: a pack asking to knock one level off Sharpness V got the whole enchantment torn off while everything looked correct from the pack side. levels now reduces each named enchantment by that many and deletes it only at zero or below, matching upstream. Omitting the field still removes outright, since that is what older packs rely on. Nothing is clamped — 0 subtracts nothing and a negative raises the level, both of which are what upstream's plain subtraction does.
  • A biome-gated power fires in the biome it names.** origins:biome accepts a nested condition with its own small grammar, where in_tag means the biome is in a biome tag rather than anything about entity types. Only temperature had ever been implemented, so every other verb failed closed and a power written that way never activated in any biome at all, in_tag being much the most common of them. Now parsed: in_tag, precipitation, high_humidity, constant, not, a nested biome form for or-lists of exact ids, and all_of / any_of as the Apoli 2.9 spellings of and / or, each honouring inverted. Two details if you write them: precipitation answers for your block rather than the biome as a whole, and high_humidity keeps Apoli's 0.85 verbatim. An unknown sub-type still fails closed, which stays right here.
  • Five item conditions that were passing every stack instead of checking it.** An unimplemented item condition returned true — it accepted every stack rather than refusing it — so a herbivore restriction written against a verb we lack permitted meat while the power loaded, gated and ticked in apparent good order. That is the quieter failure of the two, and why these went unreported for so long. armor_value, meat, constant, harvest_level and durability are all implemented now. Two are worth knowing precisely: armor_value is what one stack confers rather than the wearer's total, and meat resolves through the NeoForge common food tags, so modded meats count. The honest limit: a verb still outside the list goes on passing, since flipping that default would make every unimplemented condition block everything across packs that work today.
  • Four block conditions that were matching every block, and the fallback that hid them.** An unimplemented verb compiled to nothing, which in_block, in_block_anywhere and the narrow neoorigins:block check all read as "match anything", while on_block discarded the filter outright and turned "standing on X" into "standing on anything". inverted was no protection, since inversion applies only to a condition that compiled, and it logged at debug with no warning — so a pack reload came back clean while light_level, exposed_to_sky, movement_blocking and fluid sat silently always-true: a sun-sensitive origin's slowness and blindness fired in the dark exactly as in the sun. All four verbs are implemented, since closing the fail-open alone would have swung those powers from always on to never on, and an unknown verb now matches nothing. The docs also stop calling in_block_anywhere an alias of in_block: the first samples one block, the second counts every position the hitbox overlaps. See [CONDITIONS.md](docs/CONDITIONS.md).

  • KubeJS scripting reaches the Minecraft 26.1 build.** It was 1.21.1 only because KubeJS had published nothing for 26.1, not because anything was tied to that version. The whole surface is on both builds now: the NeoOrigins and NeoOriginsEvents globals, all fifteen events, registerCallback with the neoorigins:kubejs_callback action behind it, and the two JavaScript-backed power types neoorigins:js_custom and neoorigins:js_active. Scripts move across without porting. Two install notes that are KubeJS's requirements rather than ours: the 26.1 build wants NeoForge 26.1.2.84 or newer before KubeJS will load at all, and on 1.21.1 registerPower needs Rhino 2101.2.8-build.91 or newer. **The 26.2 build does not get this and cannot yet**, since KubeJS has published nothing past Minecraft 26.1.2 to build against — and an unrecognised power type is dropped whole, so a js_custom power copied into a 26.2 pack never appears on the origin and nothing in game says why. [KUBEJS.md](docs/KUBEJS.md) documents the whole surface.

  • Air drain is counted per air point, not per bubble.** drain_rate_ticks is ticks per single air point, and the HUD draws 300 air as 10 bubbles, so one bubble is 30 points: at 1 a bubble lasts 1.5 seconds and the full bar 15; at 10, 15 seconds and 150. Reading it as ticks per bubble puts you out by a factor of thirty, which is where both reports came from. If your bar genuinely empties slower than the table says, an install predating 2.2.22 still holds the old default of 10, which this release moves for you on the next start. [POWER_TYPES.md](docs/POWER_TYPES.md) carries the arithmetic beside the table.
> A corrective release. The ocean origins hold their depth instead of sinking the moment they stop swimming, four flying origins that glided bare-backed get wings, Sword Immortal can no longer fly empty-handed, and night-vision powers finally say which key toggles them. Most of the rest were failing quietly rather than visibly, which is why none had been reported: the Herbalist's bone meal growth never reached the client and never spent the bone meal, AppleSkin previewed vanilla's food values on every diet origin, two powers of one type shared a single toggle, ten tier night-vision powers each held an ability slot they had no business holding, and origins:remove_enchantment had never been implemented at all. On the compatibility side, two opposite failure shapes are closed: biome conditions that failed closed and could never fire anywhere, and item and block conditions that failed open and matched everything handed to them. Legacy packs load with their origins unchanged. KubeJS scripting also reaches the Minecraft 26.1 build, with scripts moving across unchanged.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • Ocean origins hold their depth instead of sinking when they stop swimming.** Holding station used to mean swimming to hold it. A new shared power, *Neutral Buoyancy*, goes to Merling, Siren, Kraken and Abyssal: -0.08 on minecraft:gravity as an add_value, conditioned on being fully submerged. That lands the attribute on exactly 0.0, and vanilla skips its in-water descent entirely at zero base gravity, so depth holds cleanly rather than trading a sink for a slow float up. Swimming down is unaffected, and puddles and shallows do not trigger it. Conditioned modifiers re-evaluate every five ticks, so expect up to a quarter-second lag at the surface. See [COOKBOOK.md](docs/COOKBOOK.md).
  • Night-vision powers say how to switch them off.** Night vision deliberately has no entry in the HUD ability cluster, because it is not one of the six numbered skills, so nothing in game ever pointed at the key that toggles it and players reasonably concluded there was no toggle at all. Twenty-two power descriptions now end with "Toggle with the Night Vision key (default K)." — worded for the binding rather than the letter, since it is rebindable. Worth knowing alongside it: the setting is remembered per player rather than per origin, so switching it off on one origin and later picking another that has night vision starts you with it already off.

  • Ten tier night-vision powers stop taking up a numbered ability slot.** persistent_effect defaults toggleable to true, and these ten never declared it, so each claimed one of the six skill slots and answered to a stray skill-key press — the exact failure the base night-vision powers force toggleable: false to avoid, and one that reads to a player as night vision switching itself off for no reason. One tier power each on Wraith, Arachnid, Caveborn, Darkness Mage, Feline, Necromancer, Sculkborn, Sporeling, Sylvan and Umbral now sets it explicitly, matching the four conduit powers that always had. They are passive tier buffs, and the Night Vision key remains their off-switch.
  • Elytrian, Phantom, Hiveling and Draconic fly with visible wings.** True of every built-in origin that flies without an elytra in its chest slot. The renderer was never at fault: neoorigins:natural_glide and neoorigins:flight simply had no way to ask for wings. Both now take the same render_elytra and texture_location pair elytra_flight already carried, so a pack can put wings on either and point them at its own texture. They default to false rather than elytra_flight's true, deliberately — these types have shipped wingless their whole life, and defaulting them on would put an elytra on the back of every existing pack that uses them. Windwalker's Sky Dancer stays bare on purpose. [POWER_TYPES.md](docs/POWER_TYPES.md) documents both.
  • The Herbalist's extra bone meal growth shows up straight away instead of after a rejoin.** Bone mealing grass placed one plant and the rest appeared only after a relog. The handler grew the blocks and let vanilla carry on, but vanilla re-checked the target against the live world, found the space filled and returned PASS — and NeoForge replays an item's block changes only on success, so the blocks were there the whole time with no client told. That same PASS also skipped the bone meal being spent, giving a Herbalist unlimited bone meal on grass. The handler now cancels the event, does the work and claims success, keeping vanilla's success roll so the power is exactly as strong as before.
  • Two powers of the same type on one origin stop sharing a single toggle.** Pressing either keybind switched both on. Toggle state was keyed off the power's config rather than the power itself, so two powers that happened to agree collapsed into one flag. The reach was wider than the report: condition_passive keyed the same way, persistent_effect keyed off its effect ids so two tiers of one buff collided, and seven more types including stealth, flight and phantom_form keyed off the class name alone and so collided unconditionally. Keys are now the power's own resource id. Flags already saved in a world are still read, so a power you had switched off stays off.
  • A gameplay.toml written before 2.2.22 has its air drain rate corrected on the next start.** [ocean_origins] drain_rate_ticks shipped as 10 up to 2.2.21 and became 1 in 2.2.22, but the config system only rewrites a key that is missing or out of range, and 10 sits well inside the declared 1 to 1200 — so every install that had ever run 2.2.21 kept it. The correction reasons from the file rather than the value, since 10 is a legitimate setting. gameplay.toml now carries a config_version, and an unstamped file holding exactly 10 is moved to 1, stamped and logged. Any other value survives, and once stamped the setting is yours again: put it back to 10 and it stays.
  • AppleSkin previews a diet origin's real food values rather than vanilla's.** True of every origin that changes what food is worth. modify_food_nutrition never rewrites the item's food data — it corrects hunger and saturation server-side at the moment of eating — so there was nothing on the stack for AppleSkin to read, and an aquatic origin holding a cod was shown vanilla's 2 and 0.4. A new bridge answers AppleSkin's event with the origin-adjusted values, leaving the vanilla figure in place for its usual struck-through comparison. The nutrition-to-saturation scaling now lives in one place called by both the real eat and the preview, so the number shown and the number received cannot drift apart. AppleSkin remains optional.
  • Sword Immortal's flight and Flickering Slash need the sword in hand.** A Sword Immortal could fly empty-handed, which the origin's own description rules out. Seven of its ten powers already carried the requirement, and Immortal Body carries none precisely because it is the fall-immune mortal left when you are disarmed; the other two could not, because neoorigins:creative_flight and neoorigins:active_dash had no condition field for one to go in. Both take one now. On the flight it is re-checked every tick rather than at takeoff, so sheathing mid-air strips the ability there and then and the drop is real — pair a conditional flight with fall-damage immunity if it should be survivable. A blocked dash spends no cooldown. Defaults to absent, so existing powers of both types are unchanged. [POWER_TYPES.md](docs/POWER_TYPES.md) documents the field on both.

  • The in-game editor gives list fields a row of real entry boxes instead of a single raw JSON box.** Adding one entity type meant typing the brackets and quotes yourself. Thirty-four fields were affected across the schema-driven forms: a power's items, tags, entity_types, damage_types, slots and hands, plus the id lists on actions, conditions and item actions. The add-and-remove widget was already in the mod but unreachable, because the layer that reads schemas into the editor's field model never carried across the element pattern the check looks for. The model now carries it, reaching all thirty-four at once. The origin creator is hand-built and the web editor reads the schema directly, so neither was ever affected.
  • The schemas stop advertising fewer verbs than the parsers accept.** Working verbs looked unsupported unless you already knew they existed. Block conditions accept ten where the list named four, gaining adjacent, block_state, height and offset; item conditions accept thirteen where the list named seven, gaining all_of, amount, any_of, custom_data, food and name. All of them already worked if you wrote them, so nothing you have written changes behaviour. Both the list and its validating pattern now come from the editors' own catalogue rather than being maintained by hand beside it. One gap stays open, better said here than found in an editor: the block condition catalogue does not carry all_of and any_of, so a block condition written that way works in game while the editors mark the file invalid — write and and or there instead.

  • origins:remove_enchantment works, so a legacy Remove Curse power removes curses.** The verb had never been implemented, so the item action parser fell through to its no-op default and the power loaded, gated and ticked while doing nothing, with no error to say so. Both field shapes are accepted, since the docs describe a singular enchantment string while real packs commonly write a plural enchantments array and both are valid upstream. reset_repair_cost is read either on the action or on the enclosing equipped_item_action, true in either position winning. An unregistered id matches nothing, and a malformed one warns and is skipped rather than taking the power down. Enchanted books go through vanilla's own dispatch.
  • levels weakens an enchantment instead of stripping it outright.** The first implementation covered three of upstream's four fields and dropped the fourth silently, which is worse than not supporting the verb at all: a pack asking to knock one level off Sharpness V got the whole enchantment torn off while everything looked correct from the pack side. levels now reduces each named enchantment by that many and deletes it only at zero or below, matching upstream. Omitting the field still removes outright, since that is what older packs rely on. Nothing is clamped — 0 subtracts nothing and a negative raises the level, both of which are what upstream's plain subtraction does.
  • A biome-gated power fires in the biome it names.** origins:biome accepts a nested condition with its own small grammar, where in_tag means the biome is in a biome tag rather than anything about entity types. Only temperature had ever been implemented, so every other verb failed closed and a power written that way never activated in any biome at all, in_tag being much the most common of them. Now parsed: in_tag, precipitation, high_humidity, constant, not, a nested biome form for or-lists of exact ids, and all_of / any_of as the Apoli 2.9 spellings of and / or, each honouring inverted. Two details if you write them: precipitation answers for your block rather than the biome as a whole, and high_humidity keeps Apoli's 0.85 verbatim. An unknown sub-type still fails closed, which stays right here.
  • Five item conditions that were passing every stack instead of checking it.** An unimplemented item condition returned true — it accepted every stack rather than refusing it — so a herbivore restriction written against a verb we lack permitted meat while the power loaded, gated and ticked in apparent good order. That is the quieter failure of the two, and why these went unreported for so long. armor_value, meat, constant, harvest_level and durability are all implemented now. Two are worth knowing precisely: armor_value is what one stack confers rather than the wearer's total, and meat resolves through the NeoForge common food tags, so modded meats count. The honest limit: a verb still outside the list goes on passing, since flipping that default would make every unimplemented condition block everything across packs that work today.
  • Four block conditions that were matching every block, and the fallback that hid them.** An unimplemented verb compiled to nothing, which in_block, in_block_anywhere and the narrow neoorigins:block check all read as "match anything", while on_block discarded the filter outright and turned "standing on X" into "standing on anything". inverted was no protection, since inversion applies only to a condition that compiled, and it logged at debug with no warning — so a pack reload came back clean while light_level, exposed_to_sky, movement_blocking and fluid sat silently always-true: a sun-sensitive origin's slowness and blindness fired in the dark exactly as in the sun. All four verbs are implemented, since closing the fail-open alone would have swung those powers from always on to never on, and an unknown verb now matches nothing. The docs also stop calling in_block_anywhere an alias of in_block: the first samples one block, the second counts every position the hitbox overlaps. See [CONDITIONS.md](docs/CONDITIONS.md).

  • KubeJS scripting reaches the Minecraft 26.1 build.** It was 1.21.1 only because KubeJS had published nothing for 26.1, not because anything was tied to that version. The whole surface is on both builds now: the NeoOrigins and NeoOriginsEvents globals, all fifteen events, registerCallback with the neoorigins:kubejs_callback action behind it, and the two JavaScript-backed power types neoorigins:js_custom and neoorigins:js_active. Scripts move across without porting. Two install notes that are KubeJS's requirements rather than ours: the 26.1 build wants NeoForge 26.1.2.84 or newer before KubeJS will load at all, and on 1.21.1 registerPower needs Rhino 2101.2.8-build.91 or newer. **The 26.2 build does not get this and cannot yet**, since KubeJS has published nothing past Minecraft 26.1.2 to build against — and an unrecognised power type is dropped whole, so a js_custom power copied into a 26.2 pack never appears on the origin and nothing in game says why. [KUBEJS.md](docs/KUBEJS.md) documents the whole surface.

  • Air drain is counted per air point, not per bubble.** drain_rate_ticks is ticks per single air point, and the HUD draws 300 air as 10 bubbles, so one bubble is 30 points: at 1 a bubble lasts 1.5 seconds and the full bar 15; at 10, 15 seconds and 150. Reading it as ticks per bubble puts you out by a factor of thirty, which is where both reports came from. If your bar genuinely empties slower than the table says, an install predating 2.2.22 still holds the old default of 10, which this release moves for you on the next start. [POWER_TYPES.md](docs/POWER_TYPES.md) carries the arithmetic beside the table.
> Two new tools for pack authors, a pass over the ocean origins, and a fix for a bug that quietly undid part of your origin. neoorigins:ignore_fluid generalises ignore_water into a power that removes a fluid from the player's world outright: no buoyancy, no drag, no current push, no drowning, no lava burn, no fog, no swim pose, for modded fluids as much as vanilla ones. It gets there by intercepting fluid **detection** rather than each effect in turn, which is why third-party mods fall away with it. neoorigins:suppression is the first status effect NeoOrigins has ever registered: a ready-made ability lock to hang a boss mechanic, a debuff zone, or a PvP counter on. And size powers now stack across the origin and class layers, where picking a class used to wipe the origin layer's size instead of adding to it, so a Golem who took Titan stood at 1.25 rather than 1.55.
>
> The aquatic origins get the pass they have been owed. Two vanilla rules were quietly undoing their signature abilities the moment they left the seafloor, so they swam and mined at their best while standing on a block and worst while genuinely swimming, which is the wrong way round. Both are corrected. Merling can see in the dark from tier 0 rather than tier 2, Siren's Beached penalty stops following her into the water, and the night vision key no longer claims success on the forty-nine built-in origins that have no night vision to toggle. Alongside them, breath_out_of_fluid honours the drain rate you author, which it had been parsing and then discarding for every custom origin that set one.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • neoorigins:ignore_fluid makes a fluid stop existing for the player.** ignore_water removes water's speed penalty and its current pushing, and nothing else: you still float, still drown, still see the blue. The new power removes the fluid entirely. No buoyancy, no drag, no current push, no drowning, no lava burn, no fog or screen overlay, no swim pose. It works by intercepting fluid **detection** rather than cancelling each behaviour one at a time: the body scan that feeds buoyancy, drag, isInWater(), isInLava() and the swim pose hands back an empty fluid state for an ignored fluid, as does the eye scan behind drowning and the air bar, the camera query behind fog and the underwater distortion, and the block's own entityInside, which is how modded fluids deliver their damage. Because every vanilla fluid behaviour reads those same values, they all fall away together, and so do most third-party mods, since they ask the same standard questions. ignore_water is unchanged and still supported: reach for it when you only want the movement penalty gone, and for this when you want the fluid to stop registering at all.
  • Naming a fluid covers its whole type, and a bad id costs you nothing.** fluid takes a fluid id ("minecraft:lava"), a fluid tag ("#c:milk"), or an array of either; fluids is the plural spelling, and both keys are read and merged, so it does not matter which one you reach for. An entry without a namespace gets minecraft:. Naming any fluid of a type ignores the type, so "minecraft:water" also covers minecraft:flowing_water, which is what makes poured buckets work. If you give neither key the power defaults to water and lava, so a marker-only entry is never a silent no-op. An unknown or misspelled id is dropped quietly rather than failing the datapack load, which matters because the whole point is naming fluids from mods that may not be installed: parsing never touches the fluid registry, so an id for an absent mod cannot throw at load or during login sync. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference and worked examples.
  • What ignore_fluid deliberately does not reach.** Fluid rendering is untouched: the fluid still draws normally, you simply pass through it as if it were air. A mod that runs its own level.getFluidState(pos) check per tick, rather than asking the entity whether it is in a fluid, is doing its own detection and cannot be intercepted from here. The same goes for anything keyed off the block state rather than the fluid state. And one side effect is intended rather than tolerated: the entityInside guard is keyed on the block's fluid state, so a *waterlogged* block's own behaviour is suppressed too while you ignore water, which in practice means bubble columns stop pushing you. That is the honest reading of "water does not affect me". On Minecraft 26.1 and 26.2 there is a further limit, and it is worth reading before you write the pack: those versions track entity fluid interaction only for fluids in the minecraft:water and minecraft:lava tags, so an entry naming a fluid outside them is accepted and syncs its capability but drives nothing on the movement side. The entityInside guard still fires there, so a modded fluid's own damage is still cancelled even where its buoyancy and drag are not. The field shape is identical on every branch on purpose, so a pack written for 1.21.1 loads and validates unchanged on 26.x; just do not expect a modded fluid to stop pushing you there.
  • neoorigins:suppression: a status effect that locks a player out of their abilities.** The mod has never registered a status effect of its own before; this is the first, and it exists so you do not have to build an ability lock out of parts. While a player holds it, every active, keybind, and toggle power refuses to fire. A key press or a click in the power GUI gets an action bar line and a short sound, because an input that does nothing needs to come with a reason: unlike a cooldown, there is nothing on the HUD telling the player why. Refusals the player did not ask for stay silent, since neoorigins:activate_power and continuous held-key bindings can both fire every tick and announcing those would flood the action bar. A toggle power that is already on when the effect lands is forced off rather than left on and locked, which would otherwise strand a player mid-transformation with the one key that undoes it refused. The amplifier carries no meaning and is reserved. Delivery is /effect and the neoorigins:apply_effect action and nothing else: no brewing recipe, no tipped arrow, and no potion item, because a craftable ability lock is a balance decision that belongs to your pack rather than one the mod should make for every world.
  • Passive powers are left to you, because you can already gate them.** Suppression covers actives, keybinds, and toggles only. That is not an oversight and it is not a first instalment: put a power_condition on a passive that tests neoorigins:has_effect for neoorigins:suppression and leave the mode at its DENY default, and the power switches off for exactly as long as the effect is held. Building passive suppression into the effect would have duplicated a surface that already works. has_effect and status_effect resolve the new effect by id like any other, so nothing else was needed to reach it. See [COOKBOOK.md](docs/COOKBOOK.md) for the worked example.

  • Ocean origins keep their swim bonus when they leave the seafloor.** Reported on Discord: aquatic origins sink and swim badly unless they are walking along the bottom. That is exactly what the numbers said should happen. Every ocean origin's swim bonus, and the shared Natural Swimmer power on top of it, is built on minecraft:water_movement_efficiency, and vanilla halves that attribute outright whenever the swimmer is not on the ground. So the entire swim kit ran at half strength in open water and full strength only while the player was standing on a block, which inverts what an ocean origin is meant to feel like. A new shared power, *Open Water*, carries +0.25 neoforge:swim_speed, an attribute vanilla reads in the same pass with no such condition, and it is granted to Merling, Siren, Kraken, and Abyssal beside their existing speed powers rather than in place of them. Nothing about water_movement_efficiency changes, so bottom-walking is as fast as it ever was and this only lifts the mid-water case that was lagging behind it. The figure is deliberately short of parity: cancelling the halving outright would take roughly +0.55, and swim_speed is not water-gated, so that would have shown up as a land movement change as well. About +0.21 restores non-sprint terminal velocity underwater, and +0.25 clears that with a little room, matches the magnitude Merling's own tier 1 bonus uses, and lifts the vertical swim impulse, which is the part that reads as sinking when it is missing. Pack authors reach the same attribute: neoforge:swim_speed resolves straight from datapack JSON in attribute_modifier, with no alias needed, and [COOKBOOK.md](docs/COOKBOOK.md) now sets out when to reach for it and when for water_movement_efficiency.
  • Aquatic origins mine at full speed while they are actually swimming.** Also reported on Discord, and both halves of the report were accurate: Aqua Affinity says these origins mine at full speed submerged, and they did, but only with their feet planted on a block. Vanilla charges two independent penalties. The first is the submerged-mining attribute, applied when the eyes are in water, which underwater_mining_speed has always cancelled. The second is a flat divide by five a few lines later for anyone off the ground, and nothing in the mod touched it, so an aquatic origin paid a fifth of its speed for the whole time it was genuinely swimming and got the full rate only in the one posture the power was least meant for. That fifth is now refunded, gated on all three of eyes in water, off the ground, and holding the power. The off-ground penalty on dry land is a separate anti-cheese rule about mining out of a jump and is deliberately left alone. The correction reads the same synced value the client holds, so break progress is predicted correctly rather than the local player watching the slow animation while the server runs the fast one. Affects Merling, Siren, Kraken, and Abyssal, plus any pack origin using underwater_mining_speed.
  • Merling sees in the dark from tier 0, as Siren already did.** Reported as the night vision keybind doing nothing on a fresh Merling while working on a Siren. Both are ocean origins that spawn in deep water, so the difference read as a bug rather than a design line, and it was neither: Siren's base power list carried night vision and Merling's carried none at all. Merling only picked it up at tier 2, folded into the Ascended Conduit alongside water breathing and haste, which left two tiers of swimming around a pitch-black ocean floor with no way to see. *Deep Sight* is now a base power, a straight copy of Siren's Ocean Eyes, and it retires at tier 2 where the conduit takes over, mirroring how Caveborn swaps its base night vision for the ascended one. There is no gap: the same tier overlay that removes the base power grants the conduit, so night vision is continuous from tier 0 upward.

  • Size powers now stack across the origin and class layers instead of the last pick winning.** A Golem (1.3) who takes the Titan class (1.25) should stand at 1.55, and did not: whichever layer was picked most recently took effect and the other was lost, in both directions. The two obvious explanations were both wrong, which is part of what kept this alive. The modifier ids are already namespaced per power, so the origin and class layers were never colliding, and the maths was already additive: the JSON authors an absolute "scale": 1.3, but the power converts that to a delta and adds it, so the operation was correct too. The fault was in removal. Revoking any one size power cleared **every** neoorigins:size_* modifier on scale and on both interaction ranges, and the layer-change step then re-granted only the layer that had actually changed, so the other layer's size was gone for good. That also explains why it looked intermittent: the first time you were granted two size layers they really did stack, and the collapse only happened when you re-picked. The over-broad sweep was not careless, it was guarding a real bug. A power whose JSON is deleted or renamed leaves a modifier behind that nothing owns, and players were once left permanently rescaled by it. So rather than narrowing the sweep and reopening that, the two jobs are now separate: revoking a power clears only the modifiers that power itself created, and the sweep for genuinely orphaned modifiers moved to the layer-change step, which is the one place that knows the full set of powers a player still has and can therefore tell an orphan from another layer's live modifier. Twelve built-in size powers are affected: Golem, Kraken, Inchling, Tiny, Dwarf, Hiveling, Gorgon, Draconic, Breeze, Caveborn, Warden, and the Titan class. Reported on Discord.
  • On Minecraft 26.1 and 26.2, changing any layer wiped every other layer's attribute_modifier bonuses.** Found while porting the fix above, unreported and considerably wider than the size bug. Those two versions had no per-layer sweep at all and cleared every origin-owned attribute modifier whenever any layer changed, so picking a class stripped the max health, armour, and reach your origin granted, and picking an origin stripped the class's, until you relogged. Both branches now use the same targeted sweep as 1.21.1. Players on 26.1 and 26.2 will notice bonuses persisting that used to quietly disappear.
  • breath_out_of_fluid honours the drain rate you authored.** Reported on Discord: a custom origin built in the web editor always dried out in about twenty seconds whatever the field said, twenty ticks and two ticks alike. The power parsed the field correctly and then threw it away. A tick handler overwrote it with the global [ocean_origins] drain_rate_ticks config on every pass, so the authored value reached nothing and every custom origin dried out at the server's rate instead of its own. The override was deliberate rather than an oversight, but it was too broad: it was written to drive the four built-in aquatic origins from one config option, and it caught custom powers on the way past. The interval is now resolved per power in the same priority order breath_in_fluid already uses, air_loss_per_second first, then drain_interval_ticks, then drain_rate as the legacy spelling, and the config applies only when none of the three is present. That last clause is the whole fix. The four built-in *_dries_out powers author no drain field at all, so they still track the config exactly as #120 left them, while an origin that names a value gets the value it named; where several such powers apply at once, the tightest interval wins. The schema is what made this reportable rather than merely wrong: it advertised drain_rate with a default of forty and a description of what it would do, with nothing to say it was inert, and the editor builds its form from the schema. All three keys are described now, and [POWER_TYPES.md](docs/POWER_TYPES.md) carries the arithmetic, so land time in seconds is roughly (300 * drain_interval_ticks) / 20 and the number stays checkable against the behaviour.
  • Siren's Beached penalty no longer follows her into the water.** The power carried a fifteen percent movement penalty with no condition on it, so a Siren swam fifteen percent slower than every other ocean origin as well as walking that much slower. It is called Beached and described as a land penalty, which is what the other three ocean origins actually do: Merling, Kraken, and Abyssal all carry "condition": "on_land" on the same power, and Siren was the odd one out, with the penalty landing hardest exactly where the origin is supposed to be strong. It is gated on land now. Its description also said ten percent while the value has always been -0.15, so the text is corrected to fifteen rather than the value being changed: Merling is the one at ten percent, and the two were most likely copied and only half edited.
  • The night vision key no longer reports success on origins that have none.** Pressing it flipped the stored flag and printed a green "Night vision on" whatever you were playing, with no check that your origin had any night vision to switch. That flag is read in exactly one place, when deciding whether to apply a night vision effect an origin actually specifies, so on an origin without one the key was reporting success for an operation that could not have an effect. Forty-nine of the seventy-eight built-in origins are in that position, so this was the common case rather than the corner one. The key now refuses with a message when there is nothing to toggle, leaves the flag untouched, and re-sends the current state, so a client that has drifted still resyncs. A power gated on a condition still counts as owning night vision, since the question is whether the origin has it rather than whether it happens to be lit at that moment: otherwise a Caveborn who walked into daylight would be told they had none. The admin kill switch is unaffected and still takes precedence, so a server that has turned night vision off gives its own message regardless of what the player is playing.
  • A parameterised particle named by bare id no longer takes the whole power down with it.** Found while boot-testing this release against a third-party pack, unreported and not new to this cycle. mrt_chemist:immunity-shot failed to load on Minecraft 26.1 and 26.2 with "missing or unknown 'particle' field" while loading fine on 1.21.1, and the pack does nothing unusual: it writes "particle": "minecraft:dragon_breath". Minecraft 26 reclassified four particles that took no arguments on 1.21.1 into parameterised ones, dragon_breath, effect, instant_effect and flash, and the power accepted an argument-free particle only by bare id. So on those versions the four stopped resolving, and because the particle field is required, the failure dropped the entire power rather than just its decoration. A parameterised particle named with no arguments now falls back to its plainest form, opaque white at unit scale with no delay, which for those four is what they looked like before the reclassification, so a pack written for 1.21.1 renders unchanged on 26.x. The same fallback picks up entity_effect, dust, sculk_charge and shriek, which are parameterised on every version and were equally unusable bare. Particles that need a referent rather than a decoration, block, item and vibration, still require the object or inline-argument form: there is no honest default for which block, so those stay an error and say so.

  • The Blazeling entries described a version of the origin that has not shipped since 2.2.** Checked against the live JSON rather than against the previous text, and four of its powers were wrong: Blaze Scales is +6 max health, not natural armour; Nether-Born grants Speed in the Nether, not faster healing; and Internal Heat costs you hunger twenty-five percent faster, so it is a drawback rather than the passive warmth aura it was written up as. The tier table was wrong in both directions too. The second tier was listed as granting Fire Resistance, which 2.2 replaced with +4 max health, and its removal entry named a power that no longer exists, so it read as removing nothing; the third tier was described as removing the Evolved health bonus when it removes the Ascended one. [ORIGINS.md](docs/ORIGINS.md) and [EVOLUTION.md](docs/EVOLUTION.md) now match what the origin actually grants.
  • An on_fire condition can never be true on a fire-immune origin.** Worth knowing before you build a mechanic on it. Fire-immune players have their remaining fire ticks zeroed every tick, which was done deliberately to stop the burning overlay flickering on origins that cannot burn, and on_fire reads that same counter. So on Blazeling, or on anything else carrying prevent_action: fire, a power gated on on_fire is not merely unlikely to fire, it is structurally dead. [CONDITIONS.md](docs/CONDITIONS.md) says so now, and points at in_lava or a dimension test as the workable alternatives.
  • modify_reach scales by default, whatever the cookbook said.** [COOKBOOK.md](docs/COOKBOOK.md) had claimed since v1.14 that reach only scales when explicitly enabled. The field has defaulted to true on every branch for as long as it has existed, so anyone who wrote a size power expecting reach to stay put has been getting scaled reach the whole time. Corrected.
  • How the two layers stack is now written down.** The bug above was possible partly because nothing said what the intended behaviour was. [POWER_TYPES.md](docs/POWER_TYPES.md) now states the stacking rule under both size_scaling and attribute_modifier, [CLASSES.md](docs/CLASSES.md) has a section on how a class layer combines with the origin layer rather than replacing it, and [COOKBOOK.md](docs/COOKBOOK.md) gains the cross-layer pitfall as a worked case.
> Two new tools for pack authors, a pass over the ocean origins, and a fix for a bug that quietly undid part of your origin. neoorigins:ignore_fluid generalises ignore_water into a power that removes a fluid from the player's world outright: no buoyancy, no drag, no current push, no drowning, no lava burn, no fog, no swim pose, for modded fluids as much as vanilla ones. It gets there by intercepting fluid **detection** rather than each effect in turn, which is why third-party mods fall away with it. neoorigins:suppression is the first status effect NeoOrigins has ever registered: a ready-made ability lock to hang a boss mechanic, a debuff zone, or a PvP counter on. And size powers now stack across the origin and class layers, where picking a class used to wipe the origin layer's size instead of adding to it, so a Golem who took Titan stood at 1.25 rather than 1.55.
>
> The aquatic origins get the pass they have been owed. Two vanilla rules were quietly undoing their signature abilities the moment they left the seafloor, so they swam and mined at their best while standing on a block and worst while genuinely swimming, which is the wrong way round. Both are corrected. Merling can see in the dark from tier 0 rather than tier 2, Siren's Beached penalty stops following her into the water, and the night vision key no longer claims success on the forty-nine built-in origins that have no night vision to toggle. Alongside them, breath_out_of_fluid honours the drain rate you author, which it had been parsing and then discarding for every custom origin that set one.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • neoorigins:ignore_fluid makes a fluid stop existing for the player.** ignore_water removes water's speed penalty and its current pushing, and nothing else: you still float, still drown, still see the blue. The new power removes the fluid entirely. No buoyancy, no drag, no current push, no drowning, no lava burn, no fog or screen overlay, no swim pose. It works by intercepting fluid **detection** rather than cancelling each behaviour one at a time: the body scan that feeds buoyancy, drag, isInWater(), isInLava() and the swim pose hands back an empty fluid state for an ignored fluid, as does the eye scan behind drowning and the air bar, the camera query behind fog and the underwater distortion, and the block's own entityInside, which is how modded fluids deliver their damage. Because every vanilla fluid behaviour reads those same values, they all fall away together, and so do most third-party mods, since they ask the same standard questions. ignore_water is unchanged and still supported: reach for it when you only want the movement penalty gone, and for this when you want the fluid to stop registering at all.
  • Naming a fluid covers its whole type, and a bad id costs you nothing.** fluid takes a fluid id ("minecraft:lava"), a fluid tag ("#c:milk"), or an array of either; fluids is the plural spelling, and both keys are read and merged, so it does not matter which one you reach for. An entry without a namespace gets minecraft:. Naming any fluid of a type ignores the type, so "minecraft:water" also covers minecraft:flowing_water, which is what makes poured buckets work. If you give neither key the power defaults to water and lava, so a marker-only entry is never a silent no-op. An unknown or misspelled id is dropped quietly rather than failing the datapack load, which matters because the whole point is naming fluids from mods that may not be installed: parsing never touches the fluid registry, so an id for an absent mod cannot throw at load or during login sync. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference and worked examples.
  • What ignore_fluid deliberately does not reach.** Fluid rendering is untouched: the fluid still draws normally, you simply pass through it as if it were air. A mod that runs its own level.getFluidState(pos) check per tick, rather than asking the entity whether it is in a fluid, is doing its own detection and cannot be intercepted from here. The same goes for anything keyed off the block state rather than the fluid state. And one side effect is intended rather than tolerated: the entityInside guard is keyed on the block's fluid state, so a *waterlogged* block's own behaviour is suppressed too while you ignore water, which in practice means bubble columns stop pushing you. That is the honest reading of "water does not affect me". On Minecraft 26.1 and 26.2 there is a further limit, and it is worth reading before you write the pack: those versions track entity fluid interaction only for fluids in the minecraft:water and minecraft:lava tags, so an entry naming a fluid outside them is accepted and syncs its capability but drives nothing on the movement side. The entityInside guard still fires there, so a modded fluid's own damage is still cancelled even where its buoyancy and drag are not. The field shape is identical on every branch on purpose, so a pack written for 1.21.1 loads and validates unchanged on 26.x; just do not expect a modded fluid to stop pushing you there.
  • neoorigins:suppression: a status effect that locks a player out of their abilities.** The mod has never registered a status effect of its own before; this is the first, and it exists so you do not have to build an ability lock out of parts. While a player holds it, every active, keybind, and toggle power refuses to fire. A key press or a click in the power GUI gets an action bar line and a short sound, because an input that does nothing needs to come with a reason: unlike a cooldown, there is nothing on the HUD telling the player why. Refusals the player did not ask for stay silent, since neoorigins:activate_power and continuous held-key bindings can both fire every tick and announcing those would flood the action bar. A toggle power that is already on when the effect lands is forced off rather than left on and locked, which would otherwise strand a player mid-transformation with the one key that undoes it refused. The amplifier carries no meaning and is reserved. Delivery is /effect and the neoorigins:apply_effect action and nothing else: no brewing recipe, no tipped arrow, and no potion item, because a craftable ability lock is a balance decision that belongs to your pack rather than one the mod should make for every world.
  • Passive powers are left to you, because you can already gate them.** Suppression covers actives, keybinds, and toggles only. That is not an oversight and it is not a first instalment: put a power_condition on a passive that tests neoorigins:has_effect for neoorigins:suppression and leave the mode at its DENY default, and the power switches off for exactly as long as the effect is held. Building passive suppression into the effect would have duplicated a surface that already works. has_effect and status_effect resolve the new effect by id like any other, so nothing else was needed to reach it. See [COOKBOOK.md](docs/COOKBOOK.md) for the worked example.

  • Ocean origins keep their swim bonus when they leave the seafloor.** Reported on Discord: aquatic origins sink and swim badly unless they are walking along the bottom. That is exactly what the numbers said should happen. Every ocean origin's swim bonus, and the shared Natural Swimmer power on top of it, is built on minecraft:water_movement_efficiency, and vanilla halves that attribute outright whenever the swimmer is not on the ground. So the entire swim kit ran at half strength in open water and full strength only while the player was standing on a block, which inverts what an ocean origin is meant to feel like. A new shared power, *Open Water*, carries +0.25 neoforge:swim_speed, an attribute vanilla reads in the same pass with no such condition, and it is granted to Merling, Siren, Kraken, and Abyssal beside their existing speed powers rather than in place of them. Nothing about water_movement_efficiency changes, so bottom-walking is as fast as it ever was and this only lifts the mid-water case that was lagging behind it. The figure is deliberately short of parity: cancelling the halving outright would take roughly +0.55, and swim_speed is not water-gated, so that would have shown up as a land movement change as well. About +0.21 restores non-sprint terminal velocity underwater, and +0.25 clears that with a little room, matches the magnitude Merling's own tier 1 bonus uses, and lifts the vertical swim impulse, which is the part that reads as sinking when it is missing. Pack authors reach the same attribute: neoforge:swim_speed resolves straight from datapack JSON in attribute_modifier, with no alias needed, and [COOKBOOK.md](docs/COOKBOOK.md) now sets out when to reach for it and when for water_movement_efficiency.
  • Aquatic origins mine at full speed while they are actually swimming.** Also reported on Discord, and both halves of the report were accurate: Aqua Affinity says these origins mine at full speed submerged, and they did, but only with their feet planted on a block. Vanilla charges two independent penalties. The first is the submerged-mining attribute, applied when the eyes are in water, which underwater_mining_speed has always cancelled. The second is a flat divide by five a few lines later for anyone off the ground, and nothing in the mod touched it, so an aquatic origin paid a fifth of its speed for the whole time it was genuinely swimming and got the full rate only in the one posture the power was least meant for. That fifth is now refunded, gated on all three of eyes in water, off the ground, and holding the power. The off-ground penalty on dry land is a separate anti-cheese rule about mining out of a jump and is deliberately left alone. The correction reads the same synced value the client holds, so break progress is predicted correctly rather than the local player watching the slow animation while the server runs the fast one. Affects Merling, Siren, Kraken, and Abyssal, plus any pack origin using underwater_mining_speed.
  • Merling sees in the dark from tier 0, as Siren already did.** Reported as the night vision keybind doing nothing on a fresh Merling while working on a Siren. Both are ocean origins that spawn in deep water, so the difference read as a bug rather than a design line, and it was neither: Siren's base power list carried night vision and Merling's carried none at all. Merling only picked it up at tier 2, folded into the Ascended Conduit alongside water breathing and haste, which left two tiers of swimming around a pitch-black ocean floor with no way to see. *Deep Sight* is now a base power, a straight copy of Siren's Ocean Eyes, and it retires at tier 2 where the conduit takes over, mirroring how Caveborn swaps its base night vision for the ascended one. There is no gap: the same tier overlay that removes the base power grants the conduit, so night vision is continuous from tier 0 upward.

  • Size powers now stack across the origin and class layers instead of the last pick winning.** A Golem (1.3) who takes the Titan class (1.25) should stand at 1.55, and did not: whichever layer was picked most recently took effect and the other was lost, in both directions. The two obvious explanations were both wrong, which is part of what kept this alive. The modifier ids are already namespaced per power, so the origin and class layers were never colliding, and the maths was already additive: the JSON authors an absolute "scale": 1.3, but the power converts that to a delta and adds it, so the operation was correct too. The fault was in removal. Revoking any one size power cleared **every** neoorigins:size_* modifier on scale and on both interaction ranges, and the layer-change step then re-granted only the layer that had actually changed, so the other layer's size was gone for good. That also explains why it looked intermittent: the first time you were granted two size layers they really did stack, and the collapse only happened when you re-picked. The over-broad sweep was not careless, it was guarding a real bug. A power whose JSON is deleted or renamed leaves a modifier behind that nothing owns, and players were once left permanently rescaled by it. So rather than narrowing the sweep and reopening that, the two jobs are now separate: revoking a power clears only the modifiers that power itself created, and the sweep for genuinely orphaned modifiers moved to the layer-change step, which is the one place that knows the full set of powers a player still has and can therefore tell an orphan from another layer's live modifier. Twelve built-in size powers are affected: Golem, Kraken, Inchling, Tiny, Dwarf, Hiveling, Gorgon, Draconic, Breeze, Caveborn, Warden, and the Titan class. Reported on Discord.
  • On Minecraft 26.1 and 26.2, changing any layer wiped every other layer's attribute_modifier bonuses.** Found while porting the fix above, unreported and considerably wider than the size bug. Those two versions had no per-layer sweep at all and cleared every origin-owned attribute modifier whenever any layer changed, so picking a class stripped the max health, armour, and reach your origin granted, and picking an origin stripped the class's, until you relogged. Both branches now use the same targeted sweep as 1.21.1. Players on 26.1 and 26.2 will notice bonuses persisting that used to quietly disappear.
  • breath_out_of_fluid honours the drain rate you authored.** Reported on Discord: a custom origin built in the web editor always dried out in about twenty seconds whatever the field said, twenty ticks and two ticks alike. The power parsed the field correctly and then threw it away. A tick handler overwrote it with the global [ocean_origins] drain_rate_ticks config on every pass, so the authored value reached nothing and every custom origin dried out at the server's rate instead of its own. The override was deliberate rather than an oversight, but it was too broad: it was written to drive the four built-in aquatic origins from one config option, and it caught custom powers on the way past. The interval is now resolved per power in the same priority order breath_in_fluid already uses, air_loss_per_second first, then drain_interval_ticks, then drain_rate as the legacy spelling, and the config applies only when none of the three is present. That last clause is the whole fix. The four built-in *_dries_out powers author no drain field at all, so they still track the config exactly as #120 left them, while an origin that names a value gets the value it named; where several such powers apply at once, the tightest interval wins. The schema is what made this reportable rather than merely wrong: it advertised drain_rate with a default of forty and a description of what it would do, with nothing to say it was inert, and the editor builds its form from the schema. All three keys are described now, and [POWER_TYPES.md](docs/POWER_TYPES.md) carries the arithmetic, so land time in seconds is roughly (300 * drain_interval_ticks) / 20 and the number stays checkable against the behaviour.
  • Siren's Beached penalty no longer follows her into the water.** The power carried a fifteen percent movement penalty with no condition on it, so a Siren swam fifteen percent slower than every other ocean origin as well as walking that much slower. It is called Beached and described as a land penalty, which is what the other three ocean origins actually do: Merling, Kraken, and Abyssal all carry "condition": "on_land" on the same power, and Siren was the odd one out, with the penalty landing hardest exactly where the origin is supposed to be strong. It is gated on land now. Its description also said ten percent while the value has always been -0.15, so the text is corrected to fifteen rather than the value being changed: Merling is the one at ten percent, and the two were most likely copied and only half edited.
  • The night vision key no longer reports success on origins that have none.** Pressing it flipped the stored flag and printed a green "Night vision on" whatever you were playing, with no check that your origin had any night vision to switch. That flag is read in exactly one place, when deciding whether to apply a night vision effect an origin actually specifies, so on an origin without one the key was reporting success for an operation that could not have an effect. Forty-nine of the seventy-eight built-in origins are in that position, so this was the common case rather than the corner one. The key now refuses with a message when there is nothing to toggle, leaves the flag untouched, and re-sends the current state, so a client that has drifted still resyncs. A power gated on a condition still counts as owning night vision, since the question is whether the origin has it rather than whether it happens to be lit at that moment: otherwise a Caveborn who walked into daylight would be told they had none. The admin kill switch is unaffected and still takes precedence, so a server that has turned night vision off gives its own message regardless of what the player is playing.
  • A parameterised particle named by bare id no longer takes the whole power down with it.** Found while boot-testing this release against a third-party pack, unreported and not new to this cycle. mrt_chemist:immunity-shot failed to load on Minecraft 26.1 and 26.2 with "missing or unknown 'particle' field" while loading fine on 1.21.1, and the pack does nothing unusual: it writes "particle": "minecraft:dragon_breath". Minecraft 26 reclassified four particles that took no arguments on 1.21.1 into parameterised ones, dragon_breath, effect, instant_effect and flash, and the power accepted an argument-free particle only by bare id. So on those versions the four stopped resolving, and because the particle field is required, the failure dropped the entire power rather than just its decoration. A parameterised particle named with no arguments now falls back to its plainest form, opaque white at unit scale with no delay, which for those four is what they looked like before the reclassification, so a pack written for 1.21.1 renders unchanged on 26.x. The same fallback picks up entity_effect, dust, sculk_charge and shriek, which are parameterised on every version and were equally unusable bare. Particles that need a referent rather than a decoration, block, item and vibration, still require the object or inline-argument form: there is no honest default for which block, so those stay an error and say so.

  • The Blazeling entries described a version of the origin that has not shipped since 2.2.** Checked against the live JSON rather than against the previous text, and four of its powers were wrong: Blaze Scales is +6 max health, not natural armour; Nether-Born grants Speed in the Nether, not faster healing; and Internal Heat costs you hunger twenty-five percent faster, so it is a drawback rather than the passive warmth aura it was written up as. The tier table was wrong in both directions too. The second tier was listed as granting Fire Resistance, which 2.2 replaced with +4 max health, and its removal entry named a power that no longer exists, so it read as removing nothing; the third tier was described as removing the Evolved health bonus when it removes the Ascended one. [ORIGINS.md](docs/ORIGINS.md) and [EVOLUTION.md](docs/EVOLUTION.md) now match what the origin actually grants.
  • An on_fire condition can never be true on a fire-immune origin.** Worth knowing before you build a mechanic on it. Fire-immune players have their remaining fire ticks zeroed every tick, which was done deliberately to stop the burning overlay flickering on origins that cannot burn, and on_fire reads that same counter. So on Blazeling, or on anything else carrying prevent_action: fire, a power gated on on_fire is not merely unlikely to fire, it is structurally dead. [CONDITIONS.md](docs/CONDITIONS.md) says so now, and points at in_lava or a dimension test as the workable alternatives.
  • modify_reach scales by default, whatever the cookbook said.** [COOKBOOK.md](docs/COOKBOOK.md) had claimed since v1.14 that reach only scales when explicitly enabled. The field has defaulted to true on every branch for as long as it has existed, so anyone who wrote a size power expecting reach to stay put has been getting scaled reach the whole time. Corrected.
  • How the two layers stack is now written down.** The bug above was possible partly because nothing said what the intended behaviour was. [POWER_TYPES.md](docs/POWER_TYPES.md) now states the stacking rule under both size_scaling and attribute_modifier, [CLASSES.md](docs/CLASSES.md) has a section on how a class layer combines with the origin layer rather than replacing it, and [COOKBOOK.md](docs/COOKBOOK.md) gains the cross-layer pitfall as a worked case.
> Two new tools for pack authors, a pass over the ocean origins, and a fix for a bug that quietly undid part of your origin. neoorigins:ignore_fluid generalises ignore_water into a power that removes a fluid from the player's world outright: no buoyancy, no drag, no current push, no drowning, no lava burn, no fog, no swim pose, for modded fluids as much as vanilla ones. It gets there by intercepting fluid **detection** rather than each effect in turn, which is why third-party mods fall away with it. neoorigins:suppression is the first status effect NeoOrigins has ever registered: a ready-made ability lock to hang a boss mechanic, a debuff zone, or a PvP counter on. And size powers now stack across the origin and class layers, where picking a class used to wipe the origin layer's size instead of adding to it, so a Golem who took Titan stood at 1.25 rather than 1.55.
>
> The aquatic origins get the pass they have been owed. Two vanilla rules were quietly undoing their signature abilities the moment they left the seafloor, so they swam and mined at their best while standing on a block and worst while genuinely swimming, which is the wrong way round. Both are corrected. Merling can see in the dark from tier 0 rather than tier 2, Siren's Beached penalty stops following her into the water, and the night vision key no longer claims success on the forty-nine built-in origins that have no night vision to toggle. Alongside them, breath_out_of_fluid honours the drain rate you author, which it had been parsing and then discarding for every custom origin that set one.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • neoorigins:ignore_fluid makes a fluid stop existing for the player.** ignore_water removes water's speed penalty and its current pushing, and nothing else: you still float, still drown, still see the blue. The new power removes the fluid entirely. No buoyancy, no drag, no current push, no drowning, no lava burn, no fog or screen overlay, no swim pose. It works by intercepting fluid **detection** rather than cancelling each behaviour one at a time: the body scan that feeds buoyancy, drag, isInWater(), isInLava() and the swim pose hands back an empty fluid state for an ignored fluid, as does the eye scan behind drowning and the air bar, the camera query behind fog and the underwater distortion, and the block's own entityInside, which is how modded fluids deliver their damage. Because every vanilla fluid behaviour reads those same values, they all fall away together, and so do most third-party mods, since they ask the same standard questions. ignore_water is unchanged and still supported: reach for it when you only want the movement penalty gone, and for this when you want the fluid to stop registering at all.
  • Naming a fluid covers its whole type, and a bad id costs you nothing.** fluid takes a fluid id ("minecraft:lava"), a fluid tag ("#c:milk"), or an array of either; fluids is the plural spelling, and both keys are read and merged, so it does not matter which one you reach for. An entry without a namespace gets minecraft:. Naming any fluid of a type ignores the type, so "minecraft:water" also covers minecraft:flowing_water, which is what makes poured buckets work. If you give neither key the power defaults to water and lava, so a marker-only entry is never a silent no-op. An unknown or misspelled id is dropped quietly rather than failing the datapack load, which matters because the whole point is naming fluids from mods that may not be installed: parsing never touches the fluid registry, so an id for an absent mod cannot throw at load or during login sync. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference and worked examples.
  • What ignore_fluid deliberately does not reach.** Fluid rendering is untouched: the fluid still draws normally, you simply pass through it as if it were air. A mod that runs its own level.getFluidState(pos) check per tick, rather than asking the entity whether it is in a fluid, is doing its own detection and cannot be intercepted from here. The same goes for anything keyed off the block state rather than the fluid state. And one side effect is intended rather than tolerated: the entityInside guard is keyed on the block's fluid state, so a *waterlogged* block's own behaviour is suppressed too while you ignore water, which in practice means bubble columns stop pushing you. That is the honest reading of "water does not affect me". On Minecraft 26.1 and 26.2 there is a further limit, and it is worth reading before you write the pack: those versions track entity fluid interaction only for fluids in the minecraft:water and minecraft:lava tags, so an entry naming a fluid outside them is accepted and syncs its capability but drives nothing on the movement side. The entityInside guard still fires there, so a modded fluid's own damage is still cancelled even where its buoyancy and drag are not. The field shape is identical on every branch on purpose, so a pack written for 1.21.1 loads and validates unchanged on 26.x; just do not expect a modded fluid to stop pushing you there.
  • neoorigins:suppression: a status effect that locks a player out of their abilities.** The mod has never registered a status effect of its own before; this is the first, and it exists so you do not have to build an ability lock out of parts. While a player holds it, every active, keybind, and toggle power refuses to fire. A key press or a click in the power GUI gets an action bar line and a short sound, because an input that does nothing needs to come with a reason: unlike a cooldown, there is nothing on the HUD telling the player why. Refusals the player did not ask for stay silent, since neoorigins:activate_power and continuous held-key bindings can both fire every tick and announcing those would flood the action bar. A toggle power that is already on when the effect lands is forced off rather than left on and locked, which would otherwise strand a player mid-transformation with the one key that undoes it refused. The amplifier carries no meaning and is reserved. Delivery is /effect and the neoorigins:apply_effect action and nothing else: no brewing recipe, no tipped arrow, and no potion item, because a craftable ability lock is a balance decision that belongs to your pack rather than one the mod should make for every world.
  • Passive powers are left to you, because you can already gate them.** Suppression covers actives, keybinds, and toggles only. That is not an oversight and it is not a first instalment: put a power_condition on a passive that tests neoorigins:has_effect for neoorigins:suppression and leave the mode at its DENY default, and the power switches off for exactly as long as the effect is held. Building passive suppression into the effect would have duplicated a surface that already works. has_effect and status_effect resolve the new effect by id like any other, so nothing else was needed to reach it. See [COOKBOOK.md](docs/COOKBOOK.md) for the worked example.

  • Ocean origins keep their swim bonus when they leave the seafloor.** Reported on Discord: aquatic origins sink and swim badly unless they are walking along the bottom. That is exactly what the numbers said should happen. Every ocean origin's swim bonus, and the shared Natural Swimmer power on top of it, is built on minecraft:water_movement_efficiency, and vanilla halves that attribute outright whenever the swimmer is not on the ground. So the entire swim kit ran at half strength in open water and full strength only while the player was standing on a block, which inverts what an ocean origin is meant to feel like. A new shared power, *Open Water*, carries +0.25 neoforge:swim_speed, an attribute vanilla reads in the same pass with no such condition, and it is granted to Merling, Siren, Kraken, and Abyssal beside their existing speed powers rather than in place of them. Nothing about water_movement_efficiency changes, so bottom-walking is as fast as it ever was and this only lifts the mid-water case that was lagging behind it. The figure is deliberately short of parity: cancelling the halving outright would take roughly +0.55, and swim_speed is not water-gated, so that would have shown up as a land movement change as well. About +0.21 restores non-sprint terminal velocity underwater, and +0.25 clears that with a little room, matches the magnitude Merling's own tier 1 bonus uses, and lifts the vertical swim impulse, which is the part that reads as sinking when it is missing. Pack authors reach the same attribute: neoforge:swim_speed resolves straight from datapack JSON in attribute_modifier, with no alias needed, and [COOKBOOK.md](docs/COOKBOOK.md) now sets out when to reach for it and when for water_movement_efficiency.
  • Aquatic origins mine at full speed while they are actually swimming.** Also reported on Discord, and both halves of the report were accurate: Aqua Affinity says these origins mine at full speed submerged, and they did, but only with their feet planted on a block. Vanilla charges two independent penalties. The first is the submerged-mining attribute, applied when the eyes are in water, which underwater_mining_speed has always cancelled. The second is a flat divide by five a few lines later for anyone off the ground, and nothing in the mod touched it, so an aquatic origin paid a fifth of its speed for the whole time it was genuinely swimming and got the full rate only in the one posture the power was least meant for. That fifth is now refunded, gated on all three of eyes in water, off the ground, and holding the power. The off-ground penalty on dry land is a separate anti-cheese rule about mining out of a jump and is deliberately left alone. The correction reads the same synced value the client holds, so break progress is predicted correctly rather than the local player watching the slow animation while the server runs the fast one. Affects Merling, Siren, Kraken, and Abyssal, plus any pack origin using underwater_mining_speed.
  • Merling sees in the dark from tier 0, as Siren already did.** Reported as the night vision keybind doing nothing on a fresh Merling while working on a Siren. Both are ocean origins that spawn in deep water, so the difference read as a bug rather than a design line, and it was neither: Siren's base power list carried night vision and Merling's carried none at all. Merling only picked it up at tier 2, folded into the Ascended Conduit alongside water breathing and haste, which left two tiers of swimming around a pitch-black ocean floor with no way to see. *Deep Sight* is now a base power, a straight copy of Siren's Ocean Eyes, and it retires at tier 2 where the conduit takes over, mirroring how Caveborn swaps its base night vision for the ascended one. There is no gap: the same tier overlay that removes the base power grants the conduit, so night vision is continuous from tier 0 upward.

  • Size powers now stack across the origin and class layers instead of the last pick winning.** A Golem (1.3) who takes the Titan class (1.25) should stand at 1.55, and did not: whichever layer was picked most recently took effect and the other was lost, in both directions. The two obvious explanations were both wrong, which is part of what kept this alive. The modifier ids are already namespaced per power, so the origin and class layers were never colliding, and the maths was already additive: the JSON authors an absolute "scale": 1.3, but the power converts that to a delta and adds it, so the operation was correct too. The fault was in removal. Revoking any one size power cleared **every** neoorigins:size_* modifier on scale and on both interaction ranges, and the layer-change step then re-granted only the layer that had actually changed, so the other layer's size was gone for good. That also explains why it looked intermittent: the first time you were granted two size layers they really did stack, and the collapse only happened when you re-picked. The over-broad sweep was not careless, it was guarding a real bug. A power whose JSON is deleted or renamed leaves a modifier behind that nothing owns, and players were once left permanently rescaled by it. So rather than narrowing the sweep and reopening that, the two jobs are now separate: revoking a power clears only the modifiers that power itself created, and the sweep for genuinely orphaned modifiers moved to the layer-change step, which is the one place that knows the full set of powers a player still has and can therefore tell an orphan from another layer's live modifier. Twelve built-in size powers are affected: Golem, Kraken, Inchling, Tiny, Dwarf, Hiveling, Gorgon, Draconic, Breeze, Caveborn, Warden, and the Titan class. Reported on Discord.
  • On Minecraft 26.1 and 26.2, changing any layer wiped every other layer's attribute_modifier bonuses.** Found while porting the fix above, unreported and considerably wider than the size bug. Those two versions had no per-layer sweep at all and cleared every origin-owned attribute modifier whenever any layer changed, so picking a class stripped the max health, armour, and reach your origin granted, and picking an origin stripped the class's, until you relogged. Both branches now use the same targeted sweep as 1.21.1. Players on 26.1 and 26.2 will notice bonuses persisting that used to quietly disappear.
  • breath_out_of_fluid honours the drain rate you authored.** Reported on Discord: a custom origin built in the web editor always dried out in about twenty seconds whatever the field said, twenty ticks and two ticks alike. The power parsed the field correctly and then threw it away. A tick handler overwrote it with the global [ocean_origins] drain_rate_ticks config on every pass, so the authored value reached nothing and every custom origin dried out at the server's rate instead of its own. The override was deliberate rather than an oversight, but it was too broad: it was written to drive the four built-in aquatic origins from one config option, and it caught custom powers on the way past. The interval is now resolved per power in the same priority order breath_in_fluid already uses, air_loss_per_second first, then drain_interval_ticks, then drain_rate as the legacy spelling, and the config applies only when none of the three is present. That last clause is the whole fix. The four built-in *_dries_out powers author no drain field at all, so they still track the config exactly as #120 left them, while an origin that names a value gets the value it named; where several such powers apply at once, the tightest interval wins. The schema is what made this reportable rather than merely wrong: it advertised drain_rate with a default of forty and a description of what it would do, with nothing to say it was inert, and the editor builds its form from the schema. All three keys are described now, and [POWER_TYPES.md](docs/POWER_TYPES.md) carries the arithmetic, so land time in seconds is roughly (300 * drain_interval_ticks) / 20 and the number stays checkable against the behaviour.
  • Siren's Beached penalty no longer follows her into the water.** The power carried a fifteen percent movement penalty with no condition on it, so a Siren swam fifteen percent slower than every other ocean origin as well as walking that much slower. It is called Beached and described as a land penalty, which is what the other three ocean origins actually do: Merling, Kraken, and Abyssal all carry "condition": "on_land" on the same power, and Siren was the odd one out, with the penalty landing hardest exactly where the origin is supposed to be strong. It is gated on land now. Its description also said ten percent while the value has always been -0.15, so the text is corrected to fifteen rather than the value being changed: Merling is the one at ten percent, and the two were most likely copied and only half edited.
  • The night vision key no longer reports success on origins that have none.** Pressing it flipped the stored flag and printed a green "Night vision on" whatever you were playing, with no check that your origin had any night vision to switch. That flag is read in exactly one place, when deciding whether to apply a night vision effect an origin actually specifies, so on an origin without one the key was reporting success for an operation that could not have an effect. Forty-nine of the seventy-eight built-in origins are in that position, so this was the common case rather than the corner one. The key now refuses with a message when there is nothing to toggle, leaves the flag untouched, and re-sends the current state, so a client that has drifted still resyncs. A power gated on a condition still counts as owning night vision, since the question is whether the origin has it rather than whether it happens to be lit at that moment: otherwise a Caveborn who walked into daylight would be told they had none. The admin kill switch is unaffected and still takes precedence, so a server that has turned night vision off gives its own message regardless of what the player is playing.
  • A parameterised particle named by bare id no longer takes the whole power down with it.** Found while boot-testing this release against a third-party pack, unreported and not new to this cycle. mrt_chemist:immunity-shot failed to load on Minecraft 26.1 and 26.2 with "missing or unknown 'particle' field" while loading fine on 1.21.1, and the pack does nothing unusual: it writes "particle": "minecraft:dragon_breath". Minecraft 26 reclassified four particles that took no arguments on 1.21.1 into parameterised ones, dragon_breath, effect, instant_effect and flash, and the power accepted an argument-free particle only by bare id. So on those versions the four stopped resolving, and because the particle field is required, the failure dropped the entire power rather than just its decoration. A parameterised particle named with no arguments now falls back to its plainest form, opaque white at unit scale with no delay, which for those four is what they looked like before the reclassification, so a pack written for 1.21.1 renders unchanged on 26.x. The same fallback picks up entity_effect, dust, sculk_charge and shriek, which are parameterised on every version and were equally unusable bare. Particles that need a referent rather than a decoration, block, item and vibration, still require the object or inline-argument form: there is no honest default for which block, so those stay an error and say so.

  • The Blazeling entries described a version of the origin that has not shipped since 2.2.** Checked against the live JSON rather than against the previous text, and four of its powers were wrong: Blaze Scales is +6 max health, not natural armour; Nether-Born grants Speed in the Nether, not faster healing; and Internal Heat costs you hunger twenty-five percent faster, so it is a drawback rather than the passive warmth aura it was written up as. The tier table was wrong in both directions too. The second tier was listed as granting Fire Resistance, which 2.2 replaced with +4 max health, and its removal entry named a power that no longer exists, so it read as removing nothing; the third tier was described as removing the Evolved health bonus when it removes the Ascended one. [ORIGINS.md](docs/ORIGINS.md) and [EVOLUTION.md](docs/EVOLUTION.md) now match what the origin actually grants.
  • An on_fire condition can never be true on a fire-immune origin.** Worth knowing before you build a mechanic on it. Fire-immune players have their remaining fire ticks zeroed every tick, which was done deliberately to stop the burning overlay flickering on origins that cannot burn, and on_fire reads that same counter. So on Blazeling, or on anything else carrying prevent_action: fire, a power gated on on_fire is not merely unlikely to fire, it is structurally dead. [CONDITIONS.md](docs/CONDITIONS.md) says so now, and points at in_lava or a dimension test as the workable alternatives.
  • modify_reach scales by default, whatever the cookbook said.** [COOKBOOK.md](docs/COOKBOOK.md) had claimed since v1.14 that reach only scales when explicitly enabled. The field has defaulted to true on every branch for as long as it has existed, so anyone who wrote a size power expecting reach to stay put has been getting scaled reach the whole time. Corrected.
  • How the two layers stack is now written down.** The bug above was possible partly because nothing said what the intended behaviour was. [POWER_TYPES.md](docs/POWER_TYPES.md) now states the stacking rule under both size_scaling and attribute_modifier, [CLASSES.md](docs/CLASSES.md) has a section on how a class layer combines with the origin layer rather than replacing it, and [COOKBOOK.md](docs/COOKBOOK.md) gains the cross-layer pitfall as a worked case.
> A legacy-compatibility and morphing release. The headline: two compatibility actions that packs lean on constantly turn out never to have worked. apply_effect resolved its effect id only from a bare string, but two hundred and fourteen of the two hundred and twenty-eight uses in the pack corpus nest it in an object, so those powers loaded, appeared on the origin, and applied nothing at all; origins:choice read the wrong key for its wrapped action, so it rolled a branch and then ran nothing. Both are fixed. Legacy 1.20-era packs also have their .mcfunction files rewritten as they are read, which took a Fairytale Origins test install from forty-two failed function loads down to nine (#118), and entity_model grows from a bare model swap into a full morph system with datapack-defined morphs, matching hitboxes, borrowed entity sounds, skin overrides, and first-person arms. Plus ten more legacy Apoli conditions understood instead of failing closed, real editor forms for twenty-nine alias power types that used to render as raw JSON, and three stability fixes: ocean origins no longer hang the server while picking a spawn point, origins:lava_vision no longer paints the whole screen a flat colour (#121), and aquatic origins dry out on land in the fifteen seconds vanilla fish get rather than two and a half minutes (#120), though an existing config file keeps the old value until you edit it.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • entity_model is now a full morph system, not just a model swap.** The power previously took a single entity_type and rendered you as that model. It now describes a whole morph. nbt selects a variant (sheep colour, villager profession, slime size); scale (default 1.0) sizes both model and hitbox; hitbox (default true) swaps your actual collision box and eye height to match, so a slime morph really does fit where a slime fits; render_held_item and render_armor (both default true) control whether your gear draws on the morph; first_person (default "item") chooses what you see in your own hands, accepting "item", "arm" for the morph's own limb, or "hidden"; and arm names an explicit bone if the automatic search picks the wrong one. Morph state is broadcast to every client tracking you, so other players see the morph too, not just you.
  • Datapack-defined morphs.** A file at data/<namespace>/neoorigins/morphs/<name>.json declares a reusable morph, and a power references it with "morph": "<id>" instead of spelling every field out inline. A bare name resolves to neoorigins:<name>, and a file whose id matches a built-in overrides it. Ten morphs ship built in (slime, magma cube, sheep, cat, villager, creeper, zombie, skeleton, enderman, and spider), and all are datapack-overridable. An unknown morph id logs a one-time warning and resolves to no morph rather than failing the power. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the full field reference.
  • Morphs can borrow the entity's sounds and reskin the player.** entity_sounds (default true) makes your hurt, death, fall, swim, and splash sounds come from the morph's entity type. A sounds object overrides any of them individually by sound-event id (hurt, death, fall_small, fall_big, swim, splash, splash_high_speed). For player-shaped morphs, a skin block sets texture, cape, and elytra asset ids and a model of "slim" or "wide"; anything left unset falls through to the player's real skin, so you can restyle only the parts you care about. Step sounds still come from the block underfoot, as in vanilla.
  • Twenty-nine legacy alias power types now have real editor forms.** Legacy types carried by the compatibility layer (the four persistent-effect aliases, seven condition_passive aliases, fourteen action_on_event aliases, and four stragglers) had no schema branch of their own, so both the web editor and the in-game editor fell back to a raw-JSON box and left the author to spell every field from memory. All twenty-nine are now modelled, and the allowlist that exempted them is empty. Alongside that: the power type picker is grouped by namespace and reads compatibility types straight off the parser rather than the native registry alone, so nothing is missing from the list; scalar-or-array reference fields (roughly twenty of them) render as proper pickers in both editors instead of raw JSON; and the top-level enabled kill switch and action_on_event's hit_dealt event are declared where they were being read but not described. The thirty-one native types that fall back to codec reflection, among them multiple, status_effect, glow, and night_vision, get their display name, description, hidden flag, and required_mods rows back. Those keys belong to no power's config record, so the fallback path had never offered them even though a datapack could always write them by hand.
  • The schemas no longer reject JSON the mod itself accepts.** Three separate cases where the editors flagged a perfectly good file as invalid. The layer schema never declared standalone, took name as a plain string only, and allowed only bare-id or single-object origin entries, while the layer loader accepts all three of the shapes it left out. The item-condition schema demanded a type that the parser has never needed, so the typeless id / item / tag shorthand, which NeoOrigins' own Jianxian powers use, failed the mod's own schema. And prevent_action declared its two enums in lowercase only, though the power upper-cases before matching, so the sixteen shipped powers written in SCREAMING_CASE were all reported invalid while working perfectly in game. All three now describe what the loader actually does.
  • The web editor imports upstream Origins-layout packs.** The importer matched only the editor's own native layout, so every pack laid out the Origins way failed at the origin step. It now tries native then compatibility layouts for origins, layers, and powers, the same pairing the server-side loaders already use, with the compatibility pattern excluding sibling directories, so origins/powers/foo.json no longer imports as an origin called powers/foo. Three ways it used to lose data are fixed alongside. It read only the nine origin fields the Identity tab covers and discarded the other six, so a round trip through the editor silently stripped evolution tiers, spawn placement, required mods, the special flag, and Figura model keys. Fifty-eight of the seventy-eight shipped origins carry tier powers, so that was the normal case, not an edge one. Unmapped keys now ride along and are written back verbatim, and the import says what it carried. A name written as {"text": "Asura"} was flattened to an empty string, which blanked the name and description of six of NeoOrigins' own origins on import. And importing a built-in power threw on a Svelte proxy and appended nothing at all.
  • lava_vision can set its fog distances directly.** The power took only a multiplicative strength, which scales both of vanilla's lava fog distances at once, so there was no way to say "fog starts at zero blocks and ends at fifteen". Two optional fields, start and end, now set those two distances in blocks outright, and either may be given on its own, with the plane you leave out still scaled by strength. Values that cannot describe a fog volume, a multiplier of zero or less, or an end at or before start, are discarded rather than applied, so a malformed field can no longer blank the screen. When more than one active power grants lava vision the most generous of each is taken: the largest multiplier, the nearest start, the furthest end. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference.
  • Wiring up a spare orb is documented.** The four inert orbs (gold, pink, purple, and teal) ship with no behaviour on purpose, for datapacks to bind. A new worked recipe walks the whole path end to end: a custom origin layer, an action_on_event power that opens the layer picker scoped to it, the global-power grant that makes the orb work whatever your origin is, and a crafting recipe for the orb itself. See [COOKBOOK.md](docs/COOKBOOK.md) § 16.

  • Night vision has its own toggle key, default K.** Community feedback asked for night vision to be switchable on any origin that grants it. The switch is a player-level flag rather than a property of one power, so a single keypress covers every tier of a multi-tier origin, and it defaults to on, so nothing changes for players who never press the key. It is deliberately its own keybind rather than an active ability: an earlier attempt spent a skill slot on it and let a stray skill keypress silently disable night vision, which testers reported as "night vision doesn't work". The server stays authoritative: the client asks for a flip and only updates once the server echoes it back, so the admin kill switch cannot be talked around. The key is listed in [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • Aquatic origins dry out ten times faster on land (#120).** [ocean_origins] drain_rate_ticks shipped at 10, meaning one air point lost every ten ticks out of a supply of three hundred: two and a half minutes of standing on dry land before drowning damage even begins. Vanilla cod and salmon lose one air point per tick, so fifteen seconds, and the power is written to mirror them. The default is now 1. The config comment is what produced the wrong number: it correctly described vanilla fish, then recommended 16 as the fish-comparable setting, which is four minutes. It now gives the arithmetic instead. Land time in seconds is roughly (300 * value) / 20, so the number stays checkable against the behaviour. If you have run the pack before, note that config files are written once and **never re-defaulted**: an existing config/neoorigins/gameplay.toml keeps drain_rate_ticks = 10 until you edit that line by hand or delete the file and let it regenerate. If fifteen seconds is too harsh for your pack, raise the number (2 is thirty seconds, 4 is a minute) or set dries_out = false to switch the mechanic off entirely.

  • Ocean origins no longer lock up the server while looking for somewhere to spawn.** Five aquatic origins, plus Forest Dragon and Enderian, find their spawn point by asking the world for the nearest matching biome, and that search ran on the server thread at a radius of 12800 blocks with a sixteen-block step: around thirty million climate samples in the worst case, with nothing able to interrupt it. Under ordinary worldgen an ocean sits a few hundred blocks out and the search finishes in milliseconds, which is exactly why this never surfaced in testing. Install a biome or terrain mod that pushes oceans away from world spawn, or one whose own oceans are not in the minecraft:is_ocean tag, and the search runs to exhaustion instead: the server thread stops responding and Minecraft's sixty-second watchdog kills the server, with nothing thrown, so it reads as a crash with no cause. The search now runs on a worker thread with a five-second budget, bounded by vanilla /locate biome's own numbers (radius 6400, horizontal step 32, vertical step 64), about twenty-seven times fewer samples. One consequence worth knowing: a matching biome that exists only between 6400 and 12800 blocks out is no longer found, and the player spawns normally with a line in the log. [spawn_location] teleports_enabled = false still disables the whole path.
  • Origin spawn teleports no longer freeze the server while terrain generates.** Once a spawn point was found, the step that turns it into a standable position force-loaded chunks a block at a time, and each of those loads blocks the server thread until the chunk exists. Landing in ungenerated terrain on a pack with worldgen mods installed therefore meant twenty to thirty seconds of a completely unresponsive server before the player was placed. The chunks that step needs are now requested up front through the ordinary chunk ticket system and polled once per tick, so the server keeps running while they generate and the placement happens only once they are all present. If they have not arrived within thirty seconds the teleport is abandoned and the player spawns normally. Placement passes over a candidate column whose clearance check would read outside the loaded area, rather than generating more chunks for it. Because the teleport now lands a generation-time later rather than on the next tick, a player who changes dimension while it is still waiting is left where they are instead of being pulled away.
  • Two hot server paths stop doing work for players who cannot trigger them.** Every monster spawn attempt walked every player in the level and every power they held looking for a spawn-warding power that almost nobody has; that scan is now gated on a cheap per-dimension probe, and the distance check it does reach dropped a square root. Separately, the capability lookup that six server mixins call per tick and per block walked the whole power list and allocated a set on every call; it now consults a cached union of the static capabilities first, used purely as a negative filter: a capability the cache does not contain cannot come from any of those powers, while one it does contain still runs the full live scan, so the shortcut can never answer yes on its own.

  • Six built-in origins granted the same status effect from two powers at once after a tier upgrade.** When a tier adds a power that supersedes a base one, the tier's remove list is what tears the old power down, and in six cases it was missing an entry. Abyssal at apex kept both its base night vision and water breathing alongside the apex conduit power that already granted them; Caveborn kept an iron-eating haste bonus underneath permanent apex haste; Verdant kept a forest regeneration power underneath permanent apex regeneration; and Kraken, Merling, and Water Mage each kept a conditional water-breathing power underneath an unconditional one. This was not merely redundant. A conditional power clears its own effect when its condition goes false, so stepping out of the water as an Abyssal at apex would strip the permanent water breathing that the apex power was maintaining. All six now remove the superseded power on upgrade, and a new test walks every built-in origin at every tier to stop it recurring.
  • Blacksmith armour toughness now applies per armour slot.** A full set of quality-crafted armour granted a single toughness bonus instead of one per piece, because all four pieces shared one attribute-modifier id and the game deduplicates modifiers by id. Each slot now carries its own id, so head, chest, legs, and feet stack independently. Mining speed and attack damage were never affected, since only one held item is ever in play.
  • Shift-clicking a quality craft no longer loses the buff.** Taking a crafted item with shift-click distributes it into your inventory before the crafted-item event fires, so the quality bonus was applied to a stack that had already been merged away and vanished. The buff is now applied to the result slot as it is assembled, which covers both the click-take and shift-click paths. Applying it twice is harmless, so nothing double-dips.
  • Legacy attribute rewriting no longer corrupts unrelated text.** The compatibility layer rewrites 1.20-era attribute ids, but the rule matched generic. anywhere in a line rather than only in attribute positions, so playsound minecraft:entity.generic.extinguish_fire was mangled into nonsense, and the same applied to quoted text in tellraw and say. Matching is now anchored to the attribute argument of the attribute command and to attribute-modifier NBT fields, and skips quoted strings entirely. On Minecraft 1.21.1 the rewrite is gone altogether: 1.21.1 still spells attributes generic.armor, and the prefix drop only landed in 1.21.2, so stripping it there turned a valid id into an invalid one.
  • Gravity Mage's Repulse pushes at the strength it was authored with.** The power asks for a knockback strength of 2.5, but it spells that field knockback_strength while the alias it routes through reads strength, so the field was inert and the ability has been pushing at the 1.0 fallback since it shipped. The name is an easy one to get wrong: Ground Slam and Tidal Wave both genuinely declare a knockback_strength field, so it looks right by analogy, and only Repulse goes through the alias. Fixed by making the authored intent the thing that runs, which means this is a live balance change: Repulse now pushes two and a half times as hard as it did.
  • Two Jianxian sword glows were invisible.** glow_alpha is a 0-255 integer, and both powers authored it as an 0-1 fraction, which floored to zero. Zero is a legal value rather than "unset", so it was accepted instead of falling back to the default, and the halos never drew at all. Converted to the intended fractions of 255, so Sword Qi and Heaven-Severing Slash gain the glow their author asked for.
  • Commands run by execute_command are no longer rewritten when they already work.** The legacy-command rewriter is a set of heuristics meant to run only on commands that fail to parse, and the chat path has guarded it that way since #92. The execute_command action skipped that guard and rewrote everything it was given, so a pack issuing a perfectly valid modern command could have it altered underneath it. It now parses the command first and leaves it alone if it already works.

  • apply_effect never applied anything in the shape almost every pack writes.** Apoli's documented shape nests the effect in an object: "effect": {"effect": "minecraft:speed", "duration": 200, "amplifier": 1}. The compatibility parser resolved the effect id only from a bare "effect" string, so every nested use fell straight through to a silent no-op. Of the two hundred and twenty-eight apply_effect uses in the pack corpus, two hundred and fourteen are that shape, spread over a hundred and twenty-four files, and not one of them did anything: the power loaded, the origin listed it, and no effect was ever applied. The remaining fourteen use the effects[] array, which the parser truncated to the first entry, so a jellyfish sting that should poison and weaken and slow only poisoned. Between the two, no apply_effect in the corpus took a path the parser handled correctly. Effect resolution now lives in one place that reads all three shapes and returns every effect asked for rather than the first, and the nested object supplies its own duration, amplifier, and display flags, because that is where authors put them. The target-entity path used by target_action and area_of_effect shares that resolver, so it no longer carries its own copy of both bugs. When nothing resolves, the parser warns and names the three shapes it accepts instead of returning quietly. That silence is the only reason this survived as long as it did.
  • origins:choice rolled a branch and then ran nothing.** Each entry in a weighted choice is a wrapper record rather than an action, and Apoli keys the wrapped action element. The parser read action instead, so every branch resolved to a no-op whichever way the roll went, and a power built entirely out of random outcomes looked like it was simply unlucky every time. element is now read, action stays accepted as a synonym so anything authored against NeoOrigins' own documentation keeps working, and element wins when an entry carries both.
  • Legacy .mcfunction files are now translated as they are read (#118).** A function file that fails to compile never runs at all, and never reaches the hook where legacy commands were previously repaired, so packs shipping 1.20 command syntax inside their functions lost those functions silently. Function contents are now rewritten at pack-read time, before the game parses them. Item NBT in give, item replace, and item modify becomes a data-component patch, covering custom names and lore, enchantments, potions, unbreakable, damage, repair cost, custom model data, and hidden tooltip flags, with anything unrecognised preserved under custom_data. clear is translated as a subset match rather than a component patch, since it takes an item predicate. And 1.20 particle arguments are converted to their 1.21 form for dust, dust_color_transition, block, item, and entity_effect. On a Fairytale Origins test install this took failed function loads from forty-two down to nine on 1.21.1, and most of what remains there needs mods that were not installed. Minecraft 26.1 and 26.2 carry seven more failures on top of those nine, in command shapes that changed after 1.21.1 and are not rewritten yet: the generic. attribute prefix, the split of minecraft:potion into thrown and lingering entities, and gamerule.
  • Three more legacy power types are implemented: modify_healing, modify_status_effect_duration, and action_on_death.** All three are authored in six packs in the corpus, and all three were rejected by the schema and dropped by the loader. modify_healing scales all healing, matching Apoli's contract rather than natural regeneration alone; modify_status_effect_duration multiplies the duration of effects as they are applied; and action_on_death fires with the killer available, so it can pair with a bientity_action. Their modifier maths reads the 1.16-era multiply_base and multiply_total spellings these packs actually use, rather than only the modern Apoli names. Reading only the modern names would have left every real use silently doing nothing. All four namespace spellings of each type are declared, so the editors get real forms for them too.
  • 1.20-style particle strings are accepted in power JSON.** A particle field written the old way, as "minecraft:dust 0.1 0.5 0.1 1" with its arguments in one string, previously failed the whole power to load. The leading particle id is now used and the power loads.
  • Ten more legacy conditions are understood instead of failing closed, and two actions accept shapes they were rejecting.** When the compatibility layer meets a type it does not know, it refuses to activate the power rather than firing it unconditionally: safe, but the power does nothing. Newly supported: statistic tests a vanilla statistic with comparison and compare_to; nearby_entities counts entities by type or tag within distance (default 16) with an optional bientity_condition filter; near_villager counts real villagers nearby; nbt matches a partial NBT tree on the target; in_tag matches the target's entity type against a tag; can_see tests unobstructed line of sight; block_state tests a single blockstate property; height tests a block's Y coordinate; adjacent counts matching face neighbours; and always_active is an unconditional true. On the action side, and now accepts a single action as well as a list, and area_of_effect accepts both an object-shaped shape and Apoli's standard bientity_action field. See [CONDITIONS.md](docs/CONDITIONS.md) and [ACTIONS.md](docs/ACTIONS.md) for the field references.
  • origins:lava_vision whited out the screen (#121).** Origins' s and v fields are absolute replacements for vanilla's two lava fog distances, measured in blocks, not multipliers. The translator mapped s onto NeoOrigins' multiplicative strength and discarded v, so the ordinary authoring of {"s": 0, "v": 15}, which means "fog starts at zero blocks and ends at fifteen", arrived as a strength of zero: both fog planes scaled to nothing, every pixel fully fogged, a flat sheet of colour. They now map to the power's new start and end. The screen came out sky blue rather than lava orange because of a second fault in the same path: the fog handler asked whether the player's body was in lava rather than whether the camera was, so standing in a one-block puddle with your eyes in air let it hijack ordinary atmospheric fog. It now runs only when the camera is genuinely in lava. Both faults were reachable on Minecraft 1.21.1 alone, since 26.1 and 26.2 have not drawn lava fog at all since the 26.1 render rework stubbed the handler out. That stub is lifted this release as well, so all three builds run the same fixed path rather than two of them running none of it.
  • origins:water_vision is no longer translated into lava vision.** It was routed onto lava_vision, which is not remotely what it does, and inherited the whiteout above along the way. Upstream it is not a power type at all: it is an instance of origins:toggle_night_vision. It now becomes NeoOrigins' night_vision gated on a submerged_in water condition, which is what the original power actually gives the player.
  • apugli:action_on_jump and apugli:action_on_target_death load at all.** Both were registered as aliases onto action_on_event, and neither ever reached the alias table: the loader rewrites apugli: to origins: before the alias pass runs, and then drops any power it cannot route, so by the time the table was asked, it was being asked about an id it has never held. A pack shipping either one lost the whole power without a word. The authored id is now kept in reserve and offered to the alias table on the drop path only, so nothing that already loaded changes route.
  • prevent_entity_use no longer blocks every interaction.** The power ignored its entity_condition and bientity_condition, so once granted it blocked the player from using any entity at all rather than only the ones the pack named. Those conditions are now compiled and tested against the entity you interact with, and if they cannot be compiled the power is refused with a warning instead of over-blocking.
  • /power has is registered.** Legacy packs test for a power with power has <target> <power> inside their functions, and NeoOrigins registered grant, revoke, and remove but not has, so any function containing it failed to compile and was lost entirely. It now returns a result usable with execute if and store result, and resolves multiple-power ids the same way grant does.

  • The Blacksmith class can now craft quality gear at modded workstations.** quality_equipment gains an intercept_menus list of menu-type ids whose result slot should also grant the quality buff, and the built-in Blacksmith power opts into Overgeared's four smithing anvils. Detection is entirely data-driven, with no compile-time dependency: an id for a mod that is not installed simply never matches, so the list is harmless either way, and pack authors can add workstations from any mod without a code change.

  • The damage action's damage_type field is documented.** It has been read since 2.0.x and the editors describe it, but [ACTIONS.md](docs/ACTIONS.md) still listed source.name as the only way to choose a damage source. damage_type resolves against the damage-type registry, so unlike the fixed keyword list it reaches datapack-defined types.
  • [THEMING.md](docs/THEMING.md) now matches the theming code.** The field table had gone stale: flat and panel_color have been parsed since the classic skin came back, but neither was listed, so there was no documented route to building a flat theme at all. The page also never mentioned classic_picker_style, the accessibility option that outranks every theme. A pack ships a theme, a player has that option turned on, and the theme has no visible effect, with nothing on the page to explain the symptom. And the bundled-font section named two files that do not exist: the assets are lowercased on disk, because NeoForge's resource-path validator rejects uppercase path segments, so anyone following the old names was chasing a missing file.
> A legacy-compatibility and morphing release. The headline: two compatibility actions that packs lean on constantly turn out never to have worked. apply_effect resolved its effect id only from a bare string, but two hundred and fourteen of the two hundred and twenty-eight uses in the pack corpus nest it in an object, so those powers loaded, appeared on the origin, and applied nothing at all; origins:choice read the wrong key for its wrapped action, so it rolled a branch and then ran nothing. Both are fixed. Legacy 1.20-era packs also have their .mcfunction files rewritten as they are read, which took a Fairytale Origins test install from forty-two failed function loads down to nine (#118), and entity_model grows from a bare model swap into a full morph system with datapack-defined morphs, matching hitboxes, borrowed entity sounds, skin overrides, and first-person arms. Plus ten more legacy Apoli conditions understood instead of failing closed, real editor forms for twenty-nine alias power types that used to render as raw JSON, and three stability fixes: ocean origins no longer hang the server while picking a spawn point, origins:lava_vision no longer paints the whole screen a flat colour (#121), and aquatic origins dry out on land in the fifteen seconds vanilla fish get rather than two and a half minutes (#120), though an existing config file keeps the old value until you edit it.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • entity_model is now a full morph system, not just a model swap.** The power previously took a single entity_type and rendered you as that model. It now describes a whole morph. nbt selects a variant (sheep colour, villager profession, slime size); scale (default 1.0) sizes both model and hitbox; hitbox (default true) swaps your actual collision box and eye height to match, so a slime morph really does fit where a slime fits; render_held_item and render_armor (both default true) control whether your gear draws on the morph; first_person (default "item") chooses what you see in your own hands, accepting "item", "arm" for the morph's own limb, or "hidden"; and arm names an explicit bone if the automatic search picks the wrong one. Morph state is broadcast to every client tracking you, so other players see the morph too, not just you.
  • Datapack-defined morphs.** A file at data/<namespace>/neoorigins/morphs/<name>.json declares a reusable morph, and a power references it with "morph": "<id>" instead of spelling every field out inline. A bare name resolves to neoorigins:<name>, and a file whose id matches a built-in overrides it. Ten morphs ship built in (slime, magma cube, sheep, cat, villager, creeper, zombie, skeleton, enderman, and spider), and all are datapack-overridable. An unknown morph id logs a one-time warning and resolves to no morph rather than failing the power. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the full field reference.
  • Morphs can borrow the entity's sounds and reskin the player.** entity_sounds (default true) makes your hurt, death, fall, swim, and splash sounds come from the morph's entity type. A sounds object overrides any of them individually by sound-event id (hurt, death, fall_small, fall_big, swim, splash, splash_high_speed). For player-shaped morphs, a skin block sets texture, cape, and elytra asset ids and a model of "slim" or "wide"; anything left unset falls through to the player's real skin, so you can restyle only the parts you care about. Step sounds still come from the block underfoot, as in vanilla.
  • Twenty-nine legacy alias power types now have real editor forms.** Legacy types carried by the compatibility layer (the four persistent-effect aliases, seven condition_passive aliases, fourteen action_on_event aliases, and four stragglers) had no schema branch of their own, so both the web editor and the in-game editor fell back to a raw-JSON box and left the author to spell every field from memory. All twenty-nine are now modelled, and the allowlist that exempted them is empty. Alongside that: the power type picker is grouped by namespace and reads compatibility types straight off the parser rather than the native registry alone, so nothing is missing from the list; scalar-or-array reference fields (roughly twenty of them) render as proper pickers in both editors instead of raw JSON; and the top-level enabled kill switch and action_on_event's hit_dealt event are declared where they were being read but not described. The thirty-one native types that fall back to codec reflection, among them multiple, status_effect, glow, and night_vision, get their display name, description, hidden flag, and required_mods rows back. Those keys belong to no power's config record, so the fallback path had never offered them even though a datapack could always write them by hand.
  • The schemas no longer reject JSON the mod itself accepts.** Three separate cases where the editors flagged a perfectly good file as invalid. The layer schema never declared standalone, took name as a plain string only, and allowed only bare-id or single-object origin entries, while the layer loader accepts all three of the shapes it left out. The item-condition schema demanded a type that the parser has never needed, so the typeless id / item / tag shorthand, which NeoOrigins' own Jianxian powers use, failed the mod's own schema. And prevent_action declared its two enums in lowercase only, though the power upper-cases before matching, so the sixteen shipped powers written in SCREAMING_CASE were all reported invalid while working perfectly in game. All three now describe what the loader actually does.
  • The web editor imports upstream Origins-layout packs.** The importer matched only the editor's own native layout, so every pack laid out the Origins way failed at the origin step. It now tries native then compatibility layouts for origins, layers, and powers, the same pairing the server-side loaders already use, with the compatibility pattern excluding sibling directories, so origins/powers/foo.json no longer imports as an origin called powers/foo. Three ways it used to lose data are fixed alongside. It read only the nine origin fields the Identity tab covers and discarded the other six, so a round trip through the editor silently stripped evolution tiers, spawn placement, required mods, the special flag, and Figura model keys. Fifty-eight of the seventy-eight shipped origins carry tier powers, so that was the normal case, not an edge one. Unmapped keys now ride along and are written back verbatim, and the import says what it carried. A name written as {"text": "Asura"} was flattened to an empty string, which blanked the name and description of six of NeoOrigins' own origins on import. And importing a built-in power threw on a Svelte proxy and appended nothing at all.
  • lava_vision can set its fog distances directly.** The power took only a multiplicative strength, which scales both of vanilla's lava fog distances at once, so there was no way to say "fog starts at zero blocks and ends at fifteen". Two optional fields, start and end, now set those two distances in blocks outright, and either may be given on its own, with the plane you leave out still scaled by strength. Values that cannot describe a fog volume, a multiplier of zero or less, or an end at or before start, are discarded rather than applied, so a malformed field can no longer blank the screen. When more than one active power grants lava vision the most generous of each is taken: the largest multiplier, the nearest start, the furthest end. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference.
  • Wiring up a spare orb is documented.** The four inert orbs (gold, pink, purple, and teal) ship with no behaviour on purpose, for datapacks to bind. A new worked recipe walks the whole path end to end: a custom origin layer, an action_on_event power that opens the layer picker scoped to it, the global-power grant that makes the orb work whatever your origin is, and a crafting recipe for the orb itself. See [COOKBOOK.md](docs/COOKBOOK.md) § 16.

  • Night vision has its own toggle key, default K.** Community feedback asked for night vision to be switchable on any origin that grants it. The switch is a player-level flag rather than a property of one power, so a single keypress covers every tier of a multi-tier origin, and it defaults to on, so nothing changes for players who never press the key. It is deliberately its own keybind rather than an active ability: an earlier attempt spent a skill slot on it and let a stray skill keypress silently disable night vision, which testers reported as "night vision doesn't work". The server stays authoritative: the client asks for a flip and only updates once the server echoes it back, so the admin kill switch cannot be talked around. The key is listed in [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • Aquatic origins dry out ten times faster on land (#120).** [ocean_origins] drain_rate_ticks shipped at 10, meaning one air point lost every ten ticks out of a supply of three hundred: two and a half minutes of standing on dry land before drowning damage even begins. Vanilla cod and salmon lose one air point per tick, so fifteen seconds, and the power is written to mirror them. The default is now 1. The config comment is what produced the wrong number: it correctly described vanilla fish, then recommended 16 as the fish-comparable setting, which is four minutes. It now gives the arithmetic instead. Land time in seconds is roughly (300 * value) / 20, so the number stays checkable against the behaviour. If you have run the pack before, note that config files are written once and **never re-defaulted**: an existing config/neoorigins/gameplay.toml keeps drain_rate_ticks = 10 until you edit that line by hand or delete the file and let it regenerate. If fifteen seconds is too harsh for your pack, raise the number (2 is thirty seconds, 4 is a minute) or set dries_out = false to switch the mechanic off entirely.

  • Ocean origins no longer lock up the server while looking for somewhere to spawn.** Five aquatic origins, plus Forest Dragon and Enderian, find their spawn point by asking the world for the nearest matching biome, and that search ran on the server thread at a radius of 12800 blocks with a sixteen-block step: around thirty million climate samples in the worst case, with nothing able to interrupt it. Under ordinary worldgen an ocean sits a few hundred blocks out and the search finishes in milliseconds, which is exactly why this never surfaced in testing. Install a biome or terrain mod that pushes oceans away from world spawn, or one whose own oceans are not in the minecraft:is_ocean tag, and the search runs to exhaustion instead: the server thread stops responding and Minecraft's sixty-second watchdog kills the server, with nothing thrown, so it reads as a crash with no cause. The search now runs on a worker thread with a five-second budget, bounded by vanilla /locate biome's own numbers (radius 6400, horizontal step 32, vertical step 64), about twenty-seven times fewer samples. One consequence worth knowing: a matching biome that exists only between 6400 and 12800 blocks out is no longer found, and the player spawns normally with a line in the log. [spawn_location] teleports_enabled = false still disables the whole path.
  • Origin spawn teleports no longer freeze the server while terrain generates.** Once a spawn point was found, the step that turns it into a standable position force-loaded chunks a block at a time, and each of those loads blocks the server thread until the chunk exists. Landing in ungenerated terrain on a pack with worldgen mods installed therefore meant twenty to thirty seconds of a completely unresponsive server before the player was placed. The chunks that step needs are now requested up front through the ordinary chunk ticket system and polled once per tick, so the server keeps running while they generate and the placement happens only once they are all present. If they have not arrived within thirty seconds the teleport is abandoned and the player spawns normally. Placement passes over a candidate column whose clearance check would read outside the loaded area, rather than generating more chunks for it. Because the teleport now lands a generation-time later rather than on the next tick, a player who changes dimension while it is still waiting is left where they are instead of being pulled away.
  • Two hot server paths stop doing work for players who cannot trigger them.** Every monster spawn attempt walked every player in the level and every power they held looking for a spawn-warding power that almost nobody has; that scan is now gated on a cheap per-dimension probe, and the distance check it does reach dropped a square root. Separately, the capability lookup that six server mixins call per tick and per block walked the whole power list and allocated a set on every call; it now consults a cached union of the static capabilities first, used purely as a negative filter: a capability the cache does not contain cannot come from any of those powers, while one it does contain still runs the full live scan, so the shortcut can never answer yes on its own.

  • Six built-in origins granted the same status effect from two powers at once after a tier upgrade.** When a tier adds a power that supersedes a base one, the tier's remove list is what tears the old power down, and in six cases it was missing an entry. Abyssal at apex kept both its base night vision and water breathing alongside the apex conduit power that already granted them; Caveborn kept an iron-eating haste bonus underneath permanent apex haste; Verdant kept a forest regeneration power underneath permanent apex regeneration; and Kraken, Merling, and Water Mage each kept a conditional water-breathing power underneath an unconditional one. This was not merely redundant. A conditional power clears its own effect when its condition goes false, so stepping out of the water as an Abyssal at apex would strip the permanent water breathing that the apex power was maintaining. All six now remove the superseded power on upgrade, and a new test walks every built-in origin at every tier to stop it recurring.
  • Blacksmith armour toughness now applies per armour slot.** A full set of quality-crafted armour granted a single toughness bonus instead of one per piece, because all four pieces shared one attribute-modifier id and the game deduplicates modifiers by id. Each slot now carries its own id, so head, chest, legs, and feet stack independently. Mining speed and attack damage were never affected, since only one held item is ever in play.
  • Shift-clicking a quality craft no longer loses the buff.** Taking a crafted item with shift-click distributes it into your inventory before the crafted-item event fires, so the quality bonus was applied to a stack that had already been merged away and vanished. The buff is now applied to the result slot as it is assembled, which covers both the click-take and shift-click paths. Applying it twice is harmless, so nothing double-dips.
  • Legacy attribute rewriting no longer corrupts unrelated text.** The compatibility layer rewrites 1.20-era attribute ids, but the rule matched generic. anywhere in a line rather than only in attribute positions, so playsound minecraft:entity.generic.extinguish_fire was mangled into nonsense, and the same applied to quoted text in tellraw and say. Matching is now anchored to the attribute argument of the attribute command and to attribute-modifier NBT fields, and skips quoted strings entirely. On Minecraft 1.21.1 the rewrite is gone altogether: 1.21.1 still spells attributes generic.armor, and the prefix drop only landed in 1.21.2, so stripping it there turned a valid id into an invalid one.
  • Gravity Mage's Repulse pushes at the strength it was authored with.** The power asks for a knockback strength of 2.5, but it spells that field knockback_strength while the alias it routes through reads strength, so the field was inert and the ability has been pushing at the 1.0 fallback since it shipped. The name is an easy one to get wrong: Ground Slam and Tidal Wave both genuinely declare a knockback_strength field, so it looks right by analogy, and only Repulse goes through the alias. Fixed by making the authored intent the thing that runs, which means this is a live balance change: Repulse now pushes two and a half times as hard as it did.
  • Two Jianxian sword glows were invisible.** glow_alpha is a 0-255 integer, and both powers authored it as an 0-1 fraction, which floored to zero. Zero is a legal value rather than "unset", so it was accepted instead of falling back to the default, and the halos never drew at all. Converted to the intended fractions of 255, so Sword Qi and Heaven-Severing Slash gain the glow their author asked for.
  • Commands run by execute_command are no longer rewritten when they already work.** The legacy-command rewriter is a set of heuristics meant to run only on commands that fail to parse, and the chat path has guarded it that way since #92. The execute_command action skipped that guard and rewrote everything it was given, so a pack issuing a perfectly valid modern command could have it altered underneath it. It now parses the command first and leaves it alone if it already works.

  • apply_effect never applied anything in the shape almost every pack writes.** Apoli's documented shape nests the effect in an object: "effect": {"effect": "minecraft:speed", "duration": 200, "amplifier": 1}. The compatibility parser resolved the effect id only from a bare "effect" string, so every nested use fell straight through to a silent no-op. Of the two hundred and twenty-eight apply_effect uses in the pack corpus, two hundred and fourteen are that shape, spread over a hundred and twenty-four files, and not one of them did anything: the power loaded, the origin listed it, and no effect was ever applied. The remaining fourteen use the effects[] array, which the parser truncated to the first entry, so a jellyfish sting that should poison and weaken and slow only poisoned. Between the two, no apply_effect in the corpus took a path the parser handled correctly. Effect resolution now lives in one place that reads all three shapes and returns every effect asked for rather than the first, and the nested object supplies its own duration, amplifier, and display flags, because that is where authors put them. The target-entity path used by target_action and area_of_effect shares that resolver, so it no longer carries its own copy of both bugs. When nothing resolves, the parser warns and names the three shapes it accepts instead of returning quietly. That silence is the only reason this survived as long as it did.
  • origins:choice rolled a branch and then ran nothing.** Each entry in a weighted choice is a wrapper record rather than an action, and Apoli keys the wrapped action element. The parser read action instead, so every branch resolved to a no-op whichever way the roll went, and a power built entirely out of random outcomes looked like it was simply unlucky every time. element is now read, action stays accepted as a synonym so anything authored against NeoOrigins' own documentation keeps working, and element wins when an entry carries both.
  • Legacy .mcfunction files are now translated as they are read (#118).** A function file that fails to compile never runs at all, and never reaches the hook where legacy commands were previously repaired, so packs shipping 1.20 command syntax inside their functions lost those functions silently. Function contents are now rewritten at pack-read time, before the game parses them. Item NBT in give, item replace, and item modify becomes a data-component patch, covering custom names and lore, enchantments, potions, unbreakable, damage, repair cost, custom model data, and hidden tooltip flags, with anything unrecognised preserved under custom_data. clear is translated as a subset match rather than a component patch, since it takes an item predicate. And 1.20 particle arguments are converted to their 1.21 form for dust, dust_color_transition, block, item, and entity_effect. On a Fairytale Origins test install this took failed function loads from forty-two down to nine on 1.21.1, and most of what remains there needs mods that were not installed. Minecraft 26.1 and 26.2 carry seven more failures on top of those nine, in command shapes that changed after 1.21.1 and are not rewritten yet: the generic. attribute prefix, the split of minecraft:potion into thrown and lingering entities, and gamerule.
  • Three more legacy power types are implemented: modify_healing, modify_status_effect_duration, and action_on_death.** All three are authored in six packs in the corpus, and all three were rejected by the schema and dropped by the loader. modify_healing scales all healing, matching Apoli's contract rather than natural regeneration alone; modify_status_effect_duration multiplies the duration of effects as they are applied; and action_on_death fires with the killer available, so it can pair with a bientity_action. Their modifier maths reads the 1.16-era multiply_base and multiply_total spellings these packs actually use, rather than only the modern Apoli names. Reading only the modern names would have left every real use silently doing nothing. All four namespace spellings of each type are declared, so the editors get real forms for them too.
  • 1.20-style particle strings are accepted in power JSON.** A particle field written the old way, as "minecraft:dust 0.1 0.5 0.1 1" with its arguments in one string, previously failed the whole power to load. The leading particle id is now used and the power loads.
  • Ten more legacy conditions are understood instead of failing closed, and two actions accept shapes they were rejecting.** When the compatibility layer meets a type it does not know, it refuses to activate the power rather than firing it unconditionally: safe, but the power does nothing. Newly supported: statistic tests a vanilla statistic with comparison and compare_to; nearby_entities counts entities by type or tag within distance (default 16) with an optional bientity_condition filter; near_villager counts real villagers nearby; nbt matches a partial NBT tree on the target; in_tag matches the target's entity type against a tag; can_see tests unobstructed line of sight; block_state tests a single blockstate property; height tests a block's Y coordinate; adjacent counts matching face neighbours; and always_active is an unconditional true. On the action side, and now accepts a single action as well as a list, and area_of_effect accepts both an object-shaped shape and Apoli's standard bientity_action field. See [CONDITIONS.md](docs/CONDITIONS.md) and [ACTIONS.md](docs/ACTIONS.md) for the field references.
  • origins:lava_vision whited out the screen (#121).** Origins' s and v fields are absolute replacements for vanilla's two lava fog distances, measured in blocks, not multipliers. The translator mapped s onto NeoOrigins' multiplicative strength and discarded v, so the ordinary authoring of {"s": 0, "v": 15}, which means "fog starts at zero blocks and ends at fifteen", arrived as a strength of zero: both fog planes scaled to nothing, every pixel fully fogged, a flat sheet of colour. They now map to the power's new start and end. The screen came out sky blue rather than lava orange because of a second fault in the same path: the fog handler asked whether the player's body was in lava rather than whether the camera was, so standing in a one-block puddle with your eyes in air let it hijack ordinary atmospheric fog. It now runs only when the camera is genuinely in lava. Both faults were reachable on Minecraft 1.21.1 alone, since 26.1 and 26.2 have not drawn lava fog at all since the 26.1 render rework stubbed the handler out. That stub is lifted this release as well, so all three builds run the same fixed path rather than two of them running none of it.
  • origins:water_vision is no longer translated into lava vision.** It was routed onto lava_vision, which is not remotely what it does, and inherited the whiteout above along the way. Upstream it is not a power type at all: it is an instance of origins:toggle_night_vision. It now becomes NeoOrigins' night_vision gated on a submerged_in water condition, which is what the original power actually gives the player.
  • apugli:action_on_jump and apugli:action_on_target_death load at all.** Both were registered as aliases onto action_on_event, and neither ever reached the alias table: the loader rewrites apugli: to origins: before the alias pass runs, and then drops any power it cannot route, so by the time the table was asked, it was being asked about an id it has never held. A pack shipping either one lost the whole power without a word. The authored id is now kept in reserve and offered to the alias table on the drop path only, so nothing that already loaded changes route.
  • prevent_entity_use no longer blocks every interaction.** The power ignored its entity_condition and bientity_condition, so once granted it blocked the player from using any entity at all rather than only the ones the pack named. Those conditions are now compiled and tested against the entity you interact with, and if they cannot be compiled the power is refused with a warning instead of over-blocking.
  • /power has is registered.** Legacy packs test for a power with power has <target> <power> inside their functions, and NeoOrigins registered grant, revoke, and remove but not has, so any function containing it failed to compile and was lost entirely. It now returns a result usable with execute if and store result, and resolves multiple-power ids the same way grant does.

  • The Blacksmith class can now craft quality gear at modded workstations.** quality_equipment gains an intercept_menus list of menu-type ids whose result slot should also grant the quality buff, and the built-in Blacksmith power opts into Overgeared's four smithing anvils. Detection is entirely data-driven, with no compile-time dependency: an id for a mod that is not installed simply never matches, so the list is harmless either way, and pack authors can add workstations from any mod without a code change.

  • The damage action's damage_type field is documented.** It has been read since 2.0.x and the editors describe it, but [ACTIONS.md](docs/ACTIONS.md) still listed source.name as the only way to choose a damage source. damage_type resolves against the damage-type registry, so unlike the fixed keyword list it reaches datapack-defined types.
  • [THEMING.md](docs/THEMING.md) now matches the theming code.** The field table had gone stale: flat and panel_color have been parsed since the classic skin came back, but neither was listed, so there was no documented route to building a flat theme at all. The page also never mentioned classic_picker_style, the accessibility option that outranks every theme. A pack ships a theme, a player has that option turned on, and the theme has no visible effect, with nothing on the page to explain the symptom. And the bundled-font section named two files that do not exist: the assets are lowercased on disk, because NeoForge's resource-path validator rejects uppercase path segments, so anyone following the old names was chasing a missing file.
> A legacy-compatibility and morphing release. The headline: two compatibility actions that packs lean on constantly turn out never to have worked. apply_effect resolved its effect id only from a bare string, but two hundred and fourteen of the two hundred and twenty-eight uses in the pack corpus nest it in an object, so those powers loaded, appeared on the origin, and applied nothing at all; origins:choice read the wrong key for its wrapped action, so it rolled a branch and then ran nothing. Both are fixed. Legacy 1.20-era packs also have their .mcfunction files rewritten as they are read, which took a Fairytale Origins test install from forty-two failed function loads down to nine (#118), and entity_model grows from a bare model swap into a full morph system with datapack-defined morphs, matching hitboxes, borrowed entity sounds, skin overrides, and first-person arms. Plus ten more legacy Apoli conditions understood instead of failing closed, real editor forms for twenty-nine alias power types that used to render as raw JSON, and three stability fixes: ocean origins no longer hang the server while picking a spawn point, origins:lava_vision no longer paints the whole screen a flat colour (#121), and aquatic origins dry out on land in the fifteen seconds vanilla fish get rather than two and a half minutes (#120), though an existing config file keeps the old value until you edit it.
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • entity_model is now a full morph system, not just a model swap.** The power previously took a single entity_type and rendered you as that model. It now describes a whole morph. nbt selects a variant (sheep colour, villager profession, slime size); scale (default 1.0) sizes both model and hitbox; hitbox (default true) swaps your actual collision box and eye height to match, so a slime morph really does fit where a slime fits; render_held_item and render_armor (both default true) control whether your gear draws on the morph; first_person (default "item") chooses what you see in your own hands, accepting "item", "arm" for the morph's own limb, or "hidden"; and arm names an explicit bone if the automatic search picks the wrong one. Morph state is broadcast to every client tracking you, so other players see the morph too, not just you.
  • Datapack-defined morphs.** A file at data/<namespace>/neoorigins/morphs/<name>.json declares a reusable morph, and a power references it with "morph": "<id>" instead of spelling every field out inline. A bare name resolves to neoorigins:<name>, and a file whose id matches a built-in overrides it. Ten morphs ship built in (slime, magma cube, sheep, cat, villager, creeper, zombie, skeleton, enderman, and spider), and all are datapack-overridable. An unknown morph id logs a one-time warning and resolves to no morph rather than failing the power. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the full field reference.
  • Morphs can borrow the entity's sounds and reskin the player.** entity_sounds (default true) makes your hurt, death, fall, swim, and splash sounds come from the morph's entity type. A sounds object overrides any of them individually by sound-event id (hurt, death, fall_small, fall_big, swim, splash, splash_high_speed). For player-shaped morphs, a skin block sets texture, cape, and elytra asset ids and a model of "slim" or "wide"; anything left unset falls through to the player's real skin, so you can restyle only the parts you care about. Step sounds still come from the block underfoot, as in vanilla.
  • Twenty-nine legacy alias power types now have real editor forms.** Legacy types carried by the compatibility layer (the four persistent-effect aliases, seven condition_passive aliases, fourteen action_on_event aliases, and four stragglers) had no schema branch of their own, so both the web editor and the in-game editor fell back to a raw-JSON box and left the author to spell every field from memory. All twenty-nine are now modelled, and the allowlist that exempted them is empty. Alongside that: the power type picker is grouped by namespace and reads compatibility types straight off the parser rather than the native registry alone, so nothing is missing from the list; scalar-or-array reference fields (roughly twenty of them) render as proper pickers in both editors instead of raw JSON; and the top-level enabled kill switch and action_on_event's hit_dealt event are declared where they were being read but not described. The thirty-one native types that fall back to codec reflection, among them multiple, status_effect, glow, and night_vision, get their display name, description, hidden flag, and required_mods rows back. Those keys belong to no power's config record, so the fallback path had never offered them even though a datapack could always write them by hand.
  • The schemas no longer reject JSON the mod itself accepts.** Three separate cases where the editors flagged a perfectly good file as invalid. The layer schema never declared standalone, took name as a plain string only, and allowed only bare-id or single-object origin entries, while the layer loader accepts all three of the shapes it left out. The item-condition schema demanded a type that the parser has never needed, so the typeless id / item / tag shorthand, which NeoOrigins' own Jianxian powers use, failed the mod's own schema. And prevent_action declared its two enums in lowercase only, though the power upper-cases before matching, so the sixteen shipped powers written in SCREAMING_CASE were all reported invalid while working perfectly in game. All three now describe what the loader actually does.
  • The web editor imports upstream Origins-layout packs.** The importer matched only the editor's own native layout, so every pack laid out the Origins way failed at the origin step. It now tries native then compatibility layouts for origins, layers, and powers, the same pairing the server-side loaders already use, with the compatibility pattern excluding sibling directories, so origins/powers/foo.json no longer imports as an origin called powers/foo. Three ways it used to lose data are fixed alongside. It read only the nine origin fields the Identity tab covers and discarded the other six, so a round trip through the editor silently stripped evolution tiers, spawn placement, required mods, the special flag, and Figura model keys. Fifty-eight of the seventy-eight shipped origins carry tier powers, so that was the normal case, not an edge one. Unmapped keys now ride along and are written back verbatim, and the import says what it carried. A name written as {"text": "Asura"} was flattened to an empty string, which blanked the name and description of six of NeoOrigins' own origins on import. And importing a built-in power threw on a Svelte proxy and appended nothing at all.
  • lava_vision can set its fog distances directly.** The power took only a multiplicative strength, which scales both of vanilla's lava fog distances at once, so there was no way to say "fog starts at zero blocks and ends at fifteen". Two optional fields, start and end, now set those two distances in blocks outright, and either may be given on its own, with the plane you leave out still scaled by strength. Values that cannot describe a fog volume, a multiplier of zero or less, or an end at or before start, are discarded rather than applied, so a malformed field can no longer blank the screen. When more than one active power grants lava vision the most generous of each is taken: the largest multiplier, the nearest start, the furthest end. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference.
  • Wiring up a spare orb is documented.** The four inert orbs (gold, pink, purple, and teal) ship with no behaviour on purpose, for datapacks to bind. A new worked recipe walks the whole path end to end: a custom origin layer, an action_on_event power that opens the layer picker scoped to it, the global-power grant that makes the orb work whatever your origin is, and a crafting recipe for the orb itself. See [COOKBOOK.md](docs/COOKBOOK.md) § 16.

  • Night vision has its own toggle key, default K.** Community feedback asked for night vision to be switchable on any origin that grants it. The switch is a player-level flag rather than a property of one power, so a single keypress covers every tier of a multi-tier origin, and it defaults to on, so nothing changes for players who never press the key. It is deliberately its own keybind rather than an active ability: an earlier attempt spent a skill slot on it and let a stray skill keypress silently disable night vision, which testers reported as "night vision doesn't work". The server stays authoritative: the client asks for a flip and only updates once the server echoes it back, so the admin kill switch cannot be talked around. The key is listed in [CLIENT_CONFIG.md](docs/CLIENT_CONFIG.md).

  • Aquatic origins dry out ten times faster on land (#120).** [ocean_origins] drain_rate_ticks shipped at 10, meaning one air point lost every ten ticks out of a supply of three hundred: two and a half minutes of standing on dry land before drowning damage even begins. Vanilla cod and salmon lose one air point per tick, so fifteen seconds, and the power is written to mirror them. The default is now 1. The config comment is what produced the wrong number: it correctly described vanilla fish, then recommended 16 as the fish-comparable setting, which is four minutes. It now gives the arithmetic instead. Land time in seconds is roughly (300 * value) / 20, so the number stays checkable against the behaviour. If you have run the pack before, note that config files are written once and **never re-defaulted**: an existing config/neoorigins/gameplay.toml keeps drain_rate_ticks = 10 until you edit that line by hand or delete the file and let it regenerate. If fifteen seconds is too harsh for your pack, raise the number (2 is thirty seconds, 4 is a minute) or set dries_out = false to switch the mechanic off entirely.

  • Ocean origins no longer lock up the server while looking for somewhere to spawn.** Five aquatic origins, plus Forest Dragon and Enderian, find their spawn point by asking the world for the nearest matching biome, and that search ran on the server thread at a radius of 12800 blocks with a sixteen-block step: around thirty million climate samples in the worst case, with nothing able to interrupt it. Under ordinary worldgen an ocean sits a few hundred blocks out and the search finishes in milliseconds, which is exactly why this never surfaced in testing. Install a biome or terrain mod that pushes oceans away from world spawn, or one whose own oceans are not in the minecraft:is_ocean tag, and the search runs to exhaustion instead: the server thread stops responding and Minecraft's sixty-second watchdog kills the server, with nothing thrown, so it reads as a crash with no cause. The search now runs on a worker thread with a five-second budget, bounded by vanilla /locate biome's own numbers (radius 6400, horizontal step 32, vertical step 64), about twenty-seven times fewer samples. One consequence worth knowing: a matching biome that exists only between 6400 and 12800 blocks out is no longer found, and the player spawns normally with a line in the log. [spawn_location] teleports_enabled = false still disables the whole path.
  • Origin spawn teleports no longer freeze the server while terrain generates.** Once a spawn point was found, the step that turns it into a standable position force-loaded chunks a block at a time, and each of those loads blocks the server thread until the chunk exists. Landing in ungenerated terrain on a pack with worldgen mods installed therefore meant twenty to thirty seconds of a completely unresponsive server before the player was placed. The chunks that step needs are now requested up front through the ordinary chunk ticket system and polled once per tick, so the server keeps running while they generate and the placement happens only once they are all present. If they have not arrived within thirty seconds the teleport is abandoned and the player spawns normally. Placement passes over a candidate column whose clearance check would read outside the loaded area, rather than generating more chunks for it. Because the teleport now lands a generation-time later rather than on the next tick, a player who changes dimension while it is still waiting is left where they are instead of being pulled away.
  • Two hot server paths stop doing work for players who cannot trigger them.** Every monster spawn attempt walked every player in the level and every power they held looking for a spawn-warding power that almost nobody has; that scan is now gated on a cheap per-dimension probe, and the distance check it does reach dropped a square root. Separately, the capability lookup that six server mixins call per tick and per block walked the whole power list and allocated a set on every call; it now consults a cached union of the static capabilities first, used purely as a negative filter: a capability the cache does not contain cannot come from any of those powers, while one it does contain still runs the full live scan, so the shortcut can never answer yes on its own.

  • Six built-in origins granted the same status effect from two powers at once after a tier upgrade.** When a tier adds a power that supersedes a base one, the tier's remove list is what tears the old power down, and in six cases it was missing an entry. Abyssal at apex kept both its base night vision and water breathing alongside the apex conduit power that already granted them; Caveborn kept an iron-eating haste bonus underneath permanent apex haste; Verdant kept a forest regeneration power underneath permanent apex regeneration; and Kraken, Merling, and Water Mage each kept a conditional water-breathing power underneath an unconditional one. This was not merely redundant. A conditional power clears its own effect when its condition goes false, so stepping out of the water as an Abyssal at apex would strip the permanent water breathing that the apex power was maintaining. All six now remove the superseded power on upgrade, and a new test walks every built-in origin at every tier to stop it recurring.
  • Blacksmith armour toughness now applies per armour slot.** A full set of quality-crafted armour granted a single toughness bonus instead of one per piece, because all four pieces shared one attribute-modifier id and the game deduplicates modifiers by id. Each slot now carries its own id, so head, chest, legs, and feet stack independently. Mining speed and attack damage were never affected, since only one held item is ever in play.
  • Shift-clicking a quality craft no longer loses the buff.** Taking a crafted item with shift-click distributes it into your inventory before the crafted-item event fires, so the quality bonus was applied to a stack that had already been merged away and vanished. The buff is now applied to the result slot as it is assembled, which covers both the click-take and shift-click paths. Applying it twice is harmless, so nothing double-dips.
  • Legacy attribute rewriting no longer corrupts unrelated text.** The compatibility layer rewrites 1.20-era attribute ids, but the rule matched generic. anywhere in a line rather than only in attribute positions, so playsound minecraft:entity.generic.extinguish_fire was mangled into nonsense, and the same applied to quoted text in tellraw and say. Matching is now anchored to the attribute argument of the attribute command and to attribute-modifier NBT fields, and skips quoted strings entirely. On Minecraft 1.21.1 the rewrite is gone altogether: 1.21.1 still spells attributes generic.armor, and the prefix drop only landed in 1.21.2, so stripping it there turned a valid id into an invalid one.
  • Gravity Mage's Repulse pushes at the strength it was authored with.** The power asks for a knockback strength of 2.5, but it spells that field knockback_strength while the alias it routes through reads strength, so the field was inert and the ability has been pushing at the 1.0 fallback since it shipped. The name is an easy one to get wrong: Ground Slam and Tidal Wave both genuinely declare a knockback_strength field, so it looks right by analogy, and only Repulse goes through the alias. Fixed by making the authored intent the thing that runs, which means this is a live balance change: Repulse now pushes two and a half times as hard as it did.
  • Two Jianxian sword glows were invisible.** glow_alpha is a 0-255 integer, and both powers authored it as an 0-1 fraction, which floored to zero. Zero is a legal value rather than "unset", so it was accepted instead of falling back to the default, and the halos never drew at all. Converted to the intended fractions of 255, so Sword Qi and Heaven-Severing Slash gain the glow their author asked for.
  • Commands run by execute_command are no longer rewritten when they already work.** The legacy-command rewriter is a set of heuristics meant to run only on commands that fail to parse, and the chat path has guarded it that way since #92. The execute_command action skipped that guard and rewrote everything it was given, so a pack issuing a perfectly valid modern command could have it altered underneath it. It now parses the command first and leaves it alone if it already works.

  • apply_effect never applied anything in the shape almost every pack writes.** Apoli's documented shape nests the effect in an object: "effect": {"effect": "minecraft:speed", "duration": 200, "amplifier": 1}. The compatibility parser resolved the effect id only from a bare "effect" string, so every nested use fell straight through to a silent no-op. Of the two hundred and twenty-eight apply_effect uses in the pack corpus, two hundred and fourteen are that shape, spread over a hundred and twenty-four files, and not one of them did anything: the power loaded, the origin listed it, and no effect was ever applied. The remaining fourteen use the effects[] array, which the parser truncated to the first entry, so a jellyfish sting that should poison and weaken and slow only poisoned. Between the two, no apply_effect in the corpus took a path the parser handled correctly. Effect resolution now lives in one place that reads all three shapes and returns every effect asked for rather than the first, and the nested object supplies its own duration, amplifier, and display flags, because that is where authors put them. The target-entity path used by target_action and area_of_effect shares that resolver, so it no longer carries its own copy of both bugs. When nothing resolves, the parser warns and names the three shapes it accepts instead of returning quietly. That silence is the only reason this survived as long as it did.
  • origins:choice rolled a branch and then ran nothing.** Each entry in a weighted choice is a wrapper record rather than an action, and Apoli keys the wrapped action element. The parser read action instead, so every branch resolved to a no-op whichever way the roll went, and a power built entirely out of random outcomes looked like it was simply unlucky every time. element is now read, action stays accepted as a synonym so anything authored against NeoOrigins' own documentation keeps working, and element wins when an entry carries both.
  • Legacy .mcfunction files are now translated as they are read (#118).** A function file that fails to compile never runs at all, and never reaches the hook where legacy commands were previously repaired, so packs shipping 1.20 command syntax inside their functions lost those functions silently. Function contents are now rewritten at pack-read time, before the game parses them. Item NBT in give, item replace, and item modify becomes a data-component patch, covering custom names and lore, enchantments, potions, unbreakable, damage, repair cost, custom model data, and hidden tooltip flags, with anything unrecognised preserved under custom_data. clear is translated as a subset match rather than a component patch, since it takes an item predicate. And 1.20 particle arguments are converted to their 1.21 form for dust, dust_color_transition, block, item, and entity_effect. On a Fairytale Origins test install this took failed function loads from forty-two down to nine on 1.21.1, and most of what remains there needs mods that were not installed. Minecraft 26.1 and 26.2 carry seven more failures on top of those nine, in command shapes that changed after 1.21.1 and are not rewritten yet: the generic. attribute prefix, the split of minecraft:potion into thrown and lingering entities, and gamerule.
  • Three more legacy power types are implemented: modify_healing, modify_status_effect_duration, and action_on_death.** All three are authored in six packs in the corpus, and all three were rejected by the schema and dropped by the loader. modify_healing scales all healing, matching Apoli's contract rather than natural regeneration alone; modify_status_effect_duration multiplies the duration of effects as they are applied; and action_on_death fires with the killer available, so it can pair with a bientity_action. Their modifier maths reads the 1.16-era multiply_base and multiply_total spellings these packs actually use, rather than only the modern Apoli names. Reading only the modern names would have left every real use silently doing nothing. All four namespace spellings of each type are declared, so the editors get real forms for them too.
  • 1.20-style particle strings are accepted in power JSON.** A particle field written the old way, as "minecraft:dust 0.1 0.5 0.1 1" with its arguments in one string, previously failed the whole power to load. The leading particle id is now used and the power loads.
  • Ten more legacy conditions are understood instead of failing closed, and two actions accept shapes they were rejecting.** When the compatibility layer meets a type it does not know, it refuses to activate the power rather than firing it unconditionally: safe, but the power does nothing. Newly supported: statistic tests a vanilla statistic with comparison and compare_to; nearby_entities counts entities by type or tag within distance (default 16) with an optional bientity_condition filter; near_villager counts real villagers nearby; nbt matches a partial NBT tree on the target; in_tag matches the target's entity type against a tag; can_see tests unobstructed line of sight; block_state tests a single blockstate property; height tests a block's Y coordinate; adjacent counts matching face neighbours; and always_active is an unconditional true. On the action side, and now accepts a single action as well as a list, and area_of_effect accepts both an object-shaped shape and Apoli's standard bientity_action field. See [CONDITIONS.md](docs/CONDITIONS.md) and [ACTIONS.md](docs/ACTIONS.md) for the field references.
  • origins:lava_vision whited out the screen (#121).** Origins' s and v fields are absolute replacements for vanilla's two lava fog distances, measured in blocks, not multipliers. The translator mapped s onto NeoOrigins' multiplicative strength and discarded v, so the ordinary authoring of {"s": 0, "v": 15}, which means "fog starts at zero blocks and ends at fifteen", arrived as a strength of zero: both fog planes scaled to nothing, every pixel fully fogged, a flat sheet of colour. They now map to the power's new start and end. The screen came out sky blue rather than lava orange because of a second fault in the same path: the fog handler asked whether the player's body was in lava rather than whether the camera was, so standing in a one-block puddle with your eyes in air let it hijack ordinary atmospheric fog. It now runs only when the camera is genuinely in lava. Both faults were reachable on Minecraft 1.21.1 alone, since 26.1 and 26.2 have not drawn lava fog at all since the 26.1 render rework stubbed the handler out. That stub is lifted this release as well, so all three builds run the same fixed path rather than two of them running none of it.
  • origins:water_vision is no longer translated into lava vision.** It was routed onto lava_vision, which is not remotely what it does, and inherited the whiteout above along the way. Upstream it is not a power type at all: it is an instance of origins:toggle_night_vision. It now becomes NeoOrigins' night_vision gated on a submerged_in water condition, which is what the original power actually gives the player.
  • apugli:action_on_jump and apugli:action_on_target_death load at all.** Both were registered as aliases onto action_on_event, and neither ever reached the alias table: the loader rewrites apugli: to origins: before the alias pass runs, and then drops any power it cannot route, so by the time the table was asked, it was being asked about an id it has never held. A pack shipping either one lost the whole power without a word. The authored id is now kept in reserve and offered to the alias table on the drop path only, so nothing that already loaded changes route.
  • prevent_entity_use no longer blocks every interaction.** The power ignored its entity_condition and bientity_condition, so once granted it blocked the player from using any entity at all rather than only the ones the pack named. Those conditions are now compiled and tested against the entity you interact with, and if they cannot be compiled the power is refused with a warning instead of over-blocking.
  • /power has is registered.** Legacy packs test for a power with power has <target> <power> inside their functions, and NeoOrigins registered grant, revoke, and remove but not has, so any function containing it failed to compile and was lost entirely. It now returns a result usable with execute if and store result, and resolves multiple-power ids the same way grant does.

  • The Blacksmith class can now craft quality gear at modded workstations.** quality_equipment gains an intercept_menus list of menu-type ids whose result slot should also grant the quality buff, and the built-in Blacksmith power opts into Overgeared's four smithing anvils. Detection is entirely data-driven, with no compile-time dependency: an id for a mod that is not installed simply never matches, so the list is harmless either way, and pack authors can add workstations from any mod without a code change.

  • The damage action's damage_type field is documented.** It has been read since 2.0.x and the editors describe it, but [ACTIONS.md](docs/ACTIONS.md) still listed source.name as the only way to choose a damage source. damage_type resolves against the damage-type registry, so unlike the fixed keyword list it reaches datapack-defined types.
  • [THEMING.md](docs/THEMING.md) now matches the theming code.** The field table had gone stale: flat and panel_color have been parsed since the classic skin came back, but neither was listed, so there was no documented route to building a flat theme at all. The page also never mentioned classic_picker_style, the accessibility option that outranks every theme. A pack ships a theme, a player has that option turned on, and the theme has no visible effect, with nothing on the page to explain the symptom. And the bundled-font section named two files that do not exist: the assets are lowercased on disk, because NeoForge's resource-path validator rejects uppercase path segments, so anyone following the old names was chasing a missing file.
> A pack-author and compatibility release built around a rebuilt entity-group system and the sun. entity_group is now fully data-driven: a datapack defines its own mob-affinity groups through declared fields, six groups ship built in (with new illager, piglin, and skeleton groups), and an unknown group id now warns instead of silently doing nothing. On the sun side, a helmet_protection toggle lets sun-burning origins burn even while helmeted, a sun_permeable tag lets open helmets pass daylight through, and the new skeleton group catches fire in the sun. Plus a Cold Sweat integration that gives eighteen built-in origins heat and cold resistances and weaknesses, an origins:strong_ankles compatibility alias for halved fall damage, and a fix for aimed teleports dropping you into a Create: Aeronautics ship's sub-level (#115).
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • entity_group is now data-driven and datapack-extensible.** The power previously understood only three hardcoded groups (undead, arthropod, water), and any other value — a bare illager, say — silently did nothing. Groups are now defined by data: a file at data/<namespace>/neoorigins/entity_groups/<name>.json declares what a group does through optional fields (immune_effects, invert_instant_effects, vulnerable_enchants, ignored_by, targeted_by, feared_by, and burns_in_sunlight), so group is just a label and no value is ever a dead no-op. A bare name resolves to neoorigins:<name>, a file whose id matches a built-in overrides it, and an unknown id now logs a one-time warning instead of failing silently. The six built-in groups are themselves data-backed and datapack-overridable. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference and a worked example.
  • Three new group behaviours: hunt, flee, and burn.** On top of the existing effect, enchant, and ignored_by fields, a group can now set targeted_by (listed mobs actively hunt the player within ~16 blocks, the way wolves hunt a skeleton), feared_by (listed mobs flee the player within ~8 blocks), and burns_in_sunlight (the player catches fire in daylight like a vanilla skeleton, honouring the same [sun_damage] helmet and umbrella rules as the exposed_to_sun condition). Player-built iron golems are exempt from targeted_by even when iron golems are listed, so only village-spawned golems turn on you.

  • Three new built-in entity groups: illager, piglin, and skeleton.** illager makes raiders (everything in #minecraft:raiders, outpost pillagers included) leave you alone, sets village-spawned iron golems hunting you while your own built golems stay loyal, and sends villagers and wandering traders fleeing. piglin treats you as kin so piglins and brutes never aggro — unconditionally, with no gold armour required, unlike vanilla. skeleton is the undead kit (Poison and Regeneration immunity, inverted instant effects, Smite vulnerability) plus wolves that hunt you and daylight that burns you. They join the existing undead, arthropod, and water groups.

  • helmet_protection: sun-burning origins can burn through helmets.** A new [sun_damage] toggle, default true so existing behaviour is unchanged. Sun-damage origins — Vampire, Phantom, Abyssal, Caveborn, Warden, and the like — were always fully shielded by any worn helmet with no way to change it, and the old helmet_dura_damage_chance = 0 even claimed to disable that protection while actually making the helmet a permanent free shield. Set helmet_protection to false and a worn helmet no longer blocks sun damage or takes durability wear from it, so those origins burn in daylight whatever they wear.
  • sun_permeable helmet tag: open helmets let daylight through.** A new item tag, neoorigins:sun_permeable, seeded with minecraft:chainmail_helmet. Any helmet in the tag counts as no helmet for sun damage: it neither shades the wearer nor takes durability from the sun. Add your own open or mesh helmets to the tag to let them pass daylight through while solid helmets keep shading.

  • Aimed teleports no longer drop you into a Create: Aeronautics ship's sub-level (#115).** Using a "teleport to where you're looking" ability while aiming at a Sable-backed airship teleported you into the contraption's hidden sub-level dimension instead of onto its deck, sending you into an endless fall that could crash the game. The cause: the raycast that finds your aim point returns a hit in the ship's internal staging space, and teleporting straight to it landed you in that empty region. The aimed teleport now lifts the hit back out into real world space, so you land on the deck you were looking at, while aiming at ordinary terrain still works exactly as before. (On 1.21.1, where Sable runs.)

  • Cold Sweat: built-in origins carry heat and cold resistances and weaknesses.** With Cold Sweat installed, the built-in origins now react to its body-temperature system. Heat-adapted origins (Blazeling, Strider, Piglin, Cinderborn, Fire Mage, and Cave Dragon) resist heat and warm faster in the cold; cold-adapted origins (Frostborn, Sea Dragon, Merling, Kraken, Abyssal, and Siren) resist cold and overheat faster, with six more (Enderian, Enderite, Avian, Windwalker, Sculkborn, and Warden) carrying a milder cold resistance — eighteen origins in all, each gated so it only applies when Cold Sweat is present and stays invisible otherwise. Two new datapack primitives drive temperature directly: a neoorigins:modify_temperature action shifts a chosen temperature trait, and a neoorigins:body_temperature condition tests it. Cold Sweat is a compile-only soft dependency: without it, the resistances never load, the action no-ops, and the condition reads false — none of which crash. See [ACTIONS.md](docs/ACTIONS.md) and [CONDITIONS.md](docs/CONDITIONS.md) for the new action and condition.

  • origins:strong_ankles now halves fall damage.** Legacy Feline-based packs list the origins:strong_ankles power by id, expecting the host mod to define it. NeoOrigins synthesizes those reference-only Feline ids, but strong_ankles was missing from the map, so it silently did nothing while its siblings — fall immunity, nine lives, weak arms, carnivore, and cat vision — all worked. It now maps to native fall-damage scaling that halves fall damage, matching the real Origins "Strong Ankles".
> A pack-author and compatibility release built around a rebuilt entity-group system and the sun. entity_group is now fully data-driven: a datapack defines its own mob-affinity groups through declared fields, six groups ship built in (with new illager, piglin, and skeleton groups), and an unknown group id now warns instead of silently doing nothing. On the sun side, a helmet_protection toggle lets sun-burning origins burn even while helmeted, a sun_permeable tag lets open helmets pass daylight through, and the new skeleton group catches fire in the sun. Plus a Cold Sweat integration that gives eighteen built-in origins heat and cold resistances and weaknesses, an origins:strong_ankles compatibility alias for halved fall damage, and a fix for aimed teleports dropping you into a Create: Aeronautics ship's sub-level (#115).
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • entity_group is now data-driven and datapack-extensible.** The power previously understood only three hardcoded groups (undead, arthropod, water), and any other value — a bare illager, say — silently did nothing. Groups are now defined by data: a file at data/<namespace>/neoorigins/entity_groups/<name>.json declares what a group does through optional fields (immune_effects, invert_instant_effects, vulnerable_enchants, ignored_by, targeted_by, feared_by, and burns_in_sunlight), so group is just a label and no value is ever a dead no-op. A bare name resolves to neoorigins:<name>, a file whose id matches a built-in overrides it, and an unknown id now logs a one-time warning instead of failing silently. The six built-in groups are themselves data-backed and datapack-overridable. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference and a worked example.
  • Three new group behaviours: hunt, flee, and burn.** On top of the existing effect, enchant, and ignored_by fields, a group can now set targeted_by (listed mobs actively hunt the player within ~16 blocks, the way wolves hunt a skeleton), feared_by (listed mobs flee the player within ~8 blocks), and burns_in_sunlight (the player catches fire in daylight like a vanilla skeleton, honouring the same [sun_damage] helmet and umbrella rules as the exposed_to_sun condition). Player-built iron golems are exempt from targeted_by even when iron golems are listed, so only village-spawned golems turn on you.

  • Three new built-in entity groups: illager, piglin, and skeleton.** illager makes raiders (everything in #minecraft:raiders, outpost pillagers included) leave you alone, sets village-spawned iron golems hunting you while your own built golems stay loyal, and sends villagers and wandering traders fleeing. piglin treats you as kin so piglins and brutes never aggro — unconditionally, with no gold armour required, unlike vanilla. skeleton is the undead kit (Poison and Regeneration immunity, inverted instant effects, Smite vulnerability) plus wolves that hunt you and daylight that burns you. They join the existing undead, arthropod, and water groups.

  • helmet_protection: sun-burning origins can burn through helmets.** A new [sun_damage] toggle, default true so existing behaviour is unchanged. Sun-damage origins — Vampire, Phantom, Abyssal, Caveborn, Warden, and the like — were always fully shielded by any worn helmet with no way to change it, and the old helmet_dura_damage_chance = 0 even claimed to disable that protection while actually making the helmet a permanent free shield. Set helmet_protection to false and a worn helmet no longer blocks sun damage or takes durability wear from it, so those origins burn in daylight whatever they wear.
  • sun_permeable helmet tag: open helmets let daylight through.** A new item tag, neoorigins:sun_permeable, seeded with minecraft:chainmail_helmet. Any helmet in the tag counts as no helmet for sun damage: it neither shades the wearer nor takes durability from the sun. Add your own open or mesh helmets to the tag to let them pass daylight through while solid helmets keep shading.

  • Aimed teleports no longer drop you into a Create: Aeronautics ship's sub-level (#115).** Using a "teleport to where you're looking" ability while aiming at a Sable-backed airship teleported you into the contraption's hidden sub-level dimension instead of onto its deck, sending you into an endless fall that could crash the game. The cause: the raycast that finds your aim point returns a hit in the ship's internal staging space, and teleporting straight to it landed you in that empty region. The aimed teleport now lifts the hit back out into real world space, so you land on the deck you were looking at, while aiming at ordinary terrain still works exactly as before. (On 1.21.1, where Sable runs.)

  • Cold Sweat: built-in origins carry heat and cold resistances and weaknesses.** With Cold Sweat installed, the built-in origins now react to its body-temperature system. Heat-adapted origins (Blazeling, Strider, Piglin, Cinderborn, Fire Mage, and Cave Dragon) resist heat and warm faster in the cold; cold-adapted origins (Frostborn, Sea Dragon, Merling, Kraken, Abyssal, and Siren) resist cold and overheat faster, with six more (Enderian, Enderite, Avian, Windwalker, Sculkborn, and Warden) carrying a milder cold resistance — eighteen origins in all, each gated so it only applies when Cold Sweat is present and stays invisible otherwise. Two new datapack primitives drive temperature directly: a neoorigins:modify_temperature action shifts a chosen temperature trait, and a neoorigins:body_temperature condition tests it. Cold Sweat is a compile-only soft dependency: without it, the resistances never load, the action no-ops, and the condition reads false — none of which crash. See [ACTIONS.md](docs/ACTIONS.md) and [CONDITIONS.md](docs/CONDITIONS.md) for the new action and condition.

  • origins:strong_ankles now halves fall damage.** Legacy Feline-based packs list the origins:strong_ankles power by id, expecting the host mod to define it. NeoOrigins synthesizes those reference-only Feline ids, but strong_ankles was missing from the map, so it silently did nothing while its siblings — fall immunity, nine lives, weak arms, carnivore, and cat vision — all worked. It now maps to native fall-damage scaling that halves fall damage, matching the real Origins "Strong Ankles".
> A pack-author and compatibility release built around a rebuilt entity-group system and the sun. entity_group is now fully data-driven: a datapack defines its own mob-affinity groups through declared fields, six groups ship built in (with new illager, piglin, and skeleton groups), and an unknown group id now warns instead of silently doing nothing. On the sun side, a helmet_protection toggle lets sun-burning origins burn even while helmeted, a sun_permeable tag lets open helmets pass daylight through, and the new skeleton group catches fire in the sun. Plus a Cold Sweat integration that gives eighteen built-in origins heat and cold resistances and weaknesses, an origins:strong_ankles compatibility alias for halved fall damage, and a fix for aimed teleports dropping you into a Create: Aeronautics ship's sub-level (#115).
>
> **Supports:** Minecraft 26.1.x (Java 25) · Minecraft 26.2 (Java 25) · Minecraft 1.21.1 (Java 21)

  • entity_group is now data-driven and datapack-extensible.** The power previously understood only three hardcoded groups (undead, arthropod, water), and any other value — a bare illager, say — silently did nothing. Groups are now defined by data: a file at data/<namespace>/neoorigins/entity_groups/<name>.json declares what a group does through optional fields (immune_effects, invert_instant_effects, vulnerable_enchants, ignored_by, targeted_by, feared_by, and burns_in_sunlight), so group is just a label and no value is ever a dead no-op. A bare name resolves to neoorigins:<name>, a file whose id matches a built-in overrides it, and an unknown id now logs a one-time warning instead of failing silently. The six built-in groups are themselves data-backed and datapack-overridable. See [POWER_TYPES.md](docs/POWER_TYPES.md) for the field reference and a worked example.
  • Three new group behaviours: hunt, flee, and burn.** On top of the existing effect, enchant, and ignored_by fields, a group can now set targeted_by (listed mobs actively hunt the player within ~16 blocks, the way wolves hunt a skeleton), feared_by (listed mobs flee the player within ~8 blocks), and burns_in_sunlight (the player catches fire in daylight like a vanilla skeleton, honouring the same [sun_damage] helmet and umbrella rules as the exposed_to_sun condition). Player-built iron golems are exempt from targeted_by even when iron golems are listed, so only village-spawned golems turn on you.

  • Three new built-in entity groups: illager, piglin, and skeleton.** illager makes raiders (everything in #minecraft:raiders, outpost pillagers included) leave you alone, sets village-spawned iron golems hunting you while your own built golems stay loyal, and sends villagers and wandering traders fleeing. piglin treats you as kin so piglins and brutes never aggro — unconditionally, with no gold armour required, unlike vanilla. skeleton is the undead kit (Poison and Regeneration immunity, inverted instant effects, Smite vulnerability) plus wolves that hunt you and daylight that burns you. They join the existing undead, arthropod, and water groups.

  • helmet_protection: sun-burning origins can burn through helmets.** A new [sun_damage] toggle, default true so existing behaviour is unchanged. Sun-damage origins — Vampire, Phantom, Abyssal, Caveborn, Warden, and the like — were always fully shielded by any worn helmet with no way to change it, and the old helmet_dura_damage_chance = 0 even claimed to disable that protection while actually making the helmet a permanent free shield. Set helmet_protection to false and a worn helmet no longer blocks sun damage or takes durability wear from it, so those origins burn in daylight whatever they wear.
  • sun_permeable helmet tag: open helmets let daylight through.** A new item tag, neoorigins:sun_permeable, seeded with minecraft:chainmail_helmet. Any helmet in the tag counts as no helmet for sun damage: it neither shades the wearer nor takes durability from the sun. Add your own open or mesh helmets to the tag to let them pass daylight through while solid helmets keep shading.

  • Aimed teleports no longer drop you into a Create: Aeronautics ship's sub-level (#115).** Using a "teleport to where you're looking" ability while aiming at a Sable-backed airship teleported you into the contraption's hidden sub-level dimension instead of onto its deck, sending you into an endless fall that could crash the game. The cause: the raycast that finds your aim point returns a hit in the ship's internal staging space, and teleporting straight to it landed you in that empty region. The aimed teleport now lifts the hit back out into real world space, so you land on the deck you were looking at, while aiming at ordinary terrain still works exactly as before. (On 1.21.1, where Sable runs.)

  • Cold Sweat: built-in origins carry heat and cold resistances and weaknesses.** With Cold Sweat installed, the built-in origins now react to its body-temperature system. Heat-adapted origins (Blazeling, Strider, Piglin, Cinderborn, Fire Mage, and Cave Dragon) resist heat and warm faster in the cold; cold-adapted origins (Frostborn, Sea Dragon, Merling, Kraken, Abyssal, and Siren) resist cold and overheat faster, with six more (Enderian, Enderite, Avian, Windwalker, Sculkborn, and Warden) carrying a milder cold resistance — eighteen origins in all, each gated so it only applies when Cold Sweat is present and stays invisible otherwise. Two new datapack primitives drive temperature directly: a neoorigins:modify_temperature action shifts a chosen temperature trait, and a neoorigins:body_temperature condition tests it. Cold Sweat is a compile-only soft dependency: without it, the resistances never load, the action no-ops, and the condition reads false — none of which crash. See [ACTIONS.md](docs/ACTIONS.md) and [CONDITIONS.md](docs/CONDITIONS.md) for the new action and condition.

  • origins:strong_ankles now halves fall damage.** Legacy Feline-based packs list the origins:strong_ankles power by id, expecting the host mod to define it. NeoOrigins synthesizes those reference-only Feline ids, but strong_ankles was missing from the map, so it silently did nothing while its siblings — fall immunity, nine lives, weak arms, carnivore, and cat vision — all worked. It now maps to native fall-damage scaling that halves fall damage, matching the real Origins "Strong Ankles".
Neo Origins Icon
Download Neo Origins
Select game version
Select platform