promotional bannermobile promotional banner

Overgrown's Apoli

A data-driven power system that's build for custom abilities, mechanics, and entire origin systems from JSON alone.
Back to Files

Apoli (1.117.0)

File nameapoli-1.117.0.jar
Uploader
OvergrownMCOvergrownMC
Uploaded
Oct 17, 2026
Downloads
92
Size
30.0 MB
Mod Loaders
Fabric
File ID
9217304
Type
R
Release
Supported game versions
  • 1.21.1

Curse Maven Snippet

Fabric

modImplementation "curse.maven:apoli-1631826:9217304"

Learn more about Curse Maven

What's new

Before you update

This covers everything since 1.115.0. Versions 1.115.1 to 1.115.3 were never uploaded, so their changes are listed under 1.115.4. Fabric 1.20.1, Fabric 1.21.1 and NeoForge 1.21.1 all get the changes below; where something applies to one version or one mod only, it says so.

  • Update the client, the server and Origins together. The network protocol changed in 1.115.5 (NeoForge) and again in 1.116.0 (every loader). A client on an older build cannot join a server on this one; on Fabric it is disconnected with an "Apoli network protocol mismatch" message.
  • apoli:creative_flight no longer prevents fall damage. Flying down to land is still safe, but a holder who stops flying in mid-air or walks off a ledge takes the fall. The 1.115.5 notes below have the example that brings the immunity back.
  • apoli:modify_velocity limits hold the real velocity. min_*, max_* and set_* now clamp your actual velocity, not only how far you move each tick. Multiplying and adding operations are unchanged.
  • result_item_action acts on the result. On apoli:action_on_use and apoli:prevent_use it now runs on result_stack before you are given it, and does nothing without one. It used to run on whatever was in your hand afterwards.
  • apoli:action_on_block_use and apoli:action_on_block_place no longer overwrite your hand. Their result_stack goes into your hand only if it is empty, otherwise into your inventory.
  • apoli:modify_accessory_slots follows its condition every tick. It used to be checked once, when the power was granted.
  • apoli:replace_sound_emission plays for the holder too. You now hear the replacement for your own hurt, death, step and eating sounds.
  • A set owned by a mob is deleted when the mob dies, and entity sets no longer carry over from one singleplayer world into the next.

1.117.0

Added — fire_projectile passes through enemies. New pierce field (integer or expression, default 0): the number of entities a projectile flies on through, hitting each once and running its hit actions. -1 passes through every entity. An entity it has passed through can be hit again after the projectile bounces off a block or turns back, so a returning shot hits the same crowd on its way home.

Added — bouncing off entities. The reflective object takes entities (default false). With it, a projectile glances off the side of the hitbox it struck after the hit actions have run, sharing max_bounces with block bounces, and cannot hit the entity it just bounced off again straight away.

Added — holding a returning projectile out. return takes a condition (bi-entity: owner → projectile). A turn called for by after or max_distance waits until it passes; hits still turn the projectile at once, and lifetime still ends it.

On a vanilla entity_type projectile, a pass-through or an entity bounce takes the place of the projectile's own impact; deal damage in the hit actions.

Fixed — summons flashing at their summoner. A minion or clone moved by its own bientity_action (a teleport_to placing it in front of you) appeared at the summoner's feet for a few ticks and slid to its spot. Players watching now see it appear in place; the summon is re-sent to them once the action has run, only if it moved.


1.116.0

