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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
73 changes: 42 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,81 +1,92 @@
name: Power Advantage 1.12 CI
name: Power Advantage 1.13 CI

on:
push:
branches:
- master-1.12.2
- 'feature/**'
branches: [master-1.13.2, 'feature/**']
pull_request:
branches:
- master-1.12.2
branches: [master-1.13.2]

permissions:
contents: read

concurrency:
group: poweradvantage-1.12-${{ github.workflow }}-${{ github.ref }}
group: poweradvantage-1.13-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build, test, and audit
runs-on: ubuntu-latest
timeout-minutes: 60

timeout-minutes: 90
steps:
- name: Check out source
- name: Check out PowerAdvantage
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Check out pinned OreSpawn
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
repository: MinecraftModDevelopmentMods/OreSpawn
ref: 6a7c2bb07b9a7771128812fcc07d185f7d9df58b
path: .ci-dependencies/OreSpawn
- name: Use canonical LF dependency inputs
# Base Metals predates archive text normalization; its LF artifact is separately pinned.
run: git config --global core.autocrlf false
- name: Check out pinned Base Metals
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
repository: MinecraftModDevelopmentMods/BaseMetals
ref: 1376a20d7d5ba22d3abc77dc34b49a2c88943697
path: .ci-dependencies/BaseMetals
- name: Install Java 8 toolchain
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '8.0.502+7'

- name: Install Java 17 for Gradle
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: microsoft
java-version: '17'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6

- name: Make the wrapper executable
run: chmod +x ./gradlew

- name: Stage exact RebornCore compile API
id: reborncore
- name: Build pinned development dependencies
id: dependencies
shell: bash
run: |
mirror="$RUNNER_TEMP/reborncore-mirror"
bash gradle/stage-reborncore-release.sh "$mirror"
echo "repository=$mirror" >> "$GITHUB_OUTPUT"

set -euo pipefail
orespawn="$GITHUB_WORKSPACE/.ci-dependencies/OreSpawn"
basemetals="$GITHUB_WORKSPACE/.ci-dependencies/BaseMetals"
chmod +x "$orespawn/gradlew" "$basemetals/gradlew"
(cd "$orespawn" && ./gradlew jar --no-daemon --stacktrace)
(cd "$basemetals" && ./gradlew jar --no-daemon --stacktrace)
osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.113021-deobf.jar"
bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.113021-deobf.jar"
test -f "$osjar" && test -f "$bmjar"
echo "orespawn=$osjar" >> "$GITHUB_OUTPUT"
echo "basemetals=$bmjar" >> "$GITHUB_OUTPUT"
- name: Build and audit release artifacts
run: >-
./gradlew clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts
writeReleaseChecksums verifyEclipseProductionClasspath
-PrebornCoreVerificationRepository=${{ steps.reborncore.outputs.repository }}
-PbaseMetalsDeobfJar=${{ steps.dependencies.outputs.basemetals }}
-PoreSpawnDeobfJar=${{ steps.dependencies.outputs.orespawn }}
--no-daemon --stacktrace

- name: Upload audited release candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: PowerAdvantage-1.12.2-${{ github.sha }}
name: PowerAdvantage-1.13.2-${{ github.sha }}
if-no-files-found: error
retention-days: 30
path: |
build/libs/PowerAdvantage-2.4.1.112021.jar
build/libs/PowerAdvantage-2.4.1.112021-sources.jar
build/libs/PowerAdvantage-2.4.1.112021-javadoc.jar
build/libs/PowerAdvantage-2.4.4.113021.jar
build/libs/PowerAdvantage-2.4.4.113021-sources.jar
build/libs/PowerAdvantage-2.4.4.113021-javadoc.jar
build/release/SHA256SUMS
CHANGELOG.txt

- name: Upload diagnostics on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: PowerAdvantage-1.12.2-diagnostics-${{ github.sha }}
name: PowerAdvantage-1.13.2-diagnostics-${{ github.sha }}
if-no-files-found: ignore
retention-days: 14
path: |
Expand Down
53 changes: 32 additions & 21 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ name: CodeQL

on:
push:
branches:
- master-1.12.2
- 'feature/**'
branches: [master-1.13.2, 'feature/**']
pull_request:
branches:
- master-1.12.2
branches: [master-1.13.2]
schedule:
- cron: '47 7 * * 4'

