### Implement GameDataProvider for Block State Upgrades Source: https://github.com/hollow-cube/schem/blob/main/README.md Implement the GameDataProvider interface to handle upgrades for block states from older Minecraft versions to newer ones. This example upgrades 'chain' to 'iron_chain' for data versions greater than or equal to 4541. ```java public class MyGameDataProviderImpl implements GameDataProvider { private static final int IRON_CHAIN_VERSION = 4541; @Override public int dataVersion() { // Must return the 'current' data version. We can delegate to Minestom. return MinecraftServer.DATA_VERSION; } @Override public String upgradeBlockState(int fromVersion, int toVersion, String blockState) { if (fromVersion < IRON_CHAIN_VERSION && toVersion >= IRON_CHAIN_VERSION) return blockState.replace("chain", "iron_chain"); return blockState; } } ``` -------------------------------- ### Create and Apply Block Batches with Schematic Source: https://context7.com/hollow-cube/schem/llms.txt Demonstrates creating various RelativeBlockBatches from a Schematic, including basic application, rotated batches, and batches with block transformations. Ensure the Schematic is loaded before creating batches. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.hollowcube.schem.util.Rotation; import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.Instance; import net.minestom.server.instance.batch.RelativeBlockBatch; import net.minestom.server.instance.block.Block; import java.nio.file.Files; import java.nio.file.Path; Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("build.schem")) ); Instance instance = /* get your Minestom instance */; // Create a basic batch and apply it RelativeBlockBatch batch = schematic.createBatch(); batch.apply(instance, new Pos(100, 64, 100), () -> { System.out.println("Schematic placed successfully!"); }); // Create a rotated batch (180 degrees) RelativeBlockBatch rotatedBatch = schematic.createBatch(Rotation.CLOCKWISE_180); rotatedBatch.apply(instance, new Pos(200, 64, 100), null); // Create a batch with block transformation RelativeBlockBatch transformedBatch = schematic.createBatch((pos, block) -> { // Replace all stone with diamond blocks if (block == Block.STONE) { return Block.DIAMOND_BLOCK; } // Return null to skip placing this block if (block == Block.AIR) { return null; } return block; }); transformedBatch.apply(instance, new Pos(300, 64, 100), null); // Create a batch with both rotation and transformation RelativeBlockBatch fullBatch = schematic.createBatch( Rotation.CLOCKWISE_270, (pos, block) -> { // Replace grass with dirt if (block == Block.GRASS_BLOCK) { return Block.DIRT; } return block; } ); fullBatch.apply(instance, new Pos(400, 64, 100), null); ``` -------------------------------- ### SchematicWriter - Writing Schematic Files Source: https://context7.com/hollow-cube/schem/llms.txt Provides static factory methods to create writers for supported output formats. Any `Schematic` object can be written to any supported format; the writer handles conversion automatically, though some format-specific data may be lost. ```APIDOC ## SchematicWriter - Writing Schematic Files ### Description Provides static factory methods to create writers for supported output formats. Any `Schematic` object can be written to any supported format - the writer handles conversion automatically, though some format-specific data may be lost during conversion. ### Method Factory methods on `SchematicWriter` interface. ### Endpoint N/A (Library API) ### Parameters N/A (Library API) ### Request Example ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.hollowcube.schem.writer.SchematicWriter; import java.nio.file.Files; import java.nio.file.Path; // Load any schematic Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("input.litematic")) ); // Write as Sponge v3 format byte[] spongeData = SchematicWriter.sponge().write(schematic); Files.write(Path.of("output.schem"), spongeData); // Write as Vanilla Structure format byte[] structureData = SchematicWriter.structure().write(schematic); Files.write(Path.of("output.nbt"), structureData); // Convert between formats Schematic litematicaSchem = SchematicReader.litematica().read( Files.readAllBytes(Path.of("build.litematic")) ); byte[] convertedData = SchematicWriter.sponge().write(litematicaSchem); Files.write(Path.of("build_converted.schem"), convertedData); ``` ### Response #### Success Response (byte array) - **byte[]** - The schematic data in the specified format. #### Response Example (Binary data representing the schematic file, not shown as JSON) ``` -------------------------------- ### Read Specific Schematic Formats Source: https://context7.com/hollow-cube/schem/llms.txt Instantiate specific readers for Sponge, Vanilla Structure, Litematica, Axiom Blueprints, or Legacy MCEdit schematics using their respective factory methods. ```java // Read specifically a Sponge schematic Schematic spongeSchematic = SchematicReader.sponge().read(data); ``` ```java // Read a Vanilla Structure file (.nbt) byte[] structureData = Files.readAllBytes(Path.of("structure.nbt")); Schematic structure = SchematicReader.structure().read(structureData); ``` ```java // Read a Litematica schematic byte[] litematicaData = Files.readAllBytes(Path.of("build.litematic")); Schematic litematicaSchematic = SchematicReader.litematica().read(litematicaData); ``` ```java // Read an Axiom Blueprint byte[] axiomData = Files.readAllBytes(Path.of("blueprint.bp")); Schematic axiomSchematic = SchematicReader.axiom().read(axiomData); ``` ```java // Read a Legacy MCEdit schematic byte[] mceditData = Files.readAllBytes(Path.of("old_build.schematic")); Schematic mceditSchematic = SchematicReader.legacyMcEdit().read(mceditData); ``` -------------------------------- ### Register GameDataProvider Source: https://github.com/hollow-cube/schem/blob/main/README.md Register your custom GameDataProvider implementation globally before reading any schematics to enable data version upgrades. ```java GameDataProvider.replaceGlobals(new MyGameDataProviderImpl()); ``` -------------------------------- ### SchematicReader - Reading Schematic Files Source: https://context7.com/hollow-cube/schem/llms.txt Provides static factory methods to create readers for specific schematic formats. The `read()` method takes a byte array of schematic data and returns a `Schematic` object. Use `detecting()` to automatically detect and parse any supported format. ```APIDOC ## SchematicReader - Reading Schematic Files ### Description Provides static factory methods to create readers for specific schematic formats. The `read()` method takes a byte array of schematic data and returns a `Schematic` object. Use `detecting()` to automatically detect and parse any supported format. ### Method Factory methods on `SchematicReader` interface. ### Endpoint N/A (Library API) ### Parameters N/A (Library API) ### Request Example ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; // Read a schematic with automatic format detection byte[] data = Files.readAllBytes(Path.of("myschematic.schem")); Schematic schematic = SchematicReader.detecting().read(data); // Access schematic metadata System.out.println("Name: " + schematic.name()); System.out.println("Author: " + schematic.author()); System.out.println("Size: " + schematic.size()); System.out.println("Offset: " + schematic.offset()); System.out.println("Created: " + schematic.createdAt()); System.out.println("Block palette size: " + schematic.blockPalette().size()); System.out.println("Block entities: " + schematic.blockEntities().size()); // Read specifically a Sponge schematic Schematic spongeSchematic = SchematicReader.sponge().read(data); // Read a Vanilla Structure file (.nbt) byte[] structureData = Files.readAllBytes(Path.of("structure.nbt")); Schematic structure = SchematicReader.structure().read(structureData); // Read a Litematica schematic byte[] litematicaData = Files.readAllBytes(Path.of("build.litematic")); Schematic litematicaSchematic = SchematicReader.litematica().read(litematicaData); // Read an Axiom Blueprint byte[] axiomData = Files.readAllBytes(Path.of("blueprint.bp")); Schematic axiomSchematic = SchematicReader.axiom().read(axiomData); // Read a Legacy MCEdit schematic byte[] mceditData = Files.readAllBytes(Path.of("old_build.schematic")); Schematic mceditSchematic = SchematicReader.legacyMcEdit().read(mceditData); ``` ### Response #### Success Response (Schematic Object) - **Schematic** (object) - A representation of the loaded schematic data. #### Response Example ```json { "name": "Example Schematic", "author": "Author Name", "size": {"x": 10, "y": 5, "z": 10}, "offset": {"x": 0, "y": 0, "z": 0}, "createdAt": "2023-10-27T10:00:00Z", "blockPaletteSize": 150, "blockEntitiesCount": 5 } ``` ``` -------------------------------- ### Write Schematic Files in Various Formats Source: https://context7.com/hollow-cube/schem/llms.txt Use `SchematicWriter` factory methods to write a `Schematic` object to different formats like Sponge or Vanilla Structure. Conversion between formats is handled automatically. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.hollowcube.schem.writer.SchematicWriter; import java.nio.file.Files; import java.nio.file.Path; // Load any schematic Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("input.litematic")) ); // Write as Sponge v3 format byte[] spongeData = SchematicWriter.sponge().write(schematic); Files.write(Path.of("output.schem"), spongeData); ``` ```java // Write as Vanilla Structure format byte[] structureData = SchematicWriter.structure().write(schematic); Files.write(Path.of("output.nbt"), structureData); ``` ```java // Convert between formats Schematic litematicaSchem = SchematicReader.litematica().read( Files.readAllBytes(Path.of("build.litematic")) ); byte[] convertedData = SchematicWriter.sponge().write(litematicaSchem); Files.write(Path.of("build_converted.schem"), convertedData); ``` -------------------------------- ### Implement Custom GameDataProvider for Schematic Upgrades Source: https://context7.com/hollow-cube/schem/llms.txt Implement the GameDataProvider interface to handle version-specific transformations for block states, block entities, and entities when loading older schematics. Register your custom provider using GameDataProvider.replaceGlobals() before reading schematics. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.hollowcube.schem.util.GameDataProvider; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.MinecraftServer; import java.nio.file.Files; import java.nio.file.Path; // Implement custom GameDataProvider for version upgrades public class MyGameDataProvider implements GameDataProvider { private static final int CHAIN_RENAME_VERSION = 2586; // 1.16 private static final int SIGN_UPDATE_VERSION = 3463; // 1.20 @Override public int dataVersion() { // Return current Minecraft data version from Minestom return MinecraftServer.DATA_VERSION; } @Override public String upgradeBlockState(int fromVersion, int toVersion, String blockState) { String result = blockState; // Rename 'chain' to 'iron_chain' (1.16 change) if (fromVersion < CHAIN_RENAME_VERSION && toVersion >= CHAIN_RENAME_VERSION) { result = result.replace("minecraft:chain", "minecraft:iron_chain"); } // Handle other block renames if (result.contains("minecraft:grass_path")) { result = result.replace("minecraft:grass_path", "minecraft:dirt_path"); } return result; } @Override public CompoundBinaryTag upgradeBlockEntity(int fromVersion, int toVersion, String id, CompoundBinaryTag data) { // Upgrade sign data format for 1.20+ if (id.equals("minecraft:sign") && fromVersion < SIGN_UPDATE_VERSION) { // Handle sign text format changes return data; // Return upgraded data } return data; } @Override public CompoundBinaryTag upgradeEntity(int fromVersion, int toVersion, CompoundBinaryTag data) { // Upgrade entity NBT data return data; } } // Register the provider before reading schematics GameDataProvider.replaceGlobals(new MyGameDataProvider()); // Now schematics are automatically upgraded when read Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("old_schematic.schem")) ); ``` -------------------------------- ### Create and Save a Fixed-Size Schematic Source: https://context7.com/hollow-cube/schem/llms.txt Use SchematicBuilder to create a schematic with a predefined size. Blocks can be placed using coordinates or Vec objects. Metadata and offset can also be set before building and saving the schematic. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.builder.SchematicBuilder; import net.hollowcube.schem.writer.SchematicWriter; import net.kyori.adventure.nbt.StringBinaryTag; import net.minestom.server.coordinate.Vec; import net.minestom.server.instance.block.Block; import java.nio.file.Files; import java.nio.file.Path; // Create a fixed-size schematic (5x5x5) SchematicBuilder builder = SchematicBuilder.builder(new Vec(5, 5, 5)); // Place blocks at specific positions builder.block(0, 0, 0, Block.STONE); builder.block(1, 0, 0, Block.COBBLESTONE); builder.block(2, 0, 0, Block.GRANITE); builder.block(new Vec(0, 1, 0), Block.DIRT); // Set metadata builder.metadata("Name", StringBinaryTag.stringBinaryTag("My Custom Build")); builder.metadata("Author", StringBinaryTag.stringBinaryTag("Developer")); // Set offset for placement reference builder.offset(0, -1, 0); // Build and save the schematic Schematic schematic = builder.build(); byte[] data = SchematicWriter.sponge().write(schematic); Files.write(Path.of("custom_build.schem"), data); ``` -------------------------------- ### Read and Access Schematic Properties Source: https://context7.com/hollow-cube/schem/llms.txt Loads a schematic from a file and accesses its basic properties, metadata, block data, biome data, and entities. Ensure the schematic file exists at the specified path. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.coordinate.Point; import net.minestom.server.instance.block.Block; import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.List; Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("build.schem")) ); // Basic properties Point size = schematic.size(); // Dimensions (width, height, length) Point offset = schematic.offset(); // Placement offset // Metadata String name = schematic.name(); // May be null String author = schematic.author(); // May be null Instant created = schematic.createdAt(); // May be null CompoundBinaryTag metadata = schematic.metadata(); // Block data access boolean hasBlocks = schematic.hasBlockData(); List palette = schematic.blockPalette(); var blockData = schematic.blockData(); // Raw block data // Biome data access boolean hasBiomes = schematic.hasBiomeData(); List biomePalette = schematic.biomePalette(); var biomeData = schematic.biomeData(); // Raw biome data // Entity data List entities = schematic.entities(); // Create an empty schematic Schematic empty = Schematic.empty(); // Print schematic info System.out.println("Schematic: " + (name != null ? name : "Unnamed")); System.out.println(" Size: " + size.x() + "x" + size.y() + "x" + size.z()); System.out.println(" Offset: " + offset); System.out.println(" Author: " + (author != null ? author : "Unknown")); System.out.println(" Unique blocks: " + palette.size()); System.out.println(" Block entities: " + schematic.blockEntities().size()); System.out.println(" Has biome data: " + hasBiomes); System.out.println(" Entities: " + entities.size()); ``` -------------------------------- ### Detect and Read Schematic Source: https://github.com/hollow-cube/schem/blob/main/README.md Load schematic data and automatically detect the format for reading. This method attempts to read any supported schematic format. ```java byte[] data = loadSchematicData(); // Read any supported schematic format. Schematic schematic = SchematicReader.detecting().read(data); ``` -------------------------------- ### Read Sponge Schematic Source: https://github.com/hollow-cube/schem/blob/main/README.md Load schematic data and read it specifically as a Sponge schematic. Throws an exception if the data is invalid. ```java byte[] data = loadSchematicData(); // Read specifically a sponge schematic (throwing if invalid). Schematic schematic = SchematicReader.sponge().read(data); ``` -------------------------------- ### Add Schem Dependency Source: https://github.com/hollow-cube/schem/blob/main/README.md Add the Schem library to your project's dependencies using Maven Central. ```groovy repositories { mavenCentral() } dependencies { implementation 'dev.hollowcube:schem:' } ``` -------------------------------- ### Read Schematic Files with Automatic Detection Source: https://context7.com/hollow-cube/schem/llms.txt Use `SchematicReader.detecting().read()` to automatically parse schematic data from various formats. Access metadata like name, author, size, and block palette. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; // Read a schematic with automatic format detection byte[] data = Files.readAllBytes(Path.of("myschematic.schem")); Schematic schematic = SchematicReader.detecting().read(data); // Access schematic metadata System.out.println("Name: " + schematic.name()); System.out.println("Author: " + schematic.author()); System.out.println("Size: " + schematic.size()); System.out.println("Offset: " + schematic.offset()); System.out.println("Created: " + schematic.createdAt()); System.out.println("Block palette size: " + schematic.blockPalette().size()); System.out.println("Block entities: " + schematic.blockEntities().size()); ``` -------------------------------- ### Create an Unbounded Schematic Source: https://context7.com/hollow-cube/schem/llms.txt Instantiate SchematicBuilder without a size to create an unbounded schematic. The size will be automatically determined by the minimum and maximum coordinates of the placed blocks. ```java // Create an unbounded schematic (size determined automatically) SchematicBuilder unboundedBuilder = SchematicBuilder.builder(); unboundedBuilder.block(0, 0, 0, Block.DIAMOND_BLOCK); unboundedBuilder.block(100, 50, 100, Block.GOLD_BLOCK); // Size will be calculated based on min/max positions Schematic unboundedSchematic = unboundedBuilder.build(); ``` -------------------------------- ### Count Block Types in Schematic Source: https://context7.com/hollow-cube/schem/llms.txt Demonstrates counting the occurrences of each block type within a schematic by iterating through all blocks and using a Map to store counts. This utilizes the basic forEachBlock iteration without rotation. ```java // Count block types in a schematic Map blockCounts = new HashMap<>(); schematic.forEachBlock((pos, block) -> { blockCounts.merge(block, 1, Integer::sum); }); blockCounts.forEach((block, count) -> System.out.println(block.name() + ": " + count) ); ``` -------------------------------- ### Write Sponge Schematic Source: https://github.com/hollow-cube/schem/blob/main/README.md Write a loaded schematic into Sponge schematic format. The writer implementation handles conversion from a generic Schematic. ```java Schematic mySchematic = fetchMyLoadedSchematic(); byte[] data = SchematicWriter.sponge().write(data); ``` -------------------------------- ### Iterate Over Schematic Blocks Source: https://context7.com/hollow-cube/schem/llms.txt Use Schematic.forEachBlock to iterate through all blocks in a schematic. This method accepts a consumer that receives the block's position and the block itself. It supports optional rotation for transforming positions and directional block states. ```java import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.hollowcube.schem.util.Rotation; import net.minestom.server.instance.block.Block; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("build.schem")) ); // Iterate over all blocks (no rotation) schematic.forEachBlock((pos, block) -> { if (block != Block.AIR) { System.out.println("Block at " + pos + ": " + block.name()); } }); ``` -------------------------------- ### Access Block Entity Information from Schematic Source: https://context7.com/hollow-cube/schem/llms.txt Iterate through a schematic's block entities using the `blockEntities()` method to access their ID, position, and NBT data. Handle specific block entity types like chests, signs, and spawners by inspecting their IDs and data. ```java import net.hollowcube.schem.BlockEntityData; import net.hollowcube.schem.Schematic; import net.hollowcube.schem.reader.SchematicReader; import net.kyori.adventure.nbt.CompoundBinaryTag; import java.nio.file.Files; import java.nio.file.Path; Schematic schematic = SchematicReader.detecting().read( Files.readAllBytes(Path.of("build_with_chests.schem")) ); // Iterate over all block entities for (BlockEntityData blockEntity : schematic.blockEntities()) { String id = blockEntity.id(); // e.g., "minecraft:chest" var position = blockEntity.position(); // Block position within schematic CompoundBinaryTag data = blockEntity.data(); // NBT data System.out.println("Block Entity: " + id + " at " + position); // Handle specific block entity types switch (id) { case "minecraft:chest", "minecraft:trapped_chest" -> { // Access chest inventory data var items = data.getList("Items"); System.out.println(" Contains " + items.size() + " item stacks"); } case "minecraft:sign" -> { // Access sign text System.out.println(" Sign data: " + data); } case "minecraft:spawner" -> { // Access spawner configuration var spawnData = data.getCompound("SpawnData"); System.out.println(" Spawner config: " + spawnData); } } } // Check if schematic has block data if (schematic.hasBlockData()) { System.out.println("Schematic has block data"); System.out.println("Block palette: " + schematic.blockPalette().size() + " unique blocks"); } ``` -------------------------------- ### Iterate with Rotation Source: https://context7.com/hollow-cube/schem/llms.txt When iterating with Schematic.forEachBlock, provide a Rotation enum value to automatically transform block positions and directional block states according to the specified rotation. ```java // Iterate with 90-degree clockwise rotation schematic.forEachBlock(Rotation.CLOCKWISE_90, (pos, block) -> { // Position and directional blocks are rotated automatically System.out.println("Rotated block at " + pos + ": " + block.name()); }); ``` -------------------------------- ### Rotate Directions and Positions with Rotation Enum Source: https://context7.com/hollow-cube/schem/llms.txt Utilizes the Rotation enum to apply 90-degree rotations to directions and convert between different rotation systems. This is useful for aligning blocks or positions correctly. ```java import net.hollowcube.schem.util.Rotation; import net.minestom.server.utils.Direction; // Available rotations Rotation none = Rotation.NONE; // 0 degrees Rotation cw90 = Rotation.CLOCKWISE_90; // 90 degrees Rotation cw180 = Rotation.CLOCKWISE_180; // 180 degrees Rotation cw270 = Rotation.CLOCKWISE_270; // 270 degrees // Get rotation in degrees System.out.println(cw90.toDegrees()); // Output: 90 // Rotate a direction Direction north = Direction.NORTH; Direction rotated = cw90.rotate(north); System.out.println(rotated); // Output: EAST // Chain rotations Rotation combined = Rotation.CLOCKWISE_90.rotate(Rotation.CLOCKWISE_90); System.out.println(combined); // Output: CLOCKWISE_180 // Convert from Minestom rotation (supports 45-degree angles, rounds down) Rotation fromMinestom = Rotation.from(net.minestom.server.utils.Rotation.CLOCKWISE); System.out.println(fromMinestom); // Output: CLOCKWISE_90 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.