Views
Actions
Difference between revisions of "Access Transformers"
(Add information on member signatures. TODO: add a link to the Java specification on signatures) |
m ("a class or field inside the class" -> "a method or field inside the class") |
||
Line 21: | Line 21: | ||
If you're targetting a class itself, you may omit the Member Signature.<br> | If you're targetting a class itself, you may omit the Member Signature.<br> | ||
− | However, it is required if you're targetting a | + | However, it is required if you're targetting a method or field inside the class.<br> |
<code>MemberSignature</code>s use the Java specification for parts.<br> | <code>MemberSignature</code>s use the Java specification for parts.<br> | ||
Importantly, classes are in the form <code>Lpath/to/Class;</code>, method descriptors are <code>name(parameters)return</code> and <code>V</code> is void.<br> | Importantly, classes are in the form <code>Lpath/to/Class;</code>, method descriptors are <code>name(parameters)return</code> and <code>V</code> is void.<br> |
Revision as of 23:39, 12 August 2021
This page is under construction.
This page is incomplete, and needs more work. Feel free to edit and improve this page!
Access Transformers are Forge's native way of allowing you to access (read and write) functions that have a lower-than-ideal visibility, and/or removing finality.
Visibility
Here's a quick rundown of the visibility options offered by Java 16:
public
visible to all classes inside and outside its packageprotected
visible only to classes inside the package and subclassesdefault
visible only to classes inside the packageprivate
visible only to inside the class
Additionally, there are final variants of each of these, each represented by the phrase "-f" on the end of the access specifier.
How It Works
As Forge is loading, it scans the jar file for the META-INF/accesstransformers.cfg file. if it's found, it is parsed according to the specification:
NewAccessSpecifier ClassSignature MemberSignature # comment
If you're targetting a class itself, you may omit the Member Signature.
However, it is required if you're targetting a method or field inside the class.
MemberSignature
s use the Java specification for parts.
Importantly, classes are in the form Lpath/to/Class;
, method descriptors are name(parameters)return
and V
is void.
A couple random examples to understand the syntax:
public net.minecraft.world.level.chunk.PaletteResize # makes the PaletteResize class public
protected net.minecraft.client.gui.Gui f_168667_ # COLOR_WHITE
public net.minecraft.client.renderer.GameRenderer m_109128_(Lnet/minecraft/resources/ResourceLocation;)V # loadEffect
If a valid entry is found on a line, Forge will look into the bytecode of the file where that member is defined, and change its access to whatever you desire it to be.
This startup modification means accessing is O(1) for all accesses after this initial change, which makes it a great option for performance if you're looking at something a lot
Removing Finality
Access transformers can also be used to remove the final keyword on code elements. To do this, append -f
to the access specifier.
An example of this in place:
public-f net.minecraft.world.level.chunk.PaletteResize # makes PaletteResize public
Note: You can also use this to add a final keyword via +f
. This is never recommended however, and should be avoided at all costs unless absolutely necessary.
Using Access Transformers in your mod
Important
Step 1: Uncomment the access transformer line in your build.gradle
Step 2: Create a new file called "accesstransformer.cfg" in the src/main/resources/META-INF/
folder.
Step 3: Refresh the Gradle project. This can be done natively in IDEA and Eclipse.
When not to use Access Transformers
- Unnecessary access transformations (e.g. using ATs to make something
public
when it's alreadypublic
)