Expand All @@ -20,44 +17,58 @@ jobs:
analyze:
name: Analyze Java
runs-on: ubuntu-latest
timeout-minutes: 45

timeout-minutes: 75
steps:
- name: Check out source
- name: Check out PowerAdvantage
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Check out pinned OreSpawn
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
repository: MinecraftModDevelopmentMods/OreSpawn
ref: 6a7c2bb07b9a7771128812fcc07d185f7d9df58b
path: .ci-dependencies/OreSpawn
- name: Use canonical LF dependency inputs
# Base Metals predates archive text normalization; its LF artifact is separately pinned.
run: git config --global core.autocrlf false
- name: Check out pinned Base Metals
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
repository: MinecraftModDevelopmentMods/BaseMetals
ref: 1376a20d7d5ba22d3abc77dc34b49a2c88943697
path: .ci-dependencies/BaseMetals
- name: Install Java 8 toolchain
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '8.0.502+7'

- name: Install Java 17 for Gradle
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: microsoft
java-version: '17'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6

- name: Stage exact RebornCore compile API
id: reborncore
- name: Build pinned development dependencies
id: dependencies
shell: bash
run: |
mirror="$RUNNER_TEMP/reborncore-mirror"
bash gradle/stage-reborncore-release.sh "$mirror"
echo "repository=$mirror" >> "$GITHUB_OUTPUT"

set -euo pipefail
orespawn="$GITHUB_WORKSPACE/.ci-dependencies/OreSpawn"
basemetals="$GITHUB_WORKSPACE/.ci-dependencies/BaseMetals"
chmod +x "$orespawn/gradlew" "$basemetals/gradlew"
(cd "$orespawn" && ./gradlew jar --no-daemon --stacktrace)
(cd "$basemetals" && ./gradlew jar --no-daemon --stacktrace)
echo "orespawn=$orespawn/build/libs-dev/OreSpawn-4.1.0.113021-deobf.jar" >> "$GITHUB_OUTPUT"
echo "basemetals=$basemetals/build/libs-dev/BaseMetals-3.0.1.113021-deobf.jar" >> "$GITHUB_OUTPUT"
- name: Initialize CodeQL
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4
with:
languages: java-kotlin

- name: Compile production code
run: |
chmod +x ./gradlew
./gradlew clean classes --rerun-tasks --no-build-cache --no-daemon --stacktrace \
-PrebornCoreVerificationRepository=${{ steps.reborncore.outputs.repository }}

-PbaseMetalsDeobfJar=${{ steps.dependencies.outputs.basemetals }} \
-PoreSpawnDeobfJar=${{ steps.dependencies.outputs.orespawn }}
- name: Analyze
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4
4 changes: 2 additions & 2 deletions .github/workflows/validate-gradle-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: Validate Gradle Wrapper
on:
push:
branches:
- master-1.12.2
- master-1.13.2
- 'feature/**'
pull_request:
branches:
- master-1.12.2
- master-1.13.2

