:!: //This is a draft! Feedback is appreciated, but keep in mind this is currently not intended to be read by Wiki users, it is not guaranteed that this page is fully accurate.// //TODO List: Example of how a direct injection attempt would fail; Note about how submixin patterns cannot contain interfaces// ====== Creating an Override in a target class (DRAFT) ====== ===== Introduction ===== When mixing into a class, you may want to modify an inherited method's behavior for your target's instances. You may then be tempted to create an override. For this tutorial, we'll use an example situation where we want to call a custom method every time a copper golem gets hurt. Specifically, we'll be using 1.21.10 with Yarn mappings. ===== The Problem ===== The class ''CopperGolemEntity'' does not have an override for ''LivingEntity#damage(ServerWorld, DamageSource, float)'', and we want to call ''ExampleMod#doSomething()'' every time a copper golem takes damage. If this were our own class, we would just create an override. ==== Direct Override: What not to do ==== We may be tempted to have our mixin class extend the super of ''CopperGolemEntity'' and override like so: @Mixin(CopperGolemEntity.class) abstract class CopperGolemEntityMixin extends GolemEntity { // Dummy constructor from extending GolemEntity protected CopperGolemEntityMixin(EntityType entityType, World wolrd) { super(entityType, world) } @Override public boolean damage(ServerWorld world, DamageSource source, float amount) { ExampleMod.doSomething(); return super.damage(world, source, amount); } } However, this is inherently incompatible with other mods who may want to apply a similar modification, and therefore should be avoided. The rest of this page will walk you through two solutions which are more compatible and do not sacrifice functionality. ===== The Solutions ===== ==== Injecting an instanceof check in the super ==== We can inject a check within the method we wish to functionally override, which will execute our custom operations if the ''this'' instance is of the intended subclass. In our case, we could create a Mixin like the following: @Mixin(LivingEntity.class) abstract class LivingEntityMixin { @WrapMethod(method = "damage") private boolean doSomethingForCopperGolem(ServerWorld world, DamageSource source, float amount, Operation original) { if ((Object) this instanceof CopperGolemEntity) { // We have to cast to Object first to satisfy the compiler ExampleMod.doSomething(); } return original.call(world, source, amount); } } Remember of course that other injectors than ''@WrapMethod'' may be more fitting depending on your specific use-case. This Mixin only covers our specific situation. ==== Submixin Pattern ==== Alternatively, we may use what is known as a submixin pattern. This will require to create two Mixin classes in dedicated files in our project's mixin package. One will target the class containing the method we want to functionally override -- we'll call it the "parent" Mixin or the "super" Mixin -- and the other will target the class we want to functionally create an override into, which we'll call the "child" Mixin or "sub" Mixin. For this tutorial, we will call the parent Mixin class ''LivingEntityMixin'', and the child mixin class ''CopperGolemEntitySubMixin''. These will be in separate files registered in our ''mixins.json'' config. === The Parent Mixin === The parent Mixin must create a "dummy" injector, with a ''protected'' handler method, which will apply no changes by itself: @Mixin(LivingEntity.class) abstract class LivingEntityMixin { @WrapMethod(method = "damage") protected boolean overrideForCopperGolem(ServerWorld world, DamageSource source, float amount, Operation original) { return original.call(world, source, amount); } } === The Child Mixin === The child Mixin, or submixin, targets the class we want to override behavior for, and extends the parent Mixin: @Mixin(CopperGolemEntity.class) abstract class CopperGolemEntitySubMixin extends LivingEntityMixin { } We then override the dummy handler, and apply the actual changes in the override. @Mixin(CopperGolemEntity.class) abstract class CopperGolemEntitySubMixin extends LivingEntityMixin { @Override protected boolean overrideForCopperGolem(ServerWorld world, DamageSource source, float amount, Operation original) { ExampleMod.doSomething(); return original.call(world, source, amount); } }