From 18ca3dfc7be8d8d51172cf662e031c019722b5fd Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Thu, 12 Nov 2026 16:27:36 +0000 Subject: [PATCH 1/3] Port Electric to Minecraft 26.2 --- .github/verify-published-pins.sh | 10 +- .github/workflows/ci.yml | 22 ++-- .github/workflows/codeql-analysis.yml | 10 +- .github/workflows/validate-gradle-build.yml | 4 +- CHANGELOG.txt | 6 + README.md | 118 +++++++----------- build.gradle | 72 ++++++----- docs/NATIVE262.md | 45 +++++++ gradle.properties | 60 ++++----- gradle/forge64-mavenizer.gradle | 36 +++--- .../mc/baseelectric/ElectricAdvantage.java | 4 +- .../graphics/ElectricRenderTypes.java | 6 +- .../graphics/HydroturbineRenderer.java | 1 - .../graphics/LaserDrillRenderer.java | 6 +- .../graphics/LaserTurretRenderer.java | 6 +- src/main/resources/META-INF/mods.toml | 4 +- src/main/resources/pack.mcmeta | 4 +- ...tricOperationalHydroturbineAnchorTest.java | 9 +- .../graphics/RendererBufferContractTest.java | 47 ++++++- .../machines/Native118ConstructionTest.java | 2 +- .../resources/BlockLootResourceTest.java | 10 +- .../resources/BuildWorkflowContractTest.java | 2 +- .../NativePackRangeContractTest.java | 12 +- .../resources/RecipeResourceTest.java | 4 +- .../resources/RecipeUnlockContractTest.java | 2 +- .../resources/ShaderResourceContractTest.java | 4 +- .../verification/NativePackResourceProof.java | 2 +- tools/verification/AuditedJUnit.java | 2 +- .../Invoke-ElectricPackagedSmoke.ps1 | 14 +-- tools/verification/Verify-ElectricEcj.ps1 | 19 +-- tools/verify-native-port.js | 22 ++-- 31 files changed, 319 insertions(+), 246 deletions(-) create mode 100644 docs/NATIVE262.md diff --git a/.github/verify-published-pins.sh b/.github/verify-published-pins.sh index eadb217..b532842 100644 --- a/.github/verify-published-pins.sh +++ b/.github/verify-published-pins.sh @@ -18,10 +18,10 @@ done require_merged() { local repo="$1" ref="$2" status [[ "$ref" =~ ^[a-f0-9]{40}$ ]] - status="$(gh api "repos/MinecraftModDevelopmentMods/$repo/compare/$ref...master-26.1.2" --jq '.status')" + status="$(gh api "repos/MinecraftModDevelopmentMods/$repo/compare/$ref...master-26.2" --jq '.status')" case "$status" in identical|ahead) ;; - *) echo "::error::$repo $ref is not on upstream master-26.1.2 ($status)."; exit 1 ;; + *) echo "::error::$repo $ref is not on upstream master-26.2 ($status)."; exit 1 ;; esac } @@ -48,7 +48,7 @@ require_merged basePower "$power_ref" require_merged BaseMetals "$(value basemetals_source_commit)" require_merged OreSpawn "$orespawn_ref" -inputs="${RUNNER_TEMP:?}/forge64-release-dependencies" +inputs="${RUNNER_TEMP:?}/forge65-release-dependencies" mkdir -p "$inputs" power="$inputs/basePower-$(value poweradvantage_version).jar" metals="$inputs/BaseMetals-$(value basemetals_version).jar" @@ -57,8 +57,8 @@ public_jar basePower 1780140 "$(value poweradvantage_public_file_id)" "$(value p public_jar BaseMetals 240967 "$(value basemetals_public_file_id)" "$(value basemetals_deobf_sha256)" "$metals" public_jar OreSpawn 245586 "$(value orespawn_public_file_id)" "$(value orespawn_deobf_sha256)" "$orespawn" -installer="$inputs/forge-26.1.2-64.1.5-installer.jar" -download 'https://maven.minecraftforge.net/net/minecraftforge/forge/26.1.2-64.1.5/forge-26.1.2-64.1.5-installer.jar' \ +installer="$inputs/forge-26.2-65.1.0-installer.jar" +download 'https://maven.minecraftforge.net/net/minecraftforge/forge/26.2-65.1.0/forge-26.2-65.1.0-installer.jar' \ "$(value forge_installer_sha256)" "$installer" { printf 'power_ref=%s\n' "$power_ref" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc08f8b..4cf99aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,16 +1,16 @@ -name: baseElectric 26.1.2 CI +name: baseElectric 26.2 CI on: push: - branches: [master-26.1.2, 'feature/**'] + branches: [master-26.2, 'feature/**'] pull_request: - branches: [master-26.1.2] + branches: [master-26.2] permissions: contents: read concurrency: - group: baseelectric-26.1.2-${{ github.workflow }}-${{ github.ref }} + group: baseelectric-26.2-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -52,7 +52,7 @@ jobs: -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Verify the Forge 64 build inputs + - name: Verify the Forge 65 build inputs shell: bash env: ORESPAWN_REF: ${{ steps.public-pins.outputs.orespawn_ref }} @@ -64,7 +64,7 @@ jobs: test "$(git -C "$orespawn" rev-parse HEAD)" = "$ORESPAWN_REF" test "$(git -C "$power" rev-parse HEAD)" = "$POWER_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" - printf '%s %s\n' 'BB0DACB3DEB2A711CA67DD402D5FDAB5A9847C37C7B9B596DEC7CF37378FA085' "$mavenizer" | sha256sum -c - + printf '%s %s\n' '5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B' "$mavenizer" | sha256sum -c - echo "MAVENIZER=$mavenizer" >> "$GITHUB_ENV" - name: Build and audit release artifacts shell: bash @@ -78,20 +78,20 @@ jobs: - name: Upload audited release candidate uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: baseElectric-26.1.2-${{ github.sha }} + name: baseElectric-26.2-${{ github.sha }} if-no-files-found: error retention-days: 30 path: | - build/libs/baseElectric-2.2.17.2601021.jar - build/libs/baseElectric-2.2.17.2601021-sources.jar - build/libs/baseElectric-2.2.17.2601021-javadoc.jar + build/libs/baseElectric-2.2.18.2602001.jar + build/libs/baseElectric-2.2.18.2602001-sources.jar + build/libs/baseElectric-2.2.18.2602001-javadoc.jar build/release/SHA256SUMS CHANGELOG.txt - name: Upload diagnostics on failure if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: baseElectric-26.1.2-diagnostics-${{ github.sha }} + name: baseElectric-26.2-diagnostics-${{ github.sha }} if-no-files-found: ignore retention-days: 14 path: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 22f5431..10d22ec 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,9 +2,9 @@ name: CodeQL on: push: - branches: [master-26.1.2, 'feature/**'] + branches: [master-26.2, 'feature/**'] pull_request: - branches: [master-26.1.2] + branches: [master-26.2] permissions: contents: read @@ -12,7 +12,7 @@ permissions: security-events: write concurrency: - group: baseelectric-26.1.2-${{ github.workflow }}-${{ github.ref }} + group: baseelectric-26.2-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -54,7 +54,7 @@ jobs: -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Verify the Forge 64 build inputs + - name: Verify the Forge 65 build inputs shell: bash env: ORESPAWN_REF: ${{ steps.public-pins.outputs.orespawn_ref }} @@ -66,7 +66,7 @@ jobs: test "$(git -C "$orespawn" rev-parse HEAD)" = "$ORESPAWN_REF" test "$(git -C "$power" rev-parse HEAD)" = "$POWER_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" - printf '%s %s\n' 'BB0DACB3DEB2A711CA67DD402D5FDAB5A9847C37C7B9B596DEC7CF37378FA085' "$mavenizer" | sha256sum -c - + printf '%s %s\n' '5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B' "$mavenizer" | sha256sum -c - echo "MAVENIZER=$mavenizer" >> "$GITHUB_ENV" - name: Initialize CodeQL uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4 diff --git a/.github/workflows/validate-gradle-build.yml b/.github/workflows/validate-gradle-build.yml index 531f53f..d8bacce 100644 --- a/.github/workflows/validate-gradle-build.yml +++ b/.github/workflows/validate-gradle-build.yml @@ -3,11 +3,11 @@ name: Validate Gradle Wrapper on: push: branches: - - master-26.1.2 + - master-26.2 - 'feature/**' pull_request: branches: - - master-26.1.2 + - master-26.2 permissions: contents: read diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 06e8588..ad3aca6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,9 @@ +baseElectric 2.2.18.2602001 - local candidate + +- Target Minecraft 26.2 and Forge 65 with Java 25. +- Keep the shared Base Metals migration hook and existing machine, item and saved-data identities. +- Retain exact dependency, native pack, artifact and classpath guards while the new candidate is qualified. + baseElectric 2.2.17.2601021 (Minecraft 26.1.2 / Forge) - Bring baseElectric to Minecraft 26.1.2 with Forge 64.1.5 and Java 25. diff --git a/README.md b/README.md index b624d73..23c04de 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,59 @@ # baseElectric -**Version 2.2.17.2601021 is accepted for release.** - -baseElectric continues DrCyano's Electric Advantage. It adds electric machines, -generation, storage, automation and defence to basePower. Its equipment appears -in the shared basePower creative tab. - -This checkout targets Minecraft **26.1.2** and -Forge **64.1.5**, using official runtime names, MCP **20260409.101008**, -ForgeGradle **7.0.34**, Gradle **9.6.1**, and Temurin **25.0.3+9**. -The frozen profile12 family has completed automated qualification and manual -testing. See the -[family qualification record](../../PowerAdvantage/docs/26.1.2/QUALIFICATION.md) -for the exact tested jars, completed checks and scope limits. Manual acceptance -is complete. Publication is being prepared; this version is not public yet. - -basePower **2.4.16.2601021** and Base Metals **3.1.2.2601021** are required on -both client and server. Their local source and ordinary-jar checkpoints are -recorded in `gradle.properties`; they remain local inputs, not public releases. -The build rejects old 1.21.11 inputs. OreSpawn -**4.1.1.2601021** is pinned to its public release (CurseForge 9572926). -See the [26.1.2 notes](docs/NATIVE2612.md). - -The accepted qualification uses Power source `d0bd0bdb` / jar `23ABCC1F` and the -exact local Base Metals hook. Verified public dependency pins are still needed -before release CI and publication. Power is published first, then Steam, then -Electric. Electric's manifest records its Power source and artifact provenance; -the public-pin rebuild will have a separate byte comparison and receipt. -The new clean release suite passes 117 unit tests and 28 native checks, and its -warm and fresh empty-cache path-with-spaces reproductions match all three -archives. Fresh ECJ passes all 117 tests with the complete compiled inventory, -and the standalone source audit passes all nine checks after its exact OreSpawn -constants were updated. The original stale-pin failures remain preserved. - -The completed [1.21.11 release](https://www.curseforge.com/minecraft/mc-mods/baseelectric/files/9567881) -and its [qualification notes](docs/NATIVE12111.md) are historical evidence, -not proof of this port. New gameplay, migration and graphical checks must use -the actual 26.1.2 jars. - -Back up your world and try the upgrade on a copy. Replace Electric Advantage -and Power Advantage with baseElectric and basePower; do not install both sets. - -## Building locally - -Use Temurin 25.0.3+9 for Gradle, Minecraft, compilation, tests, Mavenizer and -Slime Launcher. No Java 8 helper is required. Set -`-Porg.gradle.java.installations.paths=` if needed. -Use the isolated `D:/GradleCaches/baseelectric-2612-port` cache for local work. - -The independent Forge/resource checks do not require sibling jars: +**Minecraft 26.2 Forge, version 2.2.18.2602001. Local build candidate.** + +baseElectric continues DrCyano's Electric Advantage and uses basePower's shared +API, machines and creative tab. Existing `baseelectric` registry and saved-data +identities are retained. + +This port targets Forge **65.1.0**, official Minecraft **26.2** names, +MCP **20260616.103818**, Java **25.0.3+9**, ForgeGradle **7.0.34** and the +checksum-pinned Gradle **9.6.1** wrapper. Native pack formats are data +**107.1** and client **88.0**. + +## Build + +The coordinated local dependency versions are basePower **2.4.17.2602001** +and Base Metals **3.1.2.2602001**. The Base Metals hook source is +`523335a59ecff399e40a7c66eb121a3aabdc45ba`, player SHA-256 +`15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1`. +Base Metals is REQUIRED on both client and server, not an optional integration. +The approved local Power262 handoff is source +`f84b2362449e39eff5e76696dd64ce4cb144da4f`, player SHA-256 +`7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1`. + +OreSpawn **4.1.1.2602001** is the approved local retained-settings repair, +source `dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c`, SHA-256 +`BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F`. +It is not published; the public file-ID pin is deliberately empty. The older +4.1.0 public download is not substituted for these bytes. + +The Mavenizer fixture and its source-rule, patch, licence and provenance files +are checksum-sealed from the existing OS262 checkout. The established +`-Pforge64MavenizerJar` property remains a path alias; it selects the Forge65 +fixture here. Dependencies stay separate mods and must match the source and +artifact pins in `gradle.properties`. + +Use Temurin 25 and clear `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS` and +`_JAVA_OPTIONS` before qualification. The prepared sibling layout is the +default; explicit `*DeobfJar` and `*RuntimeJar`/`*PlayerJar` flags change +paths, not the required bytes. With these exact coordinated inputs: ```text -./gradlew nativeResourceChecks compileNativeApiDiagnostics verifyRecipeTagGuards processResources --max-workers=2 --no-daemon +./gradlew clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums --no-build-cache --no-daemon +./gradlew verifyEclipseProductionClasspath --no-daemon node tools/verify-native-port.js node tools/generate-recipe-unlocks.js --check ``` -For a full local build, use the exact local dependency pins in -`gradle.properties`. Path overrides never replace source or hash checks: - -```text --PpowerAdvantageRuntimeJar=/path/to/basePower-2.4.16.2601021.jar --PbaseMetalsRuntimeJar=/path/to/BaseMetals-3.1.2.2601021.jar --PforgeInstallerJar=/path/to/forge-26.1.2-64.1.5-installer.jar -``` - -Forge 64 uses the ordinary native jar for both play and development. The former -`*DeobfJar` path flags remain aliases for the same bytes. OreSpawn and the -Mavenizer fixture default to the sibling `MinecraftMineralogy/OS2612/OreSpawn` -checkout. Use `-PoreSpawnRuntimeJar` and `-Pforge64MavenizerJar` to override paths. -For the prepared cache, use `--offline` with `ORESPAWN_MAVENIZER_OFFLINE=true`. - -```text -./gradlew check build javadoc verifyLocalRuntimeInputs writeReleaseChecksums verifyEclipseProductionClasspath --no-build-cache -``` - -Use `gradlew.bat` on Windows. Output jars go to `build/libs`. Dependencies -remain separate mods. The 26.1.2 CI and CodeQL jobs require merged source pins -and checksum-matching public dependencies before checkout or compilation. -Local jars do not satisfy that gate. +See [26.2 port status](docs/NATIVE262.md). The accepted 26.1.2 family +qualification remains historical proof of those original bytes, not this port. +There is no 26.2 manual acceptance, hosted qualification or publication yet. ## Candidate09 Verification History +This section records the earlier 26.1.2 work, not qualification of this 26.2 candidate. + The previous candidate09 passed 117 unit tests, 28 independent native resource tests and 117 tests from fresh ECJ output, with no failures or skips. The ECJ gate compares every compiled test method with the Gradle XML inventory. diff --git a/build.gradle b/build.gradle index 9282a68..548f82a 100644 --- a/build.gradle +++ b/build.gradle @@ -203,7 +203,7 @@ sourceSets.main.resources { def forgeRunModClassesDirectory = layout.buildDirectory.dir('forge-run-mod-classes/main') def prepareForgeRunModClasses = tasks.register('prepareForgeRunModClasses', Sync) { group = 'ide' - description = 'Merges classes and processed resources for Forge 26.1.2 launches.' + description = 'Merges classes and processed resources for Forge 26.2 launches.' dependsOn tasks.named('classes') from sourceSets.main.output into forgeRunModClassesDirectory @@ -321,12 +321,12 @@ def requirePowerPin = { || !(project.poweradvantage_source_ref ==~ /[a-f0-9]{40}/) || ![project.poweradvantage_deobf_sha256, project.poweradvantage_runtime_sha256] .every { it ==~ /[A-F0-9]{64}/ }) { - throw new GradleException('The owner-approved basePower 26.1.2 source and artifact pins are required.') + throw new GradleException('The owner-approved basePower 26.2 source and artifact pins are required.') } } // Resolve and check only the dependencies required by the selected tasks. def powerDefaultJar = "../../PowerAdvantage/build/libs/basePower-${project.poweradvantage_version}.jar" -def metalsDefaultJar = "../../../../BaseMetals/BaseMetals 2612/BaseMetals/build/libs/BaseMetals-${project.basemetals_version}.jar" +def metalsDefaultJar = "../../../../BaseMetals/BaseMetals 262/BaseMetals/build/libs/BaseMetals-${project.basemetals_version}.jar" def powerAdvantageDeobfJar = providers.provider { requirePowerPin() pinnedFile('powerAdvantageDeobfJar', project.poweradvantage_deobf_sha256, @@ -337,7 +337,7 @@ def baseMetalsDeobfJar = providers.provider { pinnedFile('baseMetalsDeobfJar', project.basemetals_deobf_sha256, providers.gradleProperty('baseMetalsRuntimeJar').getOrElse(metalsDefaultJar)) } -def oreSpawnProject = '../../../../MinecraftMineralogy/OS2612/OreSpawn' +def oreSpawnProject = '../../../../MinecraftMineralogy/OS262/OreSpawn' def oreSpawnDeobfJar = providers.provider { requireCommittedPins('orespawn_') pinnedFile('oreSpawnDeobfJar', project.orespawn_deobf_sha256, @@ -362,8 +362,14 @@ def unitLoaderJava = providers.provider { "${powerUnitSource}/test-rig/unit-support/zone/moddev/mc/advantageworks/unit/Forge64UnitLoader.java") } def pinnedUnitSupport = layout.buildDirectory.dir('generated-unit-support') + +def unitEntityTrackerJava = providers.provider { + requireCommittedPins('unit_') + pinnedFile('unitEntityTrackerJava', project.unit_entity_tracker_java_sha256, + "${powerUnitSource}/test-rig/unit-support/zone/moddev/mc/advantageworks/unit/NativeEmptyEntityTracker.java") +} def preparePinnedUnitSupport = tasks.register('preparePinnedUnitSupport', Sync) { - from unitRegistriesJava, unitLoaderJava + from unitRegistriesJava, unitLoaderJava, unitEntityTrackerJava into pinnedUnitSupport.map { it.dir('zone/moddev/mc/advantageworks/unit') } } sourceSets.test.java.srcDir pinnedUnitSupport @@ -503,7 +509,7 @@ tasks.register('nativeUnitDiagnostics', Test) { } tasks.register('nativeResourceChecks', Test) { group = 'verification' - description = 'Checks Electric resources against native Forge 64 without sibling mod jars.' + description = 'Checks Electric resources against native Forge 65 without sibling mod jars.' dependsOn compileNativeResourceChecks, tasks.named('processResources') useJUnit() testClassesDirs = files(nativeResourceCheckClasses) @@ -590,13 +596,13 @@ def releaseJar = tasks.named('jar', Jar) tasks.register('releaseJar') { group = 'build' - description = 'Builds the native Forge 64 player jar.' + description = 'Builds the native Forge 65 player jar.' dependsOn releaseJar } tasks.register('deobfJar') { group = 'build' - description = 'Builds the same native Forge 64 jar used for development and play.' + description = 'Builds the same native Forge 65 jar used for development and play.' dependsOn tasks.named('jar') } @@ -671,22 +677,22 @@ tasks.register('verifyReleaseConfiguration') { requireCommittedPins('orespawn_') requireCommittedPins('forge_') def pack = new JsonSlurper().parse(file('src/main/resources/pack.mcmeta')).pack - if (pack.min_format != [101, 1] || pack.max_format != [101, 1] + if (pack.min_format != [107, 1] || pack.max_format != [107, 1] || pack.containsKey('pack_format') || pack.containsKey('supported_formats') || !(file('src/main/resources/META-INF/mods.toml').text =~ /(?m)^showAsResourcePack=false$/)) { - throw new GradleException('Root metadata must declare data 101.1 with the native hidden Forge client pack') + throw new GradleException('Root metadata must declare data 107.1 with the native hidden Forge client pack') } - if (project.mod_version != '2.2.17.2601021') { + if (project.mod_version != '2.2.18.2602001') { throw new GradleException("Unexpected baseElectric release version: ${project.mod_version}") } - if (project.minecraft_version != '26.1.2' - || project.minecraft_version_range != '[26.1.2]' - || project.forge_version != '64.1.5' - || project.forge_version_range != '[64.1.5,65)' - || project.loader_version_range != '[64,65)' + if (project.minecraft_version != '26.2' + || project.minecraft_version_range != '[26.2]' + || project.forge_version != '65.1.0' + || project.forge_version_range != '[65.1.0,66)' + || project.loader_version_range != '[65,66)' || project.mapping_channel != 'official' - || project.mapping_version != '26.1.2' - || project.mcp_version != '20260409.101008') { + || project.mapping_version != '26.2' + || project.mcp_version != '20260616.103818') { throw new GradleException('Unexpected Minecraft, Forge, or mappings target') } if (project.loader_name != 'forge' || project.loader_code != '1' @@ -706,17 +712,17 @@ tasks.register('verifyReleaseConfiguration') { } if (project.cf_requirements != 'basepower,base-metals' || project.cf_optionals != '' - || project.cf_versions != '26.1.2') { + || project.cf_versions != '26.2') { throw new GradleException('Unexpected CurseForge dependency or game-version metadata') } - if (project.poweradvantage_version != '2.4.16.2601021' + if (project.poweradvantage_version != '2.4.17.2602001' || project.poweradvantage_source_repository != 'MinecraftModDevelopmentMods/basePower') { throw new GradleException('Unexpected basePower compile dependency identity') } - if (!(project.basemetals_version ==~ /3\.\d+\.\d+\.2601021/) - || project.orespawn_version != '4.1.1.2601021' - || project.basemetals_built_on != '26.1.2-64.0.9' - || project.orespawn_built_on != '26.1.2-64.0.9' + if (!(project.basemetals_version ==~ /3\.\d+\.\d+\.2602001/) + || project.orespawn_version != '4.1.1.2602001' + || project.basemetals_built_on != '26.2-65.1.0' + || project.orespawn_built_on != '26.2-65.1.0' || !(project.basemetals_source_commit ==~ /[a-f0-9]{40}/) || !(project.basemetals_deobf_sha256 ==~ /[A-F0-9]{64}/) || !(project.basemetals_runtime_sha256 ==~ /[A-F0-9]{64}/) @@ -724,18 +730,18 @@ tasks.register('verifyReleaseConfiguration') { || project.orespawn_deobf_sha256 != project.orespawn_runtime_sha256 || project.basemetals_deobf_sha256 != project.basemetals_runtime_sha256 || project.poweradvantage_deobf_sha256 != project.poweradvantage_runtime_sha256 - || project.forge_installer_sha256 != '6E01323837051176762BD466340A601DA122F179FE6A00AC616E05429AE07648') { + || project.forge_installer_sha256 != '813FBBFECC3086A492783B9F5023AE15007737B42E17AAB75F48BA77403314DF') { throw new GradleException('Unexpected native dependency pins') } String mainSource = file( 'src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java').getText('UTF-8') if (!mainSource.contains('MODID = "baseelectric"') - || !mainSource.contains('VERSION = "2.2.17.2601021"')) { + || !mainSource.contains('VERSION = "2.2.18.2602001"')) { throw new GradleException('baseElectric source identity changed') } String metadata = file('src/main/resources/META-INF/mods.toml').getText('UTF-8').replace('\r\n', '\n') ['modId="baseelectric"', 'displayName="baseElectric"', 'modId="basepower"', 'modId="basemetals"', - 'versionRange="[2.4.16.2601021,3.0.0)"', 'versionRange="[3.1.2.2601021,4.0.0)"'].each { marker -> + 'versionRange="[2.4.17.2602001,3.0.0)"', 'versionRange="[3.1.2.2602001,4.0.0)"'].each { marker -> if (!metadata.contains(marker)) { throw new GradleException("Source mods.toml is missing ${marker}") } @@ -768,7 +774,7 @@ def auditModInput = { File jarFile, String modId, String version, List r def verifyOreSpawnNativeInputs = tasks.register('verifyOreSpawnNativeInputs') { group = 'verification' - description = 'Verifies the unchanged public OreSpawn jar and its own exact native build provenance.' + description = 'Verifies the approved local OreSpawn jar and its own exact native build provenance.' doLast { requireCommittedPins('orespawn_') auditModInput(oreSpawnDeobfJar.get(), 'orespawn', project.orespawn_version, []) @@ -781,7 +787,7 @@ def verifyOreSpawnNativeInputs = tasks.register('verifyOreSpawnNativeInputs') { tasks.register('verifyLocalNativeInputs') { group = 'verification' - description = 'Verifies explicit Base Metals and OreSpawn 26.1.2 development and player JARs.' + description = 'Verifies explicit Base Metals and OreSpawn 26.2 development and player JARs.' dependsOn tasks.named('verifyReleaseConfiguration') dependsOn verifyOreSpawnNativeInputs doLast { @@ -858,7 +864,7 @@ tasks.register('verifyReleaseDependencies') { ['fields.csv', 'methods.csv'].each { name -> String csv = zip.getInputStream(zip.getEntry(name)).getText('UTF-8').replace('\r\n', '\n') if (csv != 'searge,name,side,desc') { - throw new GradleException('Forge 64 official runtime mappings must be empty header-only CSVs') + throw new GradleException('Forge 65 official runtime mappings must be empty header-only CSVs') } } } @@ -1181,7 +1187,7 @@ tasks.register('validateMavenReleaseCredentials') { group = 'publishing' description = 'Rejects remote publication from this local port.' doLast { - throw new GradleException('Remote Maven publication is disabled on the local 26.1.2 port.') + throw new GradleException('Remote Maven publication is disabled on the local 26.2 port.') } } @@ -1257,7 +1263,7 @@ tasks.register('configureEclipseBuildship') { def quoteEclipseLaunchPaths = { String name, String arguments -> if (arguments.contains('--to-srg') || arguments.contains('--to-obf')) { - throw new GradleException("${name} must not remap the official Forge 64 runtime") + throw new GradleException("${name} must not remap the official Forge 65 runtime") } // ForgeGradle flattens path arguments without quoting them for Eclipse. Map nextOptions = [ @@ -1653,7 +1659,7 @@ tasks.register('verifyEclipseProductionClasspath') { || !programArguments.startsWith('--main net.minecraftforge.bootstrap.ForgeBootstrap ') || !(programArguments =~ /(?:^|\s)--launchTarget\s+${target}(?:\s|$)/).find() || !vmArguments.contains('--add-opens java.base/java.lang.invoke=ALL-UNNAMED')) { - throw new GradleException("${name} does not define the Forge 64 bootstrap and native launch target") + throw new GradleException("${name} does not define the Forge 65 bootstrap and native launch target") } ['--cache', '--metadata'].each { option -> def argument = programArguments =~ /(?:^|\s)${option}\s+(?:"([^"]+)"|([^"\s]+))(?=\s+--|$)/ diff --git a/docs/NATIVE262.md b/docs/NATIVE262.md new file mode 100644 index 0000000..06f83ec --- /dev/null +++ b/docs/NATIVE262.md @@ -0,0 +1,45 @@ +# Minecraft 26.2 local build candidate + +Version 2.2.18.2602001 targets Forge65.1.0, MCP20260616.103818, Java25 and +native pack formats107.1/88.0. This candidate is local-only. Child build gates +do not establish combined-family runtime qualification or manual acceptance. + +## Exact inputs + +- Power source f84b2362449e39eff5e76696dd64ce4cb144da4f; player/development + 7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1. +- Base Metals source 523335a59ecff399e40a7c66eb121a3aabdc45ba; player/development + 15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1. +- OreSpawn4.1.1.2602001 local retained-settings repair, source + dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c; player/development + BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F. + No public file ID is assigned to this local candidate. +- Power's checksum-pinned unit agent and committed support sources are used + separately from player bytes. No helper or test classes ship in the mod. + +## Passed child gates + +- Clean check/build/Javadoc: 49 tasks / 117 unit tests, plus 28 independent native resource tests, with no failures or skips. +- Exact source/artifact pins, release archives/checksums, GameTest source + compilation and Eclipse production-classpath isolation. +- Fresh ECJ main/test/GameTest compilation and the same complete unit inventory, + including strict inventory-rejection controls. +- All 50 recipe-unlock checks. Static source audits remain separate from runtime proof. +- Native entity bind-group layout and vertex sinks preserve the existing renderer + geometry, UV, lightmap, overlay and pose checks. A deferred collector check + confirms that later state mutation does not change submitted drill geometry. +- The native empty entity-ID tracker is an explicitly hash-pinned test fixture. + Native Entity/load methods and all four hydroturbine assertions are unchanged. +- Failed setup, compiler and test attempts are preserved separately. The + provisional old-Power/public-OreSpawn runs are not relabelled as this candidate. + +## Remaining qualification + +Independent archive reproductions and fresh-cache/offline gates remain pending. +Packaged combined-family gameplay, machine/migration/actor/dimension/order, +retained-generation and GPU/client campaigns are parent-owned and are not +claimed here. Manual acceptance is also pending. Historical 26.1.2 evidence +remains bound to its original source, profile and artifact bytes. + +Hosted CI still requires merged, public dependency inputs; local candidate +pins do not waive that gate. No 26.2 push, tag, publisher dispatch or upload. diff --git a/gradle.properties b/gradle.properties index c62a067..e8bab09 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,18 +7,18 @@ org.gradle.workers.max=2 net.minecraftforge.gradle.merge-source-sets=false reobf=false -minecraft_version=26.1.2 -minecraft_version_range=[26.1.2] -forge_version=64.1.5 -forge_installer_sha256=6E01323837051176762BD466340A601DA122F179FE6A00AC616E05429AE07648 -forge_shim_sha256=0C74CB2A8E7A71AEB7055396C1E25864584A2D837D7DD42136A06D0B41ADD545 -forge_server_sha256=C6B85C178B037519464D436A75B7C68408CBE591576270BA0E826542B50BF41B -forge_universal_sha256=687C2698ECC1906CA2AD398A445C2498CF8BC09F1CBE6C2A6E24BFC9F90736C7 -forge_version_range=[64.1.5,65) -loader_version_range=[64,65) +minecraft_version=26.2 +minecraft_version_range=[26.2] +forge_version=65.1.0 +forge_installer_sha256=813FBBFECC3086A492783B9F5023AE15007737B42E17AAB75F48BA77403314DF +forge_shim_sha256=8D113D3DFFF0F0978A1989E22A8040FAD0FE5E332EF766B3702EB29687C9F4D2 +forge_server_sha256=2DDA94C321F928934AE7E3B8DB45AAE0FD994A9FA7BBDCDDC0AF1F9170A581DA +forge_universal_sha256=3C8816B687BA6F7404E35ED11397F6ABFB00A8C800286E43E038DBBD8FA5525F +forge_version_range=[65.1.0,66) +loader_version_range=[65,66) mapping_channel=official -mapping_version=26.1.2 -mcp_version=20260409.101008 +mapping_version=26.2 +mcp_version=20260616.103818 loader_name=forge loader_code=1 @@ -31,40 +31,42 @@ curseforge_project_id=1783006 mod_id=baseelectric mod_name=baseElectric mod_license=GPL-3.0-only -mod_version=2.2.17.2601021 +mod_version=2.2.18.2602001 mod_group=zone.moddev.mc.baseelectric mod_authors=DrCyano mod_description=Electric-powered machines and infrastructure for basePower. cf_requirements=basepower,base-metals cf_optionals= -cf_versions=26.1.2 +cf_versions=26.2 -poweradvantage_version=2.4.16.2601021 +poweradvantage_version=2.4.17.2602001 poweradvantage_pin_state=LOCAL_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Owner-approved local integration checkpoint, not a public or family-qualified release. -poweradvantage_source_ref=d0bd0bdbde6c499e800e5a5b4ecc7f9ac63d2055 +# Owner-approved local Power262 compile/test handoff; not a public release. +poweradvantage_source_ref=f84b2362449e39eff5e76696dd64ce4cb144da4f poweradvantage_public_file_id= -poweradvantage_deobf_sha256=23ABCC1FEFDAA6988BF709437EB165C8948C757E773ADAB738092EB93CA8D2B0 -poweradvantage_runtime_sha256=23ABCC1FEFDAA6988BF709437EB165C8948C757E773ADAB738092EB93CA8D2B0 +poweradvantage_deobf_sha256=7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1 +poweradvantage_runtime_sha256=7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1 -basemetals_version=3.1.2.2601021 -basemetals_built_on=26.1.2-64.0.9 +basemetals_version=3.1.2.2602001 +basemetals_built_on=26.2-65.1.0 # Local native shared-hook checkpoint; family qualification is separate. -basemetals_source_commit=331fa46914f854db71a8c33500cc559a8878b7d3 +basemetals_source_commit=523335a59ecff399e40a7c66eb121a3aabdc45ba basemetals_public_file_id= -basemetals_deobf_sha256=6786238835D4D8A653C769F3B0E61D226959146300E17523799CFDF17540FD19 -basemetals_runtime_sha256=6786238835D4D8A653C769F3B0E61D226959146300E17523799CFDF17540FD19 +basemetals_deobf_sha256=15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1 +basemetals_runtime_sha256=15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1 unit_bootstrap_sha256=088FC137BEBB9B2E75C596DE868499E6099CF228BECFCF07EAE36791245FD1B6 unit_bootstrap_java_sha256=D4B72FD65D9F8549B142507C6446E3B1E047B637784AF9FA74E8F28413E14A51 unit_registries_java_sha256=01DDE50C9874C2DC501BE2F699CD8D16D6974FACFAAC1B803434CA8C64227ABF unit_loader_java_sha256=455CA9403D9CBEA72E7D055966D6CDC822E634418C14B3CAD0500588DEE35E5B +unit_entity_tracker_java_sha256=EB2A83A35F617BC52D322332C824BE83A3BFE4C83CEB0418F77687EA93978E6D -orespawn_version=4.1.1.2601021 -orespawn_built_on=26.1.2-64.0.9 -orespawn_source_commit=101fd12b598934c353e417c57edc5c2bbefd5f53 -orespawn_public_file_id=9572926 -orespawn_deobf_sha256=810284ECB32D5249381F246498CEFA57E70FFF7CCC40110F799FC276CBC42BF7 -orespawn_runtime_sha256=810284ECB32D5249381F246498CEFA57E70FFF7CCC40110F799FC276CBC42BF7 +orespawn_version=4.1.1.2602001 +orespawn_built_on=26.2-65.1.0 +orespawn_source_commit=dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c +# Approved LOCAL source candidate; not CurseForge file 9332183. +orespawn_public_file_id= +orespawn_deobf_sha256=BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F +orespawn_runtime_sha256=BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F diff --git a/gradle/forge64-mavenizer.gradle b/gradle/forge64-mavenizer.gradle index a84b873..f40f1f8 100644 --- a/gradle/forge64-mavenizer.gradle +++ b/gradle/forge64-mavenizer.gradle @@ -1,22 +1,26 @@ import java.security.MessageDigest import org.gradle.jvm.toolchain.JvmVendorSpec -def fixture = file(providers.gradleProperty('forge64MavenizerJar').getOrElse( - '../../../../MinecraftMineralogy/OS2612/OreSpawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar')) -def expected = 'BB0DACB3DEB2A711CA67DD402D5FDAB5A9847C37C7B9B596DEC7CF37378FA085' -if (!fixture.isFile()) { - throw new GradleException("Missing Forge 64 Mavenizer fixture: ${fixture}. Set -Pforge64MavenizerJar=.") -} -def actual = MessageDigest.getInstance('SHA-256').digest(fixture.bytes).encodeHex().toString().toUpperCase(Locale.ROOT) -if (actual != expected) { - throw new GradleException("Forge 64 Mavenizer fixture SHA-256 mismatch: expected ${expected}, got ${actual}") -} - -def rules = new File(fixture.parentFile, 'minecraft-source-compatibility.json') -def expectedRules = '21D1F5984E735BCEA1B1EFB9F965655796B39538FC91AAED1C3474004710423D' -if (!rules.isFile() || MessageDigest.getInstance('SHA-256').digest(rules.bytes) - .encodeHex().toString().toUpperCase(Locale.ROOT) != expectedRules) { - throw new GradleException("Missing or mismatched Forge 64 Mavenizer rules: ${rules}") +// Keep the preparation tool and its source-rule/license evidence together. +// A different checkout layout can override the jar path without editing this file. +def tool = 'ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar' +def defaultJar = project.extensions.extraProperties.has('forge64MavenizerDefault') + ? project.forge64MavenizerDefault + : "../../../../MinecraftMineralogy/OS262/OreSpawn/${tool}" +def fixture = file(providers.gradleProperty('forge64MavenizerJar').getOrElse(defaultJar)) +def checksums = [ + (fixture.name): '5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B', + 'minecraft-source-compatibility.json': '9437E03FC5E1CB5D605D72F0538C4DF4417B64DB0A57D0AABDC5184781517AC1', + 'minecraft-mavenizer-0.5.21-orespawn-compat.patch': '2DA8DD0FD5F112F5B7591113AED06D9A58C584A25F8705E26445A6D2E9D5C78E', + 'LICENSE-MAVENIZER.txt': '20C17D8B8C48A600800DFD14F95D5CB9FF47066A9641DDEAB48DC54AEC96E331', + 'README.md': 'EAD1477F393897C491A10FB86178213A99C360571A8063D551DA0579DF65BA6F' +] +checksums.each { name, expected -> + File input = new File(fixture.parentFile, name) + if (!input.isFile() || MessageDigest.getInstance('SHA-256').digest(input.bytes) + .encodeHex().toString().toUpperCase(Locale.ROOT) != expected) { + throw new GradleException("Missing or altered Forge 65 Mavenizer fixture: ${input}") + } } fgtools.configure('mavenizer') { diff --git a/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java b/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java index bcedea4..e7530be 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java +++ b/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java @@ -24,13 +24,13 @@ import zone.moddev.mc.baseelectric.recipe.RecipeConditions; import zone.moddev.mc.baseelectric.migration.ElectricLegacyMigrations; -/** Forge 26.1.2 entry point for baseElectric. */ +/** Forge 26.2 entry point for baseElectric. */ @Mod(ElectricAdvantage.MODID) public final class ElectricAdvantage { public static final String MODID = "baseelectric"; public static final String LEGACY_MODID = "electricadvantage"; public static final String NAME = "baseElectric"; - public static final String VERSION = "2.2.17.2601021"; + public static final String VERSION = "2.2.18.2602001"; public static final Logger LOGGER = LogManager.getLogger(MODID); public static ElectricAdvantage INSTANCE; diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java index 9fae384..17ae643 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.pipeline.BlendFunction; import com.mojang.blaze3d.pipeline.ColorTargetState; import com.mojang.blaze3d.pipeline.RenderPipeline; +import net.minecraft.client.renderer.BindGroupLayouts; import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.renderer.rendertype.RenderSetup; import net.minecraft.client.renderer.rendertype.RenderType; @@ -19,7 +20,8 @@ private static RenderPipeline pipeline(boolean translucent) { var builder = RenderPipeline.builder(RenderPipelines.ENTITY_SNIPPET) .withLocation(Identifier.fromNamespaceAndPath("baseelectric", translucent ? "pipeline/unshaded_translucent" : "pipeline/unshaded")) - .withShaderDefine("NO_CARDINAL_LIGHTING").withSampler("Sampler1").withCull(false); + .withShaderDefine("NO_CARDINAL_LIGHTING") + .withBindGroupLayout(BindGroupLayouts.SAMPLER1).withCull(false); if (translucent) builder.withColorTargetState(new ColorTargetState(BlendFunction.TRANSLUCENT)); RenderPipeline pipeline = builder.build(); RenderPipelines.PIPELINES_BY_LOCATION.put(pipeline.getLocation(), pipeline); @@ -28,7 +30,7 @@ private static RenderPipeline pipeline(boolean translucent) { static RenderType unshaded(Identifier texture, boolean translucent) { var setup = RenderSetup.builder(translucent ? TRANSLUCENT : OPAQUE) - .withTexture("Sampler0", texture).useLightmap().useOverlay().bufferSize(256); + .withTexture("Sampler0", texture).useLightmap().useOverlay(); if (translucent) setup.sortOnUpload(); return RenderType.create("baseelectric_unshaded", setup.createRenderSetup()); } diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java index 81472d9..2ace839 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java @@ -3,7 +3,6 @@ import zone.moddev.mc.baseelectric.ElectricAdvantage; import zone.moddev.mc.baseelectric.entities.HydroturbineEntity; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.rendertype.RenderTypes; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.entity.state.EntityRenderState; diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java index 1bbfeb3..cee6e9e 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java @@ -3,7 +3,7 @@ import zone.moddev.mc.baseelectric.ElectricAdvantage; import zone.moddev.mc.baseelectric.machines.ElectricDrillTileEntity; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; +import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; @@ -51,13 +51,13 @@ public static final class State extends BlockEntityRenderState { } public void render(final ElectricDrillTileEntity e, final float partialTick, final PoseStack matrices, - final MultiBufferSource buffers, final int packedLight, final int packedOverlay) { + final VertexConsumer vertices, final int packedLight, final int packedOverlay) { float laserBlastLength = e.getDrillLength(); if(laserBlastLength > 0){ transform(matrices, e.getFacing()); - draw(laserBlastLength, matrices.last(), buffers.getBuffer(beamType), packedOverlay); + draw(laserBlastLength, matrices.last(), vertices, packedOverlay); matrices.popPose(); } } diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java index 40e46bc..5209951 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java @@ -3,7 +3,7 @@ import zone.moddev.mc.baseelectric.ElectricAdvantage; import zone.moddev.mc.baseelectric.machines.LaserTurretTileEntity; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; +import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; @@ -62,11 +62,11 @@ private static void capture(LaserTurretTileEntity entity, State state, float par } public void render(final LaserTurretTileEntity e, final float partialTick, final PoseStack matrices, - final MultiBufferSource buffers, final int packedLight, final int packedOverlay) { + final VertexConsumer vertices, final int packedLight, final int packedOverlay) { State state = new State(); capture(e, state, partialTick); transform(matrices, state.yaw, state.pitch); - draw(state, matrices.last(), buffers.getBuffer(renderType), packedLight, packedOverlay); + draw(state, matrices.last(), vertices, packedLight, packedOverlay); matrices.popPose(); } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 4020e36..39729b0 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -31,13 +31,13 @@ side="BOTH" [[dependencies.baseelectric]] modId="basepower" mandatory=true -versionRange="[2.4.16.2601021,3.0.0)" +versionRange="[2.4.17.2602001,3.0.0)" ordering="AFTER" side="BOTH" [[dependencies.baseelectric]] modId="basemetals" mandatory=true -versionRange="[3.1.2.2601021,4.0.0)" +versionRange="[3.1.2.2602001,4.0.0)" ordering="AFTER" side="BOTH" diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 0140236..a866191 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,7 +1,7 @@ { "pack":{ - "min_format":[101,1], - "max_format":[101,1], + "min_format":[107,1], + "max_format":[107,1], "description":"baseElectric" } } diff --git a/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java b/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java index a3f75a9..4556de5 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java @@ -102,19 +102,14 @@ private static Level world() throws Exception { Field field = allocator.getDeclaredField("theUnsafe"); field.setAccessible(true); Level world = (Level)allocator.getMethod("allocateInstance", Class.class) - .invoke(field.get(null), NoTickWorld.class); + .invoke(field.get(null), ServerLevel.class); Field random = Level.class.getDeclaredField("random"); random.setAccessible(true); random.set(world, RandomSource.create(0)); + zone.moddev.mc.advantageworks.unit.NativeEmptyEntityTracker.install((ServerLevel) world); return world; } - private static final class NoTickWorld extends ServerLevel { - private NoTickWorld() { - super(null, null, null, null, null, null, false, 0L, Collections.emptyList(), false); - } - } - private static final class ControlEntity extends Entity { ControlEntity(EntityType type, Level world) { super(type, world); } @Override protected void defineSynchedData(net.minecraft.network.syncher.SynchedEntityData.Builder builder) {} diff --git a/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java index c410f59..bff6d79 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java @@ -8,7 +8,7 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; -import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.SubmitNodeCollector; import org.joml.Matrix4f; import net.minecraft.client.renderer.rendertype.RenderType; import com.mojang.math.Axis; @@ -82,6 +82,29 @@ public class RendererBufferContractTest { assertArrayEquals(new float[] {0, 1}, vertex.uv, 0F); } assertNormals(buffer); + LaserDrillRenderer.State state = renderer.createRenderState(); + state.length = drill.getDrillLength(); + state.facing = drill.getFacing(); + RecordingBuffer deferred = new RecordingBuffer(); + renderer.submit(state, matrices, deferred.collector(), null); + assertSame(before, matrices.last()); + assertEquals(matrix, matrices.last().pose()); + assertTrue(matrices.isEmpty()); + assertTrue(deferred.vertices.isEmpty()); + assertEquals(1, deferred.pending.size()); + state.length = 99; + state.facing = direction.getOpposite(); + deferred.flush(); + assertEquals(16, deferred.vertices.size()); + for (int index = 0; index < buffer.vertices.size(); index++) { + Vertex expected = buffer.vertices.get(index), actual = deferred.vertices.get(index); + assertArrayEquals(expected.position, actual.position, 0.00001F); + assertArrayEquals(expected.normal, actual.normal, 0.00001F); + assertArrayEquals(expected.uv, actual.uv, 0F); + assertArrayEquals(expected.color, actual.color); + assertEquals(FULL_BRIGHT, actual.light); + assertEquals(net.minecraft.client.renderer.texture.OverlayTexture.NO_OVERLAY, actual.overlay); + } } } @@ -183,10 +206,28 @@ private static final class Vertex { int overlay; } - private static final class RecordingBuffer implements VertexConsumer, MultiBufferSource { + private static final class RecordingBuffer implements VertexConsumer { final List vertices = new ArrayList<>(); + final List pending = new ArrayList<>(); Vertex vertex = new Vertex(); - @Override public VertexConsumer getBuffer(RenderType type) { return this; } + SubmitNodeCollector collector() { + return (SubmitNodeCollector) java.lang.reflect.Proxy.newProxyInstance( + SubmitNodeCollector.class.getClassLoader(), new Class[] {SubmitNodeCollector.class}, + (proxy, method, arguments) -> { + if (!method.getName().equals("submitCustomGeometry")) { + throw new AssertionError("Unexpected native submission: " + method); + } + assertNotNull((RenderType) arguments[1]); + PoseStack.Pose pose = ((PoseStack) arguments[0]).last().copy(); + var geometry = (SubmitNodeCollector.CustomGeometryRenderer) arguments[2]; + pending.add(() -> geometry.render(pose, this)); + return null; + }); + } + void flush() { + pending.forEach(Runnable::run); + pending.clear(); + } @Override public VertexConsumer addVertex(float x, float y, float z) { vertex = new Vertex(); vertex.position = new float[] {x, y, z}; diff --git a/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java b/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java index 32712ec..6e097b7 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java @@ -84,7 +84,7 @@ private PacketWorld() { try { zone.moddev.mc.baseelectric.init.Entities.LED = type; assertNotNull(block.getTicker(null, block.defaultBlockState(), type)); - assertNull(block.getTicker(null, block.defaultBlockState(), BlockEntityType.CHEST)); + assertNull(block.getTicker(null, block.defaultBlockState(), net.minecraft.world.level.block.entity.BlockEntityTypes.CHEST)); } finally { zone.moddev.mc.baseelectric.init.Entities.LED = previous; } diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java index 58e4fb2..e95216e 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java @@ -35,8 +35,8 @@ public class BlockLootResourceTest { @Test public void resourcePackDeclaresTheNativeTwentySixFormat() throws Exception { JsonObject pack = read(Paths.get("src/main/resources/pack.mcmeta")).getAsJsonObject("pack"); - assertEquals(JsonParser.parseString("[101,1]"), pack.get("min_format")); - assertEquals(JsonParser.parseString("[101,1]"), pack.get("max_format")); + assertEquals(JsonParser.parseString("[107,1]"), pack.get("min_format")); + assertEquals(JsonParser.parseString("[107,1]"), pack.get("max_format")); assertFalse(pack.has("pack_format")); assertFalse(pack.has("supported_formats")); assertFalse(pack.has("forge:server_data_pack_format")); @@ -44,9 +44,9 @@ public class BlockLootResourceTest { .matcher(Files.readString(Path.of("src/main/resources/META-INF/mods.toml"))).find()); zone.moddev.mc.baseelectric.verification.NativeTestBootstrap.initialize(); var version = net.minecraft.SharedConstants.getCurrentVersion(); - assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(84, 0), + assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(88, 0), version.packVersion(net.minecraft.server.packs.PackType.CLIENT_RESOURCES)); - assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(101, 1), + assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(107, 1), version.packVersion(net.minecraft.server.packs.PackType.SERVER_DATA)); var proof = zone.moddev.mc.baseelectric.verification.NativePackResourceProof.read(); assertEquals(0, proof.getAsJsonArray("warningsAndErrors").size()); @@ -73,7 +73,7 @@ public class BlockLootResourceTest { assertEquals("COMPATIBLE", client.get("loaderCompatibility").getAsString()); assertEquals("COMPATIBLE", server.get("loaderCompatibility").getAsString()); JsonObject insufficient = pack.deepCopy(); - insufficient.add("min_format", JsonParser.parseString("[84,0]")); + insufficient.add("min_format", JsonParser.parseString("[88,0]")); insufficient.remove("pack_format"); insufficient.remove("supported_formats"); var broad = net.minecraft.server.packs.metadata.pack.PackFormat.packCodec( diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java index 488db44..5edc206 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java @@ -47,7 +47,7 @@ public class BuildWorkflowContractTest { } assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.orespawn_ref }}")); assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.power_ref }}")); - assertTrue(source.contains("branches: [master-26.1.2")); + assertTrue(source.contains("branches: [master-26.2")); assertTrue(source.contains("-Pforge64MavenizerJar=$MAVENIZER")); assertTrue(source.contains("-PpowerAdvantageDeobfJar=$POWER_PLAYER")); assertFalse(source.contains("forge47")); diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java index 414aeab..7e21771 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java @@ -98,7 +98,7 @@ public class NativePackRangeContractTest { assertEquals(java.util.Set.of("forge", "minecraft", "basepower", "basemetals"), dependencies.keySet()); var metals = dependencies.getAsJsonObject("basemetals"); assertTrue("Forge must require Base Metals on both sides", metals.get("mandatory").getAsBoolean()); - assertEquals("[3.1.2.2601021,4.0.0)", metals.get("versionRange").getAsString()); + assertEquals("[3.1.2.2602001,4.0.0)", metals.get("versionRange").getAsString()); assertEquals("AFTER", metals.get("ordering").getAsString()); assertEquals("BOTH", metals.get("side").getAsString()); var control = proof.getAsJsonObject("optionalBaseMetalsControl"); @@ -117,9 +117,9 @@ public class NativePackRangeContractTest { JsonObject pack = side.getAsJsonObject("nativeMetadata"); var range = PackFormat.packCodec(type).codec().parse(JsonOps.INSTANCE, pack).getOrThrow(); assertEquals(type.toString(), type == PackType.CLIENT_RESOURCES, - range.isValueInRange(PackFormat.of(84, 0))); + range.isValueInRange(PackFormat.of(88, 0))); assertEquals(type.toString(), type == PackType.SERVER_DATA, - range.isValueInRange(PackFormat.of(101, 1))); + range.isValueInRange(PackFormat.of(107, 1))); assertFalse(range.isValueInRange(PackFormat.of(83))); assertFalse(range.isValueInRange(PackFormat.of(102))); } @@ -143,11 +143,11 @@ public class NativePackRangeContractTest { } @Test public void dataOnlyRangeDoesNotQualifyClientResources() { - JsonObject dataOnly = JsonParser.parseString("{\"min_format\":[101,1],\"max_format\":[101,1]}") + JsonObject dataOnly = JsonParser.parseString("{\"min_format\":[107,1],\"max_format\":[107,1]}") .getAsJsonObject(); var range = PackFormat.packCodec(PackType.CLIENT_RESOURCES).codec() .parse(JsonOps.INSTANCE, dataOnly).getOrThrow(); - assertFalse(range.isValueInRange(PackFormat.of(84, 0))); - assertTrue(range.isValueInRange(PackFormat.of(101, 1))); + assertFalse(range.isValueInRange(PackFormat.of(88, 0))); + assertTrue(range.isValueInRange(PackFormat.of(107, 1))); } } diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java index 99e5965..672a7fa 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java @@ -32,7 +32,7 @@ public class RecipeResourceTest { String text = new String(Files.readAllBytes(file), StandardCharsets.UTF_8); JsonObject json = new JsonParser().parse(text).getAsJsonObject(); String type = json.get("type").getAsString(); - assertTrue(file + " must use the 26.1.2 result template codec", json.getAsJsonObject("result").has("id")); + assertTrue(file + " must use the 26.2 result template codec", json.getAsJsonObject("result").has("id")); assertFalse(file + " still has pre-1.21.11 Forge conditions", json.has("conditions")); assertTrue(file + " has unsupported serializer " + type, "minecraft:crafting_shaped".equals(type) @@ -96,7 +96,7 @@ private static void assertNativeCodecShapes() throws ReflectiveOperationExceptio } for (String obsolete : List.of("{\"item\":\"minecraft:apple\"}", "{\"tag\":\"baseelectric:codec_test_choices\"}")) { - assertTrue("Forge 64 must reject old ingredient objects: " + obsolete, + assertTrue("Forge 65 must reject old ingredient objects: " + obsolete, net.minecraft.world.item.crafting.Ingredient.CODEC.parse(ops, JsonParser.parseString(obsolete)).error().isPresent()); } diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java index 1589dee..6c6bf5b 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java @@ -19,7 +19,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import com.mojang.serialization.JsonOps; -import net.minecraft.advancements.criterion.ItemPredicate; +import net.minecraft.advancements.predicates.ItemPredicate; import net.minecraft.world.item.Items; import org.junit.Test; import static org.junit.Assert.*; diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java index 436fc83..7cb2410 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java @@ -15,7 +15,7 @@ public class ShaderResourceContractTest { String pipeline = Files.readString(PIPELINES); assertTrue(pipeline.contains("RenderPipelines.ENTITY_SNIPPET")); assertTrue(pipeline.contains("withShaderDefine(\"NO_CARDINAL_LIGHTING\")")); - assertTrue(pipeline.contains("withSampler(\"Sampler1\")")); + assertTrue(pipeline.contains("withBindGroupLayout(BindGroupLayouts.SAMPLER1)")); assertTrue(pipeline.contains("withCull(false)")); assertTrue(pipeline.contains("BlendFunction.TRANSLUCENT")); assertFalse(pipeline.contains("ShaderInstance")); @@ -29,7 +29,7 @@ public class ShaderResourceContractTest { assertFalse(vertex.contains("IViewRotMat")); for (String renderer : Arrays.asList("HydroturbineRenderer", "LaserDrillRenderer", "LaserTurretRenderer")) { String source = Files.readString(PIPELINES.resolveSibling(renderer + ".java")); - assertFalse("Forge 64 warns about mod-owned class annotations: " + renderer, source.contains("@OnlyIn")); + assertFalse("Forge 65 warns about mod-owned class annotations: " + renderer, source.contains("@OnlyIn")); } String registration = Files.readString(PIPELINES.resolveSibling("ClientRegistration.java")); assertTrue(registration.contains("value = Dist.CLIENT")); diff --git a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java index 928bddf..3ee723b 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java +++ b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java @@ -234,7 +234,7 @@ public static void main(String[] args) throws Exception { } private static void initializeNativeModList(ModFile mod) throws ReflectiveOperationException { - // Forge 64 freezes discovery before ModList's static initialization. No mod code runs in this child. + // Forge 65 freezes discovery before ModList's static initialization. No mod code runs in this child. Class stateType = Class.forName("net.minecraftforge.fml.loading.ModSorter$State"); var constructor = stateType.getDeclaredConstructor(List.class, List.class); constructor.setAccessible(true); diff --git a/tools/verification/AuditedJUnit.java b/tools/verification/AuditedJUnit.java index 42511ed..4dd922c 100644 --- a/tools/verification/AuditedJUnit.java +++ b/tools/verification/AuditedJUnit.java @@ -30,7 +30,7 @@ public static void main(String[] args) throws Exception { XMLStreamWriter xml = XMLOutputFactory.newFactory().createXMLStreamWriter(output, "UTF-8"); xml.writeStartDocument("UTF-8", "1.0"); xml.writeStartElement("testsuite"); - xml.writeAttribute("name", "baseElectric-26.1.2-ECJ"); + xml.writeAttribute("name", "baseElectric-26.2-ECJ"); xml.writeAttribute("tests", Integer.toString(result.getRunCount())); xml.writeAttribute("failures", Integer.toString(result.getFailureCount())); xml.writeAttribute("ignored", Integer.toString(result.getIgnoreCount())); diff --git a/tools/verification/Invoke-ElectricPackagedSmoke.ps1 b/tools/verification/Invoke-ElectricPackagedSmoke.ps1 index f15f3d7..c0f62cf 100644 --- a/tools/verification/Invoke-ElectricPackagedSmoke.ps1 +++ b/tools/verification/Invoke-ElectricPackagedSmoke.ps1 @@ -30,7 +30,7 @@ $target = "$($pins.minecraft_version)-$($pins.forge_version)" $forgeDir = "libraries/net/minecraftforge/forge/$target" $winArgs = "$forgeDir/win_args.txt" $receipt = [ordered]@{ - status = 'FAIL'; scope = 'Packaged Forge 26.1.2 dedicated server and legacy inventory probe; no client or whole-world upgrade proof' + status = 'FAIL'; scope = 'Packaged Forge 26.2 dedicated server and legacy inventory probe; no client or whole-world upgrade proof' baseMetalsIncluded = !$WithoutBaseMetals seed = $seed; java = $javaPath; inputs = @(); checks = [ordered]@{}; exitCode = $null; error = $null } @@ -63,8 +63,8 @@ function Send-Command([string]$Command) { } try { - if ($target -cne '26.1.2-64.1.5' -or $pins.mod_version -cne '2.2.17.2601021') { - throw 'This smoke runner is bound to baseElectric 2.2.17.2601021 on Forge 64.1.5.' + if ($target -cne '26.2-65.1.0' -or $pins.mod_version -cne '2.2.18.2602001') { + throw 'This smoke runner is bound to baseElectric 2.2.18.2602001 on Forge 65.1.0.' } if ($pins.poweradvantage_pin_state -notin @('LOCAL_SOURCE', 'MERGED_SOURCE') -or $PowerSha256 -ne $pins.poweradvantage_runtime_sha256) { throw 'Packaged smoke requires the exact source-pinned basePower player JAR.' @@ -78,16 +78,16 @@ try { $receipt.javaSha256 = (Get-FileHash -LiteralPath $javaPath).Hash $argsText = Get-Content -LiteralPath (Join-Path $seed $winArgs) -Raw $shim = "forge-$target-shim.jar" - if (!$argsText.Contains("-jar $shim")) { throw 'Unexpected Forge 64 server argument file.' } + if (!$argsText.Contains("-jar $shim")) { throw 'Unexpected Forge 65 server argument file.' } $receipt.shimSha256 = (Get-FileHash -LiteralPath (Join-Path $seed $shim)).Hash - if ($receipt.shimSha256 -cne $pins.forge_shim_sha256) { throw 'Forge shim differs from the recorded 64.1.5 runtime pin.' } + if ($receipt.shimSha256 -cne $pins.forge_shim_sha256) { throw 'Forge shim differs from the recorded 65.1.0 runtime pin.' } $receipt.seedArgumentsSha256 = (Get-FileHash -LiteralPath (Join-Path $seed $winArgs)).Hash $forgeUniversal = Join-Path $seed "$forgeDir/forge-$target-universal.jar" $receipt.forgeUniversalSha256 = (Get-FileHash -LiteralPath $forgeUniversal).Hash - if ($receipt.forgeUniversalSha256 -cne $pins.forge_universal_sha256) { throw 'Forge universal differs from the recorded 64.1.5 runtime pin.' } + if ($receipt.forgeUniversalSha256 -cne $pins.forge_universal_sha256) { throw 'Forge universal differs from the recorded 65.1.0 runtime pin.' } $forgeServer = Join-Path $seed "$forgeDir/forge-$target-server.jar" $receipt.forgeServerSha256 = (Get-FileHash -LiteralPath $forgeServer).Hash - if ($receipt.forgeServerSha256 -cne $pins.forge_server_sha256) { throw 'Forge server differs from the recorded 64.1.5 runtime pin.' } + if ($receipt.forgeServerSha256 -cne $pins.forge_server_sha256) { throw 'Forge server differs from the recorded 65.1.0 runtime pin.' } if ((Get-Content -LiteralPath $EulaFile -Raw) -notmatch '(?m)^eula=true\s*$') { throw 'Pass the existing accepted EULA from the local smoke fixture.' } diff --git a/tools/verification/Verify-ElectricEcj.ps1 b/tools/verification/Verify-ElectricEcj.ps1 index e6e5a21..b83f3c3 100644 --- a/tools/verification/Verify-ElectricEcj.ps1 +++ b/tools/verification/Verify-ElectricEcj.ps1 @@ -67,16 +67,16 @@ function Invoke-Ecj([string]$Name, [string[]]$Sources, [string[]]$Libraries) { } $report = [ordered]@{ status = 'RUNNING'; project = $ProjectRoot; evidence = $Evidence - scope = 'Pinned local baseElectric 26.1.2 candidate; fresh ECJ main/test/helper outputs and worldless Java 25 JUnit; no Gradle or Minecraft launch' + scope = 'Pinned local baseElectric 26.2 candidate; fresh ECJ main/test/helper outputs and worldless Java 25 JUnit; no Gradle or Minecraft launch' compiler = $null; toolchains = $null; libraries = @(); sources = @(); gradleInventory = @() compilations = [ordered]@{}; junit = $null; negativeControl = $null; apiPinState = $null } try { $properties = ConvertFrom-StringData -StringData (Get-Content -LiteralPath (Join-Path $ProjectRoot 'gradle.properties') -Raw) $report.apiPinState = $properties.poweradvantage_pin_state - if ($properties.mod_id -ne 'baseelectric' -or $properties.mod_version -ne '2.2.17.2601021' -or - $properties.minecraft_version -ne '26.1.2' -or $properties.forge_version -ne '64.1.5' -or - $properties.poweradvantage_version -ne '2.4.16.2601021' -or $properties.basemetals_version -ne '3.1.2.2601021' -or - $properties.orespawn_version -ne '4.1.1.2601021' -or + if ($properties.mod_id -ne 'baseelectric' -or $properties.mod_version -ne '2.2.18.2602001' -or + $properties.minecraft_version -ne '26.2' -or $properties.forge_version -ne '65.1.0' -or + $properties.poweradvantage_version -ne '2.4.17.2602001' -or $properties.basemetals_version -ne '3.1.2.2602001' -or + $properties.orespawn_version -ne '4.1.1.2602001' -or $properties.poweradvantage_pin_state -notin @('LOCAL_SOURCE', 'MERGED_SOURCE') -or $properties.poweradvantage_source_ref -cnotmatch '^[a-f0-9]{40}$' -or $properties.poweradvantage_runtime_sha256 -cnotmatch '^[A-F0-9]{64}$' -or @@ -84,7 +84,7 @@ try { $properties.poweradvantage_deobf_sha256 -cnotmatch '^[A-F0-9]{64}$' -or $properties.basemetals_deobf_sha256 -cnotmatch '^[A-F0-9]{64}$' -or $properties.orespawn_deobf_sha256 -cnotmatch '^[A-F0-9]{64}$') { - throw 'This verifier requires the source-pinned baseElectric 26.1.2 inputs' + throw 'This verifier requires the source-pinned baseElectric 26.2 inputs' } $report.compiler = Get-Pin $Compiler if ($report.compiler.sha256 -ne 'D0D43F8E2D7003E5EFED612E2CBB5F01870043397D8F1BBE536FD9128F4FCBF7') { throw 'ECJ compiler pin mismatch' } @@ -151,10 +151,11 @@ try { } $report.gradleInventory += Get-Pin $xml.FullName } - if ($classes.Count -ne 33 -or $expected -ne 117 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 87) { throw 'Unexpected Electric 26.1.2 source/test inventory' } + if ($classes.Count -ne 33 -or $expected -ne 117 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 87) { throw 'Unexpected Electric 26.2 source/test inventory' } $support = @(Get-ChildItem -LiteralPath (Join-Path $ProjectRoot 'build/generated-unit-support') -Recurse -File -Filter '*.java' | Sort-Object Name) - if ($support.Count -ne 2) { throw 'Expected exactly the two pinned native unit support sources' } - $supportPins = @{ 'ForgeUnitRegistries.java' = $properties.unit_registries_java_sha256; 'Forge64UnitLoader.java' = $properties.unit_loader_java_sha256 } + if ($support.Count -ne 3) { throw 'Expected exactly the three pinned native unit support sources' } + $supportPins = @{ 'ForgeUnitRegistries.java' = $properties.unit_registries_java_sha256; 'Forge64UnitLoader.java' = $properties.unit_loader_java_sha256; + 'NativeEmptyEntityTracker.java' = $properties.unit_entity_tracker_java_sha256 } foreach ($source in $support) { $pin = Get-Pin $source.FullName if (!$supportPins.ContainsKey($source.Name) -or $pin.sha256 -cne $supportPins[$source.Name]) { throw 'Pinned unit support source mismatch' } diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index c5b407a..4b1fbe7 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -35,26 +35,26 @@ function check(name, run) { catch (error) { checks.push({name, pass: false, error: error.message}); } } -check('Exact Forge 64 and local port identity', () => { +check('Exact Forge 65 and local port identity', () => { const props = Object.fromEntries(read('gradle.properties').toString().split(/\r?\n/) .filter(line => /^[a-z][a-z_\d]*=/.test(line)).map(line => line.split(/=(.*)/s).slice(0, 2))); for (const [key, value] of Object.entries({ - minecraft_version: '26.1.2', forge_version: '64.1.5', mapping_channel: 'official', - mapping_version: '26.1.2', mcp_version: '20260409.101008', java_version: '25', - mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.17.2601021', - poweradvantage_version: '2.4.16.2601021', basemetals_version: '3.1.2.2601021', - orespawn_source_commit: '101fd12b598934c353e417c57edc5c2bbefd5f53', - orespawn_deobf_sha256: '810284ECB32D5249381F246498CEFA57E70FFF7CCC40110F799FC276CBC42BF7', - orespawn_version: '4.1.1.2601021', curseforge_project_id: '1783006', + minecraft_version: '26.2', forge_version: '65.1.0', mapping_channel: 'official', + mapping_version: '26.2', mcp_version: '20260616.103818', java_version: '25', + mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.18.2602001', + poweradvantage_version: '2.4.17.2602001', basemetals_version: '3.1.2.2602001', + orespawn_source_commit: 'dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c', + orespawn_deobf_sha256: 'BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F', + orespawn_version: '4.1.1.2602001', curseforge_project_id: '1783006', cf_requirements: 'basepower,base-metals' })) assert.equal(props[key], value, key); assert.equal(props.reobf, 'false'); assert.deepEqual(json('src/main/resources/pack.mcmeta').pack, - {min_format:[101,1], max_format:[101,1], description:'baseElectric'}); + {min_format:[107,1], max_format:[107,1], description:'baseElectric'}); const mods = read('src/main/resources/META-INF/mods.toml').toString(); assert.match(mods, /^showAsResourcePack=false$/m); - assert.match(mods, /modId="basepower"\s+mandatory=true\s+versionRange="\[2\.4\.16\.2601021,3\.0\.0\)"/); - assert.match(mods, /modId="basemetals"\s+mandatory=true\s+versionRange="\[3\.1\.2\.2601021,4\.0\.0\)"/); + assert.match(mods, /modId="basepower"\s+mandatory=true\s+versionRange="\[2\.4\.17\.2602001,3\.0\.0\)"/); + assert.match(mods, /modId="basemetals"\s+mandatory=true\s+versionRange="\[3\.1\.2\.2602001,4\.0\.0\)"/); const build = read('build.gradle').toString(); assert.match(build, /inputs\.files\(javadocTool\.map/); assert.match(build, /legal\/java\.base/); From a34f6bba1ec87f911da65ec2b50eab89629f2ea8 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Thu, 12 Nov 2026 17:51:16 +0000 Subject: [PATCH 2/3] Record the 26.2 combined checks and remaining root gate --- CHANGELOG.txt | 4 +++- README.md | 18 ++++++++++++++---- docs/NATIVE262.md | 46 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 704b9cc..f8a8b73 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,7 +2,9 @@ baseElectric 2.2.18.2602001 - local candidate - Target Minecraft 26.2 and Forge 65 with Java 25. - Keep the shared Base Metals migration hook and existing machine, item and saved-data identities. -- Retain exact dependency, native pack, artifact and classpath guards while the new candidate is qualified. +- Retain exact dependency, native pack, artifact and classpath guards. +- Pass the combined profile03 machine, migration, actor/order, client and two-world endurance checks, including independent 66-checkpoint replay. +- Prepare for manual testing once the final root cold-cache gate is confirmed; manual acceptance and publication remain pending. baseElectric 2.2.17.2601021 (Minecraft 26.1.2 / Forge) diff --git a/README.md b/README.md index 23c04de..3f1895c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # baseElectric -**Minecraft 26.2 Forge, version 2.2.18.2602001. Local build candidate.** +**Minecraft 26.2 Forge, version 2.2.18.2602001. Combined checks passed; final root build pending.** baseElectric continues DrCyano's Electric Advantage and uses basePower's shared API, machines and creative tab. Existing `baseelectric` registry and saved-data @@ -46,9 +46,19 @@ node tools/verify-native-port.js node tools/generate-recipe-unlocks.js --check ``` -See [26.2 port status](docs/NATIVE262.md). The accepted 26.1.2 family -qualification remains historical proof of those original bytes, not this port. -There is no 26.2 manual acceptance, hosted qualification or publication yet. +## Qualification + +Combined profile03 passed the machine, migration, actor/dimension, actual +transformer-order and real-client checks, plus two 30-minute worlds, restart +and independent 66-checkpoint replay. See [26.2 port status](docs/NATIVE262.md) +for the counts and exact inputs. The [family qualification record](../../PowerAdvantage/docs/26.2/QUALIFICATION.md) +is being finalized in the sibling Power checkout. + +Ready for manual testing once the final root cold-cache gate is confirmed. +Overall sign-off and user manual acceptance are not claimed here. Base Metals +and OreSpawn are unpublished local 26.2 inputs; these changes remain local, +with no 26.2 push or publication. The accepted 26.1.2 records remain historical +proof of their original bytes, not qualification of this port. ## Candidate09 Verification History diff --git a/docs/NATIVE262.md b/docs/NATIVE262.md index 06f83ec..2baf344 100644 --- a/docs/NATIVE262.md +++ b/docs/NATIVE262.md @@ -1,11 +1,15 @@ -# Minecraft 26.2 local build candidate +# Minecraft 26.2 combined checks passed Version 2.2.18.2602001 targets Forge65.1.0, MCP20260616.103818, Java25 and -native pack formats107.1/88.0. This candidate is local-only. Child build gates -do not establish combined-family runtime qualification or manual acceptance. +native pack formats107.1/88.0. This candidate is local-only. The combined +checks below passed; the final root cold-cache gate is still pending. +Ready for manual testing once that gate is confirmed. Overall sign-off, +manual acceptance and publication are not claimed. ## Exact inputs +- Electric player/development SHA-256: + A7D12A66CA91A6BACCFEFD2CED9D3EC962F5FEB73BF632E1683F99084384F938. - Power source f84b2362449e39eff5e76696dd64ce4cb144da4f; player/development 7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1. - Base Metals source 523335a59ecff399e40a7c66eb121a3aabdc45ba; player/development @@ -24,6 +28,10 @@ do not establish combined-family runtime qualification or manual acceptance. compilation and Eclipse production-classpath isolation. - Fresh ECJ main/test/GameTest compilation and the same complete unit inventory, including strict inventory-rejection controls. +- Committed-source offline and fresh unseeded-cache builds with paths containing + spaces reproduce all three release archives. The cold build executes 52 tasks, + including the 28 native tests; both regenerated Forge SDK jars also match. + No rebuild was needed for the later docs-only ancestry merges. - All 50 recipe-unlock checks. Static source audits remain separate from runtime proof. - Native entity bind-group layout and vertex sinks preserve the existing renderer geometry, UV, lightmap, overlay and pose checks. A deferred collector check @@ -33,13 +41,31 @@ do not establish combined-family runtime qualification or manual acceptance. - Failed setup, compiler and test attempts are preserved separately. The provisional old-Power/public-OreSpawn runs are not relabelled as this candidate. -## Remaining qualification +## Passed combined checks -Independent archive reproductions and fresh-cache/offline gates remain pending. -Packaged combined-family gameplay, machine/migration/actor/dimension/order, -retained-generation and GPU/client campaigns are parent-owned and are not -claimed here. Manual acceptance is also pending. Historical 26.1.2 evidence -remains bound to its original source, profile and artifact bytes. +These results use frozen profile03, SHA-256 +A98D4F9B54A0AE47392D9A3CF81335F5E228F718C7D322DF9838A94AD27D9736, +and basePower's combined-family rig: + +- All eight machine campaigns, including moving, partial and bridge networks. +- All eight machine migration routes and the additional 26.1.2 route. +- Oil, resource and all three retained-generation routes. +- Nine actor/dimension routes. Six dimension routes retain raw wolf differences + backed by independent native controls; no other semantic difference is waived. +- Both actual transformer orders for machines and actors, with the instrumented + sidecars kept separate from ordinary production qualification. All 39 owned + game JVMs closed; 117 strict closed logs were audited. +- Real client07: 39 GUIs, 351 text checks, 26 tank gauges and 1,247 frames. +- Two genuine worlds ran for 1,800 seconds each, passed restart and passed + independent 66-checkpoint replay. The family verification root's + `endurance-independent-replay-03.json` records `PASS`. + +The [family qualification record](../../../PowerAdvantage/docs/26.2/QUALIFICATION.md) +is being finalized. Its remaining root cold-cache gate must be confirmed before +manual testing. Hydroturbine orientation/spin geometry in a fresh client world +remains an explicit manual gap. Historical records and failed receipts remain +unchanged and bound to their original inputs. Hosted CI still requires merged, public dependency inputs; local candidate -pins do not waive that gate. No 26.2 push, tag, publisher dispatch or upload. +pins do not waive that gate. Base Metals and OreSpawn 26.2 remain unpublished +local inputs. No 26.2 push, tag, publisher dispatch or upload. From 5542135abc15343addfab05bc96af8e93c2c3269 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Fri, 13 Nov 2026 00:25:41 +0000 Subject: [PATCH 3/3] Pin public 26.2 dependencies and qualified unit support --- .github/verify-published-pins.sh | 3 ++ .github/workflows/ci.yml | 6 +-- .github/workflows/codeql-analysis.yml | 6 +-- CHANGELOG.txt | 1 + README.md | 46 ++++++++++--------- gradle.properties | 22 +++++---- .../resources/BuildWorkflowContractTest.java | 8 +++- tools/verify-native-port.js | 11 ++++- 8 files changed, 62 insertions(+), 41 deletions(-) diff --git a/.github/verify-published-pins.sh b/.github/verify-published-pins.sh index b532842..7aa539d 100644 --- a/.github/verify-published-pins.sh +++ b/.github/verify-published-pins.sh @@ -43,8 +43,10 @@ public_jar() { } power_ref="$(value poweradvantage_source_ref)" +unit_support_ref="$(value unit_support_source_ref)" orespawn_ref="$(value orespawn_source_commit)" require_merged basePower "$power_ref" +require_merged basePower "$unit_support_ref" require_merged BaseMetals "$(value basemetals_source_commit)" require_merged OreSpawn "$orespawn_ref" @@ -62,6 +64,7 @@ download 'https://maven.minecraftforge.net/net/minecraftforge/forge/26.2-65.1.0/ "$(value forge_installer_sha256)" "$installer" { printf 'power_ref=%s\n' "$power_ref" + printf 'unit_support_ref=%s\n' "$unit_support_ref" printf 'orespawn_ref=%s\n' "$orespawn_ref" } >> "${GITHUB_OUTPUT:?}" { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4cf99aa..9a0c8de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,11 +34,11 @@ jobs: repository: MinecraftModDevelopmentMods/OreSpawn ref: ${{ steps.public-pins.outputs.orespawn_ref }} path: .ci-dependencies/OreSpawn - - name: Check out released basePower source + - name: Check out qualified basePower unit-support source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/basePower - ref: ${{ steps.public-pins.outputs.power_ref }} + ref: ${{ steps.public-pins.outputs.unit_support_ref }} path: .ci-dependencies/basePower - name: Install Java 25 for all build and runtime roles uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 @@ -56,7 +56,7 @@ jobs: shell: bash env: ORESPAWN_REF: ${{ steps.public-pins.outputs.orespawn_ref }} - POWER_REF: ${{ steps.public-pins.outputs.power_ref }} + POWER_REF: ${{ steps.public-pins.outputs.unit_support_ref }} run: | set -euo pipefail orespawn="$GITHUB_WORKSPACE/.ci-dependencies/OreSpawn" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 10d22ec..e6145f9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -36,11 +36,11 @@ jobs: repository: MinecraftModDevelopmentMods/OreSpawn ref: ${{ steps.public-pins.outputs.orespawn_ref }} path: .ci-dependencies/OreSpawn - - name: Check out released basePower source + - name: Check out qualified basePower unit-support source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/basePower - ref: ${{ steps.public-pins.outputs.power_ref }} + ref: ${{ steps.public-pins.outputs.unit_support_ref }} path: .ci-dependencies/basePower - name: Install Java 25 for all build and runtime roles uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 @@ -58,7 +58,7 @@ jobs: shell: bash env: ORESPAWN_REF: ${{ steps.public-pins.outputs.orespawn_ref }} - POWER_REF: ${{ steps.public-pins.outputs.power_ref }} + POWER_REF: ${{ steps.public-pins.outputs.unit_support_ref }} run: | set -euo pipefail orespawn="$GITHUB_WORKSPACE/.ci-dependencies/OreSpawn" diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e78d7fe..aba38ac 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,6 +5,7 @@ baseElectric 2.2.18.2602001 (Minecraft 26.2 / Forge) - Retain exact dependency, native pack, artifact and classpath guards. - Pass the combined profile03 machine, migration, actor/order, client and two-world endurance checks, including independent 66-checkpoint replay. - Complete the full release, cold-cache and manual checks. Publish after basePower so the expansion uses the released dependency. +- Pin the verified public basePower, Base Metals and OreSpawn releases. baseElectric 2.2.17.2601021 (Minecraft 26.1.2 / Forge) diff --git a/README.md b/README.md index c6063f1..25a9076 100644 --- a/README.md +++ b/README.md @@ -18,20 +18,16 @@ apply to this branch. ## Build -The coordinated local dependency versions are basePower **2.4.17.2602001** -and Base Metals **3.1.2.2602001**. The Base Metals hook source is -`523335a59ecff399e40a7c66eb121a3aabdc45ba`, player SHA-256 -`15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1`. -Base Metals is REQUIRED on both client and server, not an optional integration. -The approved local Power262 handoff is source -`f84b2362449e39eff5e76696dd64ce4cb144da4f`, player SHA-256 -`7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1`. - -OreSpawn **4.1.1.2602001** is the approved local retained-settings repair, -source `dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c`, SHA-256 -`BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F`. -It is not published; the public file-ID pin is deliberately empty. The older -4.1.0 public download is not substituted for these bytes. +The coordinated dependencies are +[basePower **2.4.17.2602001**](https://www.curseforge.com/minecraft/mc-mods/basepower/files/9583433), +[Base Metals **3.1.2.2602001**](https://www.curseforge.com/minecraft/mc-mods/base-metals/files/9583122) +and [OreSpawn **4.1.1.2602001**](https://www.curseforge.com/minecraft/mc-mods/mmd-orespawn/files/9582731). +Base Metals is required on both client and server. These two published +dependency patches match the jars used for the combined tests; older downloads +do not include the same migration and retained-settings repairs. + +All three dependency downloads have been checked against their release builds. +Exact source, download and SHA-256 pins are kept together in `gradle.properties`. The Mavenizer fixture and its source-rule, patch, licence and provenance files are checksum-sealed from the existing OS262 checkout. The established @@ -44,6 +40,12 @@ Use Temurin 25 and clear `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS` and default; explicit `*DeobfJar` and `*RuntimeJar`/`*PlayerJar` flags change paths, not the required bytes. With these exact coordinated inputs: +Unit support keeps its separately qualified Power source revision in +`unit_support_source_ref`. Pass that source directory with `-PpowerUnitSource` +when the sibling Power checkout is newer; the four source hashes remain fixed. +Hosted builds check out this test-only revision separately from the public +Power player pin. + ```text ./gradlew clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums --no-build-cache --no-daemon ./gradlew verifyEclipseProductionClasspath --no-daemon @@ -56,14 +58,14 @@ node tools/generate-recipe-unlocks.js --check Combined profile03 passed the machine, migration, actor/dimension, actual transformer-order and real-client checks, plus two 30-minute worlds, restart and independent 66-checkpoint replay. See [26.2 port status](docs/NATIVE262.md) -for the counts and exact inputs. The [family qualification record](../../PowerAdvantage/docs/26.2/QUALIFICATION.md) -is being finalized in the sibling Power checkout. - -Ready for manual testing once the final root cold-cache gate is confirmed. -Overall sign-off and user manual acceptance are not claimed here. Base Metals -and OreSpawn are unpublished local 26.2 inputs; these changes remain local, -with no 26.2 push or publication. The accepted 26.1.2 records remain historical -proof of their original bytes, not qualification of this port. +for the counts and exact inputs. The [family qualification record](https://github.com/MinecraftModDevelopmentMods/basePower/blob/master-26.2/docs/26.2/QUALIFICATION.md) +keeps the completed checks and their scope limits together. + +The final root build and cold-cache checks passed, and manual testing was +accepted on 12 November 2026. Publication follows the dependency order: +OreSpawn and Base Metals, then basePower and baseSteam, then this expansion. +The accepted 26.1.2 records remain historical proof of their original bytes, +not a substitute for the 26.2 results. ## Candidate09 Verification History diff --git a/gradle.properties b/gradle.properties index e8bab09..db1d75d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,22 +41,24 @@ cf_optionals= cf_versions=26.2 poweradvantage_version=2.4.17.2602001 -poweradvantage_pin_state=LOCAL_SOURCE +poweradvantage_pin_state=MERGED_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Owner-approved local Power262 compile/test handoff; not a public release. -poweradvantage_source_ref=f84b2362449e39eff5e76696dd64ce4cb144da4f -poweradvantage_public_file_id= +# Released basePower, checked against its CurseForge, Maven and GitHub downloads. +poweradvantage_source_ref=98863570ae84c5658a6b8ec2f8878e1f10009192 +poweradvantage_public_file_id=9583433 poweradvantage_deobf_sha256=7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1 poweradvantage_runtime_sha256=7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1 basemetals_version=3.1.2.2602001 basemetals_built_on=26.2-65.1.0 -# Local native shared-hook checkpoint; family qualification is separate. -basemetals_source_commit=523335a59ecff399e40a7c66eb121a3aabdc45ba -basemetals_public_file_id= +# Released shared-hook patch, verified against the qualified player jar. +basemetals_source_commit=a68fe5a74f05ea8dae61bc718e67062f2fc4063b +basemetals_public_file_id=9583122 basemetals_deobf_sha256=15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1 basemetals_runtime_sha256=15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1 +# Qualified test-only source; independent of the released basePower player pin. +unit_support_source_ref=f84b2362449e39eff5e76696dd64ce4cb144da4f unit_bootstrap_sha256=088FC137BEBB9B2E75C596DE868499E6099CF228BECFCF07EAE36791245FD1B6 unit_bootstrap_java_sha256=D4B72FD65D9F8549B142507C6446E3B1E047B637784AF9FA74E8F28413E14A51 unit_registries_java_sha256=01DDE50C9874C2DC501BE2F699CD8D16D6974FACFAAC1B803434CA8C64227ABF @@ -65,8 +67,8 @@ unit_entity_tracker_java_sha256=EB2A83A35F617BC52D322332C824BE83A3BFE4C83CEB0418 orespawn_version=4.1.1.2602001 orespawn_built_on=26.2-65.1.0 -orespawn_source_commit=dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c -# Approved LOCAL source candidate; not CurseForge file 9332183. -orespawn_public_file_id= +orespawn_source_commit=a3973534f51c24ccfb8313541f47204c75d9dbeb +# Released retained-settings patch; the player bytes match qualification. +orespawn_public_file_id=9582731 orespawn_deobf_sha256=BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F orespawn_runtime_sha256=BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java index 5edc206..69057e6 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java @@ -46,7 +46,8 @@ public class BuildWorkflowContractTest { assertTrue(published < source.indexOf("repository: MinecraftModDevelopmentMods/" + repository)); } assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.orespawn_ref }}")); - assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.power_ref }}")); + assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.unit_support_ref }}")); + assertFalse(source.contains("ref: ${{ steps.public-pins.outputs.power_ref }}")); assertTrue(source.contains("branches: [master-26.2")); assertTrue(source.contains("-Pforge64MavenizerJar=$MAVENIZER")); assertTrue(source.contains("-PpowerAdvantageDeobfJar=$POWER_PLAYER")); @@ -61,6 +62,11 @@ public class BuildWorkflowContractTest { assertTrue(script.contains("$(value " + dependency + "_public_file_id)")); } assertTrue(script.contains("sha256sum -c -")); + assertTrue(script.contains("unit_support_ref=\"$(value unit_support_source_ref)\"")); + assertTrue(script.contains("require_merged basePower \"$unit_support_ref\"")); + String properties = Files.readString(Paths.get("gradle.properties")); + assertTrue(properties.contains("unit_support_source_ref=f84b2362449e39eff5e76696dd64ce4cb144da4f")); + assertTrue(properties.contains("unit_entity_tracker_java_sha256=EB2A83A35F617BC52D322332C824BE83A3BFE4C83CEB0418F77687EA93978E6D")); assertTrue(script.contains("$(value poweradvantage_pin_state)")); assertTrue(script.contains("!= 'MERGED_SOURCE'")); assertTrue(script.indexOf("!= 'MERGED_SOURCE'") < script.indexOf("require_merged()")); diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index 4b1fbe7..ae35226 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -35,7 +35,7 @@ function check(name, run) { catch (error) { checks.push({name, pass: false, error: error.message}); } } -check('Exact Forge 65 and local port identity', () => { +check('Exact Forge 65 and public release identity', () => { const props = Object.fromEntries(read('gradle.properties').toString().split(/\r?\n/) .filter(line => /^[a-z][a-z_\d]*=/.test(line)).map(line => line.split(/=(.*)/s).slice(0, 2))); for (const [key, value] of Object.entries({ @@ -43,7 +43,14 @@ check('Exact Forge 65 and local port identity', () => { mapping_version: '26.2', mcp_version: '20260616.103818', java_version: '25', mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.18.2602001', poweradvantage_version: '2.4.17.2602001', basemetals_version: '3.1.2.2602001', - orespawn_source_commit: 'dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c', + poweradvantage_pin_state: 'MERGED_SOURCE', + poweradvantage_source_ref: '98863570ae84c5658a6b8ec2f8878e1f10009192', + poweradvantage_public_file_id: '9583433', + basemetals_source_commit: 'a68fe5a74f05ea8dae61bc718e67062f2fc4063b', + basemetals_public_file_id: '9583122', + orespawn_source_commit: 'a3973534f51c24ccfb8313541f47204c75d9dbeb', + orespawn_public_file_id: '9582731', + unit_support_source_ref: 'f84b2362449e39eff5e76696dd64ce4cb144da4f', orespawn_deobf_sha256: 'BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F', orespawn_version: '4.1.1.2602001', curseforge_project_id: '1783006', cf_requirements: 'basepower,base-metals'