MinecraftFreecam / Freecam

A highly customizable freecam mod for Minecraft. [Maintiners: @hashalite @MattSturgeon]
https://curseforge.com/minecraft/mc-mods/free-cam
MIT License
75 stars 30 forks source link

Refactor build system to support modrinth tweaks #123

Closed MattSturgeon closed 11 months ago

MattSturgeon commented 11 months ago

Status

This PR is finished, however it isn't the best way to approach the issue. See this comment.

The replacement will involve moving away from Autoconfig & using Java SPI to load different Behaviour implementations.

I'll likely close this in favor of another PR once I have one ready.


Original description

I'm opening this PR early in an unfinished state to give an idea of what I'm working on for integrating the modrinth tweaks into the main branch.

At this stage I've stubbed out a gradle multi-project build as follows:

> Task :projects

------------------------------------------------------------
Root project 'freecam'
------------------------------------------------------------

Root project 'freecam'
+--- Project ':common'
+--- Project ':fabric'
+--- Project ':fabric-modrinth'
+--- Project ':forge'
+--- Project ':forge-modrinth'
\--- Project ':modrinth'

TODO:

Preprocessing

~~Use [JCP](https://github.com/raydac/java-comment-preprocessor) or [RM's equivalent](https://github.com/ReplayMod/preprocessor) to pre-process the common/modrinth sources~~ _EDIT: I've done a POC using JCP, which reminded me how clunky java preprocessing can be. I think generating a config class would be simpler:_ - Dependency injection - `:common` & `:modrinth` inject different implementations of some interface - Source code generation - a class is rendered using a gradle task - Self-targeting mixins - `:modrinth` adds mixins that hook into `:common`'s code ~~Personally I think preprocessing is the simplest, especially for the case where `@ConfigEntry.Tooltip` annotations need different values.~~ It would mean additional noise where changes are required, however I don't think there will need to be a lot of differences. _EDIT: annotation values can be set to static-final fields, so code-gen could still work here..._ Lang files would need to be handled separately. I'm imagining a gradle copy task that can be used within `processResources`. The task would parse the base lang file as json, then parse an override file as well. Merge the changes and write the result to the build outputs. _EDIT: this is done._

Note on Convention Plugins

Convention plugins are small gradle plugins located in buildSrc that each describe a "trait" of our config. They can be used modularly throughout the actual config as a more flexible alternative to allprojects and subprojects. The official guide, and sample projects are worth a quick look if you're unfamiliar. After these changes most of the shared configuration logic lives under buildSrc.

MattSturgeon commented 11 months ago

Progress

This is coming along now. Just need to merge the modrinth branch's mixin patches, expand more properties in mods.toml & fabric.mod.json, cleanup git history, rebase once #122 is merged, test, polish & review.

There's two main systems in play to handle the modrinth differences:

JSON overloading

I've introduced a small gradle plugin which hooks into processResources in order to modify assets without needing to duplicate/replace them.

BuildConfig source generation

I've introduced a GenerateSource task which makes use of javapoet to render a simple java class full of a bunch of static-final fields. The new BuildConfigPlugin then uses this task to add a generated BuildConfig.java to the :common & :modrinth main source sets.

We can use BuildConfig to control cheat restriction, tooltip lengths, as well as hold other potentially useful build info.

BuildConfig is common accross forge & fabric, so we can't store a ENVIRONMENT = FABRIC style field, but that's a non-issue because a) we don't care if we're in forge or fabric at runtime and b) we can get that infomation from Architectury API anyway.

MattSturgeon commented 11 months ago

This is feature complete, somewhat tested and ready for review. :tada:

There are some related commits that could be squashed further before merging, and others that would become redundant if other PRs get merged. I've left the history somewhat granular to hopefully aid review.

If anything looks complex I'm happy to explain and/or refactor.

MattSturgeon commented 11 months ago

After a conversation with @wagyourtail there's a few improvements that can be made to this PR:

MattSturgeon commented 11 months ago

Superseded by #132