From 0f14222d5a1ccb4be6eca52b20524ede04b7a6c1 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 20:30:15 +0200 Subject: [PATCH 01/11] Add Overview Comments and start Block Datafixer Documentation --- .../McRegionToStationFlatteningChunkFix.java | 32 ++++++++++++------- .../schema/McRegionSchemaB1_7_3.java | 3 ++ .../datafixer/VanillaDataFixerImpl.java | 3 ++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java index 9600999e7..519e47f3a 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java @@ -24,6 +24,11 @@ import static net.modificationstation.stationapi.impl.world.FlattenedWorldManager.SECTIONS; +/** + * Datafixer used for converting McRegion worlds (Vanilla Beta 1.7.3 world format) + *

+ * Handles block conversions + */ public class McRegionToStationFlatteningChunkFix extends DataFix { private final String name; @@ -75,7 +80,7 @@ public Level(Dynamic dynamic) { public Dynamic transform() { Dynamic self = this.level; - // create sections with blocks + // Create sections with blocks Section[] sections = new Section[8]; for (int i = 0; i < 32768; i++) { int worldY = i & 0b1111111; @@ -84,17 +89,19 @@ public Dynamic transform() { int z = i >> 7 & 0b1111; int x = i >> 11; int block = Byte.toUnsignedInt(blocks.get(i)); - int data = this.data.get(x, worldY, z); - if (block > 0 || data > 0) { + int metadata = this.data.get(x, worldY, z); + if (block > 0 || metadata > 0) { if (sections[sectionY] == null) sections[sectionY] = new Section(self.createMap(Map.of(self.createString("y"), self.createByte((byte) sectionY)))); Section section = sections[sectionY]; - section.setBlock(x, y, z, StationFlatteningItemStackSchema.lookupState(block)); // do not convert just yet. we need same references for faster key comparison - section.setData(x, y, z, data); + // Preparation for conversion. References are maintained for faster key comparison + // See "transform" method at the bottom of this file for actual conversion + section.setBlock(x, y, z, StationFlatteningItemStackSchema.lookupState(block)); + section.setMetadata(x, y, z, metadata); } } - // add lighting in created sections + // Add lighting in created sections for (Section section : sections) { if (section != null) { int sectionY = section.y; @@ -110,13 +117,13 @@ public Dynamic transform() { } } - // expand height map - byte[] height_map = new byte[512]; - for (int i = 0; i < height_map.length >> 1; i++) height_map[i << 1] = this.height_map.get(i); + // Expand height map + byte[] heightMap = new byte[512]; + for (int i = 0; i < heightMap.length >> 1; i++) heightMap[i << 1] = this.height_map.get(i); return self .set(SECTIONS, self.createList(Arrays.stream(sections).filter(Objects::nonNull).map(Section::transform))) - .set("height_map", self.createByteList(ByteBuffer.wrap(height_map))) + .set("height_map", self.createByteList(ByteBuffer.wrap(heightMap))) .remove("BlockLight") .remove("Blocks") .remove("Data") @@ -170,7 +177,7 @@ public void setBlock(int x, int y, int z, Dynamic state) { states[(y << 4 | z) << 4 | x] = addTo(paletteMap, state); } - public void setData(int x, int y, int z, int data) { + public void setMetadata(int x, int y, int z, int data) { this.data.setValue(x << 8 | y << 4 | z, data); } @@ -180,7 +187,8 @@ public void setBlockLight(int x, int y, int z, int blockLight) { public Dynamic transform() { Dynamic self = this.section; - Dynamic palette = self.createList(paletteData.stream().map(dynamic -> dynamic.convert(self.getOps()))); // instead, convert when used + // Convert previously prepared values + Dynamic palette = self.createList(paletteData.stream().map(dynamic -> dynamic.convert(self.getOps()))); PackedIntegerArray array = new PackedIntegerArray(Math.max(4, MathHelper.ceilLog2(paletteData.size())), states.length); for (int i = 0; i < states.length; i++) array.set(i, states[i]); Dynamic data = self.createLongList(Arrays.stream(array.getData())); diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java index cbc1025a9..fae8cc190 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java @@ -9,6 +9,9 @@ import java.util.Map; import java.util.function.Supplier; +/** + * + */ public class McRegionSchemaB1_7_3 extends Schema { public McRegionSchemaB1_7_3(int versionKey, Schema parent) { super(versionKey, parent); diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/datafixer/VanillaDataFixerImpl.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/datafixer/VanillaDataFixerImpl.java index 099e8e807..09bb408f3 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/datafixer/VanillaDataFixerImpl.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/datafixer/VanillaDataFixerImpl.java @@ -52,9 +52,12 @@ public final class VanillaDataFixerImpl { private static void registerFixer(DataFixerRegisterEvent event) { DataFixers.registerFixer(NAMESPACE, executor -> { DataFixerBuilder builder = new DataFixerBuilder(CURRENT_VERSION); + // This schema provides the conversion rules for everything found inside chunks: + // Entities, block entities, players, and items Schema schema19132 = builder.addSchema(19132, McRegionSchemaB1_7_3::new); Schema schema69420 = builder.addSchema(69420, StationFlatteningItemStackSchema::new); builder.addFixer(new McRegionToStationFlatteningItemStackFix(schema69420, "McRegionToStationFlatteningItemStackFix")); + // This schema gets used for converting blocks from the standard Beta 1.7.3 world format Schema schema69421 = builder.addSchema(69421, StationFlatteningChunkSchema::new); builder.addFixer(new McRegionToStationFlatteningChunkFix(schema69421, "McRegionToStationFlatteningChunkFix")); return builder.build().fixer(); From fd5c752bf082ae3f7e3da3b583ac6936da6e8d5d Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 20:33:39 +0200 Subject: [PATCH 02/11] McRegionSchemaB1_7_3 Class Documentation --- .../api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java index fae8cc190..61bd21d09 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/McRegionSchemaB1_7_3.java @@ -10,7 +10,9 @@ import java.util.function.Supplier; /** - * + * Defines conversion rules for different parts of the chunk data + *

+ * Includes registries for Vanilla entities and block entities */ public class McRegionSchemaB1_7_3 extends Schema { public McRegionSchemaB1_7_3(int versionKey, Schema parent) { From a2aa9300917f6735198f503efddd940345e077c8 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 21:47:01 +0200 Subject: [PATCH 03/11] ItemStack Schema Documentation --- .../schema/StationFlatteningItemStackSchema.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index d355aba37..52129411a 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -28,10 +28,20 @@ public static void putState(int oldId, String id, NbtCompound properties) { })); } + /** + * Assigns a numeric block ID to its new identifier + * @param oldId Numeric block ID to be converted + * @param id New identifier (including the namespace) + */ public static void putState(int oldId, String id) { putState(oldId, Util.make(new NbtCompound(), tag -> tag.putString("Name", id))); } + /** + * Assigns a numeric block ID to an NBT compound with the new identifier and block state rules + * @param oldId Numeric block ID to be converted + * @param tag Tag with the identifier and block state rules + */ public static void putState(int oldId, NbtCompound tag) { String id = tag.getString("Name"); BLOCK_TO_OLD_ID.put(id, oldId); @@ -40,6 +50,11 @@ public static void putState(int oldId, NbtCompound tag) { putItem(oldId, id); } + /** + * Takes a numeric block ID and returns a block entry for the datafixer + * @param stateId Numeric ID of the block + * @return Dynamic which contains the new ID + */ public static Dynamic lookupState(int stateId) { Dynamic dynamic = null; if (stateId >= 0 && stateId < OLD_ID_TO_BLOCKSTATE.length) { From aef57fe13c2505840d2ab3fc157b63b3b3c0a904 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 22:00:09 +0200 Subject: [PATCH 04/11] Documentation for reversed Conversion --- .../damage/StationFlatteningToMcRegionChunkDamage.java | 3 +++ .../datafixer/schema/StationFlatteningItemStackSchema.java | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datadamager/damage/StationFlatteningToMcRegionChunkDamage.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datadamager/damage/StationFlatteningToMcRegionChunkDamage.java index 21381f150..25411814b 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datadamager/damage/StationFlatteningToMcRegionChunkDamage.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datadamager/damage/StationFlatteningToMcRegionChunkDamage.java @@ -23,6 +23,9 @@ import static net.modificationstation.stationapi.impl.world.FlattenedWorldManager.SECTIONS; +/** + * Reverses Station API's block conversion into identifiers and reverts blocks into numeric IDs + */ public class StationFlatteningToMcRegionChunkDamage extends DataFix { private final static int CHUNK_SIZE = 16 * 128 * 16; private final static byte[] DEFAULT_BLOCK_LIGHT = new byte[CHUNK_SIZE >> 1]; diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index 52129411a..fd2ab9b13 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -71,6 +71,12 @@ public static String lookupBlockId(int id) { return dynamic == null ? "minecraft:air" : dynamic.get("Name").asString(""); } + /** + * Reversed direction converter which turns an identifier into a numeric ID + * @param dynamic Dynamic with an identifier inside + * @return numeric ID + * @param Type of the dynamic + */ public static int lookupOldBlockId(Dynamic dynamic) { return BLOCK_TO_OLD_ID.getInt(dynamic.get("Name").asString("")); } From b1d8e84aa08ea33a44d3729acc155485ee5223e2 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 22:32:45 +0200 Subject: [PATCH 05/11] Data Structures for handling Metadata in Block Conversions --- .../util/MetaDependentIdConversion.java | 63 +++++++++++++++++++ .../vanillafix/util/MetaIntervalToTag.java | 6 ++ 2 files changed, 69 insertions(+) create mode 100644 station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java create mode 100644 station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java new file mode 100644 index 000000000..40e895ee5 --- /dev/null +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java @@ -0,0 +1,63 @@ +package net.modificationstation.stationapi.api.vanillafix.util; + +import com.mojang.serialization.Dynamic; +import lombok.Getter; +import net.minecraft.nbt.NbtCompound; +import net.modificationstation.stationapi.api.nbt.NbtOps; + +/** + * Provides advanced conversion rules which depend on metadata + *

+ * Contains a default tag for unspecified metadata rules + */ +public class MetaDependentIdConversion { + @Getter + private final Dynamic defaultTag; + private final Dynamic[] metaDependentTags = new Dynamic[16]; + + /** + * @param defaultTag Tag to be used for unspecified metadata rules + */ + public MetaDependentIdConversion(NbtCompound defaultTag) { + this.defaultTag = toDynamic(defaultTag); + } + + /** + * Adds a meta rule + * @param meta Metadata of the rule + * @param metaDependentTag Rule to be added + */ + public void addMetaDependentTag(int meta, NbtCompound metaDependentTag) { + if (meta < metaDependentTags.length) { + metaDependentTags[meta] = toDynamic(metaDependentTag); + } + } + + /** + * Adds the same meta rule across an entire interval + * @param interval Interval to determine metadata values of the rule + * @param intervalTag Rule to be added + */ + public void addMetaDependentTagInterval(MetaIntervalToTag interval, NbtCompound intervalTag) { + for (int meta = interval.start(); meta < interval.end(); meta++) { + addMetaDependentTag(meta, intervalTag); + } + } + + /** + * Provides a conversion rule for a given metadata value + * @param meta Metadata to check the rule for + * @return Specific rule or default if unspecified + */ + public Dynamic getTagForMeta(int meta) { + Dynamic tag = metaDependentTags[meta]; + if (tag == null) { + return defaultTag; + } + return tag; + } + + private Dynamic toDynamic(NbtCompound tag) { + return new Dynamic<>(NbtOps.INSTANCE, tag); + } +} diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java new file mode 100644 index 000000000..421e55c79 --- /dev/null +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java @@ -0,0 +1,6 @@ +package net.modificationstation.stationapi.api.vanillafix.util; + +import net.minecraft.nbt.NbtCompound; + +public record MetaIntervalToTag(int start, int end, NbtCompound tag) { +} From f08c380c193932a642ca57f3e744c0c10cee5d10 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 22:38:38 +0200 Subject: [PATCH 06/11] Adapt existing Rules to new Logic --- .../StationFlatteningItemStackSchema.java | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index fd2ab9b13..7a042eae2 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -7,8 +7,8 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.nbt.NbtCompound; import net.modificationstation.stationapi.api.datafixer.TypeReferences; -import net.modificationstation.stationapi.api.nbt.NbtOps; import net.modificationstation.stationapi.api.util.Util; +import net.modificationstation.stationapi.api.vanillafix.util.MetaDependentIdConversion; import java.util.Map; import java.util.function.Supplier; @@ -16,7 +16,7 @@ import static net.modificationstation.stationapi.impl.vanillafix.datafixer.VanillaDataFixerImpl.STATION_ID; public class StationFlatteningItemStackSchema extends Schema { - private static final Dynamic[] OLD_ID_TO_BLOCKSTATE = new Dynamic[256]; + private static final MetaDependentIdConversion[] OLD_ID_TO_BLOCKSTATE = new MetaDependentIdConversion[256]; private static final Object2IntOpenHashMap BLOCK_TO_OLD_ID = Util.make(new Object2IntOpenHashMap<>(256), map -> map.defaultReturnValue(0)); private static final String[] OLD_ID_TO_ITEM = new String[32000]; private static final Object2IntOpenHashMap ITEM_TO_OLD_ID = Util.make(new Object2IntOpenHashMap<>(512), map -> map.defaultReturnValue(0)); @@ -45,8 +45,7 @@ public static void putState(int oldId, String id) { public static void putState(int oldId, NbtCompound tag) { String id = tag.getString("Name"); BLOCK_TO_OLD_ID.put(id, oldId); - Dynamic dynamic = new Dynamic<>(NbtOps.INSTANCE, tag); - OLD_ID_TO_BLOCKSTATE[oldId] = dynamic; + OLD_ID_TO_BLOCKSTATE[oldId] = new MetaDependentIdConversion(tag); putItem(oldId, id); } @@ -56,19 +55,11 @@ public static void putState(int oldId, NbtCompound tag) { * @return Dynamic which contains the new ID */ public static Dynamic lookupState(int stateId) { - Dynamic dynamic = null; + MetaDependentIdConversion rule = null; if (stateId >= 0 && stateId < OLD_ID_TO_BLOCKSTATE.length) { - dynamic = OLD_ID_TO_BLOCKSTATE[stateId]; + rule = OLD_ID_TO_BLOCKSTATE[stateId]; } - return dynamic == null ? OLD_ID_TO_BLOCKSTATE[0] : dynamic; - } - - public static String lookupBlockId(int id) { - if (id < 0 || id >= OLD_ID_TO_BLOCKSTATE.length) { - return "minecraft:air"; - } - Dynamic dynamic = OLD_ID_TO_BLOCKSTATE[id]; - return dynamic == null ? "minecraft:air" : dynamic.get("Name").asString(""); + return rule == null ? OLD_ID_TO_BLOCKSTATE[0].getDefaultTag() : rule.getDefaultTag(); } /** From afb4eae4d6927229ba83f5c1ec8b14a394db97c3 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 22:51:51 +0200 Subject: [PATCH 07/11] Make Metadata Rules fully functional --- .../sltest/datafixer/DataFixerListener.java | 4 ++-- .../McRegionToStationFlatteningChunkFix.java | 4 ++-- .../StationFlatteningItemStackSchema.java | 20 +++++++++++++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java b/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java index de17ef907..24f1fa553 100644 --- a/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java +++ b/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java @@ -8,8 +8,7 @@ import java.lang.invoke.MethodHandles; -import static net.modificationstation.stationapi.api.vanillafix.datafixer.schema.StationFlatteningItemStackSchema.putItem; -import static net.modificationstation.stationapi.api.vanillafix.datafixer.schema.StationFlatteningItemStackSchema.putState; +import static net.modificationstation.stationapi.api.vanillafix.datafixer.schema.StationFlatteningItemStackSchema.*; public class DataFixerListener { static { @@ -23,6 +22,7 @@ private static void registerFixer(DataFixerRegisterEvent event) { putState(99, "sltest:farlands_block", Util.make(new NbtCompound(), tag -> tag.putString("facing", "north"))); putState(100, "sltest:freezer"); putState(101, "sltest:altar"); + putStateMetaRule(17, 2, "minecraft:wool"); putItem(360, "sltest:test_item"); putItem(361, "sltest:test_pickaxe"); putItem(362, "sltest:nbt_item"); diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java index 519e47f3a..577633bf8 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java @@ -96,7 +96,7 @@ public Dynamic transform() { Section section = sections[sectionY]; // Preparation for conversion. References are maintained for faster key comparison // See "transform" method at the bottom of this file for actual conversion - section.setBlock(x, y, z, StationFlatteningItemStackSchema.lookupState(block)); + section.setBlock(x, y, z, StationFlatteningItemStackSchema.lookupState(block, metadata)); section.setMetadata(x, y, z, metadata); } } @@ -162,7 +162,7 @@ static final class Section { public Section(Dynamic section) { this.section = section; y = section.get("y").asInt(0); - Dynamic air = StationFlatteningItemStackSchema.lookupState(0); // same applies + Dynamic air = StationFlatteningItemStackSchema.lookupState(0, 0); // same applies seenStates.add(air); paletteData.add(air); paletteMap.add(air); diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index 7a042eae2..cb11b7df5 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -49,17 +49,33 @@ public static void putState(int oldId, NbtCompound tag) { putItem(oldId, id); } + public static void putStateMetaRule(int oldId, int meta, String id) { + putStateMetaRule(oldId, meta, Util.make(new NbtCompound(), tag -> tag.putString("Name", id))); + } + + public static void putStateMetaRule(int oldId, int meta, NbtCompound tag) { + MetaDependentIdConversion rule; + if (oldId >= 0 && oldId < OLD_ID_TO_BLOCKSTATE.length) { + rule = OLD_ID_TO_BLOCKSTATE[oldId]; + if (rule != null) { + rule.addMetaDependentTag(meta, tag); + OLD_ID_TO_BLOCKSTATE[oldId] = rule; + } + } + } + /** * Takes a numeric block ID and returns a block entry for the datafixer * @param stateId Numeric ID of the block + * @param metadata Metadata of the block * @return Dynamic which contains the new ID */ - public static Dynamic lookupState(int stateId) { + public static Dynamic lookupState(int stateId, int metadata) { MetaDependentIdConversion rule = null; if (stateId >= 0 && stateId < OLD_ID_TO_BLOCKSTATE.length) { rule = OLD_ID_TO_BLOCKSTATE[stateId]; } - return rule == null ? OLD_ID_TO_BLOCKSTATE[0].getDefaultTag() : rule.getDefaultTag(); + return rule == null ? OLD_ID_TO_BLOCKSTATE[0].getDefaultTag() : rule.getTagForMeta(metadata); } /** From f510c48c90d84b0aaf82162113400437018a510d Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 23:12:21 +0200 Subject: [PATCH 08/11] Output Metadata Rule Expansion --- .../sltest/datafixer/DataFixerListener.java | 2 +- .../McRegionToStationFlatteningChunkFix.java | 7 ++++++- .../StationFlatteningItemStackSchema.java | 16 ++++++++++++---- .../util/MetaDependentIdConversion.java | 17 +++++++++++++++-- .../api/vanillafix/util/MetaIntervalToTag.java | 2 +- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java b/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java index 24f1fa553..e499d0646 100644 --- a/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java +++ b/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java @@ -22,7 +22,7 @@ private static void registerFixer(DataFixerRegisterEvent event) { putState(99, "sltest:farlands_block", Util.make(new NbtCompound(), tag -> tag.putString("facing", "north"))); putState(100, "sltest:freezer"); putState(101, "sltest:altar"); - putStateMetaRule(17, 2, "minecraft:wool"); + putStateMetaRule(17, 2, 10, "minecraft:wool"); putItem(360, "sltest:test_item"); putItem(361, "sltest:test_pickaxe"); putItem(362, "sltest:nbt_item"); diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java index 577633bf8..21ec6bac6 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java @@ -15,6 +15,7 @@ import net.modificationstation.stationapi.api.util.collection.PackedIntegerArray; import net.modificationstation.stationapi.api.util.math.MathHelper; import net.modificationstation.stationapi.api.vanillafix.datafixer.schema.StationFlatteningItemStackSchema; +import net.modificationstation.stationapi.api.vanillafix.util.MetaDependentIdConversion; import java.nio.ByteBuffer; import java.util.Arrays; @@ -97,7 +98,11 @@ public Dynamic transform() { // Preparation for conversion. References are maintained for faster key comparison // See "transform" method at the bottom of this file for actual conversion section.setBlock(x, y, z, StationFlatteningItemStackSchema.lookupState(block, metadata)); - section.setMetadata(x, y, z, metadata); + int newMetadata = StationFlatteningItemStackSchema.lookupMetadata(block, metadata); + if (newMetadata == MetaDependentIdConversion.UNSPECIFIED_META) { + newMetadata = metadata; + } + section.setMetadata(x, y, z, newMetadata); } } diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index cb11b7df5..3cd1ed65f 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -49,16 +49,16 @@ public static void putState(int oldId, NbtCompound tag) { putItem(oldId, id); } - public static void putStateMetaRule(int oldId, int meta, String id) { - putStateMetaRule(oldId, meta, Util.make(new NbtCompound(), tag -> tag.putString("Name", id))); + public static void putStateMetaRule(int oldId, int meta, int outputMeta, String id) { + putStateMetaRule(oldId, meta, outputMeta, Util.make(new NbtCompound(), tag -> tag.putString("Name", id))); } - public static void putStateMetaRule(int oldId, int meta, NbtCompound tag) { + public static void putStateMetaRule(int oldId, int meta, int outputMeta, NbtCompound tag) { MetaDependentIdConversion rule; if (oldId >= 0 && oldId < OLD_ID_TO_BLOCKSTATE.length) { rule = OLD_ID_TO_BLOCKSTATE[oldId]; if (rule != null) { - rule.addMetaDependentTag(meta, tag); + rule.addMetaDependentTag(meta, tag, outputMeta); OLD_ID_TO_BLOCKSTATE[oldId] = rule; } } @@ -78,6 +78,14 @@ public static Dynamic lookupState(int stateId, int metadata) { return rule == null ? OLD_ID_TO_BLOCKSTATE[0].getDefaultTag() : rule.getTagForMeta(metadata); } + public static int lookupMetadata(int stateId, int metadata) { + MetaDependentIdConversion rule = null; + if (stateId >= 0 && stateId < OLD_ID_TO_BLOCKSTATE.length) { + rule = OLD_ID_TO_BLOCKSTATE[stateId]; + } + return rule == null ? MetaDependentIdConversion.UNSPECIFIED_META : rule.getOutputMeta(metadata); + } + /** * Reversed direction converter which turns an identifier into a numeric ID * @param dynamic Dynamic with an identifier inside diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java index 40e895ee5..a5b1b8cf6 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java @@ -11,9 +11,12 @@ * Contains a default tag for unspecified metadata rules */ public class MetaDependentIdConversion { + public static final int UNSPECIFIED_META = -1; + @Getter private final Dynamic defaultTag; private final Dynamic[] metaDependentTags = new Dynamic[16]; + private final Integer[] outputMetas = new Integer[16]; /** * @param defaultTag Tag to be used for unspecified metadata rules @@ -26,10 +29,12 @@ public MetaDependentIdConversion(NbtCompound defaultTag) { * Adds a meta rule * @param meta Metadata of the rule * @param metaDependentTag Rule to be added + * @param outputMeta New metadata of the converted block */ - public void addMetaDependentTag(int meta, NbtCompound metaDependentTag) { + public void addMetaDependentTag(int meta, NbtCompound metaDependentTag, int outputMeta) { if (meta < metaDependentTags.length) { metaDependentTags[meta] = toDynamic(metaDependentTag); + outputMetas[meta] = outputMeta; } } @@ -40,7 +45,7 @@ public void addMetaDependentTag(int meta, NbtCompound metaDependentTag) { */ public void addMetaDependentTagInterval(MetaIntervalToTag interval, NbtCompound intervalTag) { for (int meta = interval.start(); meta < interval.end(); meta++) { - addMetaDependentTag(meta, intervalTag); + addMetaDependentTag(meta, intervalTag, interval.outputMeta()); } } @@ -57,6 +62,14 @@ public Dynamic getTagForMeta(int meta) { return tag; } + public int getOutputMeta(int meta) { + Integer outputMeta = null; + if (meta < outputMetas.length) { + outputMeta = outputMetas[meta]; + } + return outputMeta == null ? UNSPECIFIED_META : outputMeta; + } + private Dynamic toDynamic(NbtCompound tag) { return new Dynamic<>(NbtOps.INSTANCE, tag); } diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java index 421e55c79..ecb4e24c1 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java @@ -2,5 +2,5 @@ import net.minecraft.nbt.NbtCompound; -public record MetaIntervalToTag(int start, int end, NbtCompound tag) { +public record MetaIntervalToTag(int start, int end, NbtCompound tag, int outputMeta) { } From a49ad2572f907e85aa64735ab7b59836390f3c41 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 23:22:52 +0200 Subject: [PATCH 09/11] Document new Datafixer Code --- .../McRegionToStationFlatteningChunkFix.java | 1 + .../StationFlatteningItemStackSchema.java | 24 +++++++++++++++++++ .../util/MetaDependentIdConversion.java | 16 ++++--------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java index 21ec6bac6..cddd124f4 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/fix/McRegionToStationFlatteningChunkFix.java @@ -98,6 +98,7 @@ public Dynamic transform() { // Preparation for conversion. References are maintained for faster key comparison // See "transform" method at the bottom of this file for actual conversion section.setBlock(x, y, z, StationFlatteningItemStackSchema.lookupState(block, metadata)); + // Replace old metadata with new one if specified int newMetadata = StationFlatteningItemStackSchema.lookupMetadata(block, metadata); if (newMetadata == MetaDependentIdConversion.UNSPECIFIED_META) { newMetadata = metadata; diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index 3cd1ed65f..86abd45c0 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -49,10 +49,28 @@ public static void putState(int oldId, NbtCompound tag) { putItem(oldId, id); } + /** + * Creates a metadata specific conversion rule for a block + *

+ * Must be used after the putState method + * @param oldId Numeric block ID to add the rule to + * @param meta Old metadata + * @param outputMeta New metadata + * @param id New identifier (including the namespace) + */ public static void putStateMetaRule(int oldId, int meta, int outputMeta, String id) { putStateMetaRule(oldId, meta, outputMeta, Util.make(new NbtCompound(), tag -> tag.putString("Name", id))); } + /** + * Creates a metadata specific conversion rule for a block + *

+ * Must be used after the putState method + * @param oldId Numeric block ID to add the rule to + * @param meta Old metadata + * @param outputMeta New metadata + * @param tag Tag with the identifier and block state rules + */ public static void putStateMetaRule(int oldId, int meta, int outputMeta, NbtCompound tag) { MetaDependentIdConversion rule; if (oldId >= 0 && oldId < OLD_ID_TO_BLOCKSTATE.length) { @@ -78,6 +96,12 @@ public static Dynamic lookupState(int stateId, int metadata) { return rule == null ? OLD_ID_TO_BLOCKSTATE[0].getDefaultTag() : rule.getTagForMeta(metadata); } + /** + * Replaces an old metadata with a new one for the given block + * @param stateId Numeric ID of the block + * @param metadata Old metadata + * @return New metadata or -1 if not specified + */ public static int lookupMetadata(int stateId, int metadata) { MetaDependentIdConversion rule = null; if (stateId >= 0 && stateId < OLD_ID_TO_BLOCKSTATE.length) { diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java index a5b1b8cf6..4a84345f5 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaDependentIdConversion.java @@ -38,17 +38,6 @@ public void addMetaDependentTag(int meta, NbtCompound metaDependentTag, int outp } } - /** - * Adds the same meta rule across an entire interval - * @param interval Interval to determine metadata values of the rule - * @param intervalTag Rule to be added - */ - public void addMetaDependentTagInterval(MetaIntervalToTag interval, NbtCompound intervalTag) { - for (int meta = interval.start(); meta < interval.end(); meta++) { - addMetaDependentTag(meta, intervalTag, interval.outputMeta()); - } - } - /** * Provides a conversion rule for a given metadata value * @param meta Metadata to check the rule for @@ -62,6 +51,11 @@ public Dynamic getTagForMeta(int meta) { return tag; } + /** + * Replaces an old metadata value with a new one + * @param meta Old metadata to be replaced + * @return New metadata or -1 if not specified + */ public int getOutputMeta(int meta) { Integer outputMeta = null; if (meta < outputMetas.length) { From 7aac38c199fb1846e8644cc4bed4df6e5c226065 Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Mon, 17 Aug 2026 23:23:23 +0200 Subject: [PATCH 10/11] Remove MetaIntervalToTag (not worth implementing) --- .../stationapi/api/vanillafix/util/MetaIntervalToTag.java | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java deleted file mode 100644 index ecb4e24c1..000000000 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/util/MetaIntervalToTag.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.modificationstation.stationapi.api.vanillafix.util; - -import net.minecraft.nbt.NbtCompound; - -public record MetaIntervalToTag(int start, int end, NbtCompound tag, int outputMeta) { -} From 33fee70b727c371e7e286668e6c1fd6e2d2c82bb Mon Sep 17 00:00:00 2001 From: Atilist <71230342+Atilist@users.noreply.github.com> Date: Tue, 18 Aug 2026 00:28:26 +0200 Subject: [PATCH 11/11] Move Output Metadata Argument to the End --- .../sltest/datafixer/DataFixerListener.java | 2 +- .../schema/StationFlatteningItemStackSchema.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java b/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java index e499d0646..1409112d7 100644 --- a/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java +++ b/src/test/java/net/modificationstation/sltest/datafixer/DataFixerListener.java @@ -22,7 +22,7 @@ private static void registerFixer(DataFixerRegisterEvent event) { putState(99, "sltest:farlands_block", Util.make(new NbtCompound(), tag -> tag.putString("facing", "north"))); putState(100, "sltest:freezer"); putState(101, "sltest:altar"); - putStateMetaRule(17, 2, 10, "minecraft:wool"); + putStateMetaRule(17, 2, "minecraft:wool", 10); putItem(360, "sltest:test_item"); putItem(361, "sltest:test_pickaxe"); putItem(362, "sltest:nbt_item"); diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java index 86abd45c0..b1770fbdf 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/api/vanillafix/datafixer/schema/StationFlatteningItemStackSchema.java @@ -55,11 +55,11 @@ public static void putState(int oldId, NbtCompound tag) { * Must be used after the putState method * @param oldId Numeric block ID to add the rule to * @param meta Old metadata - * @param outputMeta New metadata * @param id New identifier (including the namespace) + * @param outputMeta New metadata */ - public static void putStateMetaRule(int oldId, int meta, int outputMeta, String id) { - putStateMetaRule(oldId, meta, outputMeta, Util.make(new NbtCompound(), tag -> tag.putString("Name", id))); + public static void putStateMetaRule(int oldId, int meta, String id, int outputMeta) { + putStateMetaRule(oldId, meta, Util.make(new NbtCompound(), tag -> tag.putString("Name", id)), outputMeta); } /** @@ -68,10 +68,10 @@ public static void putStateMetaRule(int oldId, int meta, int outputMeta, String * Must be used after the putState method * @param oldId Numeric block ID to add the rule to * @param meta Old metadata - * @param outputMeta New metadata * @param tag Tag with the identifier and block state rules + * @param outputMeta New metadata */ - public static void putStateMetaRule(int oldId, int meta, int outputMeta, NbtCompound tag) { + public static void putStateMetaRule(int oldId, int meta, NbtCompound tag, int outputMeta) { MetaDependentIdConversion rule; if (oldId >= 0 && oldId < OLD_ID_TO_BLOCKSTATE.length) { rule = OLD_ID_TO_BLOCKSTATE[oldId];