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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,19 @@ jobs:
--no-daemon --stacktrace
first="$RUNNER_TEMP/basemetals-first"
mkdir -p "$first"
cp build/libs/BaseMetals-3.1.1.120061.jar "$first/"
cp build/libs/BaseMetals-3.1.1.120061-sources.jar "$first/"
cp build/libs/BaseMetals-3.1.1.120061-javadoc.jar "$first/"
cp build/libs/BaseMetals-3.1.2.120061.jar "$first/"
cp build/libs/BaseMetals-3.1.2.120061-sources.jar "$first/"
cp build/libs/BaseMetals-3.1.2.120061-javadoc.jar "$first/"
cp build/release/SHA256SUMS "$first/"

- name: Rebuild and prove byte-identical archives
run: |
./gradlew clean assemble verifyReleaseArtifacts writeReleaseChecksums \
-PorespawnVerificationRepository="${{ steps.orespawn.outputs.repository }}" \
--no-daemon --stacktrace
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.1.120061.jar" build/libs/BaseMetals-3.1.1.120061.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.1.120061-sources.jar" build/libs/BaseMetals-3.1.1.120061-sources.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.1.120061-javadoc.jar" build/libs/BaseMetals-3.1.1.120061-javadoc.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.2.120061.jar" build/libs/BaseMetals-3.1.2.120061.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.2.120061-sources.jar" build/libs/BaseMetals-3.1.2.120061-sources.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.2.120061-javadoc.jar" build/libs/BaseMetals-3.1.2.120061-javadoc.jar
cmp "$RUNNER_TEMP/basemetals-first/SHA256SUMS" build/release/SHA256SUMS

- name: Run all required GameTests
Expand Down Expand Up @@ -146,9 +146,9 @@ jobs:
if-no-files-found: error
retention-days: 30
path: |
build/libs/BaseMetals-3.1.1.120061.jar
build/libs/BaseMetals-3.1.1.120061-sources.jar
build/libs/BaseMetals-3.1.1.120061-javadoc.jar
build/libs/BaseMetals-3.1.2.120061.jar
build/libs/BaseMetals-3.1.2.120061-sources.jar
build/libs/BaseMetals-3.1.2.120061-javadoc.jar
build/release/SHA256SUMS
CHANGELOG.txt

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Base Metals 3.1.2.120061

- Let companion mods preserve their own item and block data during legacy world upgrades.
- Preserve custom names and enchantments on old player items before Minecraft converts them to components.

Base Metals 3.1.1.120061

- Fix startup failures when Base Metals is added to an existing modern world, including worlds with LZ4-compressed chunks, external chunks or empty region files.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ shields, bows, crossbows, arrows, and bolts. The mod also includes Crack
Hammers, scythes, metal anvils, the human detector, villager trades,
advancements, and structure loot.

This is the Minecraft 1.20.6 Forge version, `3.1.1.120061`. It keeps the
This is the Minecraft 1.20.6 Forge version, `3.1.2.120061`. It keeps the
fixes and features from the released 1.20.1 version, including raw metals, ore texture
overlays and High/Low Fantasy modes. Existing Base Metals items and blocks keep
their registry IDs. OreSpawn handles ore generation; MMDLib and Additional Loot
Expand All @@ -26,7 +26,7 @@ Tables are no longer needed.
- OreSpawn `[4.1.0.120061,5.0.0)` on both client and server

This version uses OreSpawn `4.1.0.120061`. Put
`BaseMetals-3.1.1.120061.jar` and a compatible OreSpawn JAR in the `mods`
`BaseMetals-3.1.2.120061.jar` and a compatible OreSpawn JAR in the `mods`
directory. MMDLib and Additional Loot Tables must not be carried forward from
an older installation. Mineralogy is optional.

Expand Down Expand Up @@ -189,7 +189,7 @@ artifacts. GameTests, smoke probes, migration fixtures, and reference sources
are isolated from the published JAR.

