AkumaLib 2.2.0
Curse Maven Snippet
What's new
AkumaLib 2.2.0
Six additions and one behaviour change since 2.1.0. No existing signature moved, so an addon built against 2.1.0 keeps compiling. That is why this is a minor bump.
Requires Minecraft 1.20.1, Forge 47+ and Mine Mine no Mi 0.11.5.
⚠️ One default changed: a TornadoEntity is no longer put out by rain. See Changes below.
New
AkumaLootInjection — addon fruits inside the base mod's own box pool
An addon fruit could never come out of the base mod's 5% tier cascade — the roll where a wooden box upgrades into an iron one — because that nested roll resolves through a code path that skips loot modifiers by design. Every addon fruit was therefore rarer than a base mod fruit of the same tier, and no number in a loot file could fix it.
The fruit is now added as an entry inside the pool mineminenomi:fruits, while the table is
still being loaded:
- Parity is weight 100, the figure every base mod fruit already carries. No share to compute and nothing to re-tune when a fruit is added.
- The cascade works, because the upgraded roll draws from a pool that now holds the addon fruit.
- The base mod's own guard applies: the entry carries
FruitAlreadyExistsFunction, as theirs do.
registerFruitItem injects by default, into the box matching the fruit's tier, with an
inLootBoxes overload to opt out. That removes a whole class of bug: a fruit registered with no loot
entry exists, drops from commands and grants its abilities, and cannot be found in survival — with
nothing logged. Two consumers had shipped exactly that.
AkumaLootInjection.addFruit(...) is public for anything registered another way. Each injected table
logs one line at server start.
BlockHighlightManager — outline block positions through terrain, for one player
Draws a box around scattered block positions visible through walls, sent to a single player. The
three obvious routes each fail: particles are depth-tested against terrain, glowing marker entities
cost hundreds of real entities per player, and BlockOverlayManager shades a contiguous zone rather
than single blocks.
BlockHighlightManager.show(player, groupId, positions, colour, ticks);
BlockHighlightManager.clear(player, groupId);
- Positions travel in groups, one colour each, keyed by a UUID the caller owns.
- A group counts itself down on the client: an ability showing something for twelve seconds sends one packet and never has to take it away.
- ⚠️ Capped at 512 positions per group, enforced when writing and when reading.
- Cleared on level unload, so highlights never survive into the next world.
GrabAbility.beginGrab(user, target) — a grab that is not a melee swing
GrabAbility only knew one way to catch somebody: open a reach window, then turn the next hit into
the grab. A ranged grab — a tongue, a rope, a harpoon — decides its target when a projectile
arrives, with no swing to intercept. beginGrab is that entry; the pull, the hold and the release
run exactly as they do for a melee catch.
- It applies the one-tick
ANTI_KNOCKBACKthe melee path applies. Without it, the impact that caught the target knocks them straight back out of the grab. - Server side only, and it refuses to start a second grab while one is running.
AkumaTargeting.inCone(caster, target, halfAngleDegrees)
The cone test two consumers were carrying as character-for-character copies. Written as a plain dot
product against a cosine rather than delegated to TargetPredicate.testAdvancedInView(float), whose
float is documented nowhere. A target standing exactly on the caster counts as inside the cone.
IAwakenZoanSmokeLayerHeadAnchor — the awakened-zoan smoke follows the model's head
A form implementing this marker has its smoke moved to the pivot of the morph model's head, read at render time, before its Y/Z offsets apply. On most morph models that pivot is where the neck leaves the body, so the offsets shrink to small corrections — and the scarf follows the model when it moves its head.
- Only Y and Z follow the pivot, never X: some models shift the head group sideways and compensate in the cubes.
- Opt-in: a form without the marker renders exactly as before.
AkumaRollTableModifier — an insertion mode
"mode": "append" (the default, and what every existing file already means) or "mode": "compete".
compete inserts the rolled loot at the front of the list, for a container that keeps only its
first match. An unrecognised value is a hard codec error rather than a silent fall back to append.
For Devil Fruit boxes you no longer need this at all — AkumaLootInjection handles them. It stays
for chests and any container whose pool cannot be reached.
Changes
A tornado is no longer put out by rain
TornadoEntity was a copy of the base mod's Suna Suna no Mi sandstorm, and it inherited the
sandstorm's rule: water and rain discard it. A generic funnel switching itself off when the weather
turns is nonsense, so the rule is now two hooks:
| Hook | Default | |
|---|---|---|
isQuenchedByWater() |
true |
kept — water is the universal Devil Fruit weakness |
isQuenchedByRain() |
false |
changed — override and return true for a sand funnel |
⚠️ This changes existing consumers. A tornado subclass that overrides neither hook now survives rain where it did not before — AwakenAwakenNoMi's diamond funnel among them.
Fixes
competecould replace a higher-tier fruit with a lower one. The cascade pool is rolled before the same-tier pool, so its fruit heads the list, and acompeteinsert went in front of it: the player lost the upgrade, and nothing said so.
Notes for addon developers
- Bump your
akumalib_versionto2.2.0so yourmods.tomlrange refuses an older library rather than loading against one and crashing during registration. - ⚠️ If you shipped loot modifier files for Devil Fruit boxes, delete them. With injection on by default, keeping them makes a fruit appear in the pool and get inserted by the modifier.
- The distributable jar still comes from
gradlew releaseJar, inbuild/release— never frombuild/libs. - Run the control build (
gradlew build -PakumalibFromMavenin the consumer, aftergradlew publishToMavenLocalhere) before releasing anything that depends on this version.
Consumers released alongside
- Awaken Awaken no Mi 1.1.0 requires AkumaLib 2.2.0: its twelve new awakened forms place their smoke with the head anchor.
This mod has no additional files

