This page is currently only a draft! It is not intended to be read by Wiki users yet!
This page should be read after having already read the Mixin Introduction page.
Mixins are a tool that is, by virtue of modifying potentially vastly different targets, a tool that changes its usage on a case-by-case basis. As such, which tool is right for the job, if Mixin is fitting in the first place, will change for every single case. This page will attempt to go over when to use different kinds of tools in Mixin and MixinExtras.
Could not find any more specific things than “Existing Events” thus far for this section. Whilst the section does have a conclusion that tries to teach the broader idea of when not to use Mixins, it's likely I'm missing something here, feedback and advice is very welcome! -GauntRecluse
Sometimes, the goal to be fulfilled is simply not something Mixin is fit for. A good rule of thumb to avoid creating unnecessary Mixins is to only use them when other options such as existing events and other tools integrated into the modding framework are insufficient or greatly impractical. In other words, Mixin is not a first resort tool.
A very frequent use case for Mixins is to “listen” for a specific operation in code, and react to it. Modloaders, however, typically already have a large amount of events built into them. As such, when trying to “listen” to a given action in Vanilla code, a dev should first search through the relevant events of their modding framework.
This is however not the only case where events are the better option. For instance, say you wanted to add functionality upon interacting (most often via right clicking) a block that is registered as a Block
. One may want to use a Mixin to register it as a custom class to give it all sorts of functionality. However, if the only desirable trait is to do something when right clicking on it, it may be relevant to instead consider using the modding framework's event for interacting with blocks, and checking if the block interacted with is the one we wish to add a functionality to.
It may be unintuitive at first, however the reason this may be an approach to consider is that changing the class it is registered as can cause a lot of issues for other mods who may want to do a similar action, or for mods that may rely on that block being the class it is registered as. Changing the registration class via Mixin would have ripple effects and potentially have issues. At that point, it may not be worth using Mixins anymore.
Do not use Mixins when there are ways for events or other non-Mixin tools to substitute them in a way that is less intrusive and/or incompatible. This fits into the broader principle that Mixins need to, when they must be used, be used in the most precise way as to cause the least potential issues.
Overwriting, done via @Overwrite
, is the tool within Mixin with the least use-cases. In this context, overwriting means replacing the target method whole-sale with your own. This is incredibly incompatible and almost never the right thing to do. There are no typical use-cases where @Overwrite
is the correct choice, and it should be your very last resort.
If you feel that you need to use @Overwrite
, you should first seek support and second opinions from other devs, as it is likely you missed something.
Redirecting, in the context of Mixins, consists of using @Redirect
or any other redirector to replace the targeted operation with a call to your own. This replacement aspect means that it cannot be chained.
The fact that redirectors cannot chain means that Mixin will cause a hard crash if it tries to use two required redirectors on the same target. This, in most situations, simply makes them a worse alternative to the current set of injectors. The exception in that is when you intend to crash when another mod tries to redirect the same target as you, or when you want to leverage the hard incompatibility aspect of Redirectors. Do note that injectors such as @WrapOperation
can be used on a redirected target, as they can chain and are applied after redirectors.
In short, redirectors should only be used when you directly intend to use the incompatibility aspect of it. Otherwise, injectors should be used.
@Inject
is the easiest to understand out of all injectors. The annotated handler method is merged into the target class, and Mixin inserts a call back (AKA a “callback instruction”) to that merged method at the specified point(s) based on the metadata in the annotation. It may also be used to create early returns in the target method, cancelling the rest of it. This is useful for a vast variety of things, but this page will list a couple cases where it may be typically preferrable. Though, depending on your intention, you may benefit from using another injector.
Using @Inject
to insert a call just before or just after a specific operation in the target code, allows you to effectively detect and react to that action. This is specifically useful when there are no events in your modloader environment that suit your needs for listening to an action taking place.