Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: Sky's Grass Slabs 26.2 CI
name: Sky's Grass Slabs 26.3 CI

on:
push:
branches:
- master-26.2
- master-26.3
pull_request:
branches:
- master-26.2
- master-26.3

permissions:
contents: read

concurrency:
group: skysgrassslabs-26.2-${{ github.workflow }}-${{ github.ref }}
group: skysgrassslabs-26.3-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
Expand Down Expand Up @@ -107,21 +107,21 @@ jobs:
- name: Upload audited release candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: SkysGrassSlabs-26.2-${{ github.sha }}
name: SkysGrassSlabs-26.3-${{ github.sha }}
if-no-files-found: error
retention-days: 30
path: |
build/libs/SkysGrassSlabs-1.1.2.2602001.jar
build/libs/SkysGrassSlabs-1.1.2.2602001-sources.jar
build/libs/SkysGrassSlabs-1.1.2.2602001-javadoc.jar
build/libs/SkysGrassSlabs-1.1.2.2603001.jar
build/libs/SkysGrassSlabs-1.1.2.2603001-sources.jar
build/libs/SkysGrassSlabs-1.1.2.2603001-javadoc.jar
build/release/SHA256SUMS
CHANGELOG.md

- name: Upload diagnostics on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: SkysGrassSlabs-26.2-diagnostics-${{ github.sha }}
name: SkysGrassSlabs-26.3-diagnostics-${{ github.sha }}
if-no-files-found: ignore
retention-days: 14
path: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: CodeQL
on:
push:
branches:
- master-26.2
- master-26.3
pull_request:
branches:
- master-26.2
- master-26.3
schedule:
- cron: '53 7 * * 4'

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/validate-gradle-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Validate Gradle Wrapper
on:
push:
branches:
- master-26.2
- master-26.3
pull_request:
branches:
- master-26.2
- master-26.3

permissions:
contents: read
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 1.1.2.2603001 - Minecraft 26.3

- Ported the complete feature set to Minecraft 26.3 and Forge 66.
- Preserved all blocks, recipes, settings and supported world upgrades.
- Updated shovel handling, bonemeal growth, world generation and data files
for Minecraft 26.3.
- Corrected grass, snowy dirt and path slab models so their exposed inner
surfaces remain visible beside blocks.

## 1.1.2.2602001 - Minecraft 26.2

- Corrected snowy grass slabs so their exposed top uses the snow texture
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ thin layer of turf. Grass spreads naturally between full blocks and slabs,
while new Overworld terrain uses grass slabs to soften suitable one block
steps.

This branch is for Minecraft 26.2. Version `1.1.2.2602001` requires Forge
65.1.0 or a compatible Forge 65 build and Java 25.
This branch is for Minecraft 26.3. Version `1.1.2.2603001` requires Forge
66.0.0 or a compatible Forge 66 build and Java 25.

## Installation

Expand Down Expand Up @@ -34,7 +34,7 @@ or updating world changing mods.
- [Gameplay and recipes](docs/GAMEPLAY.md)
- [Configuration](docs/CONFIGURATION.md)
- [Upgrading an older world](docs/WORLD-UPGRADES.md)
- [Release notes](docs/RELEASE-1.1.2.2602001.md)
- [Release notes](docs/RELEASE-1.1.2.2603001.md)

## License

Expand Down
48 changes: 24 additions & 24 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ def mavenizerLicense = mavenizerToolsDirectory.file('LICENSE-MAVENIZER.txt')
def mavenizerReadme = mavenizerToolsDirectory.file('README.md')
def mavenizerFixtureChecksums = [
(mavenizerCompatibilityJar.asFile):
'5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B',
'4150926F33A696B2088AB2675C1C3B45745CE4F9F2DEB31CCD88C9ADC834062F',
(mavenizerRuleManifest.asFile):
'9437E03FC5E1CB5D605D72F0538C4DF4417B64DB0A57D0AABDC5184781517AC1',
'829400D74ECB1BF0CC6107D9980B8328365E3F56D9A5342002D8DF340571BDB7',
(mavenizerSourcePatch.asFile):
'2DA8DD0FD5F112F5B7591113AED06D9A58C584A25F8705E26445A6D2E9D5C78E',
'9F0C34529D41C9CD5804C32608FE548D09A0AC3A95D337EE2EF4377680C1B2DD',
(mavenizerLicense.asFile):
'20C17D8B8C48A600800DFD14F95D5CB9FF47066A9641DDEAB48DC54AEC96E331',
(mavenizerReadme.asFile):
'EAD1477F393897C491A10FB86178213A99C360571A8063D551DA0579DF65BA6F'
'A35B80BA8D7557A31E0378787C06FE86C8C627061BF313A6886205F62A46C09F'
]

