isXander / isXander/Controlify

Provide a public API-only JAR for third-party mod integration

Open
#737 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
341
Forks
97
Avg merge
1h
Merged PRs (30d)
1

Description

Motivation
  • Some consumers or orgs (example) prefer strong backward compatibility and stability over internal code enhancements.
    • It's a common use case to depend only on Controlify's public API using Gradle build scripts without linting, GitHub workflow or AI reviewers that warn from using imports outside of dev.isxander.controlify.api.*.
  • Move common APIs such as
    dev.isxander.controlify.bindings.ControlifyBindings to the public API
    public API in Controlify v3 (it can be done without any breaking changes, though)
Alternatives

Two Gradle modules, main and api, can be tricky to maintain and may introduce additional complications due to the tight coupling between Controlify's public and internal APIs.

The Controlify public API is already well-designed, though. Separate Gradle modules just for this feature can create a maintenance burden when using StoneCutter (different MC targets in one Git branch).

Proposal

Keep one main module, but with Gradle tasks that generate JAR files only with the public API package:

// The API JAR file includes only classes from the API package.

val apiPackage = "dev/isxander/controlify/api/**"
val apiJarClassifier = "api"

val apiJar by tasks.registering(Jar::class) {
    group = "build"
    archiveClassifier.set(apiJarClassifier)

    from(sourceSets.main.get().output) { include(apiPackage) }
}

val apiSourcesJar by tasks.registering(Jar::class) {
    group = "build"
    archiveClassifier.set("$apiJarClassifier-sources") // Important to use this suffix, to follow standards

    from(sourceSets.main.get().allSource) { include(apiPackage) }
}

artifacts {
    archives(apiJar); archives(apiSourcesJar)
}

[!NOTE]
The proposal above may require more consideration for more advanced builds, like with StoneCutter + Modstitch and 12+ different MC targets, so each target is provided with API and the corresponding source JAR files.

Then publish the JAR files to IsXander's Maven repo to allow consumers using it in their Gradle build scripts:

dependencies {
  compileOnly(libs.controlify.api)
  runtimeOnly(libs.controlify.full)
}

[!TIP]
This is beneficial for other mod devs who want to add Controlify integration (we're adding many integrations as of now), but it's also important to review whether a consumer can register keybinds, radial menus, input bind contexts, events, and screen processors with no non-public API imports, to prevent future breakage in non-major versions. See the list below.

List of common non-public imports

import dev.isxander.controlify.bindings.BindContext;
import dev.isxander.controlify.bindings.ControlifyBindings;
import dev.isxander.controlify.bindings.RadialIcons;
import dev.isxander.controlify.controller.ControllerEntity;
import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
import dev.isxander.controlify.utils.render.Blit;
import dev.isxander.controlify.utils.render.CGuiPose;

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by inspecting the Gradle build scripts and the StoneCutter/Modstitch setup mentioned in the proposal. Check how the listed bindings, controller, screen-operation, and rendering imports relate to the public API package across Minecraft targets. Done means API and API-sources JARs are generated for each target and published to the Maven repository without exposing non-public classes.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, build-system, developer-experience
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.