本条基于 Minecraft 1.20.1 + Forge、Java 17。
Mixin(SpongePowered Mixin)是基于 objectweb asm 的字节码注入框架,在类加载时把“混入类”里的代码合并进目标类。Forge 自 1.16.5 起内置 Mixin,模组只需声明 mixin 配置文件即可使用。
原理
- 以 ModLauncher 的转换服务接入,由 TransformingClassLoader 在加载目标类时调用,对其
ClassNode进行变换。 - 混入类本身不会作为普通类使用,其字段、方法和注入点在运行时合并进目标类。
- 开发环境写 Mojang 映射名,编译时生成 refmap,生产环境靠它把名字映射到 SRG 名。
常用注解
@Mixin:指定目标类@Inject:在方法头、返回前、调用处等位置插入回调,配合CallbackInfo可取消或改返回值@Redirect、@ModifyArg、@ModifyVariable:替换调用、参数、局部变量@Overwrite:整个覆盖方法@Shadow、@Unique、@Accessor、@Invoker:引用、新增、暴露目标类的成员
与实体的关系
常见用法是注入 EntityTickList、EntityLookup、LevelRenderer 等类,改变实体是否被 tick、被查询或被渲染。
局限
- 只能处理尚未加载的类;已加载的类需要 Instrumentation 的 retransform 等手段。
- 不能修改由引导类加载器加载的 JDK 类(如
java.*),因为它们不经过 TransformingClassLoader。 - 多个模组注入同一位置可能冲突,
@Overwrite和@Redirect尤其容易冲突。