Tags
Creators
Details
1.124.0
Compatibility
Required content
Changes
1.124.0
Before you update
apoli:sneakyandapoli:share_effectsare gone, and a power that uses either one no longer loads. Both can be built from other powers.
Removed: apoli:sneaky and apoli:share_effects
apoli:sneaky and apoli:share_effects were both compositions of powers Apoli already has. For Sneaky, apoli:scale on apoli:visibility makes mobs notice the player from 80% of the usual distance. apoli:modify_label_render fades the nameplate and hides it past 32 blocks with an apoli:distance condition. apoli:replace_sound_emission mutes step sounds while apoli:on_block holds, and apoli:prevent_game_event stops the minecraft:step vibration. Foxes and the "Time Sneaked" statistic read vanilla's sneak flag directly, so those are the two things the composition doesn't cover.
For Share Effects, an apoli:action_over_time that runs an apoli:area_of_effect with apoli:transfer_effects does the same job. This one gives the holder's tamed pets within 8 blocks a copy of every effect the holder has, twice a second:
{
"type": "apoli:action_over_time",
"interval": 10,
"entity_action": {
"type": "apoli:area_of_effect",
"radius": {
"x": 8,
"y": 2,
"z": 8
},
"bientity_condition": {
"type": "apoli:all_of",
"conditions": [
{
"type": "apoli:owner"
},
{
"type": "apoli:target_condition",
"condition": {
"type": "apoli:tamed"
}
}
]
},
"bientity_action": {
"type": "apoli:transfer_effects",
"mode": "give",
"copy": true
}
}
}
Performance: apoli:attribute
Attribute powers now use less memory and CPU. They check their modifiers every tick. That is how the modifiers come back after a login or a reload, and how they follow a condition. The check used to build a lookup key, a string and a modifier id for every modifier on every holder, every tick, and on 1.20.1 it also hashed the id with MD5. Apoli now works out the ids once per power and reads the value it applies straight from the entity's own attribute. A power with four modifiers went from 1.1 KB of garbage and 1.1 µs per tick to none and 0.13 µs on 1.21.1, and from 2.8 KB and 1.7 µs to 64 bytes and 0.09 µs on 1.20.1. Apoli tests the condition once per power instead of once per modifier, and it no longer scans every attribute modifier in the world when an entity is removed.
1.123.0
Before you update
- The voice chat and speech powers left Apoli for a new addon, Birdsong:
action_on_speak,action_on_reply,action_on_speech,modify_speaking_range, the fivevoice_*conditions and thevoice_*expression variables. Install Birdsong to keep them working. Without it, packs that use theapoli:ids still load, but those powers do nothing, the conditions readfalseand the variables read0. loading_prioritynow decides between packs for global power sets and origins, so a lower pack with a higher priority can win over the top pack.- Speech settings move from
apoli-client.jsonto Birdsong'sbirdsong-client.jsonthe first time Birdsong starts.
Added: JSONC and JSON5 data files
Every Apoli and Origins data folder now also accepts .jsonc files, which allow // and /* */ comments and a comma after the last item. These folders also accept .json5 files, which allow names without quotes, single quotes, hexadecimal numbers, .5 and 5., Infinity and NaN, along with the JSONC features. That covers powers, macros, global power sets, custom status effects, keybinds, skill trees, origins, layers and badges. Apoli reads them with its own parser, so it doesn't need Quilt's parser library. Thanks to FLD for the original pull request.
{
type: 'apoli:swim_speed',
name: 'Strong Swimmer',
modifier: {
operation: 'multiply_total_multiplicative',
value: .5,
},
}
Apoli skips a file that doesn't parse, and the log names its pack, the line, the column and the path to the bad value. When a plain .json file has a comment or trailing comma, the error names the extension that would accept it. Text after the last bracket only logs a warning. Two files with the same id in one pack, such as swim.json and swim.json5, log a warning, and the .json file wins. Between packs, the higher pack wins whatever the extension.
Fixed: loading_priority on global power sets
Global power sets used to read only the top pack's file, so loading_priority did nothing. It now decides which pack's version wins, the same way custom status effects already did.
Changed: voice chat and speech moved to Birdsong
Birdsong registers the voice types as birdsong: ids and keeps every apoli: id as an alias, so existing packs work unchanged after you install it. The Speech to Action key, the speech settings and /apoli:speech moved with it. Speech recognition no longer ships inside Apoli, and Apoli's jar went from 31.7 MB to 4.3 MB.
Changed: loaders
This release is built against Fabric Loader 0.20.1, Fabric API 0.116.17 on 1.21.1 and 0.92.12 on 1.20.1, and NeoForge 21.1.265.
Performance: faster data loading
The new parser reads data files about twice as fast as Gson did.
1.122.0
Added: play a chosen sound file
apoli:play_sound takes an index: which of the sound event's sound files to play, counting from 0 in the order sounds.json lists them. Without an index, a random one plays, as before, and an index past the end of the list also plays a random one. The index can be an expression too.
{
"type": "apoli:play_sound",
"sound": "minecraft:entity.pig.ambient",
"index": 2
}
Each player's game picks the file from its own copy of the sound, so a resource pack that changes the list changes which file an index plays for that player.
1.121.0
Before you update
apoli:stacking_status_effectnow lets the count sink tomin_stackswhile the power is inactive, and only applies effects while it is active. A pack with a negativemin_stacksgets the delay it asked for: Elytrian's claustrophobia waits about ten seconds under a low ceiling.- When
apoli:poseforces a player intosittingorsliding, they get a lower hitbox and camera.
Fixed: Pose
apoli:pose changed the hitbox for some poses but left the model as it was. Every pose now shows on players and on mobs that use the humanoid model, such as zombies and skeletons.
crouchingcrouches the player's own model, and the player moves at sneaking speed.sitting,sliding,shooting,inhaling,long_jumping,croaking,using_tongue,roaring,sniffing,emerginganddiggingeach have a pose of their own. The Pose page in the Handbook describes them.dyingfalls over sideways and stays down, andfall_flyingglides fully.sittinglowers a player's hitbox to 1.2 blocks with the eyes at 1.0, andslidingto 0.9 with the eyes at 0.6, so a sliding player fits under a one-block gap.
sliding, shooting and inhaling only exist on 1.21.1.
Fixed: stacking status effect
A negative min_stacks delayed nothing, so Elytrian got Weakness and Slowness the moment it walked under a low ceiling. The count now has to climb back above 0 before the effects start, and a newly granted power starts at min_stacks when it is negative.
Fixed: sounds from resource packs
apoli:play_sound, the sound of apoli:fire_projectile and the consume_sound of apoli:edible_item played nothing for a sound that only a resource pack defines. They play it now, for every player who has the pack.
Added: fallback textures for HUD bars
hud_render takes a fallback: a texture, an object with its own sprite_location, bar_index and icon_index, or a list of them. Players who don't have the resource pack behind sprite_location see the first fallback that exists instead of the missing texture.
"hud_render": {
"sprite_location": "example:textures/gui/mana_bar.png",
"fallback": {
"sprite_location": "apoli:textures/gui/resource_bar.png",
"bar_index": 3,
"icon_index": 2
}
}
Added: spawn offsets
apoli:spawn_entity (entity and block action), apoli:summon_clone, apoli:summon_minion and apoli:spawn_effect_cloud take an offset. The entity actions also take a space, so "local" places the entity relative to where the caster is looking.
{
"type": "apoli:spawn_entity",
"entity_type": "minecraft:armor_stand",
"offset": { "z": 2 },
"space": "local"
}
1.120.0
Added: Modify Player Spawn fields
apoli:modify_player_spawn has four new fields, contributed by FLDebug10.
| Field | Type | Default | Description |
|---|---|---|---|
biome_condition |
Biome condition | optional | Spawn in the nearest biome that passes it. With biome set too, either one counts. |
structure_tag |
Identifier | optional | Spawn at the nearest structure in this tag. With structure set too, either one counts. |
block_condition |
Block condition | optional | Only accept a spot where the block at the player's feet passes it. Wrap it in apoli:offset with "y": -1 to test the floor. |
search_radius |
Integer | 32 |
How many blocks the safe-spot search reaches, from 1 to 64. A value outside that range is clamped with a warning. |
{
"type": "apoli:modify_player_spawn",
"dimension": "minecraft:overworld",
"structure_tag": "minecraft:village",
"block_condition": {
"type": "apoli:offset",
"y": -1,
"condition": {
"type": "apoli:block",
"block": "minecraft:grass_block"
}
}
}
Performance: Modify Player Spawn
The power no longer keeps a 23×23-chunk area loaded around every spawn point it finds; those chunks stayed loaded and ticking for as long as the server ran. Apoli remembers biome and structure searches until the data pack reloads, so only the first player with the power waits for them. It does not repeat a safe-spot search that finds nothing for five minutes.
Fixed: Modify Player Spawn
- On 1.20.1, choosing an origin with this power, such as Blazeborn, only moved the respawn point and didn't teleport the player. It teleports them now.
block_conditionchecked the neighbouring block at negative coordinates.- The safe-spot search could put a player on top of the Nether's bedrock roof.
Fixed: reach on 1.20.1
Reach from other mods, such as Reach Entity Attributes (which many 1.20.1 mods bundle), was overridden on the server, so a block mined from beyond vanilla reach broke on the client, reappeared and dropped nothing. That reach now stacks with Apoli's. Apoli's own reach also works for using and placing blocks more than about 8 blocks away.
Fixed: ropes
- A rope could stay on screen after you left a server while attached, even in later sessions.
- Apoli hides a rope whose end is out of sight instead of freezing it in place.
- Players who join, respawn or change dimension now see ropes that already exist.
Fixed: keybinds
Origins' and Apoli's ability keys reset to their defaults whenever options were saved outside a world, for example after changing a setting on the title screen. Bindings now survive. On NeoForge, Apoli also restores a binding with a modifier such as Shift+G correctly.
Optional dependencies
Supplementary resources
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:i2NQbLvK:8d2KKcww"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:i2NQbLvK:8d2KKcww"
}

