Skip to content

Commit 81793f6

Browse files
MildestToucanits-miromacassiancc
authored
Class Tweakers: Introduction & Access Widening (#517)
Co-authored-by: Miroma <its.miroma@proton.me> Co-authored-by: Cassian <cassian@godsted.com>
1 parent 25fda7a commit 81793f6

File tree

15 files changed

+307
-3
lines changed

15 files changed

+307
-3
lines changed

.vitepress/sidebars/develop.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,20 @@ export default [
383383
},
384384
],
385385
},
386+
{
387+
text: "develop.class_tweakers",
388+
collapsed: true,
389+
items: [
390+
{
391+
text: "develop.class_tweakers.introduction",
392+
link: "/develop/class-tweakers/",
393+
},
394+
{
395+
text: "develop.class_tweakers.access_widening",
396+
link: "/develop/class-tweakers/access-widening",
397+
},
398+
],
399+
},
386400
{
387401
text: "develop.misc",
388402
collapsed: true,
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
---
2+
title: Access Widening
3+
description: Learn how to use access wideners from class tweaker files.
4+
authors-nogithub:
5+
- lightningtow
6+
- siglong
7+
authors:
8+
- Ayutac
9+
- cassiancc
10+
- cootshk
11+
- Earthcomputer
12+
- florensie
13+
- froyo4u
14+
- haykam821
15+
- hYdos
16+
- its-miroma
17+
- kb-1000
18+
- kcrca
19+
- liach
20+
- lmvdz
21+
- matjojo
22+
- MildestToucan
23+
- modmuss50
24+
- octylFractal
25+
- OroArmor
26+
- T3sT3ro
27+
- Technici4n
28+
- TheGlitch76
29+
- UpcraftLP
30+
- YTG1234
31+
---
32+
33+
Access widening is a type of [class tweaking](../class-tweakers) used to loosen the access limits of classes, methods and fields and reflect that change in the decompiled source.
34+
This includes making them public, extendable and/or mutable.
35+
36+
To access fields or methods, it can be safer and simpler to use [accessor mixins](https://wiki.fabricmc.net/tutorial:mixin_accessors),
37+
but there are two situations where accessors are insufficient and access widening is necessary:
38+
39+
- If you need to access a `private`, `protected` or package-private class
40+
- If you need to override a `final` method, or subclass a `final` class
41+
42+
However, unlike [accessor mixins](https://wiki.fabricmc.net/tutorial:mixin_accessors), [class tweaking](../class-tweakers) only works on Vanilla Minecraft classes, and not on other mods.
43+
44+
## Access Directives {#access-directives}
45+
46+
Access widener entries start with one of three directive keywords to specify the type of modification to apply.
47+
48+
### Accessible {#accessible}
49+
50+
`accessible` can target classes, methods and fields:
51+
52+
- Fields and Classes are made public.
53+
- Methods are made public, and final if originally private.
54+
55+
Making a method or field accessible also makes its class accessible.
56+
57+
### Extendable {#extendable}
58+
59+
`extendable` can target classes and methods:
60+
61+
- Classes are made public and non-final
62+
- Methods are made protected and non-final
63+
64+
Making a method extendable also makes its class extendable.
65+
66+
### Mutable {#mutable}
67+
68+
`mutable` can make a field non-final.
69+
70+
To make a private final field both accessible and mutable, you must make two separate entries in the file.
71+
72+
### Transitive Directives {#transitive-directives}
73+
74+
In order to expose certain access widener changes to mods depending on yours, you prefix the relevant directives with `transitive-*`:
75+
76+
```txt:no-line-numbers
77+
transitive-accessible
78+
transitive-extendable
79+
transitive-mutable
80+
```
81+
82+
## Specifying Targets {#specifying-targets}
83+
84+
For class tweaking, classes use their [internal names](../mixins/bytecode#class-names). For fields and methods you must specify their class name, their name, and their [bytecode descriptor](../mixins/bytecode#field-and-method-descriptors).
85+
86+
::: tip
87+
88+
The names of targets need to correspond to your current mappings.
89+
90+
:::
91+
92+
::: tabs
93+
94+
== Classes
95+
96+
Format:
97+
98+
```txt:no-line-numbers
99+
<accessible / extendable> class <className>
100+
```
101+
102+
Example:
103+
104+
@[code lang=txt:no-line-numbers transcludeWith=:::accesswidening-examples:classes:::](@/reference/latest/src/main/resources/example-mod.classtweaker)
105+
106+
== Methods
107+
108+
Format:
109+
110+
```txt:no-line-numbers
111+
<accessible / extendable> method <className> <methodName> <methodDescriptor>
112+
```
113+
114+
Example:
115+
116+
@[code lang=txt:no-line-numbers transcludeWith=:::accesswidening-examples:methods:::](@/reference/latest/src/main/resources/example-mod.classtweaker)
117+
118+
== Fields
119+
120+
Format:
121+
122+
```txt:no-line-numbers
123+
<accessible / mutable> field <className> <fieldName> <fieldDescriptor>
124+
```
125+
126+
Example:
127+
128+
@[code lang=txt:no-line-numbers transcludeWith=:::accesswidening-examples:fields:::](@/reference/latest/src/main/resources/example-mod.classtweaker)
129+
130+
:::
131+
132+
## Generating Entries {#generating-entries}
133+
134+
Manually writing access widener entries is time-consuming and prone to human error. Let's look at tools that simplify a part of the process by allowing you to generate and copy entries.
135+
136+
### mcsrc.dev {#mcsrc-dev}
137+
138+
Available for all versions with an [unobfuscated JAR](../migrating-mappings/index#whats-going-on-with-mappings) namely 1.21.11 and above,
139+
[mcsrc](https://mcsrc.dev) allows you to decompile and navigate Minecraft source in the browser and copy Mixin, access widener or access transformer targets to clipboard.
140+
The names of classes, methods and fields on [mcsrc](https://mcsrc.dev) will align with [Mojang Mappings](../migrating-mappings/index#mappings).
141+
142+
To copy an access widener entry, first navigate to the class which you want to modify, and right-click on your target to open the popup menu.
143+
144+
![Right-clicking on a target in mcsrc](/assets/develop/class-tweakers/access-widening/mcsrc-right-click-on-aw-target.png)
145+
146+
Then, click on `Copy Class Tweaker / Access Widener`, and a confirmation should appear at the top of the page.
147+
148+
![AW copy confirmation on mcsrc](/assets/develop/class-tweakers/access-widening/mcsrc-aw-copy-confirmation.png)
149+
150+
You can then paste the entry in your class tweaker file.
151+
152+
### Minecraft Development Plugin (IntelliJ IDEA) {#mcdev-plugin}
153+
154+
The [Minecraft Development Plugin](../getting-started/intellij-idea/setting-up#installing-idea-plugins), also known as MCDev, is an IntelliJ IDEA plugin to assist in various aspects of Minecraft mod development.
155+
For example, it lets you copy access widener entries from the decompiled source target to the clipboard.
156+
157+
To copy an access widener entry, first navigate to the class which you want to modify, and right-click on your target to open the popup menu.
158+
159+
![Right-clicking on a target with MCDev](/assets/develop/class-tweakers/access-widening/mcdev-right-click-on-aw-target.png)
160+
161+
Then, click on `Copy / Paste Special` and `AW Entry`.
162+
163+
![Copy/Paste special with MCDev](/assets/develop/class-tweakers/access-widening/mcdev-copy-paste-special-menu.png)
164+
165+
A confirmation should now pop up on the element you right-clicked.
166+
167+
![AW copy confirmation with MCDev](/assets/develop/class-tweakers/access-widening/mcdev-aw-copy-confirmation.png)
168+
169+
You can then paste the entry in your class tweaker file.
170+
171+
### Linkie {#linkie}
172+
173+
[Linkie](https://linkie.shedaniel.dev) is a website that allows you to browse and translate across mappings. It also provides access widener entries for the class, method or field you're viewing.
174+
175+
First, make sure you have the correct version and mappings selected on the menu on the left:
176+
177+
![Correct version and mappings selected on Linkie](/assets/develop/class-tweakers/access-widening/linkie-version-mappings-select.png)
178+
179+
Then, search for the element you want to modify, and the access widener entry will be listed as `AW` under the result:
180+
181+
![A search result in Linkie](/assets/develop/class-tweakers/access-widening/linkie-search-results.png)
182+
183+
You can copy it and then paste the entry in your class tweaker file.
184+
185+
## Applying Changes {#applying-changes}
186+
187+
To see your changes applied, you must refresh your Gradle project by [regenerating sources](../getting-started/generating-sources). The elements you targeted should
188+
have their access limits modified accordingly. If modifications do not appear, you can try [validating the file](../class-tweakers/index#validating-the-file)
189+
and checking if any errors appear.

develop/class-tweakers/index.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Class Tweakers
3+
description: Learn what class tweakers are, and how to set them up.
4+
authors:
5+
- cassiancc
6+
- Earthcomputer
7+
- its-miroma
8+
- MildestToucan
9+
---
10+
11+
Class tweakers, formerly known as access wideners before gaining further functionality, provide transformation tools complementary to Mixin bytecode manipulation. They also allow some runtime modifications to be accessible within the development environment.
12+
13+
::: warning
14+
15+
Class tweakers are not specific to a given Minecraft version, but are only available starting from Fabric Loader 0.18.0, and may only target Vanilla Minecraft classes.
16+
17+
:::
18+
19+
## Setup {#setup}
20+
21+
### File Format {#file-format}
22+
23+
Class tweaker files are conventionally named after your modid, `example-mod.classtweaker`, to help IDE plugins recognize them. They should be stored in `resources`.
24+
25+
The file must have the following header as its first line:
26+
27+
```txt
28+
classTweaker v1 named
29+
```
30+
31+
Class tweaker files can have blank lines and comments starting with `#`. Comments can start at the end of a line.
32+
33+
Whilst the specific syntax depends on the feature, modifications are each declared on separate lines. An entry's elements can be separated using any whitespace, including tabs.
34+
35+
### Specifying The File Location {#specifying-the-file-location}
36+
37+
The class tweaker file's location must be specified in your `build.gradle` and `fabric.mod.json` files. Remember that you must also depend on Fabric Loader 0.18.0 or above to use class tweakers.
38+
39+
The specifications are still named after access wideners to preserve backwards compatibility.
40+
41+
#### build.gradle {#build-gradle}
42+
43+
@[code lang=gradle:no-line-numbers transcludeWith=:::classtweaker-setup:gradle:::](@/reference/latest/build.gradle)
44+
45+
#### fabric.mod.json {#fabric-mod-json}
46+
47+
```json:no-line-numbers
48+
...
49+
50+
"accessWidener": "example-mod.classtweaker",
51+
52+
...
53+
```
54+
55+
After specifying the file location in your `build.gradle` file, make sure to reload your Gradle project in the IDE.
56+
57+
## Validating the File {#validating-the-file}
58+
59+
By default, class tweaker will ignore entries referencing modification targets that cannot be found. To check if all the classes, fields and methods specified in the file are valid, run the `validateAccessWidener` Gradle task.
60+
61+
Errors will point out any invalid entry, but they can be about which part of an entry is invalid.

develop/loom/options.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ This page contains a reference for all options present in the `loom` Gradle exte
1616

1717
```groovy
1818
loom {
19-
// Set the access widener path, see https://wiki.fabricmc.net/tutorial:accesswidening
20-
accessWidenerPath = file("src/main/resources/example-mod.accesswidener")
19+
// Set the class tweaker file path, see https://docs.fabricmc.net/develop/class-tweakers/
20+
accessWidenerPath = file("src/main/resources/example-mod.classtweaker")
2121
2222
// Add additional log4j config files.
2323
log4jConfigs.from(file("log4j.xml"))
46.9 KB
Loading
36.6 KB
Loading
24.9 KB
Loading
38.5 KB
Loading
73.4 KB
Loading
3.4 KB
Loading

0 commit comments

Comments
 (0)