Release artifacts use Maven coordinate
`zone.moddev.mc.basemetals:BaseMetals:3.1.1.120061`.
`zone.moddev.mc.basemetals:BaseMetals:3.1.2.120061`.

Report defects and compatibility problems through the
[Base Metals issue tracker](https://github.com/MinecraftModDevelopmentMods/BaseMetals/issues).
Expand Down
22 changes: 19 additions & 3 deletions docs/MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ summary or that no legacy content was present; subsequent starts do nothing.

The packaged fallback map covers the exact public 1.12 runtime. With a saved
legacy registry map, blocks from the world's other 1.10/1.12 mods also retain
their registry name and original block-entity data, although block states
without a Base Metals-owned metadata decoder fall back to that mod's default
state. Base Metals and historical `mmdlib:*` states retain their old metadata
their registry name and original block-entity data. Without a Base Metals or
companion metadata decoder, those blocks use the registered default state.
Base Metals and historical `mmdlib:*` states retain their old metadata
semantics, including complete paired-door state. If neither legacy level file
contains an ID used by a numeric chunk, migration stops instead of guessing or
deleting it. Restore the backed-up regions and recover the world's original
Expand Down Expand Up @@ -58,6 +58,22 @@ upgrade start. Missing mappings also forward:
- historical `mmdlib:*` Vanilla Bits blocks, items, and fluids to matching
`basemetals:*` IDs.

### Companion mods

Register a `Legacy112MigrationExtension` with a unique ID during common setup.
The extension runs only for a legacy Base Metals world that has not completed
pre-flattening. It can prepare legacy chunks and player NBT and decode raw
four-bit block metadata for its own blocks. It does not replace Base Metals'
decoders. Multiple claims for a block or a decoded air state stop conversion.

Keep stacks in vanilla-recognized inventories in legacy `Count` and `tag`
format during preparation. Minecraft's data fixer converts them to `count` and
`components` on load. The embedded player callback receives the prepared
legacy snapshot and the current componentized result. Detached playerdata runs
only the prepare callback; vanilla loads and fixes that file later. Vanilla
does not fix arbitrary item stacks inside opaque mod block-entity or player
data; the companion mod owns those formats.

## Moving from 1.13 through 1.19

These worlds already use named block states, so they do not need the numeric
Expand Down
4 changes: 2 additions & 2 deletions docs/VERSIONS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Supported versions

Base Metals `3.1.1.120061` targets Minecraft 1.20.6, Forge 50.2.0 and Java 21.
Base Metals `3.1.2.120061` targets Minecraft 1.20.6, Forge 50.2.0 and Java 21.
OreSpawn `4.1.0.120061` is the exact build and test dependency. Clients and
servers need OreSpawn `[4.1.0.120061,5.0.0)`.

Expand All @@ -10,7 +10,7 @@ Its SHA-256 is
`FAA7107B9FB84E2C62ED847CAFD880AA3C4238A37799BAD955EA9602A944AA26`.

Release artifacts use Maven coordinate
`zone.moddev.mc.basemetals:BaseMetals:3.1.1.120061`.
`zone.moddev.mc.basemetals:BaseMetals:3.1.2.120061`.

The provider remains schema 3, revision 1. OreSpawn 4.1 is needed for the
configuration-screen API; the provider's eleven rule IDs and 1.18 distributions
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ mod_name=Base Metals
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=LGPL-2.1
# The mod version. See https://semver.org/
mod_version=3.1.1.120061
mod_version=3.1.2.120061
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
Expand Down
2 changes: 1 addition & 1 deletion gradle/ide/eclipse.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def verifyEclipseProductionClasspath = tasks.register('verifyEclipseProductionCl
}
}
String metadata = new File(projectDir, 'bin/main/META-INF/mods.toml').getText('UTF-8')
if (metadata.contains('${') || !metadata.contains('version="3.1.1.120061"')) {
if (metadata.contains('${') || !metadata.contains('version="3.1.2.120061"')) {
throw new GradleException('Eclipse output contains unresolved or invalid Base Metals version metadata')
}
}
Expand Down
4 changes: 2 additions & 2 deletions gradle/release/artifacts.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ tasks.register('verifyReleaseConfiguration') {
dependsOn tasks.named('verifyMavenizerCompatibilityFixture')
dependsOn tasks.named('verifyJava21Toolchain')
doLast {
if (configuredReleaseIdentity.modVersion != '3.1.1.120061'
if (configuredReleaseIdentity.modVersion != '3.1.2.120061'
|| configuredReleaseIdentity.modGroup != expectedMavenGroup
|| configuredReleaseIdentity.minecraftVersion != '1.20.6'
|| configuredReleaseIdentity.forgeVersion != '50.2.0'
Expand Down Expand Up @@ -320,7 +320,7 @@ tasks.register('verifyReleaseArtifacts') {
}
String modsToml = zip.getInputStream(zip.getEntry('META-INF/mods.toml')).getText('UTF-8')
if (modsToml.contains('${')
|| !modsToml.contains('version="3.1.1.120061"')
|| !modsToml.contains('version="3.1.2.120061"')
|| !modsToml.contains('versionRange="[4.1.0.120061,5.0.0)"')) {
throw new GradleException('Release mods.toml contains unresolved or incompatible metadata')
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/verification/packaged-runtime.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def packagedServerStartupSmoke = tasks.register('packagedServerStartupSmoke', Ex
if (!marker.isFile()) throw new GradleException('Packaged dedicated-server completion marker is missing')
Properties values = new Properties()
marker.withInputStream { values.load(it) }
if (values.getProperty('basemetals') != '3.1.1.120061'
if (values.getProperty('basemetals') != '3.1.2.120061'
|| values.getProperty('orespawn') != '4.1.0.120061'
|| values.getProperty('forge') != '50.2.0') {
throw new GradleException("Packaged dedicated-server versions are wrong: ${values}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package zone.moddev.mc.basemetals.api.migration;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.BlockState;
import zone.moddev.mc.basemetals.migration.Legacy112WorldMigrator;

/**
* Lets a companion mod preserve its data when Base Metals pre-flattens a
* Minecraft 1.10 or 1.12 world. Register during common setup, before worlds load.
*/
public interface Legacy112MigrationExtension {
enum Payload { CHUNK, PLAYER }

/**
* Updates a legacy chunk or player payload in place, before vanilla's data
* fixer or the migrator's block entity snapshot. Leave stacks that vanilla
* recognizes in the legacy item format so its fixer can componentize them.
* Return true on mutation.
*/
default boolean prepareData(CompoundTag tag, int dataVersion, Payload payload) { return false; }

/** Runs immediately before the intermediate chunk data fix, only for chunks being converted. */
default void beforeChunkFlattening(CompoundTag chunk) { }

/**
* Checks or restores extension data after vanilla flattens the embedded
* single-player record to the 1.20.1 schema (data version 3465). The prepared
* source is a read-only legacy snapshot; the mutable result still stores
* items as {@code Count} and {@code tag}. Base Metals runs the remaining native data fixes,
* including item component conversion, after all callbacks return. Vanilla
* does not componentize arbitrary stacks inside opaque mod payloads.
*/
default void afterPlayerFlattening(CompoundTag preparedSource, CompoundTag result) { }

/**
* Returns the native state for an owned legacy block, or null for an ID
* this extension does not own. Metadata is the original four-bit value.
*/
default BlockState decodeBlockState(ResourceLocation legacyId, int metadata) { return null; }

/** The ID identifies the registering extension and must be unique. */
static void register(ResourceLocation id, Legacy112MigrationExtension extension) {
Legacy112WorldMigrator.registerExtension(id, extension);
}
}
Loading
Loading