tutorial:mixin_your_first_mixin
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tutorial:mixin_your_first_mixin [2025/10/16 17:42] – Fix remaining GauntTutorialMod mentions, misc. fixes based on bawnorton's feedback gauntrecluse | tutorial:mixin_your_first_mixin [2026/01/23 19:44] (current) – Transition example code from Yarn to MojMaps gauntrecluse | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | :!: //This page is currently a draft! It is not intended to be read by users of the wiki yet. Feedback will be appreciated but trust this page's information at your own risk!//\\ | + | ====== Tutorial: Making your first Mixin ====== |
| - | //Contact GauntRecluse (paleintrovert) on Discord to give feedback and suggestions on this draft// | + | |
| - | + | ||
| - | ====== Tutorial: Making your first Mixin (DRAFT) | + | |
| ===== Preamble ===== | ===== Preamble ===== | ||
| - | This is meant to be complementary to the [[tutorial: | + | This is meant to be complementary to the [[tutorial: |
| See [[tutorial: | See [[tutorial: | ||
| - | This tutorial will be made using a 1.21.1 Fabric Project as reference. It is recommended to develop using IntelliJ IDEa Community Edition to be able to leverage the [[https:// | + | This tutorial will be made using a 1.21.1 Fabric Project as reference. It is recommended to develop using IntelliJ IDEa Community Edition to be able to leverage the [[https:// |
| ---- | ---- | ||
| Line 22: | Line 19: | ||
| After following the necessary steps described in [[tutorial: | After following the necessary steps described in [[tutorial: | ||
| - | <yarncode | + | <code java> |
| @Mixin(MinecraftServer.class) | @Mixin(MinecraftServer.class) | ||
| abstract class TutorialFirstMixin { | abstract class TutorialFirstMixin { | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| - | It is conventional practice to name your Mixin classes the target class with '' | + | It is conventional practice to name your Mixin classes the target class with '' |
| - | You'll notice we made the Mixin class '' | + | You'll notice we made the Mixin class '' |
| Accordingly, | Accordingly, | ||
| Line 53: | Line 50: | ||
| The first step, assuming nothing has caused a crash or gone to hell yet, is to create a " | The first step, assuming nothing has caused a crash or gone to hell yet, is to create a " | ||
| - | <yarncode | + | <code java> |
| @Mixin(MinecraftServer.class) | @Mixin(MinecraftServer.class) | ||
| abstract class TutorialFirstMixin { | abstract class TutorialFirstMixin { | ||
| Line 60: | Line 57: | ||
| } | } | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| Your Mixin injectors' | Your Mixin injectors' | ||
| Next, we add the annotation: | Next, we add the annotation: | ||
| - | <yarncode | + | <code java> |
| abstract class TutorialFirstMixin { | abstract class TutorialFirstMixin { | ||
| - | @Inject(method = "method_3735") | + | @Inject(method = "loadLevel") |
| private void logOnWorldLoad() { | private void logOnWorldLoad() { | ||
| | | ||
| } | } | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| This now specifies to Mixin that, when this method gets merged into '' | This now specifies to Mixin that, when this method gets merged into '' | ||
| Now, to specify where in the targeted method we want our injection to happen, we add something that may be a bit counterintuitive to some, an '' | Now, to specify where in the targeted method we want our injection to happen, we add something that may be a bit counterintuitive to some, an '' | ||
| - | <yarncode | + | <code java> |
| abstract class TutorialFirstMixin { | abstract class TutorialFirstMixin { | ||
| - | @Inject(method = "method_3735", at = @At(value = " | + | @Inject(method = "loadLevel", at = @At(value = " |
| private void logOnWorldLoad() { | private void logOnWorldLoad() { | ||
| } | } | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| Now, let's look closer at the annotations we have thus far. Think of them as holding a series of hierarchized instructions. A very simplified explanation would be: | Now, let's look closer at the annotations we have thus far. Think of them as holding a series of hierarchized instructions. A very simplified explanation would be: | ||
| * '' | * '' | ||
| - | * '' | + | * '' |
| * '' | * '' | ||
| - | * '' | + | * '' |
| //Sidenote: one does not need to put '' | //Sidenote: one does not need to put '' | ||
| Line 98: | Line 95: | ||
| If we fix the signature and add a call to our mod's logger, the full class becomes: | If we fix the signature and add a call to our mod's logger, the full class becomes: | ||
| - | <yarncode | + | <code java> |
| @Mixin(MinecraftServer.class) | @Mixin(MinecraftServer.class) | ||
| abstract class TutorialFirstMixin { | abstract class TutorialFirstMixin { | ||
| - | @Inject(method = "method_3735", at = @At(value = " | + | @Inject(method = "loadLevel", at = @At(value = " |
| private void logOnWorldLoad(CallbackInfo ci) { | private void logOnWorldLoad(CallbackInfo ci) { | ||
| - | ExampleMod.LOGGER.info(" | + | ExampleMod.LOGGER.info(" |
| } | } | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| And that's it for making this Mixin! | And that's it for making this Mixin! | ||
| Line 117: | Line 114: | ||
| ==== Extending the target class' | ==== Extending the target class' | ||
| When the class you're targeting extends and/or implements parents, mimicking that on your Mixin class is an overall benefit, as it allows you to get all of the parent methods directly. For our example Mixin it'll look like: | When the class you're targeting extends and/or implements parents, mimicking that on your Mixin class is an overall benefit, as it allows you to get all of the parent methods directly. For our example Mixin it'll look like: | ||
| - | <yarncode | + | <code java> |
| - | abstract class TutorialFirstMixin extends | + | abstract class TutorialFirstMixin extends |
| public TutorialFirstMixin(String string) { | public TutorialFirstMixin(String string) { | ||
| super(string) | super(string) | ||
| } | } | ||
| - | @Inject(method = "method_3735", at = @At(value = " | + | @Inject(method = "loadLevel", at = @At(value = " |
| private void logOnWorldLoad(CallbackInfo ci) { | private void logOnWorldLoad(CallbackInfo ci) { | ||
| - | ExampleMod.LOGGER.info(" | + | ExampleMod.LOGGER.info(" |
| } | } | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| - | The constructor | + | The constructor |
| ==== Debugging Mixins ==== | ==== Debugging Mixins ==== | ||
| Line 136: | Line 133: | ||
| === Exporting === | === Exporting === | ||
| Mixin provides debugging utilities, one of them is the ability to export the transformed classes once they' | Mixin provides debugging utilities, one of them is the ability to export the transformed classes once they' | ||
| - | This section' | + | This section' |
| Exporting our Mixin would look like: | Exporting our Mixin would look like: | ||
| - | <yarncode | + | <code java> |
| @Debug(export = true) | @Debug(export = true) | ||
| @Mixin(MinecraftServer.class) | @Mixin(MinecraftServer.class) | ||
| - | abstract class TutorialFirstMixin extends | + | abstract class TutorialFirstMixin extends |
| + | public TutorialFirstMixin(String string) { | ||
| + | super(string) | ||
| + | } | ||
| - | @Inject(method = "method_3735", at = @At(value = " | + | @Inject(method = "loadLevel", at = @At(value = " |
| private void logOnWorldLoad(CallbackInfo ci) { | private void logOnWorldLoad(CallbackInfo ci) { | ||
| - | | + | |
| } | } | ||
| } | } | ||
| - | </yarncode> | + | </code> |
| Setting a Mixin to be exported makes it so that once the targeted class has been transformed and has loaded (which could be anytime between the client starting and a world loading) Mixin will export a version of that now transformed class. It should be exported to the directory '' | Setting a Mixin to be exported makes it so that once the targeted class has been transformed and has loaded (which could be anytime between the client starting and a world loading) Mixin will export a version of that now transformed class. It should be exported to the directory '' | ||
tutorial/mixin_your_first_mixin.1760636527.txt.gz · Last modified: 2025/10/16 17:42 by gauntrecluse