Preprocessing Maps
Generate Minecraft worlds by map images!
It’s recommended to preprocess the map image in order to ensure there are no invalid pixel colors and the world will be of the desired scale. The implemented preprocessing algorithms scale a map where each pixel equals one chunk to a map where each pixel equals 4x4 blocks.
To also view a map in the map menu, save the map that shall be displayed at /assets/<namespace>/textures/gui/<map id>.png
.
Via Command Line
You can use the mod file as a command line tool to upscale your map image.
usage: java -jar ctgen-0.25.jar -i <arg> -z <arg> -o <arg> [-c <arg>] [-oc]
Tool for upscaling map images so they can be properly read by
the Crafted Terrain Generation Mod (CTGen).
Every image file path must end with ".png"
-i,--input <arg> Input map image, no alpha supported!
-z,--zones <arg> directory containing the zones as json files
-o,--output <arg> Output map image
-c,--corrected <arg> Optional file to save an image with only the corrected colors
-oc,--only-changed Works only in addition to --corrected, the corrected image will only show the changed pixel.
Copyright (c) 2024 To_Craft. Licensed under the Crafted License 1.0
For example, you can use the CLI like the following:
java -jar ctgen-1.0.jar -i map.png -o upscaled_map.png -z zones/
The example uses the following file structure:
<dir>
├── ctgen-0.25.jar -- The mod file for CTGen
├── map.png -- Your input file
├── upscaled_map.png -- Will be generated or overwritten if already existing
└── zones -- Directory containing the zones files that are also included in the data pack
├── zone_a.json
├── zone_b.json
└── zone_c.json
Via Data Generators
You can take a look at ASOS to see how they handle the map upscaling.
In this example, a map at the resource /assets/mymod/textures/gui/my_map.png
is parsed and automatically saved as a map with the id mymod:my_map
.
Forge:
import java.util.concurrent.CompletableFuture;
@Mod.EventBusSubscriber(modid = MyMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class DataGenerators {
public static BufferedImage getOriginalMapImage() {
URL orignalMapUrl = MyMod.class.getResource("/assets/mymod/textures/gui/my_map.png");
try {
return ImageIO.read(Objects.requireNonNull(orignalMapUrl));
} catch (IOException e) {
throw new RuntimeException("Failed to load biome map located at: " + (orignalMapUrl != null ? orignalMapUrl.getPath() : "invalid location"), e);
}
}
@SubscribeEvent
public static void gatherData(GatherDataEvent event) {
DataGenerator generator = event.getGenerator();
PackOutput packOutput = generator.getPackOutput();
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
// World gen maps
generator.addProvider(true, new MapProvider(getOriginalMapImage(), ResourceLocation.parse("mymod:my_map"), lookupProvider.thenCompose(oProvider -> {
// this is where you want to extract the list of zones you previously registered
return new CompletableFuture<List<Zone>>();
}), packOutput));
}
}
Fabric:
public final class MyDataGen implements DataGeneratorEntrypoint {
public static BufferedImage getOriginalMapImage() {
URL orignalMapUrl = MyMod.class.getResource("/assets/mymod/textures/gui/my_map.png");
try {
return ImageIO.read(Objects.requireNonNull(orignalMapUrl));
} catch (IOException e) {
throw new RuntimeException("Failed to load biome map located at: " + (orignalMapUrl != null ? orignalMapUrl.getPath() : "invalid location"), e);
}
}
@Override
public void onInitializeDataGenerator(@NotNull FabricDataGenerator generator) {
FabricDataGenerator.Pack pack = generator.createPack();
// generate zones here
// upscale map
pack.addProvider((output, lookupProvider) -> new MapProvider(getOriginalMapImage(), ResourceLocation.parse("mymod:my_map"), lookupProvider.thenCompose(oProvider -> {
// this is where you want to extract the list of zones you previously registered
return new CompletableFuture<List<Zone>>();
}), output));
}
}
One more addition to the Map Menu: If you’re a coder and want to redirect the open-map-button, call CTGClient.registerMenu(mapId, (minecraft, packet) -> screen);
to provide a custom screen. You can use MapWidget.ofPacket(minecraft, x, y, width, height, packet);
to create a new MapWidget
with many options to customize it.
Continue with Carvers