### PolarWorld Instantiation Examples Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/types.md Demonstrates various ways to obtain a PolarWorld instance. ```java PolarWorld world = PolarReader.read(bytes); PolarWorld world = new PolarWorld(); PolarWorld world = AnvilPolar.anvilToPolar(path); PolarWorld world = loader.world(); ``` -------------------------------- ### Version Conversion Implementation Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Shows an example of implementing version-aware transformations for data compatibility. ```java class MyConverter extends PolarDataConverter { @Override public void convert(Chunk chunk, int targetVersion) { // ... custom conversion logic ... } } ``` -------------------------------- ### Enable Logging with SLF4J Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Configure logging for debugging. This example suggests using SLF4J and provides a hint for Logback configuration. ```java // Use SLF4J with appropriate backend // Example with Logback: set "" ``` -------------------------------- ### Convert Block Palette Example Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarDataConverter.md Converts a block palette from an older version to a newer one. This example specifically handles converting old sculk block IDs to the new 'sculk_shrieker' ID before version 1.19.3. ```java @Override public void convertBlockPalette(String[] palette, int fromVersion, int toVersion) { if (fromVersion < 2584) { // Before 1.19.3 for (int i = 0; i < palette.length; i++) { // Convert old sculk blocks to new ID if (palette[i].contains("sculk")) { palette[i] = palette[i].replace("minecraft:sculk", "minecraft:sculk_shrieker"); } } } } ``` -------------------------------- ### Saving All Instance Chunks Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Example of how to save all chunks belonging to an instance using the saveChunks method. ```java loader.saveChunks(instance.getChunks()); ``` -------------------------------- ### Setting Chunk Loader Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Example of how to set a custom chunk loader for an instance. The loadInstance method is called automatically by Minestom. ```java instance.setChunkLoader(loader); // loadInstance is called automatically by Minestom ``` -------------------------------- ### Performing Streaming Load with FileChannel Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Example of how to use the experimental streamLoad method by opening a FileChannel and providing necessary parameters. The operation is joined to wait for completion. ```java try (var channel = FileChannel.open(path, StandardOpenOption.READ)) { long size = Files.size(path); PolarLoader.streamLoad(instance, channel, size, null, null, true).join(); } ``` -------------------------------- ### Target Data Version Implementation Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarDataConverter.md Returns the target data version for conversions. This example targets the latest Minestom data version. ```java @Override public int dataVersion() { return MinecraftServer.DATA_VERSION; // Target latest } ``` -------------------------------- ### Streaming Large Worlds Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Example usage of the experimental StreamingPolarLoader for handling very large worlds efficiently. ```java StreamingPolarLoader streamLoader = new StreamingPolarLoader(worldAccess); streamLoader.streamChunk(chunkPos); ``` -------------------------------- ### Selective Chunk Conversion Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Provides an example of converting specific chunks using ChunkSelector. ```java ChunkSelector selector = ChunkSelector.byCoordinates(x, z); AnvilPolar.convertWorld(world, selector, new MyConverter()); ``` -------------------------------- ### Default Data Version Implementation Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarDataConverter.md Returns the data version to assume for older Polar format versions that do not store version information. This example assumes the 1.20.1 data version. ```java @Override public int defaultDataVersion() { // Assume 1.20.1 data version for old worlds return 3450; // 1.20.1 data version } ``` -------------------------------- ### Attach PolarLoader with Custom Access Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Example of attaching a custom PolarWorldAccess implementation to a PolarLoader. This configures the loader to use the provided world access logic for persistence. ```java var loader = new PolarLoader(Path.of("world.polar")); loader.setWorldAccess(new ChunkTimestampAccess()); instance.setChunkLoader(loader); ``` -------------------------------- ### Create New Empty PolarWorld Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Creates a new empty PolarWorld instance with default settings. This is useful for starting a new world with standard configurations. ```java public PolarWorld() ``` ```java PolarWorld world = new PolarWorld(); ``` -------------------------------- ### Convert Block Entity Data Example Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarDataConverter.md Converts block entity data, specifically for signs, from older versions to the format used in 1.19.3 and later. It reconstructs the 'front_text' NBT tag from old 'Text1-4' fields if necessary. ```java @Override public Map.Entry convertBlockEntityData( String id, CompoundBinaryTag data, int fromVersion, int toVersion ) { if ("minecraft:sign".equals(id) && fromVersion < 2584) { // 1.19.3 changed sign data format from Text1-4 to front_text var frontText = data.getCompound("front_text"); if (frontText == null) { // Reconstruct from old format var newFront = CompoundBinaryTag.builder(); for (int i = 1; i <= 4; i++) { var line = data.getString("Text" + i); if (line != null && !line.isEmpty()) { newFront.putString("messages", line); } } data = data.remove("Text1").remove("Text2") .remove("Text3").remove("Text4") .put("front_text", newFront.build()); } } return Map.entry(id, data); } ``` -------------------------------- ### Implement Custom User Data Handling for Polar Chunks Source: https://github.com/hollow-cube/polar/blob/main/README.md Implement the PolarWorldAccess interface to manage custom user data within Polar chunks. This example saves the current time as user data. ```java public class UpdateTimeWorldAccess implements PolarWorldAccess { private static final Logger logger = LoggerFactory.getLogger(UpdateTimeWorldAccess.class); @Override public void loadChunkData(@NotNull Chunk chunk, @Nullable NetworkBuffer userData) { if (userData == null) return; // No saved data, probably first load long lastSaveTime = userData.read(NetworkBuffer.LONG); logger.info("loading chunk {}, {} which was saved at {}.", chunk.getChunkX(), chunk.getChunkZ(), lastSaveTime); } @Override public void saveChunkData(@NotNull Chunk chunk, @NotNull NetworkBuffer userData) { userData.write(NetworkBuffer.LONG, System.currentTimeMillis()); } } // Usage: // new PolarLoader(world).setWorldAccess(new UpdateTimeWorldAccess()) ``` -------------------------------- ### Version-Safe Polar World Reading with Recovery Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/errors.md This example shows how to safely read Polar world data, handling potential 'PolarReader.Error' exceptions that indicate an invalid world format. It includes a placeholder for fallback logic if an error occurs. ```java byte[] data = Files.readAllBytes(path); try { PolarWorld world = PolarReader.read(data, myDataConverter); } catch (PolarReader.Error e) { System.err.println("Invalid world format: " + e.getMessage()); // Load fallback or handle error } ``` -------------------------------- ### Enable Debug Logging for Polar Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/errors.md To enable detailed logging for the Polar library, set the system property 'org.slf4j.simpleLogger.defaultLogLevel' to 'DEBUG' before the application starts. This is useful for diagnosing issues. ```java // Set system property before loading Polar System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "DEBUG"); ``` -------------------------------- ### Custom ChunkSelector Implementations Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/ChunkSelector.md Implement the ChunkSelector interface directly using lambda expressions for custom selection logic. Examples include rectangular regions, checkerboard patterns, and time-based filtering. ```java // Select chunks in a rectangular region ChunkSelector rect = (x, z) -> x >= -5 && x <= 5 && z >= -5 && z <= 5; // Select checkerboard pattern ChunkSelector checkerboard = (x, z) -> (x + z) % 2 == 0; // Select only chunks modified after a certain time ChunkSelector recent = (x, z) -> { Path chunkFile = Path.of("region").resolve("r." + (x >> 5) + "." + (z >> 5) + ".mca"); return Files.getLastModifiedTime(chunkFile).toMillis() > cutoffTime; }; ``` -------------------------------- ### Load and Configure Polar World Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/README.md Demonstrates how to initialize a PolarLoader and configure its behavior, such as custom data handling, parallel operations, and lighting data loading. ```java var loader = new PolarLoader(path); loader.setWorldAccess(access) // Custom data handling .setParallel(true) // Parallel load/save .setLoadLighting(false); // Skip lighting data ``` -------------------------------- ### loadInstance Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Loads an entire instance when it is created. It can invoke custom callbacks for world user data. ```APIDOC ## loadInstance(Instance instance) ### Description Called when the instance is created. Invokes the custom `PolarWorldAccess.loadWorldData()` callback if world user data is present. ### Method `loadInstance` ### Parameters #### Path Parameters - **instance** (Instance) - Required - The Minestom instance being initialized ### Request Example ```java instance.setChunkLoader(loader); // loadInstance is called automatically by Minestom ``` ``` -------------------------------- ### Stream-loading a Large World with StreamingPolarLoader Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/StreamingPolarLoader.md Demonstrates how to stream-load a large world file using StreamingPolarLoader. Includes optional data converter and world access, and enables lighting load. Handles completion and errors asynchronously. ```java // Stream-load a large world Path path = Path.of("large-world.polar"); InstanceContainer instance = new InstanceContainer(...); try (var channel = FileChannel.open(path, StandardOpenOption.READ)) { long size = Files.size(path); var future = PolarLoader.streamLoad( instance, channel, size, new MyDataConverter(), // Optional new MyWorldAccess(), // Optional true // Load lighting ); // Wait for completion or handle asynchronously future.thenApply(v -> { System.out.println("World loaded!"); return null; }).exceptionally(e -> { System.err.println("Load failed: " + e.getMessage()); return null; }); } catch (IOException e) { System.err.println("Cannot open file: " + e.getMessage()); } ``` -------------------------------- ### Get All Chunks Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Returns a collection of all PolarChunk objects currently in the world. Useful for iterating over all stored chunks. ```java public @NotNull Collection chunks() ``` ```java for (PolarChunk chunk : world.chunks()) { System.out.println("Chunk at " + chunk.x() + ", " + chunk.z()); } ``` -------------------------------- ### Get Underlying World Data Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Retrieves the PolarWorld object managed by this loader, which contains all chunk and metadata for the world. ```java public @NotNull PolarWorld world() ``` ```java PolarWorld worldData = loader.world(); System.out.println("Chunks: " + worldData.chunks().size()); ``` -------------------------------- ### Basic Loading and Saving Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Demonstrates fundamental operations for loading and saving data using the Polar library. ```java PolarReader reader = new PolarReader(file); PolarWorld world = reader.loadWorld(); PolarWriter writer = new PolarWriter(file); writer.saveWorld(world); ``` -------------------------------- ### Run Benchmark with PolarLoader Source: https://github.com/hollow-cube/polar/blob/main/BENCHMARK.md This Java code initializes the Minecraft server, creates an instance, and then runs a benchmark loop. It measures the time taken to load chunks using PolarLoader for a specified number of iterations and chunk coordinates. Finally, it prints the average time per iteration and stops the server. ```java public class ScuffedBenchmark { public static void main(String[] args) throws Exception { MinecraftServer.init(); var instance = MinecraftServer.getInstanceManager().createInstanceContainer(); long start = System.nanoTime(); for (int iter = 0; iter < 10; iter++) { System.out.println("Starting iteration " + iter); // TNTLoader loader = new TNTLoader(new FileTNTSource(Path.of("src/test/resources/bench/bench.tnt"))); // AnvilLoader loader = new AnvilLoader(Path.of("src/test/resources/bench")); PolarLoader loader = new PolarLoader(PolarReader.read(Files.readAllBytes(Path.of("src/test/resources/bench.polar")))); for (int x = 0; x < 32; x++) { for (int z = 0; z < 32; z++) { loader.loadChunk(instance, 0, 0).join(); } } } long end = System.nanoTime(); System.out.println("Took " + (end - start) / 1_000_000_000.0 / 10.0 + " seconds/iter"); MinecraftServer.stopCleanly(); } } ``` -------------------------------- ### Main Entry Point for Streaming Load Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/StreamingPolarLoader.md This method is the primary entry point for the streaming load process, called internally by `streamLoad()`. It handles the sequential reading and processing of the Polar file from the provided channel. ```java public void loadAllSequential(ReadableByteChannel channel, long fileSize) throws IOException ``` -------------------------------- ### Get Chunk at Coordinates Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves a specific PolarChunk at the given X and Z coordinates. Returns null if the chunk is not present. ```java public @Nullable PolarChunk chunkAt(int x, int z) ``` ```java PolarChunk chunk = world.chunkAt(0, 0); if (chunk != null) { System.out.println("Chunk sections: " + chunk.sections().length); } ``` -------------------------------- ### Get Heightmap by Type Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/types.md Returns the heightmap of the given type, or null if not present. The type is specified using constants like HEIGHTMAP_MOTION_BLOCKING. ```java public int[] heightmap(int type) ``` -------------------------------- ### Static Access Point for Streaming Load Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/StreamingPolarLoader.md This is the static method used to initiate the streaming load process. It takes various parameters to configure the loading process, including the instance, input channel, file size, data converter, world access, and lighting options. ```java public static @NotNull CompletableFuture streamLoad( @NotNull InstanceContainer instance, @NotNull ReadableByteChannel is, long fileSize, @Nullable PolarDataConverter dataConverter, @Nullable PolarWorldAccess worldAccess, boolean loadLighting ) ``` -------------------------------- ### Configuration Methods Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Methods to configure the behavior of the PolarLoader, including world access, parallel operations, and lighting data loading. ```APIDOC ## setWorldAccess(PolarWorldAccess worldAccess) ### Description Sets a custom `PolarWorldAccess` implementation for handling world and chunk-specific data callbacks. ### Parameters #### Path Parameters - **worldAccess** (PolarWorldAccess) - Required - Implementation providing custom world access behavior ### Response this (for method chaining) ### Example: ```java loader.setWorldAccess(new UpdateTimeWorldAccess()); ``` ``` ```APIDOC ## setParallel(boolean parallel) ### Description Enables or disables parallel chunk loading and saving. The Polar loader itself supports parallel operations, but custom `PolarWorldAccess` implementations may not. ### Parameters #### Path Parameters - **parallel** (boolean) - Required - True to enable parallel operations ### Response this (for method chaining) ### Example: ```java loader.setParallel(true); ``` ``` ```APIDOC ## setLoadLighting(boolean loadLighting) ### Description Controls whether lighting data should be loaded from the world file. ### Parameters #### Path Parameters - **loadLighting** (boolean) - Required - True to load and apply stored lighting data ### Response this (for method chaining) ``` -------------------------------- ### Get World User Data Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the world-level user data buffer. This is useful for applications using PolarWorldAccess to manage custom data. ```java public byte @NotNull [] userData() ``` ```java byte[] data = world.userData(); NetworkBuffer buffer = NetworkBuffer.wrap(data, 0, data.length); ``` -------------------------------- ### Get PolarWorld Maximum Section Y Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the maximum Y-coordinate for sections in the PolarWorld. This defines the upper boundary of the world's vertical space. ```java public byte maxSection() ``` -------------------------------- ### Handling File I/O Errors with IOException Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/errors.md Shows how to catch and manage IOException during PolarLoader initialization, providing a fallback mechanism for world loading. ```java try { var loader = new PolarLoader(Path.of("world.polar")); } catch (IOException e) { System.err.println("Cannot load world: " + e.getMessage()); // Fallback to empty world loader = new PolarLoader(new PolarWorld()); } ``` -------------------------------- ### Instance Initialization Callback Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md This method is automatically called by Minestom when an instance is created. It can be used to invoke custom world data loading logic. ```java @Override public void loadInstance(@NotNull Instance instance) ``` -------------------------------- ### Get PolarWorld Minimum Section Y Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the minimum Y-coordinate for sections in the PolarWorld. This defines the lower boundary of the world's vertical space. ```java public byte minSection() ``` -------------------------------- ### Get PolarWorld Compression Type Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the compression scheme used for the PolarWorld. This indicates whether data is compressed and using which algorithm (e.g., ZSTD). ```java public @NotNull CompressionType compression() ``` ```java if (world.compression() == PolarWorld.CompressionType.ZSTD) { System.out.println("Using Zstd compression"); } ``` -------------------------------- ### Get PolarWorld Data Version Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the Minecraft data version associated with the PolarWorld. This version is crucial for handling data upgrades and ensuring compatibility. ```java public int dataVersion() ``` -------------------------------- ### Custom Data Handling with PolarWorldAccess Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Illustrates how to extend Polar functionality by implementing custom data handling logic. ```java class MyWorldAccess implements PolarWorldAccess { // ... implementation of callback methods ... } PolarLoader loader = new PolarLoader(new MyWorldAccess()); ``` -------------------------------- ### Load World Data Callback Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Callback invoked when an instance is loaded. Use to initialize world properties from saved user data. Expects a NetworkBuffer containing saved world data. ```java default void loadWorldData( @NotNull Instance instance, @Nullable NetworkBuffer userData ) ``` ```java @Override public void loadWorldData(Instance instance, NetworkBuffer userData) { if (userData == null) return; long worldTime = userData.read(NetworkBuffer.LONG); String worldName = userData.read(NetworkBuffer.STRING); System.out.println("Loaded world: " + worldName + " (time: " + worldTime + ")"); } ``` -------------------------------- ### Load and Save Chunks Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/INDEX.md Initializes a PolarLoader and sets it for the instance to save chunks to storage. See QUICK_START.md for basic usage. ```java var loader = new PolarLoader(path); instance.setChunkLoader(loader); instance.saveChunksToStorage(); ``` -------------------------------- ### Set Compression Type and Write World Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWriter.md Demonstrates how to set the compression type for a PolarWorld object before writing it. ZSTD compression is recommended for smaller file sizes, while NONE appends content directly. ```java world.setCompression(PolarWorld.CompressionType.ZSTD); byte[] compressed = PolarWriter.write(world); world.setCompression(PolarWorld.CompressionType.NONE); byte[] uncompressed = PolarWriter.write(world); ``` -------------------------------- ### Set Custom World Access Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/INDEX.md Configures the loader to use a custom world access implementation for handling user data. See PolarWorldAccess.md for usage examples. ```java loader.setWorldAccess(new MyWorldAccess()); ``` -------------------------------- ### Custom Biome ID Mapping Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Implement `getBiomeId` in `PolarWorldAccess` to provide custom mappings for unsupported or old biome names. This example maps a custom name to 'minecraft:plains'. ```java public class BiomeMapAccess implements PolarWorldAccess { @Override public int getBiomeId(String name) { // Custom mapping for unsupported biomes if ("minecraft:old_biome".equals(name)) { return super.getBiomeId("minecraft:plains"); } return super.getBiomeId(name); } } ``` -------------------------------- ### Polar Project File Structure Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/INDEX.md Overview of the directory structure for the Polar project, highlighting key documentation and API reference files. ```text output/ ├── README.md ← Start here ├── QUICK_START.md ← Code examples ├── INDEX.md ← This file ├── types.md ← All type definitions ├── errors.md ← All error conditions └── api-reference/ ├── PolarLoader.md ├── PolarWorld.md ├── PolarReader.md ├── PolarWriter.md ├── AnvilPolar.md ├── ChunkSelector.md ├── PolarWorldAccess.md ├── PolarDataConverter.md └── StreamingPolarLoader.md ``` -------------------------------- ### Load Heightmaps Callback (Experimental) Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Experimental callback for loading heightmap data. The default implementation does nothing. This method is intended for advanced heightmap manipulation. ```java @ApiStatus.Experimental default void loadHeightmaps( @NotNull Chunk chunk, int[][] heightmaps ) ``` -------------------------------- ### loadWorldData(Instance instance, NetworkBuffer userData) Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Callback to load custom world data. Implement this to load data saved by saveWorldData. ```APIDOC ## loadWorldData(Instance instance, NetworkBuffer userData) ### Description Callback to load custom world data. Implement this to load data saved by saveWorldData. ### Parameters #### Path Parameters - instance (Instance) - Required - The instance to load data into. - userData (NetworkBuffer) - Required - The buffer containing the world data. ### Example ```java @Override public void loadWorldData(Instance instance, NetworkBuffer userData) { if (userData == null) return; long creationTime = userData.read(NetworkBuffer.LONG); instance.setTag("creation_time", creationTime); logger.info("Loaded world created at: " + new Date(creationTime)); } ``` ``` -------------------------------- ### Get Biome ID from Name Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Converts a biome namespace string to its integer registry ID. The default implementation uses Minestom's biome registry. Returns -1 if the biome is not found. ```java default int getBiomeId(@NotNull String name) ``` -------------------------------- ### Custom Biome ID Lookup Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Example of overriding the default getBiomeId method to provide custom mapping or log unknown biomes. It calls the superclass method and handles cases where the biome ID is not found. ```java @Override public int getBiomeId(String name) { // Custom mapping or logging int id = super.getBiomeId(name); if (id == -1) { System.err.println("Unknown biome: " + name); } return id; } ``` -------------------------------- ### PolarLoader Constructors Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Provides different ways to instantiate a PolarLoader, from a file path, an existing PolarWorld object, an input stream, or a PolarWorld object without persistence. ```APIDOC ## PolarLoader(Path path) ### Description Creates a loader from a filesystem path. If the file exists, it is immediately loaded into memory. If not, a new empty world is created. ### Parameters #### Path Parameters - **path** (Path) - Required - Filesystem path to the Polar world file (`.polar` extension expected) ### Response #### Success Response A new PolarLoader instance ### Throws `IOException` if the file exists but cannot be read ### Example: ```java var loader = new PolarLoader(Path.of("world.polar")); instance.setChunkLoader(loader); ``` ``` ```APIDOC ## PolarLoader(Path savePath, PolarWorld worldData) ### Description Creates a loader with an existing PolarWorld object and an optional save path. ### Parameters #### Path Parameters - **savePath** (Path) - Required - Path where the world will be saved (can be null) - **worldData** (PolarWorld) - Required - The world data to use ### Response A new PolarLoader instance ``` ```APIDOC ## PolarLoader(InputStream inputStream) ### Description Creates a loader from an input stream. The stream is read and closed by this constructor. ### Parameters #### Path Parameters - **inputStream** (InputStream) - Required - Stream containing compressed or uncompressed Polar world data ### Response A new PolarLoader instance ### Throws `IOException` if the stream cannot be read ``` ```APIDOC ## PolarLoader(PolarWorld world) ### Description Creates a loader from an existing PolarWorld object with no filesystem persistence. ### Parameters #### Path Parameters - **world** (PolarWorld) - Required - The world data to use ### Response A new PolarLoader instance ``` -------------------------------- ### loadHeightmaps Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Experimental callback for loading heightmap data. Default implementation does nothing. ```APIDOC ## loadHeightmaps(Chunk chunk, int[][] heightmaps) ### Description Experimental callback for loading heightmap data. Default implementation does nothing. ### Method Default (no-op) implementation provided, intended to be overridden. ### Parameters #### Path Parameters - chunk (Chunk) - Required - The chunk being loaded - heightmaps (int[][]) - Required - Array of heightmap arrays (may contain nulls) ### Note The Polar format supports standard Minecraft heightmap types (motion blocking, ocean floor, world surface, etc.). See `PolarChunk` for heightmap type constants. ``` -------------------------------- ### Convert Specific Regions using ChunkSelector Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/ChunkSelector.md Define a ChunkSelector to target a specific 32x32 chunk region for conversion. This example selects chunks within the 0 to 31 range for both X and Z coordinates. ```java // Convert only one 32x32 chunk region // Region boundaries: chunk coordinates are 32*regionX to 32*regionX+31 ChunkSelector region0_0 = (x, z) -> x >= 0 && x < 32 && z >= 0 && z < 32; var world = AnvilPolar.anvilToPolar(path, region0_0); ``` -------------------------------- ### PolarLoader.streamLoad() Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/StreamingPolarLoader.md Loads Polar worlds sequentially from a channel without loading the entire file into memory first. Uses virtual threads for non-blocking I/O. ```APIDOC ## PolarLoader.streamLoad() ### Description Loads Polar worlds sequentially from a channel without loading the entire file into memory first. This method is designed for memory efficiency, especially for large world files, by processing chunks as they are read and then discarding references, allowing for garbage collection. ### Method CompletableFuture ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **instance** (InstanceContainer) - Required - The instance container to load the world into. - **is** (ReadableByteChannel) - Required - The readable byte channel to read the world data from. - **fileSize** (long) - Required - The total size of the world file in bytes. - **dataConverter** (PolarDataConverter) - Optional - A converter for Polar data. - **worldAccess** (PolarWorldAccess) - Optional - An interface for accessing and modifying the world during loading. - **loadLighting** (boolean) - Optional - Whether to load lighting data. ### Request Example None ### Response #### Success Response (CompletableFuture completes) - The loading process completes successfully. #### Response Example None ERROR HANDLING: - The CompletableFuture will complete exceptionally if any errors occur during the loading process, such as IOExceptions during reading or errors due to an invalid file format. ``` -------------------------------- ### PolarWorld(short version, int dataVersion, CompressionType compression, byte minSection, byte maxSection, byte[] userData, List chunks) Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Creates a PolarWorld instance with explicitly defined parameters. This constructor is primarily used internally by readers and builders to construct a world from existing data. ```APIDOC ## PolarWorld(short version, int dataVersion, CompressionType compression, byte minSection, byte maxSection, byte[] userData, List chunks) ### Description Creates a world with explicit parameters. Used internally by readers and builders. ### Method Constructor ### Parameters #### Path Parameters - **version** (short) - Required - Format version (typically `LATEST_VERSION = 7`) - **dataVersion** (int) - Required - Minecraft data version for version upgrades - **compression** (CompressionType) - Required - Compression scheme (NONE or ZSTD) - **minSection** (byte) - Required - Minimum section Y coordinate (e.g., -4) - **maxSection** (byte) - Required - Maximum section Y coordinate (e.g., 19) - **userData** (byte[]) - Required - Arbitrary world-level data (empty array if none) - **chunks** (List) - Required - List of all chunks in the world ### Returns New PolarWorld instance ``` -------------------------------- ### Get Biome Name from ID Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Converts a biome registry ID to its namespace string. The default implementation uses Minestom's biome registry. It provides a fallback to 'minecraft:plains' if the ID is not found. ```java default @NotNull String getBiomeName(int id) ``` -------------------------------- ### AnvilPolar API Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Documentation for Anvil world conversion using AnvilPolar, including static method overloads. ```APIDOC ## AnvilPolar ### Description Provides functionality for converting Anvil world formats to Polar. This class offers static methods to facilitate the conversion process. ### Class AnvilPolar ### Methods - **Static Method Overloads**: 4 overloads available for different conversion scenarios. ``` -------------------------------- ### Save Subset of Chunks using ChunkSelector Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/ChunkSelector.md Utilize ChunkSelectors during save operations to persist only a selected portion of the world data. This example demonstrates loading a full world and then saving only chunks within a radius of 10. ```java // Load a full world var loader = new PolarLoader(Path.of("world.polar")); var instance = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD); instance.setChunkLoader(loader); // Convert to save only spawn area var selector = ChunkSelector.radius(10); var spawnWorld = AnvilPolar.anvilToPolar( anvilPath, selector ); // Save the subset var spawnLoader = new PolarLoader(spawnWorld); spawnLoader.saveChunks(loadedChunks); ``` -------------------------------- ### Experimental Streaming Instance Load Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Loads an instance using a streaming approach to minimize memory usage. This experimental feature uses virtual threads internally. ```java @ApiStatus.Experimental public static @NotNull CompletableFuture streamLoad( @NotNull InstanceContainer instance, @NotNull ReadableByteChannel is, long fileSize, @Nullable PolarDataConverter dataConverter, @Nullable PolarWorldAccess worldAccess, boolean loadLighting ) ``` -------------------------------- ### Multi-Version World Loading with Conversion Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Load world data that may be in an older format. The `UpgradeConverter` handles necessary conversions automatically. ```java // Load with conversion if needed PolarWorld world = PolarReader.read(data, new UpgradeConverter()); PolarLoader loader = new PolarLoader(world); instance.setChunkLoader(loader); ``` -------------------------------- ### PolarWorld() Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Creates a new empty PolarWorld instance with default settings. These include the latest format version, current Minestom data version, Zstd compression, and a standard height range of -4 to 19 sections. ```APIDOC ## PolarWorld() ### Description Creates a new empty world with default settings: latest format version, current Minestom data version, Zstd compression, and vanilla height range (-4 to 19 sections). ### Method Constructor ### Returns New empty PolarWorld instance ### Example ```java PolarWorld world = new PolarWorld(); ``` ``` -------------------------------- ### Virtual Thread Execution for Loading Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/StreamingPolarLoader.md The entire loading process is executed on a virtual thread to allow non-blocking I/O without consuming platform threads. This method ensures that the loading process completes or fails gracefully. ```java Thread.startVirtualThread(() -> { try { loader.loadAllSequential(is, fileSize); future.complete(null); } catch (Throwable e) { future.completeExceptionally(e); } }); ``` -------------------------------- ### Control Lighting Data Loading Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Determines whether lighting data should be loaded from the world file. Set to true to load and apply stored lighting information. ```java @Contract("_ -> this") public @NotNull PolarLoader setLoadLighting(boolean loadLighting) ``` -------------------------------- ### Safe Polar Instance Creation with Error Handling Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/errors.md This snippet illustrates how to safely initialize an instance with a Polar chunk loader, catching both IOExceptions and RuntimeExceptions. If an error occurs during loading, it falls back to creating an empty instance. ```java try { var loader = new PolarLoader(path); var instance = new InstanceContainer(...); instance.setChunkLoader(loader); } catch (IOException | RuntimeException e) { logger.error("Failed to load world, creating empty", e); var instance = new InstanceContainer(...); instance.setChunkLoader(new PolarLoader(new PolarWorld())); } ``` -------------------------------- ### Defensive Polar World Loading Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/errors.md This code demonstrates a robust approach to loading a Polar world, including a fallback mechanism to create a new empty world if the specified file cannot be loaded due to an IOException. It ensures that a loader is always available. ```java Path worldPath = Path.of("world.polar"); PolarLoader loader; try { loader = new PolarLoader(worldPath); } catch (IOException e) { // Fallback to new empty world System.err.println("Cannot load world: " + e.getMessage()); loader = new PolarLoader(worldPath, new PolarWorld()); } ``` -------------------------------- ### Create PolarLoader from File Path Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Creates a PolarLoader instance from a filesystem path. If the file exists, it's loaded; otherwise, a new world is created. Ensure the path has a .polar extension. ```java public PolarLoader(@NotNull Path path) throws IOException ``` ```java var loader = new PolarLoader(Path.of("world.polar")); instance.setChunkLoader(loader); ``` -------------------------------- ### StreamingPolarLoader API Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Documentation for the experimental StreamingPolarLoader class, noting its internal methods. ```APIDOC ## StreamingPolarLoader ### Description An experimental class for streaming world data loading in the Polar format. While it has several internal methods, its primary purpose is to offer a streaming approach to loading. ### Class StreamingPolarLoader ### Methods - **Internal Methods**: 6+ internal methods are part of this experimental loader. ``` -------------------------------- ### Conversion Tools Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Information on conversion tools like AnvilPolar, ChunkSelector, and PolarDataConverter. ```APIDOC ## Conversion Tools ### AnvilPolar - Provides 4 overloaded methods for converting between Anvil and Polar formats. ### ChunkSelector - Offers 3 static factories for selecting chunks. - Supports custom implementation patterns for advanced selection logic. ### PolarDataConverter - Implements version-aware transformations for Polar data. ``` -------------------------------- ### Create a ChunkSelector that Selects All Chunks Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/ChunkSelector.md Use the 'all()' static factory method to create a ChunkSelector that includes every chunk. This is equivalent to a lambda expression that always returns true. ```java static @NotNull ChunkSelector all() // Example: var selector = ChunkSelector.all(); var world = AnvilPolar.anvilToPolar(path, selector); ``` -------------------------------- ### Load Chunk Data Callback Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Callback invoked when a chunk is loaded. Use to initialize chunk properties from saved user data. Expects a NetworkBuffer containing saved chunk data. ```java default void loadChunkData( @NotNull Chunk chunk, @Nullable NetworkBuffer userData ) ``` ```java @Override public void loadChunkData(Chunk chunk, NetworkBuffer userData) { if (userData == null) return; int chunkPopulationTime = userData.read(NetworkBuffer.INT); chunk.setTag("population_time", chunkPopulationTime); } ``` -------------------------------- ### Load a Polar World into an Instance Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Creates a new instance and sets a PolarLoader to load world data from a specified file path. ```java import net.hollowcube.polar.*; import net.minestom.server.instance.*; import java.nio.file.Path; import java.util.UUID; // Create instance Instance instance = new InstanceContainer( UUID.randomUUID(), DimensionType.OVERWORLD ); // Load Polar world try { PolarLoader loader = new PolarLoader(Path.of("world.polar")); instance.setChunkLoader(loader); } catch (IOException e) { System.err.println("Failed to load world: " + e.getMessage()); } ``` -------------------------------- ### loadWorldData Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Called when an instance is first loaded from a chunk loader. Can initialize world properties from saved user data. ```APIDOC ## loadWorldData(Instance instance, NetworkBuffer userData) ### Description Called when an instance is first loaded from a chunk loader. Can initialize world properties from saved user data. ### Method Default (no-op) implementation provided, intended to be overridden. ### Parameters #### Path Parameters - instance (Instance) - Required - The Minestom instance being created - userData (NetworkBuffer) - Optional - Saved world user data, or null if none was stored ### Request Example ```java @Override public void loadWorldData(Instance instance, NetworkBuffer userData) { if (userData == null) return; long worldTime = userData.read(NetworkBuffer.LONG); String worldName = userData.read(NetworkBuffer.STRING); System.out.println("Loaded world: " + worldName + " (time: " + worldTime + ")"); } ``` ``` -------------------------------- ### Stream Loading with MyDataConverter Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarDataConverter.md Initiates a streaming load operation using a custom MyDataConverter. Ensure all necessary parameters like instance, channel, and world access are provided. ```java var converter = new MyDataConverter(); PolarLoader.streamLoad( instance, channel, fileSize, converter, worldAccess, true ); ``` -------------------------------- ### ChunkLoader Interface Implementation Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Methods implementing the ChunkLoader interface, indicating support for parallel operations. ```APIDOC ## supportsParallelLoading() ### Description Returns true if parallel loading was enabled via `setParallel(true)`. ### Response boolean ``` ```APIDOC ## supportsParallelSaving() ### Description Returns true if parallel saving was enabled via `setParallel(true)`. ### Response boolean ``` -------------------------------- ### PolarLoader API Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Documentation for the main ChunkLoader implementation, including constructor overloads and methods for loading world data. ```APIDOC ## PolarLoader ### Description Provides the main ChunkLoader implementation for the Polar world format. It includes numerous constructor and static overloads for flexible initialization and a rich set of methods for loading world data. ### Class PolarLoader ### Methods - **Constructor Overloads**: 10 available for various initialization scenarios. - **Methods**: 15+ methods documented for loading and managing world data. ### Parameters Detailed parameter tables with types and descriptions are available for all methods and constructors. ``` -------------------------------- ### Accessing Block in Loaded Chunk Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Demonstrates how to retrieve a chunk and then access a specific block within it, provided the chunk was successfully loaded. ```java Chunk chunk = loader.loadChunk(instance, 0, 0); if (chunk != null) { Block block = chunk.getBlock(5, 64, 5); } ``` -------------------------------- ### Convert Anvil World to Polar (Simple) Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/START_HERE.md Perform a straightforward conversion of an Anvil world to the Polar format and write it to a file. ```java // Simple conversion var polar = AnvilPolar.anvilToPolar(Path.of("anvil/world")); Files.write(Path.of("world.polar"), PolarWriter.write(polar)); ``` -------------------------------- ### Implement Custom World Data Access Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Provides custom logic for loading and saving application-specific data associated with the world. ```java public class GameStateWorldAccess implements PolarWorldAccess { @Override public void loadWorldData(Instance instance, NetworkBuffer userData) { if (userData == null) return; int gameMode = userData.read(NetworkBuffer.INT); String gameName = userData.read(NetworkBuffer.STRING); instance.setTag("game_mode", gameMode); instance.setTag("game_name", gameName); } @Override public void saveWorldData(Instance instance, NetworkBuffer userData) { Integer gameMode = instance.getTag("game_mode"); String gameName = instance.getTag("game_name"); userData.write(NetworkBuffer.INT, gameMode != null ? gameMode : 0); userData.write(NetworkBuffer.STRING, gameName != null ? gameName : "Unnamed"); } } // Attach to loader var loader = new PolarLoader(path); loader.setWorldAccess(new GameStateWorldAccess()); instance.setChunkLoader(loader); ``` -------------------------------- ### PolarWriter API Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Documentation for binary serialization using PolarWriter, including available static methods. ```APIDOC ## PolarWriter ### Description Handles binary serialization for the Polar format. This class provides static methods for writing data to the specified format. ### Class PolarWriter ### Methods - **Static Methods**: 2 static methods available for serialization tasks. ``` -------------------------------- ### saveInstance Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Saves the entire instance's chunks and world metadata, invoking custom save callbacks and synchronizing dimension height settings. ```APIDOC ## saveInstance(Instance instance) ### Description Saves the entire instance's chunks and world metadata. Invokes `PolarWorldAccess.saveWorldData()` callbacks. Automatically synchronizes dimension height settings with the loaded world. ### Method `saveInstance` ### Parameters #### Path Parameters - **instance** (Instance) - Required - The instance to save ``` -------------------------------- ### Create PolarLoader with Existing World Data Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Creates a PolarLoader using an existing PolarWorld object and an optional save path. ```java public PolarLoader(@NotNull Path savePath, @NotNull PolarWorld worldData) ``` -------------------------------- ### Parallel Operations Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Demonstrates how to leverage parallel processing for improved performance in Polar operations. ```java PolarLoader loader = new PolarLoader(worldAccess, ParallelOptions.defaultOptions()); loader.loadChunk(chunkPos); ``` -------------------------------- ### Lobby World Configuration Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Configure `PolarLoader` for a small, static lobby world by disabling parallelism. This optimizes loading for predictable, unchanging environments. ```java // Fast, predictable load PolarLoader loader = new PolarLoader(Path.of("lobby.polar")); loader.setParallel(false); // No need for parallelism instance.setChunkLoader(loader); ``` -------------------------------- ### saveWorldData(Instance instance, NetworkBuffer userData) Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorldAccess.md Callback to save custom world data. This data will be available in subsequent loadWorldData calls. ```APIDOC ## saveWorldData(Instance instance, NetworkBuffer userData) ### Description Callback to save custom world data. This data will be available in subsequent loadWorldData calls. ### Parameters #### Path Parameters - instance (Instance) - Required - The instance to save data from. - userData (NetworkBuffer) - Required - The buffer to write the world data into. ### Example ```java @Override public void saveWorldData(Instance instance, NetworkBuffer userData) { Long creationTime = instance.getTag("creation_time"); if (creationTime == null) { creationTime = System.currentTimeMillis(); instance.setTag("creation_time", creationTime); } userData.write(NetworkBuffer.LONG, creationTime); } ``` ``` -------------------------------- ### version() Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the format version of the PolarWorld. This indicates the specific version of the Polar world file format being used. ```APIDOC ## version() ### Description Returns the format version of this world. ### Method Accessor ### Returns short (version number) ### Example ```java if (world.version() >= PolarWorld.VERSION_DATA_CONVERTER) { System.out.println("Data converter supported"); } ``` ``` -------------------------------- ### compression() Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarWorld.md Retrieves the compression scheme currently applied to the PolarWorld. This specifies how the world's data is compressed, typically using NONE or ZSTD. ```APIDOC ## compression() ### Description Returns the compression scheme applied to this world. ### Method Accessor ### Returns CompressionType enum value ### Example ```java if (world.compression() == PolarWorld.CompressionType.ZSTD) { System.out.println("Using Zstd compression"); } ``` ``` -------------------------------- ### Game Arena Loading from Anvil Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Convert and load a fixed region of a world from Anvil format using a specified radius. This is useful for creating game arenas. ```java // Convert only relevant area from Anvil PolarWorld polar = AnvilPolar.anvilToPolar( anvilPath, ChunkSelector.radius(50, 50, 50) // 50-chunk radius around (50, 50) ); PolarLoader loader = new PolarLoader(polar); instance.setChunkLoader(loader); ``` -------------------------------- ### Saving an Entire Instance Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarLoader.md Saves all chunks and metadata for a given instance. This method also synchronizes dimension height settings and invokes custom save callbacks. ```java @Override public void saveInstance(@NotNull Instance instance) ``` -------------------------------- ### PolarWorld API Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Documentation for the PolarWorld class, including constructors, version constants, compression types, and chunk access methods. ```APIDOC ## PolarWorld ### Description Represents the Polar world, offering constructors for various scenarios, version information, compression handling, and chunk/height management. ### Constructors - 3 constructors for different use cases. ### Versioning - Constants and metadata related to world versions. ### Compression - `CompressionType` enum with conversion utilities. ### Chunk Access - Methods for accessing and manipulating chunks within the world. ### Height Management - Utilities for managing world height. ``` -------------------------------- ### convertBlockPalette(String[] palette, int fromVersion, int toVersion) Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/api-reference/PolarDataConverter.md Converts a block palette, represented as an array of block state strings, from a source data version to a target data version. Implementations should modify the provided array in-place. This method is invoked during the reading process when the file's data version differs from the target version. ```APIDOC ## convertBlockPalette(String[] palette, int fromVersion, int toVersion) ### Description Converts a block palette (array of block state strings) from one version to another. Implementations should modify the array in-place. Called during reading if file version differs from target version. ### Parameters #### Path Parameters - **palette** (String[]) - Required - Array of block state strings like "minecraft:stone_stairs[facing=north]" - **fromVersion** (int) - Required - The current data version of the palette - **toVersion** (int) - Required - The target data version ### Note The palette contains block states as strings that may be parsed/validated only during loading, so version-specific property changes should be applied here. ### Example ```java @Override public void convertBlockPalette(String[] palette, int fromVersion, int toVersion) { if (fromVersion < 2584) { // Before 1.19.3 for (int i = 0; i < palette.length; i++) { // Convert old sculk blocks to new ID if (palette[i].contains("sculk")) { palette[i] = palette[i].replace("minecraft:sculk", "minecraft:sculk_shrieker"); } } } } ``` ``` -------------------------------- ### Implement Custom Chunk Data Access Source: https://github.com/hollow-cube/polar/blob/main/_autodocs/QUICK_START.md Enables loading and saving of custom metadata for individual chunks. ```java public class ChunkMetadataAccess implements PolarWorldAccess { @Override public void loadChunkData(Chunk chunk, NetworkBuffer userData) { if (userData == null) return; long generatedTime = userData.read(NetworkBuffer.LONG); chunk.setTag("generated_at", generatedTime); } @Override public void saveChunkData(Chunk chunk, NetworkBuffer userData) { Long generatedAt = chunk.getTag("generated_at"); if (generatedAt == null) { generatedAt = System.currentTimeMillis(); chunk.setTag("generated_at", generatedAt); } userData.write(NetworkBuffer.LONG, generatedAt); } } ```