This is a collection of general information and tips about Fabric modding. Credit is provided where possible in the format creator, location.
Please open a PR if you have any addition / modification suggestion !
Understanding Mixin Architecture
The Mixin Environment
Obfuscation and Mixins
Resolving Method Signature Conflicts
Overwriting Methods
About Hierarchy Validation in Mixins
PSA Forward Compatibility Features in Mixin
Flippin' Mixins, how do they work?
Overwrite
Inject
Redirect
ModifyVariable
ModifyConstant
ModifyArg
ModifyArgs
Mutable
Shadow
Constant
Final
Unique
CallbackInfo
CallbackInfoReturnable
InjectionPoint
Constant.Condition
LocalCapture
Fabric API
SpongeCommon
SpongeForge
You should never store null in compound tags since you end up becoming incompatable with Sponge since their data processor system specifically expects the contents of a CompoundTag to be never null and will crash as a result.
i509VCB, Fabric Discord
Mojang technically disallow null too they just aren't defensive with it. It's common knowledge that they use ParametersAreNonnullByDefault on all their packages. It's just stripped by proguard. Forge adds it back but Loom doesn't
Chloe Dawn, Fabric Discord
Inventory syncing conventionally happens via the container. Any other type of syncing is only necessary when the client needs to know outside the GUI. Please don't use block entity updates and similar if you don't have to
JamiesWhiteShirt, Fabric Discord
Adding numbers to container slots in debug:
package [...].mixin.client;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.ContainerProvider;
import net.minecraft.client.gui.screen.ingame.ContainerScreen;
import net.minecraft.container.Container;
import net.minecraft.container.Slot;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ContainerScreen.class)
@Environment(EnvType.CLIENT)
public abstract class ContainerScreenMixin<T extends Container> extends Screen implements ContainerProvider<T> {
private static final boolean DEBUG = FabricLoader.getInstance().isDevelopmentEnvironment();
@Shadow @Final protected T container;
@Shadow protected int x;
@Shadow protected int y;
private ContainerScreenMixin(Text title) {
super(title);
}
@Inject(
method = "render",
at = @At("TAIL")
)
private void render(int mouseX, int mouseY, float delta, CallbackInfo ci) {
if(DEBUG) {
for(Slot slot : container.slots) {
if(slot != null)
font.draw("" + slot.id, slot.xPosition + x, slot.yPosition + y, 0xFFFFFF);
}
}
}
}
Gudenau, Fabric Discord
Chloe Dawn: My mod references bindTexture, but method_4618 became a pointer to bindTextureInner in 1.15.2? Thalia/Christie: Intermediaries are matched by method content. If mojang refactors a method into api/impl then the intermediary name will go to the impl method. The same thing happened with Biome#getTemperature in 1.14.4
Thalia/Christie, Fabric Discord