Build 1.21.4 with Stonecutter; every version now shares src/
Check / compile (pull_request) Successful in 7m44s
Check / compile (pull_request) Successful in 7m44s
Step 6 of #8. versions/1.21.4/src is gone, so all eight versions (1.21.4 to 1.21.11) build from src/. 1.21.4's differences from 1.21.5 are behind version comments: - The end gateway render layer has no render pipeline before 1.21.5 (ShaderUtils: the pipeline field only exists from 1.21.5, and the layer is a four-way chain). - Hat head rotation, the NativeImageBackedTexture constructor, armor slots (inventory.armor vs getEquippedStack), MatrixStackMixin's Quaternionf, and inside the pre-1.21.6 implementations: prevHeadYaw, GUI lighting, ModelTransformationMode, item depth, setShaderTexture and the blur uniform call. Those are one-line version comments, since the pre-1.21.6 blocks are already inside /* */ on newer versions. 1.21.5's drawItem wrapped its body in a second isEmpty check after already returning early for empty stacks; the redundant check is gone, so 1.21.4 and 1.21.5 share the body. Freelook's zoom-out (FreelookMod.shouldZoomOut in GameRendererMixin) only existed on 1.21.4. It doesn't depend on the Minecraft version, so it's back on every version. With no old copies left, the mc-<v> fallback in settings.gradle.kts and scripts/port.sh are removed, and README and VERSION_GUIDE describe the single layout. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
+10
-25
@@ -4,13 +4,13 @@ How Saturn Client supports several Minecraft versions, and how to change or add
|
||||
|
||||
## Layout
|
||||
|
||||
Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version:
|
||||
Every supported Minecraft version (1.21.4 to 1.21.11) builds from one copy of the version-specific code with [Stonecutter](https://stonecutter.kikugie.dev/):
|
||||
|
||||
- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`.
|
||||
- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.6 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:<mc>`, and `versions/<mc>/` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`.
|
||||
- `versions/<mc>/src/`: the versions not moved yet (1.21.4 and 1.21.5), each a full copy, as the Gradle project `:mc-<mc>` with its own `build.gradle`.
|
||||
- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs), one copy for every version. Where Minecraft's API differs between versions, the code goes behind version comments (see below).
|
||||
- `versions/<mc>/`: each version's `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), plus its `build/` and `run/` folders. Each version is the Gradle project `:<mc>`.
|
||||
|
||||
`settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-<mc>`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`.
|
||||
`settings.gradle.kts` lists the versions in `stonecutterVersions`. The root `build.gradle.kts` builds each version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version is `loom_version` in the root `gradle.properties`.
|
||||
|
||||
## Version-specific code with Stonecutter
|
||||
|
||||
@@ -48,36 +48,21 @@ Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */`
|
||||
|
||||
The `emotes` repository uses the same setup, and its `BentCubeRenderer` and `PlayerModelMixin` are small examples of version comments.
|
||||
|
||||
## Porting a change to the other versions
|
||||
## Checking a change on every version
|
||||
|
||||
Make the change in one version, usually the newest, then run:
|
||||
|
||||
```sh
|
||||
scripts/port.sh # port uncommitted changes to every other version
|
||||
scripts/port.sh --dry-run # see what would apply cleanly first
|
||||
scripts/port.sh --to 1.21.4,1.21.5 # only some versions
|
||||
scripts/port.sh --commit <rev> # port what a commit changed instead
|
||||
```
|
||||
|
||||
The script applies the diff under one version's source to each other version with `git apply --3way`. The Stonecutter `src/` counts as one version (1.21.11), so changes port between it and the old copies in both directions:
|
||||
|
||||
- **applied**: the files matched, and nothing else is needed.
|
||||
- **CONFLICTS**: that version's code really differs. The file gets normal conflict markers, with the version's own code in `ours` and the ported change in `theirs`. Adapt the change to that version's API and resolve.
|
||||
- **already has this change**: nothing to do, which is safe to see when re-running.
|
||||
|
||||
Only source is ported. `build.gradle` and `gradle.properties` are version-specific on purpose. Then build everything:
|
||||
Since every version shares `src/`, a change applies to all of them at once. Code that uses the Minecraft API may still only compile on some, so build them all:
|
||||
|
||||
```sh
|
||||
./gradlew compileJava
|
||||
```
|
||||
|
||||
The **Check** workflow runs the same compile on every pull request, so a version that was missed or mis-ported fails before merging.
|
||||
The **Check** workflow runs the same compile on every pull request, so a version a change doesn't compile on fails before merging. Mixins whose target changed fail at startup rather than at compile time, so launch the versions a change touches with `./gradlew :<mc>:runClient`.
|
||||
|
||||
For bigger changes, `./gradlew buildAll` builds every version's jar into `build/allJars/`.
|
||||
|
||||
## Adding a Minecraft version
|
||||
|
||||
Add new versions to Stonecutter rather than copying a folder:
|
||||
|
||||
1. Create `versions/<new>/gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at <https://fabricmc.net/develop>). Loom's version is shared, in the root `gradle.properties`.
|
||||
2. Add `<new>` to `stonecutterVersions` in `settings.gradle.kts`. When moving an existing `mc-<v>` version over instead, delete its `versions/<v>/src` and run `./gradlew :<v>:clean` once: the new project shares the old one's `build/` folder, and classes compiled from the removed sources would otherwise end up in the jar.
|
||||
2. Add `<new>` to `stonecutterVersions` in `settings.gradle.kts`.
|
||||
3. Build it with `./gradlew :<new>:compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew :<new>:runClient`.
|
||||
4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing.
|
||||
|
||||
Reference in New Issue
Block a user