// ForgeGradle invokes Mavenizer while configuring the project. Verify the
Expand Down Expand Up @@ -87,7 +87,7 @@ java {
withJavadocJar()
}

// ForgeGradle declares Slime Launcher as Java 8-compatible, but Forge 65 and
// ForgeGradle declares Slime Launcher as Java 8-compatible, but Forge 66 and
// this project run entirely on Java 25. Bind the launcher explicitly so a
// clean setup does not depend on an unrelated legacy JDK.
fgtools.configure('slimelauncher') {
Expand Down Expand Up @@ -261,7 +261,7 @@ tasks.named('check').configure {

// A Forge process is not green merely because it returns exit code zero. The
// loader can log a worldgen or linkage failure and still shut down normally.
def acceptedForge65LogNoise = [
def acceptedForge66LogNoise = [
~/FML appears to be missing any signature data/,
~/Found multiple arguments for option fml\.mcVersion/,
~/Found multiple arguments for option fml\.forgeVersion/,
Expand All @@ -281,7 +281,7 @@ def packagedOfflineAuthenticationNoise = [
~/\/ERROR\] \[com\.mojang\.realmsclient\.RealmsAvailability\/\]: Couldn't connect to realms$/,
~/^com\.mojang\.realmsclient\.exception\.RealmsServiceException: Realms authentication error with message 'java\.lang\.RuntimeException: Failed to parse into SignedJWT: validation-token'$/
]
// Forge 65 asks OSHI for Windows performance counters while preloading its
// Forge 66 asks OSHI for Windows performance counters while preloading its
// system report. Control Forge runtimes reproduced these exact signatures and
// continued to Done. Keep the exception scoped to Windows runs that opt in.
def windowsOshiSystemReportNoise = [
Expand Down Expand Up @@ -319,7 +319,7 @@ def assertRuntimeLogsClean = { File runDirectory, String context, Set priorCrash
log.eachLine('UTF-8') { String line ->
lineNumber++
boolean unexpectedSeverity = line ==~ /.*\/(?:ERROR|FATAL)\].*/
boolean knownNoise = acceptedForge65LogNoise.any { line =~ it }
boolean knownNoise = acceptedForge66LogNoise.any { line =~ it }
|| contextNoise.any { line =~ it }
boolean exceptionRoot = line ==~ /^(?:Caused by: )?[A-Za-z_$][A-Za-z0-9_.$]*(?:Exception|Error)(?::.*)?$/
boolean fatalText = line.contains('Encountered an unexpected exception') ||
Expand Down Expand Up @@ -359,7 +359,7 @@ tasks.register('runtimeLogScannerTest') {
'java.lang.UnsupportedOperationException: sun.misc.Unsafe unavailable\n'
+ 'java.lang.UnsupportedOperationException: Native access (restricted methods) is not enabled for the io.netty.common module.\n',
'UTF-8')
assertRuntimeLogsClean(probe, 'scanner-forge65-netty-noise-probe', [] as Set)
assertRuntimeLogsClean(probe, 'scanner-forge66-netty-noise-probe', [] as Set)
new File(logs, 'debug.log').delete()
new File(logs, 'latest.log').setText(
'[Download-2/ERROR] [net.minecraft.client.Minecraft/]: Failed to fetch user properties\n'
Expand Down Expand Up @@ -430,7 +430,7 @@ def processedMainResourcesPath = {
project.relativePath(processedMainResourcesDirectory()).replace('\\', '/')
}

// ForgeGradle 7 models Forge 65 source sets as merged output directories.
// ForgeGradle 7 models Forge 66 source sets as merged output directories.
// Compile through staging so Gradle and Eclipse never write classes and
// processed resources to the same location at the same time.
def compiledMainClasses = layout.buildDirectory.dir('compiled-classes/main')
Expand Down Expand Up @@ -529,13 +529,13 @@ repositories {
dependencies {
implementation minecraft.dependency(
"net.minecraftforge:forge:${project.minecraft_version}-${project.forge_version}")
testImplementation 'net.minecraftforge:eventbus-validator:7.0.1'
testImplementation 'net.minecraftforge:eventbus-validator:7.0.6'
testImplementation 'junit:junit:4.13.2'
}

def verifyMavenizerCompatibilityFixture = tasks.register('verifyMavenizerCompatibilityFixture') {
group = 'verification'
description = 'Verifies the checksum-sealed Forge 26.2 Mavenizer compatibility fixture.'
description = 'Verifies the checksum-sealed Forge 26.3 Mavenizer compatibility fixture.'
inputs.files mavenizerFixtureChecksums.keySet()
doLast {
mavenizerFixtureChecksums.each { File fixture, String expected ->
Expand All @@ -550,13 +550,13 @@ def verifyMavenizerCompatibilityFixture = tasks.register('verifyMavenizerCompati
}

def parsed = new JsonSlurper().parse(mavenizerRuleManifest.asFile)
String target = 'net.minecraftforge:forge:26.2-65.1.0'
String target = 'net.minecraftforge:forge:26.3-66.0.0'
if (parsed.schema != 1 || parsed.targets.keySet() != [target] as Set) {
throw new GradleException('Mavenizer target-rule manifest has unexpected targets or schema')
}
def forgeRules = parsed.targets[target]
if (forgeRules.expectedApplications != 0 || !forgeRules.rules.isEmpty()) {
throw new GradleException('Forge 65 Mavenizer target must be an explicit zero-rule qualification')
throw new GradleException('Forge 66 Mavenizer target must be an explicit zero-rule qualification')
}

ZipFile fixtureJar = new ZipFile(mavenizerCompatibilityJar.asFile)
Expand Down Expand Up @@ -605,7 +605,7 @@ def verifyMavenizerCompatibilityFixture = tasks.register('verifyMavenizerCompati
String licenseText = mavenizerLicense.asFile.getText('UTF-8')
if (!readme.contains('6968241ce7a0a902cdc1c534b976e8373a423091')
|| !readme.contains('Temurin `25.0.3+9`')
|| !readme.contains('26.2-65.1.0')) {
|| !readme.contains('26.3-66.0.0')) {
throw new GradleException('Mavenizer provenance, target, or Java 25 build instructions are incomplete')
}
if (!patchText.contains('SourceCompatibilityPatcher.java')
Expand Down Expand Up @@ -686,12 +686,12 @@ def releaseFiles = provider {
tasks.register('verifyReleaseMetadata') {
group = 'verification'
doLast {
if (project.minecraft_version != '26.2' || project.forge_version != '65.1.0' ||
project.mapping_channel != 'official' || project.mapping_version != '26.2' ||
if (project.minecraft_version != '26.3' || project.forge_version != '66.0.0' ||
project.mapping_channel != 'official' || project.mapping_version != '26.3' ||
project.loader_name != 'forge' || project.loader_code != '1' ||
project.java_version != '25' || project.java_toolchain_version != '25.0.3+9' ||
project.gradle_java_version != '25' || project.curseforge_project_id != '1677588') {
throw new GradleException('Unexpected 26.2 release metadata')
throw new GradleException('Unexpected 26.3 release metadata')
}
}
}
Expand Down Expand Up @@ -769,8 +769,8 @@ tasks.register('verifyReleaseArtifacts') {

String metadata = zip.getInputStream(zip.getEntry('META-INF/mods.toml'))
.getText(StandardCharsets.UTF_8.name())
if (!metadata.contains('versionRange="[26.2,26.3,)"') ||
!metadata.contains('versionRange="[65,)"')) {
if (!metadata.contains('versionRange="[26.3,26.4,)"') ||
!metadata.contains('versionRange="[66,)"')) {
throw new GradleException('Packaged Forge metadata targets the wrong version')
}

Expand Down Expand Up @@ -987,9 +987,9 @@ eclipse {
synchronizationTasks 'isolateEclipseProductionRuns'
}

def syncForge65EclipseLaunches = tasks.register('syncForge65EclipseLaunches') {
def syncForge66EclipseLaunches = tasks.register('syncForge66EclipseLaunches') {
group = 'ide'
description = 'Normalizes ForgeGradle 7 Eclipse launch outputs for Forge 65.'
description = 'Normalizes ForgeGradle 7 Eclipse launch outputs for Forge 66.'
doLast {
String mainOutput = new File(projectDir, 'bin/main').absolutePath
String gameTestOutput = new File(projectDir, 'bin/gameTest').absolutePath
Expand Down Expand Up @@ -1059,14 +1059,14 @@ def syncForge65EclipseLaunches = tasks.register('syncForge65EclipseLaunches') {
}

tasks.matching { it.name == 'genEclipseRuns' }.configureEach {
finalizedBy syncForge65EclipseLaunches
finalizedBy syncForge66EclipseLaunches
}

def isolateEclipseProductionRuns = tasks.register('isolateEclipseProductionRuns') {
group = 'ide'
description = 'Prepares the complete ForgeGradle 7 Eclipse project configuration.'
dependsOn tasks.named('genEclipseRuns')
dependsOn syncForge65EclipseLaunches
dependsOn syncForge66EclipseLaunches
dependsOn configureEclipseBuildship
dependsOn prepareEclipseResources
}
Expand Down
6 changes: 3 additions & 3 deletions ci-fixtures/tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This directory contains a build-only derivative of MinecraftForge's
MinecraftMavenizer `0.5.21`. It is used only while ForgeGradle prepares the
exact Forge `26.2-65.1.0` development dependency and is excluded from every
exact Forge `26.3-66.0.0` development dependency and is excluded from every
OreSpawn publication artifact.

## Provenance and licence
Expand All @@ -21,13 +21,13 @@ declaration and one accessor in that record. Missing, partial, duplicate or
ambiguous states fail preparation. Targets without an explicit rule set are
left unchanged.

Forge `26.2-65.1.0` compiles without source compatibility edits. Its explicit
Forge `26.3-66.0.0` compiles without source compatibility edits. Its explicit
zero-rule entry proves that result is intentional and target-qualified rather
than an accidental fall-through. A marker beside Mavenizer's output records
the target and manifest SHA-256. Reprocessing the same source is idempotent.

The derivative also propagates Gradle offline mode when the build sets
`ORESPAWN_MAVENIZER_OFFLINE=true`. Mavenizer, OreSpawn and Minecraft 26.2 all
`ORESPAWN_MAVENIZER_OFFLINE=true`. Mavenizer, Sky's Grass Slabs and Minecraft 26.3 all
run and compile with Java 25.

## Rebuild
Expand Down
Binary file modified ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From 96468d9931e7f1448d9fb00f13ec0a6559ee0054 Mon Sep 17 00:00:00 2001
From: OreSpawn Build Fixture <orespawn-fixture@invalid.local>
Date: Fri, 28 Aug 2026 15:21:10 +0100
Subject: [PATCH] Add target-aware source compatibility rules
From debd1358466af4d21ae25079ade85486fb267762 Mon Sep 17 00:00:00 2001
From: JohnBraham <johnbraham1978@outlook.com>
Date: Sat, 19 Sep 2026 16:12:24 +0100
Subject: [PATCH] Qualify Mavenizer for Forge 26.3

---
build.gradle | 2 +-
Expand Down Expand Up @@ -364,18 +364,19 @@ index 0000000..4d72d34
+}
diff --git a/src/main/resources/META-INF/orespawn/minecraft-source-compatibility.json b/src/main/resources/META-INF/orespawn/minecraft-source-compatibility.json
new file mode 100644
index 0000000..702d759
index 0000000..3451901
--- /dev/null
+++ b/src/main/resources/META-INF/orespawn/minecraft-source-compatibility.json
@@ -0,0 +1,9 @@
+{
+ "schema": 1,
+ "targets": {
+ "net.minecraftforge:forge:26.2-65.1.0": {
+ "net.minecraftforge:forge:26.3-66.0.0": {
+ "expectedApplications": 0,
+ "rules": []
+ }
+ }
+}
--
2.55.0.windows.3

2 changes: 1 addition & 1 deletion ci-fixtures/tools/minecraft-source-compatibility.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schema": 1,
"targets": {
"net.minecraftforge:forge:26.2-65.1.0": {
"net.minecraftforge:forge:26.3-66.0.0": {
"expectedApplications": 0,
"rules": []
}
Expand Down
15 changes: 15 additions & 0 deletions docs/RELEASE-1.1.2.2603001.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Sky's Grass Slabs 1.1.2 for Minecraft 26.3

This release brings the complete Sky's Grass Slabs feature set to Minecraft
26.3 and Forge 66. Dirt, grass and path slabs, turf, grass spreading, shovel
flattening and terrain smoothing retain their established behaviour.

Slab surfaces remain visible when another block is placed above a bottom slab
or below a top slab. The correction also covers snowy dirt and path slabs.

Existing Sky's Grass Slabs worlds and the supported older slab migrations
remain compatible. Back up an existing world before changing its Minecraft or
Forge version.

Requires Minecraft 26.3, Forge 66.0.0 or a compatible Forge 66 build, and
Java 25.
6 changes: 3 additions & 3 deletions docs/WORLD-UPGRADES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ world has been checked in game.

## Sky's Grass Slabs content

Install `SkysGrassSlabs-1.1.2.2602001.jar` before opening a world that used an
Install `SkysGrassSlabs-1.1.2.2603001.jar` before opening a world that used an
earlier release. The permanent dirt slab, grass slab, path slab and turf IDs
are unchanged.

Expand Down Expand Up @@ -70,8 +70,8 @@ When both mods remain installed, their content is left alone by default. See
## Modpack checklist

1. Back up the complete instance and world.
2. Update Forge and every required mod to a matching Minecraft 26.2 build.
3. Install the 26.2 Sky's Grass Slabs jar before the first upgraded start.
2. Update Forge and every required mod to a matching Minecraft 26.3 build.
3. Install the 26.3 Sky's Grass Slabs jar before the first upgraded start.
4. Read the complete Forge missing content list before confirming it.
5. Check representative slabs, turf, paths, inventories and old terrain.
6. Stop and start the upgraded copy once more, then repeat the checks.
Expand Down
Loading
Loading