Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the Ornithe tool-chain (OSL / Feather / Nests) #48

Open
4 of 6 tasks
halotroop2288 opened this issue Nov 17, 2023 · 10 comments
Open
4 of 6 tasks

Support the Ornithe tool-chain (OSL / Feather / Nests) #48

halotroop2288 opened this issue Nov 17, 2023 · 10 comments
Labels
enhancement New feature or request priority: low fixable with a minor change to build.gradle

Comments

@halotroop2288
Copy link
Contributor

halotroop2288 commented Nov 17, 2023

Reasoning

I've recently decided to switch to using OrnitheMC's Feather mappings for mod development since they have such wide coverage.
Cat Core and I would like to see them implemented in Unimined so we can use it to develop our projects.

Ornithe propagates their mappings to every supported version at once every time a change is made. This leads to higher cross-version compatibility. Their set of API libraries, OSL, attempts to maintain compatibility for every supported Minecraft version at once (to varying degrees of success).
So using Ornithe's tool-chain has the potential to make multi-version mod development much more efficient.

Requirements

OrnitheMC uses a library called Nests to handle nested classes in development environments before Minecraft version 1.8.4, when Mojang's Proguard configuration stopped stripping inner class attributes.

OrnitheMC's Ploceus implements this nested mappings layer for Ornithe environments under Loom.
Ploceus also handles version-specific OSL dependencies for mods.

Request for comments

This description was based off of comments on the subject from @SpaceWalkerRS and @thecatcore.
They may have more to add to this conversation, and may be able to clarify or correct what I've said so far.

Completion

Helper methods have been implemented for the following features.
When all of these are checked off, you can consider this issue complete.

@SpaceWalkerRS
Copy link

To add on to this, all of Ornithe's artifacts are hosted on our maven.

As for Feather, supporting it should be similar to how support for Yarn is implemented. Similar to Yarn publications, Feather is published as Tiny V1, Tiny V2, and merged (meaning official -> intermediary -> named in Tiny V2 format).

The intermediary we use is called Calamus (hosted here). It's unfortunately not inter compatible with Fabric's intermediary.

Nests are a lot trickier to implement. You can use Nester to patch the jar to add the inner class attributes, using the Nests for that specific version. However, since this 'nesting' is done only in development environments, and not in production environments, the nests must be applied after the jar is mapped to intermediary. This means the nests themselves must be remapped to intermediary. In addition to this, the Feather mappings must be patched, but only the named namespace. This is by far the jankiest part of the setup, as you can see in our implementation in Ploceus (which is an extension to Loom). The nesting is strictly not necessary, but it is nice to have.

Then a note on versions prior to 1.3. As they cannot be merged, all the intermediary and Feather mappings, as well as the nests, for those versions have separate publications for the client and server side. In terms of maven artifacts that means the artifact id has a -client or -server suffix after the version number (e.g. 1.2.5 client intermediary, 1.2.5 server intermediary, 1.3 intermediary).

Finally about the versions manifest. We used Skyrising's version manifest (hosted here). This manifest often uses different version ids than Mojang's official manifest, which is where the funny version number in 1.3's intermediary publication comes from.

@wagyourtail
Copy link
Collaborator

wagyourtail commented Dec 4, 2023

@SpaceWalkerRS why isn't the nesting just done based on the names in the mappings.. it would be so easy to add innerclass information if the classes are just named with the usual outer$inner name in the mappings. I could do that in a simple pass with my transform fixers, like I do for fixing annotations on synthetic parameters due to proguard issues on inner classes https://github.com/unimined/unimined/blob/0e2438576dce37f7bcba02e0808ab830e543a3cd/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/AbstractMinecraftTransformer.kt#L141C19-L141C19

I even have a function for fixing nested class names if that information is in the intermediary mappings but not named. (either because the class doesn't have a named name, or because of bad named mappings) I use this on yarn
https://github.com/unimined/unimined/blob/0e2438576dce37f7bcba02e0808ab830e543a3cd/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/MappingDepConfigImpl.kt#L190C19-L190C19

@SpaceWalkerRS
Copy link

It could be parsed from the mappings directly, but given that e.g. TinyRemapper is not able to fix inner class attributes, we needed a separate tool for that anyway, and we chose to separate it from the mappings entirely. This made is easier as well to implement in different places (Loom/Ploceus for mod dev environments, Feather for mapping development).
The jar might be obfuscated such that the inner class attributes are stripped, yet the class names still contain $ characters (a few MC 1.5 snapshots are like that, as well as early classic versions), how would you parse that from the mappings?

@wagyourtail
Copy link
Collaborator

wagyourtail commented Dec 5, 2023

well, I don't apply renest to intermediaries, only yarn. so it would only do it based on the intermediary class names. is there at least a spec on how the .nest format works... (also, have you thought about putting signature information that gets stripped in those versions back as well)

wait, they are distributued with calamus but only applied to feather, why not distrubute them intermediary mapped in feather if they're for dev only

@wagyourtail
Copy link
Collaborator

Then a note on versions prior to 1.3. As they cannot be merged, all the intermediary and Feather mappings, as well as the nests, for those versions have separate publications for the client and server side.

well, they can be merged, see babric.

@wagyourtail
Copy link
Collaborator

hm... what if I just featherMappings.replace("__", "$") and then write a thing to restore innerclass attributes based on class name

@SpaceWalkerRS
Copy link

hm... what if I just featherMappings.replace("__", "$") and then write a thing to restore innerclass attributes based on class name

That could work, but to be safe that should only be done on the named namespace, the intermediary names should remain unchanged.

@SpaceWalkerRS
Copy link

Then a note on versions prior to 1.3. As they cannot be merged, all the intermediary and Feather mappings, as well as the nests, for those versions have separate publications for the client and server side.

well, they can be merged, see babric.

Fair enough. I haven't looked too closely at it, but iirc Babric first maps both jars to intermediary, and then those jars can be merged by Fabric's jar merger, right? I've thought of adopting such a system for Ornithe but for that to work we need good server -> client matches, which is a lot of work with hundreds of versions to support.

@wagyourtail wagyourtail added enhancement New feature or request priority: low fixable with a minor change to build.gradle labels Dec 19, 2023
@thecatcore
Copy link
Contributor

Ornithe Standard Library support is complete as of 1.4.
What is the status for nest, signature and exception support?

@wagyourtail
Copy link
Collaborator

work in progress

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request priority: low fixable with a minor change to build.gradle
Projects
None yet
Development

No branches or pull requests

4 participants