permissions:
contents: read
Expand Down
38 changes: 35 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
/run/
/run-data/
/run.*
/$run/
/eula.txt
/server.properties
/*.log
/classes/
/logs/
Expand Down Expand Up @@ -52,10 +55,39 @@
/hs_err_pid*.log
/replay_pid*.log

# Local dependency experiments; the RF API is an intentional tracked input.
# Nested Advantage Works outputs
/test-rig/.gradle/
/test-rig/.cache/
/test-rig/build/
/test-rig/migration-probe/.gradle/
/test-rig/migration-probe/build/
/test-rig/migration/.venv/
/test-rig/migration/__pycache__/

# Local dependency artifacts; 1.13 converters use Forge Energy instead.
/libs/*
!/libs/RF-API.jar
!/libs/RF-API.zip
*.jar
*.zip
!/gradle/wrapper/gradle-wrapper.jar

/secret.json
# Nested local tooling and generated output
AGENTS.md
AGENT.md
CLAUDE.md
GEMINI.md
ARCHITECT.md
agent-notes/
.codex/
.agent/
.agents/
.claude/
.gemini/
.cursor/
agent-*.md
codex-*.md
*.log
*.class
__pycache__/
*.pyc
/.DS_Store
13 changes: 13 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Power Advantage 2.4.4.113021

- Port Power Advantage to Minecraft 1.13.2 with ForgeGradle 7 and Java 8 support.
- Keep existing block, item, fluid and saved-state names, the legacy public API and Iron Age Furniture compatibility facades.
- Add direct 1.10 and 1.12 world migration, including inventories, fluids, entities, pets, enchantments and old configuration files. Back up worlds before upgrading.
- Restore conduit connections after reloads without forcing unloaded chunks to load.
- Fix models, translations, oil buckets, fluid gauges and transparent floor edges around containers.
- Add ingredient-based recipe discoveries, separate unrelated recipe-book entries, and allow potatoes to be crafted into starch.
- Restore processing, recycling and parts-loot paths while retaining recipe modes and configured material aliases.
- Use Forge tags, Base Metals crushing and OreSpawn 4 deposits; retain old generation settings and user overrides.
- Keep the RF and Tech Reborn converter names but use Forge Energy instead of obsolete external APIs.
- Add separate Power-only and combined Eclipse launches, reproducible builds and repeatable migration and operating tests. See the qualification notes for remaining coverage gaps.

Power Advantage 2.4.1.112021

- Restore conduit networks and machine GUI state after a world reload.
Expand Down
67 changes: 60 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,74 @@
# PowerAdvantage

Power Advantage provides shared power, fluid, and item transport systems for its Minecraft 1.12.2 expansion mods.
Power Advantage provides shared power, fluid, item transport, and compatibility APIs for its Minecraft 1.13.2 expansion mods.

## Building Minecraft 1.12.2
This port keeps existing registry names and includes migration from 1.10 and 1.12.
Always back up a world before upgrading, and check that its other mods also support the target version.
The [qualification notes](docs/1.13/CURRENT-QUALIFICATION.md) separate tested scenarios from remaining gaps;
they are not a guarantee that an entire modpack can be upgraded without losses.

The `master-1.12.2` build uses ForgeGradle 7.0.34 and Gradle 9.6.1. Run Gradle with Java 17; Gradle resolves the Java 8 toolchain used for compilation.
Recipe-book discovery now follows relevant ingredients. See the [all-Advantage material checklist and automated discovery tests](docs/1.13/RECIPE-DISCOVERY.md). To regenerate the checked-in unlock JSON after changing recipes, run `node tools/generate-recipe-unlocks.js`; `check` rejects missing or stale ingredient criteria.

The [manufacturing progression audit](docs/1.13/MANUFACTURING-PROGRESSION.md) traces survival parts from raw resources, including configured material aliases, processing, loot-only parts and automated restart checks.

## Building Minecraft 1.13.2

The `master-1.13.2` build uses ForgeGradle 7.0.34 and Gradle 9.6.1. Run Gradle with Java 17; Gradle resolves the Java 8 production toolchain.

Build the pinned Base Metals `3.0.1.113021` and OreSpawn `4.1.0.113021` deobf jars in their sibling checkouts, then run:

```text
gradlew.bat clean check build verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums
gradlew.bat clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums verifyEclipseProductionClasspath
```

Release jars are written to `build/libs`. The deobfuscated development jar for sibling mod compilation is written to `build/libs-dev` by `deobfJar` or `build`.
The default dependency paths follow the local MMD checkout layout. Other layouts can pass `-PbaseMetalsDeobfJar=<path>` and `-PoreSpawnDeobfJar=<path>`. Dependencies are present on development classpaths but are never embedded in PowerAdvantage artifacts.

The pinned Base Metals development jar predates archive line-ending normalization.
Both the original Windows-input jar and a clean LF-checkout build have exact
checksums in `gradle.properties`. Their class bytes and archive entries match;
only text line endings differ. CI uses the LF build. Unknown hashes still fail.
Advantage's own archives normalize text to LF.

For Eclipse, import the repository as an existing Gradle project and run:
Release jars are written to `build/libs`; `deobfJar` writes the sibling-development jar to `build/libs-dev`.

For Eclipse, import this repository as an existing Gradle project and run:

```text
gradlew.bat cleanEclipse verifyEclipseProductionClasspath
```

Base Metals and OreSpawn remain required distribution dependencies but are deliberately absent from the compile classpath. Optional RF and RebornCore integrations compile against SHA-256-pinned API inputs and are not bundled or added to normal development launches. CI stages the exact historical RebornCore Maven release because the later CurseForge archive with the same version has different contents.
Refresh the project in Eclipse, allow its Java build to finish, and launch the generated `runClient.launch`. Eclipse launches discover the mod from `bin/main`; command-line Gradle launches use `build/forge-run-mod-classes/main`. The Eclipse audit checks that discovery points at the same production output Eclipse compiles into, preventing a client that starts without PowerAdvantage.

Eclipse copies production resources from `build/resources/main`, not directly from `src/main/resources`. This prevents its builder from overwriting the expanded `mods.toml` with raw `${version}` placeholders. After updating this setup, use **Gradle > Refresh Gradle Project**, then **Project > Clean** before relaunching. After editing resources or version properties, run `processResources` or refresh the Gradle project before the Eclipse build. See the [metadata regression notes](docs/1.13/ECLIPSE-METADATA.md).

To test all three Advantage mods together, run `gradlew.bat prepareCombinedEclipseLaunch`, refresh Eclipse, and launch `runClientAllAdvantage.launch`. This additional profile loads the pinned Steam/Electric deobf jars, Base Metals and OreSpawn alongside Power's Eclipse output. It uses the same `run` directory and test saves; it does not copy, open or modify a save automatically. The ordinary `runClient.launch` remains Power-only. Alternative checkout layouts can pass `-PsteamAdvantageDeobfJar=<path>` and `-PelectricAdvantageDeobfJar=<path>`; supplied jars must match the `test-rig/profiles/dev-core.json` pins. Regenerate the combined launch after refreshing its dependencies or the base launch.

The combined [client resource probe](test-rig/client-resources/README.md), with `-RequireExtensions`, checks item names, baked models, textures and every valid block state across all three Advantage mods. The legacy Steam/Electric model-path and selector failures are repaired; [the qualification notes](docs/1.13/OIL-TRANSFER.md#combined-resource-repair-21-october-2026) retain the failing evidence and subsequent full-scope result. Native resource checks remain separate from manual graphical/gameplay acceptance.

The [client resource probe](test-rig/client-resources/README.md) checks native baked models, textures, creative entries, and translated item names without opening a world. Static resource and locale regressions also run under `check`.

## Compatibility

The implementation namespace is `zone.moddev.mc.poweradvantage`. The historical `cyano.poweradvantage.api` surface, including `FluidNetworkApi`, remains available to dependent mods. Registry names, fluids, tile IDs, NBT keys, OreSpawn provider IDs, and configuration meaning remain stable.

PowerAdvantage owns the shared pre-flattening migration hook used by all three Advantage mods. See [the 1.13 migration guide](docs/1.13/MIGRATION.md) before opening an irreplaceable 1.10 or 1.12 world. The [Advantage Works rig](test-rig/README.md) provides repeatable machine, restart, world-generation, and migration checks.

The [endurance protocol](docs/1.13/ENDURANCE.md) exercises repeat-batch operation in fresh and migrated disposable worlds, followed by a complete server-process restart. Its coverage limits are separate from frozen-state migration and manual client acceptance.

The [chunk and moving-drill protocol](docs/1.13/CHUNK-AND-DRILLS.md) adds genuine chunk unload/reload witnesses, finite-energy track moves in all six facings, rear-output conservation, and mid-block progress checks.

The [partial-network and extended-drill protocol](docs/1.13/PARTIAL-NETWORKS-AND-EXTENDED-DRILLS.md) separates endpoint unloading/recovery from whole-network reloads, and covers repeated moves, vertical track travel, junctions, blocked output and redstone interruption.

The [player and entity migration report](docs/1.13/PLAYER-AND-ENTITY-MIGRATION.md) covers player files, inventories, nested items, ownership, saved entities and full restarts. The eight tested routes pass with the repaired 1.12 bridge. Use Electric Advantage `2.2.3.112021` for the current turbine and drill fixes; the original `2.2.1.112021` jar remains a failing historical control.

The [additional-dimension protocol](docs/1.13/DIMENSIONS-AND-ENTITY-LIFECYCLE.md)
covers Nether/End player and entity fixtures, native passenger/leash relationships
and separate death/respawn controls. The [transformer-order report](docs/1.13/TRANSFORMER-ORDERING.md)
qualifies both BaseMetals/Advantage application orders and records the
order-dependent provenance of loose-file backups.

Networks use loaded chunks only. Missing conduit sections interrupt distribution;
normal chunk loading reconnects them without replacing pipes. The same protocol
records acquisition-stack diagnostics and pipe-only bridge regressions.

The historical 1.10 handbook remains on the [1.10.2 branch](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.10.2/docs/1.10/README.md).
Loading
Loading