Added — apoli:status_bar_texture. A new power that replaces the textures of the status bars (health, hunger, armor, air, experience, the mount's health and jump bar) and other HUD sprites for the player who has it.

Field Type Default Description
texture Identifier optional A sprite sheet in the classic textures/gui/icons.png layout (256×256, or any larger multiple of it). Every status bar icon is drawn from the same spot on it.
texture_map Object of Identifier pairs optional Each key is a HUD sprite to replace, each value the sprite drawn in its place, both GUI sprite names such as minecraft:hud/heart/full.
priority Integer 0 Which power wins when several replace the same sprite. Higher wins.

Give texture, texture_map, or both. Several powers combine sprite by sprite, so one can restyle the hearts while another restyles the hunger bar. The same sprite names work on 1.20.1 and 1.21.1; on 1.21.1 texture_map can replace any sprite the HUD draws, on 1.20.1 it covers the vanilla bars, crosshair and hotbar. Sheets made for Apace's Apoli work unchanged.

{
  "type": "apoli:status_bar_texture",
  "texture_map": {
    "minecraft:hud/heart/full": "minecraft:hud/heart/frozen_full",
    "minecraft:hud/heart/half": "minecraft:hud/heart/frozen_half"
  }
}

Added — persistent entity sets. apoli:entity_set takes persistent (default false). A persistent set keeps its members when they die or log out, stays on the server while its owner is offline, and is saved with the world, so it comes back after a restart. A member leaves only through apoli:remove_from_entity_set, a time_limit, or the owner losing the power, so a permanent link between players is one power instead of a set mirrored into command tags. Sets that are not persistent behave as before. Two things change for every set: one owned by a mob is deleted when the mob dies instead of staying in memory until the server stops, and sets no longer carry over from one singleplayer world into the next.

Added — offline players in set actions. apoli:action_on_entity_set takes include_offline (default false). With it, an owner or member who is offline is visited as an offline copy loaded from their saved data, so a member can check conditions against an owner who is away, or leave their set. apoli:online is a new name for the apoli:exists entity condition, which is false for an offline copy.

Added — hollow shapes. Every shape has a hollow version: cube_hollow, sphere_hollow, star_hollow and cone_hollow. They keep only the outer layer of the solid shape, hollow_thickness blocks thick (a number or an expression, default 1). The field sits beside shape on the entity and block apoli:area_of_effect actions, on apoli:block_in_radius and apoli:entity_in_radius, and on apoli:modify_tick_rate; apoli:distance_from_coordinates accepts the hollow names and measures them like the solid shape. A block area_of_effect with sphere_hollow builds a sealed dome, and entity_in_radius with it counts the entities in a ring around you.

Added — acting when a key is released. apoli:action_on_key_press takes entity_action_released, which runs once when the key comes back up after a press that fired entity_action. While it runs, the expression variable held_ticks is how many ticks the key was held, so a charged ability is a single power:

{
  "type": "apoli:action_on_key_press",
  "cooldown": 40,
  "entity_action": {
    "type": "apoli:apply_effect",
    "effect": {
      "effect": "minecraft:slowness",
      "duration": 200,
      "amplifier": 2
    }
  },
  "entity_action_released": {
    "type": "apoli:and",
    "actions": [
      {
        "type": "apoli:clear_effect",
        "effect": "minecraft:slowness"
      },
      {
        "type": "apoli:add_velocity",
        "z": "min(held_ticks, 40) / 20",
        "space": "local"
      }
    ]
  }
}

Added — paying for skills with items. A skill's cost can ask for items as well as points: {"points": 20, "item": "minecraft:dirt", "count": 2}, or an items list with an optional item_condition on each entry. The skill tree tooltip lists the items, and a refund gives back exactly what was paid.

Added — power tags in the power conditions. apoli:power and apoli:power_active take tags (one string or a list), matching the tags a power declares. Give power, tags or both; with both, the condition passes when either matches. "Has any power tagged mypack.flight" no longer needs a list of every flight power.


1.115.5

Fixed — entity sets in client-side conditions on dedicated servers. A bi-entity apoli:in_entity_set check inside a power that the client evaluates did nothing on a dedicated server; the usual case is an apoli:entity_glow that should light up only the entities in your set. It worked in singleplayer, on a LAN host and on an Essential-hosted world, because there the client could read the server's memory. Sets are now sent to their owner and to every player who can see the owner, so the glow behaves the same everywhere. That includes an apoli:self_glow that tests the glowing entity's own set, and the apoli:entity_set_size condition on the client.

Fixed — result_item_action acts on the result. On apoli:action_on_use and apoli:prevent_use it ran on whatever was in your hand after result_stack had been handed over, usually the item you used (that is held_item_action's job), so the stack you were given came out unchanged. It now runs on result_stack before it is given to you, as it already did on the block and food powers. Without a result_stack it does nothing.

Fixed — block use and place no longer delete what you hold. apoli:action_on_block_use and apoli:action_on_block_place put their result_stack straight into your hand, overwriting whatever was left of the stack you were holding. The result now goes into your hand only if it is empty, into your inventory otherwise, and is dropped if the inventory is full.

Fixed — accessory slots follow their condition. apoli:modify_accessory_slots checked its condition once, when it was granted: get it while the condition passed and the extra slot stayed whatever happened afterwards. The condition is now checked every tick and the slots come and go with it; logging back in or respawning applies them on the first tick. With Trinkets, taking a slot away (revoking the power, for example) could crash the server on the next tick, because the player's inventory screen still pointed at the removed slot. Apoli now has Trinkets rebuild that screen as soon as the slots change.

Fixed — you hear your own replaced sounds. apoli:replace_sound_emission replaced the sounds you make for everyone except you, because your game plays your own hurt, death, step and eating sounds itself instead of waiting for the server. That path is covered now. The power's entity_action still runs once, on the server.

Fixed — modify_velocity limits hold the speed. With a limit such as min_base on the y axis, apoli:modify_velocity capped how far you moved each tick while gravity kept adding up in your real velocity underneath, and all of that speed arrived at once when the power stopped or its condition failed. The limits (min_*, max_*, set_*) now hold the velocity itself, so a min_base of -0.1 is a true terminal velocity. Multiplying and adding operations still scale the movement each tick, as before.

Changed — apoli:creative_flight and fall damage. Minecraft skips fall damage for anyone who is allowed to fly, so the power made its holder immune to every fall, flying or not. Flight from the power no longer does that: stop flying in mid-air or walk off a ledge and you take the fall like anyone else. Flying down to land is still safe, and creative and spectator players are untouched. To keep the immunity, pair the power with a fall apoli:invulnerability:

{
  "type": "apoli:multiple",
  "flight": {
    "type": "apoli:creative_flight"
  },
  "no_fall_damage": {
    "type": "apoli:invulnerability",
    "damage_condition": {
      "type": "apoli:from_falling"
    }
  }
}

1.115.4

Includes everything from 1.115.1, 1.115.2 and 1.115.3, which were never uploaded.

Fixed — crash on startup with BadOptimizations. With BadOptimizations 2.4.1 installed, the game crashed while starting, naming apoli$disguiseModel. BadOptimizations replaces the lookup that picks an entity's renderer with a cache, and Apoli's disguise hook sat inside the code it replaces. The hook now works on whatever renderer the lookup returns, so the two load together and a player disguise still gets the right arm width from the cache. If you turned off enable_entity_renderer_caching to get past the crash, you can turn it back on.

Fixed — apoli:night_vision with BadOptimizations. BadOptimizations skips lightmap redraws until something it watches changes, and the power's strength was not one of those things: night vision could take seconds to show, or never show with the daylight cycle stopped. Apoli now tells BadOptimizations to redraw when the strength changes.

Fixed — apoli:modify_fov with BadOptimizations. With the FOV Effects slider at 0%, BadOptimizations skips the field-of-view calculation apoli:modify_fov works through, so the power did nothing. Apoli now turns off that one BadOptimizations option (enable_remove_redundant_fov_calculations) and leaves the rest on.

Fixed — the key that closes a menu no longer reopens it. Pressing an apoli:inventory power's key a second time closed the inventory and then, a tick later, opened it again: once the screen was gone, the same press was read as a new one. A press made while any screen is open no longer counts after the screen closes, so the key closes the inventory, or an apoli:radial_menu, and does nothing else. Let go and press again to reopen it.

Fixed — hiding the hat under Fresh Animations. With Entity Model Features and the Fresh Animations Player Extension, an apoli:modify_model_parts power that hid the hat could still show it. The pack draws the hat from boxes of its own, which hidden never reached, and the EMF Compat addons copy the head's visibility onto the hat while they hold a pose, which undid visible for the length of a Better Combat swing. visible and hidden now hide the boxes the pack gives a part as well, so the hat stays hidden through both.

Fixed — custom skins stay on the arm. After a Better Combat swing, an Iron's Spells cast or an Immersive Melodies song, with the EMF Compat addons that keep those poses under Fresh Animations, an apoli:custom_model_render skin on the first-person arm could drift off the hand until you cycled the camera with F5. Apoli holds the pack's animation while it draws its own layers, and the addons were lifting that hold. It now uses EMF's per-entity pause, which they respect, so the overlay stays on the arm.

Performance — less garbage in crowded scenes. Apoli checks its powers inside vanilla code that runs constantly: collision checks between every pair of nearby entities, every entity drawn every frame, every movement tick. Several of those checks created short-lived objects on every call, whether or not anyone had a power. In a test scene with about 400 entities, Apoli was producing roughly 85 MB of garbage per second, mostly from collision checks, from positioning each entity for rendering, and from looking up client-side powers by entity id. It now produces about 0.1 MB/s, and the game's total allocation rate in that scene fell from 575 to 473 MB/s. That means fewer garbage-collection pauses on busy servers and on clients looking at crowds. Nothing about how powers behave has changed.

Performance — cheaper invisibility and glow checks. apoli:invisibility and apoli:entity_glow hook the getters Minecraft calls several times per entity per frame, and those hooks used to allocate on every call. They are now allocation-free with or without BadOptimizations, and skip themselves entirely while no loaded power uses those types. isInvisible on an entity without the power went from 11 ns and 64 bytes per call to 7.7 ns and none, and isInvisibleTo from 25 ns and 112 bytes to 12 ns and none. On 1.20.1, where BadOptimizations keeps these flags in plain fields, Apoli's hook had become the most expensive part of reading them.

Type
Name
Game Versions
Mod Loaders
Size
Downloads
Uploaded