Development¶
This page covers working on an addon and on AkumaLib at the same time, and building a release that actually works once installed.
Developing an addon alongside the library¶
The intended layout is two checkouts side by side:
Your addon's settings.gradle includes the library build directly:
if (!gradle.startParameter.projectProperties.containsKey('akumalibFromMaven')) {
includeBuild('../AkumaLib')
}
With that, implementation "com.inovactio:akumalib:${akumalib_version}" resolves to the sibling checkout rather than to a published jar. Editing the library and rebuilding your addon needs no publish step in between.
The module name must match
The library pins rootProject.name to akumalib. If a checkout ends up with a different module name, the substitution silently fails to match and Gradle falls through to a published artifact that may not exist.
Two consumption modes¶
The two ways of consuming the library need different treatment, so the switch is an explicit flag rather than something inferred.
| Mode | Command | What your addon compiles against |
|---|---|---|
| Development (default) | gradlew build |
the library's mapped jar, through includeBuild |
| Control build | gradlew build -PakumalibFromMaven |
the reobfuscated published jar, through fg.deobf |
dependencies {
if (project.hasProperty('akumalibFromMaven')) {
implementation fg.deobf("com.inovactio:akumalib:${akumalib_version}")
} else {
implementation "com.inovactio:akumalib:${akumalib_version}"
}
}
Run the control build before any release
The composite build puts the library's classes on the classpath directly, which completely hides a resource missing from the packaged jar: the lang file, a texture, mods.toml itself. The control build is the only build that catches it.
Building AkumaLib from source¶
The source repository is not public yet
These steps assume a checkout of the AkumaLib sources.
The jar trap¶
gradlew build produces a jar for development only
Reobfuscation is deferred to publishing, so build leaves a jar in Minecraft's mapped names. Installed in a real game, that jar loads and then fails on its first Minecraft call.
The deferral exists for the composite build. Reobfuscating the jar task in place would hand your addon SRG names (addAdditionalSaveData becomes m_7380_), and every subclass of a library type would fail to compile with an error that names your class and says nothing about mappings:
MyTornadoEntity is not abstract and does not override abstract method
addAdditionalSaveData(CompoundTag) in Entity
The dangerous half is that build/libs holds whichever shape the last task left behind: mapped after build, reobfuscated after publish. Same file name, same size. That is why releaseJar copies the release artifact to its own build/release directory.
Mixins¶
The library ships its own mixin configuration, mixins.akumalib.json:
| Mixin | Target | Why it exists |
|---|---|---|
AbilityHelperMixin |
AbilityHelper.emergencyStopAbility (HEAD) |
interrupts a running charge through AkumaCharges.interrupt, so a forced stop takes back what the charge started. See Charges |
EntitySizeMixin |
Entity.getDimensions |
applies the SIZE attribute, which is inert without it |
client.HumanoidArmorLayerMixin |
HumanoidArmorLayer.renderArmorPiece |
lets an animation hide the wearer's armour |
A library mixin runs in every game that installs the library
An injection into a hot path is paid by every addon, including those that never use the feature. That cost is weighed before any mixin is added.
Versioning¶
Publishing freezes the API. A breaking change to the shared surface is a major version bump and forces a synchronised release of the library and its addons. In your mods.toml, give AkumaLib a version range that names the lowest version you need and leaves the top open, so a player can run any newer AkumaLib. A range that stops at the next major ([4.0.0,5)) refuses it and forces a new release of your addon:
[[dependencies.yourmodid]]
modId = "akumalib"
mandatory = true
versionRange = "[6.6.0,)"
ordering = "AFTER"
side = "BOTH"
Known mixin incompatibilities¶
AkumaLib changes a few of Minecraft's most shared methods. Another mod that changes the same ones may clash with it. None of this has been tried against a modpack: it comes from reading the mixins (audit #802).
| AkumaLib mixin | Minecraft method | How | What can clash |
|---|---|---|---|
Vec3DistanceMixin |
Vec3.distanceTo, distanceToSqr (both forms) |
@Overwrite, so a distance allocates nothing |
another mod's @Overwrite: one of the two loses, with a warning in the log |
EntityDistanceMixin |
Entity.distanceTo, distanceToSqr (both forms) |
@Overwrite, same reason |
same |
EntityPushSizeMixin |
the two push(DDD) calls in Entity.push(Entity), by ordinal |
@Redirect |
another @Redirect on the same call |
LivingEntityKnockbackSizeMixin |
the setDeltaMovement call in LivingEntity.knockback |
@Redirect |
another @Redirect on the same call |
The mixin config sets defaultRequire = 1, so an injection that finds nothing to work on stops the game at startup instead of doing nothing. Physics and combat mods are the likely ones. If a modpack meets one of these, the crash report names the mixin, and the fix is to move that mixin to MixinExtras' @WrapOperation, which chains with other mods. AkumaLib does not bundle MixinExtras today, and nothing has been changed for a clash no one has measured.