Table of Contents
Access Widening
Access widening provides a way to loosen the access limits of classes, methods or fields. This includes making them public, or making them extendable (subclassable).
Access widening may be used instead of accessor mixins, and there are currently 2 cases where the functionality provided by mixin is not sufficient:
- Needing to access a (package) private class, especially for the purpose of shadowing or accessing a field or method in a mixin.
- Being able to override final methods or subclass final classes.
- If you want to subclass a class with only (package) private constructors, wideners are a good choice.
Access widening is a type of class tweaking, and is defined in the class tweaker file. In previous Fabric versions (before Loom 1.13), the class tweaker was known as the “access widener” (as it had no other functionality).
As with other types of class tweaking, in order for access widening changes to show up in the decompiled source, run the genSources gradle task and then reload the gradle project in your IDE.
Note: Unlike accessor mixins, class tweaking only works on Minecraft code, and not on other mods.
File format
A specific file format is used to define the access changes included in your mod. To aid IDEs you should use the .classtweaker file extension.
The file must start with the following header. namespace should usually always be set to the word named, and not your project namespace. Loom will remap the class tweaker file for you into intermediary along with your mod. In unobfuscated versions (upcoming, 26.1+), the namespace will be official, and the class tweaker will not be remapped.
classTweaker v1 <namespace>
Once again, the namespace should be named in most if not all cases
Class tweaker files can have blank lines and comments starting with #
# Comments like this are supported, as well as at the end of the line
Any whitespace can be used to separate in the class tweaker file, tab is recommended.
Class names are separated with a / and not .
For inner classes, you should use $ instead of /
Classes
Class access can be changed by specifying the access and the class name as named the mappings namespace defined in the header.
<access> class <className>
- access can be accessible or extendable
Methods
Method access can be changed by specifying the access, class name, method name and method descriptor as named the mappings namespace defined in the header.
<access> method <className> <methodName> <methodDesc>
- access can be accessible or extendable
- className is the owner class
- methodName is the method name
- methodDesc is the method descriptor
Fields
Field access can be changed by specifying the access, class name, field name and field descriptor as named the mappings namespace defined in the header.
<access> field <className> <fieldName> <fieldDesc>
- access can be accessible or mutable
- className is the owner class
- fieldName is the field name
- fieldDesc is the field descriptor
Access Changes
Extendable
Extendable should be used where you want to extend a class or override a method.
- Classes are made public and final is removed
- Methods are made protected and final is removed
Making a method extendable also makes the class extendable.
Accessible
Accessible should be used when you want to access a class, field or method from another class.
- Classes are made public
- Methods are made public and final if private
- Fields are made public
Making a method or field accessible also makes the class accessible.
Mutable
Mutable should be used when you want to mutate a final field
- Fields have final removed
If you want to make a private final field both accessible and mutable, you need to use two directives, one for each change.
Specifying file location
The access widener file location must be specified in your build.gradle and in your fabric.mod.json file. It should be stored in the resources as it needs to be included in the exported jar file. (Replace “modid” in the example with your own mod ID.)
build.gradle:
loom { accessWidenerPath = file("src/main/resources/modid.classtweaker") }
fabric.mod.json:
... "accessWidener" : "modid.classtweaker", ...
Note that for backwards compatibility reasons, the class tweaker is still referred to as an “access widener” in the build.gradle and the fabric.mod.json. It will be renamed in FMJ2.0.
Validating the file
By default, class tweaker entries that don't exist are ignored.
You can run the validateAccessWidener gradle task (./gradlew validateAccessWidener) to check that all the classes, fields and methods specified in the class tweaker file exist.
The error messages can be a little cryptic. For example, if you make a mistake in specifying a field, the error doesn't say whether the name or the type is the problem. For example, if it says it cannot find the field “fooI”, it could mean there is no field named foo, or that it exists but isn't an int (I).
Transitive class tweakers
On all access widener directives, the transitive-* prefixed keywords can be used:
transitive-accessibletransitive-extendabletransitive-mutable
They differ from their regular, non-prefixed variants in that they also apply to mods that depend on this one. This is useful for library mods that want to expose their class tweaker changes.