
Overgrown's Apoli
A data-driven power system that's build for custom abilities, mechanics, and entire origin systems from JSON alone.
Список изменений
Fixes
-
apoli:change_slotsilently did nothing whenever either slot was an armour slot. Vanilla wraps every equipment slot except the head, mainhand and offhand in a filter that rejects any item whose natural equipment slot is not that one, so an attempt to swap something like a blaze rod intoarmor.feetwas refused and the whole swap rolled back without any error. The action now bypasses that accessor for the six equipment slots and writes to them directly, which is what a data pack asking for an arbitrary item in an arbitrary slot actually means. -
apoli:if_else_listran through every branch in a single tick instead of only the branches that genuinely matched. Each branch's condition was being tested immediately before that branch's action ran, so an action near the top of the list could change the very state that a condition further down was about to read, and the whole list would cascade. All conditions are now evaluated before any action runs, so each branch is judged against the state as it was when the list started. The list still fires every branch whose condition holds, which is the intended behaviour; only the cascade is gone. Adding a delay to work around this is no longer necessary. -
apoli:action_on_landfired late, and on long falls often appeared not to fire at all. It had been polling the entity's on-ground flag at the end of each server tick and reconstructing the fall distance from a value it wrote into the power's auxiliary data on every airborne tick. It now hooks the exact moment vanilla processes a landing, which fires precisely once per landing and has the real fall distance available. As a side effect the power no longer writes auxiliary data and sends a power sync packet on every tick of a fall. -
Powers stopped working entirely for a player after going through a portal. The tick registry drops any entity that is flagged as removed, which happens during a dimension transfer, and the only path that added an entity back required its power container to have been empty beforehand, so a player who already had powers was never re-registered. Dimension changes and respawns now explicitly resume ticking and resend the player's powers to the client.
-
Powers from a removed source could survive their removal. When a power was fully removed, the sweep that drops anything granted underneath it only ran if the power's own definition happened to be missing; when the definition was present the code trusted the power's own cleanup hook to cascade. The unconditional sweep that the full-removal path already performed is now used in both cases. This is the mechanism behind old powers lingering after an origin switch.
-
apoli:action_over_timenever re-ran itsrising_actionafter the holder died. The flag recording whether the power was already active lives in persisted container data and survives a respawn, so if the condition was still true after respawning there was no rising edge to detect and the action never ran again. That flag is now cleared on respawn. -
A
conditiononapoli:effect_immunityhad no visible effect. Immunity was only ever consulted at the moment an effect was applied, so an effect picked up while the condition was false simply stayed on the entity forever once the condition became true. While the power is active it now also strips any effect it covers that the entity already has. -
The
lockoption onapoli:conjure_equipmentwas only half enforced. It correctly stopped the item being moved in the inventory screen, but the drop key bypassed it completely, and the cleanup that deletes a conjured item once it reaches the ground only ran on an item entity's very first tick, so anything that slipped through stayed in the world permanently. Dropping a locked conjured item is now refused outright, conjured items are never spawned as item entities in the first place, and the cleanup no longer depends on the item entity being brand new. -
An
apoli:inventorypower used withinventory_type: "power"allowed items to be duplicated. Opening the inventory screen created one container instance backed by the stored data, while actions such asdrop_inventory,inventory_actionandchange_slotcreated a second, independent instance from that same stored data. An action could therefore empty its copy and save it while the open screen still held the old contents, and the next change in the screen wrote those stale contents straight back over the save — leaving the items both on the ground and still in the inventory. There is now exactly one live container per player and power, shared by the screen and by every action that touches it. -
A misspelled or unrecognized field on
apoli:damageturned the action into a guaranteed kill. Unknown keys in JSON are ignored, and an absentamountis meaningful — it tells the action to use the target's max health as the base value, which is how you write "damage a fraction of max health" using only modifiers. The combination meant that writing, for example,damageinstead ofamountproduced an action that always dealt exactly the target's max health, with nothing in the log. A present but unparseableamountis now a load error that names the power instead of being silently discarded, and both damage actions acceptdamageas an alias foramountso the most common version of this mistake simply works.
Additions and changes
-
The food component now supports a per-effect
chance. Vanilla has always supported a probability on each food effect and the documentation already described the field, but it was hardcoded to always apply. Botheffectandeffectsnow take an optionalchancebetween0.0and1.0, defaulting to1.0. Existing food components are unaffected. -
The bi-entity form of
apoli:damagenow accepts an expression foramountrather than only a plain number, matching the entity form of the same action. -
The bi-entity form of
apoli:add_velocitynow accepts expressions forx,yandzrather than only plain numbers, matching the entity form of the same action. They are evaluated against the entity being pushed. -
Both damage actions accept
damageas an alias foramount.
