-
Notifications
You must be signed in to change notification settings - Fork 2
Schema
In standard mixins, you often need to write the same thing in several places. For example, first you want to inject into the head of the method:
@Inject(
method = "Lnet/minecraft/world/entity/player/Player;crit(Lnet/minecraft/world/entity/Entity;)V",
at = @At(value = "HEAD")
)
private void doStuff(Entity entity, CallbackInfo ci) {}Then you will want to change the argument when calling it from another method:
@WrapOperation(
method = "Lnet/minecraft/world/entity/player/Player;attackVisualEffects(Lnet/minecraft/world/entity/Entity;ZZZZF)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;crit(Lnet/minecraft/world/entity/Entity;)V")
)
private void doStuffAgain(Player instance, Entity entity, Operation<Void> original) {}Then you want to call this method directly in mixin and use @Shadow:
@Shadow
public abstract void crit(Entity entity);And finally, if you need to call this method from outside the mixin and it is private, then you create an separate class with @Invoker:
@Mixin(Player.class)
interface PlayerAccessor {
@Invoker("crit")
void crit(Entity entity);
}Or you use AW for it (text file outside of code):
accessible method net/minecraft/world/entity/player/Player crit (Lnet/minecraft/world/entity/Entity;)V
This triggers a "redundancy cycle" where you manually duplicate the signature across injection parameters, @At targets, original.call arguments, @Shadow and @Invoker methods, and external files—effectively turning modding into error-prone manual data entry. Maintaining this is highly inefficient: a single change to the crit method signature in a future Minecraft update would require manual updates in multiple locations, making the codebase fragile and difficult to refactor.
Single Source of Truth (SSoT)