Development resources/Example Minecraft Classic Level Editing Class

To compile and use this class, have your classpath include the path to the LevelEditor.java file and the minecraft-server.jar file. javac -classpath .:minecraft-server.jar LevelEditor.java

java -classpath .:minecraft-server.jar LevelEditor or java -classpath .:minecraft-server.jar LevelEditor new_server_level.dat

import java.io.*; import java.text.DateFormat; import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPInputStream; public class LevelEditor { private com.mojang.minecraft.level.Level level = null; LevelEditor { } 	// load from file called filename public void load(String filename) { FileInputStream fis = null; GZIPInputStream gzis = null; ObjectInputStream in = null; DataInputStream inputstream = null; try { fis = new FileInputStream(filename); gzis = new GZIPInputStream(fis); inputstream = new DataInputStream(gzis); if((inputstream.readInt) != 0x271bb788) { return; } 			if((inputstream.readByte) > 2) { System.out.println("Error: Level version > 2, this is unexpected!"); return; } 			in = new ObjectInputStream(gzis); level = (com.mojang.minecraft.level.Level)in.readObject; inputstream.close; in.close; System.out.println("Loading level "+filename+" successful"); } catch(IOException ex) { ex.printStackTrace; } catch(ClassNotFoundException ex) { ex.printStackTrace; } 		level.initTransient; } 	// save in file called filename public void save(String filename) { FileOutputStream fos = null; GZIPOutputStream gzos = null; ObjectOutputStream out = null; DataOutputStream outputstream = null; try { fos = new FileOutputStream(filename); gzos = new GZIPOutputStream(fos); outputstream = new DataOutputStream(gzos); outputstream.writeInt(0x271bb788); outputstream.writeByte(2); out = new ObjectOutputStream(gzos); out.writeObject(level); outputstream.close; out.close; System.out.println("Saving level "+filename+" successful"); } catch(IOException ex) { ex.printStackTrace; } 	} 	// prints all there is to know about a level, except for the blocks data public void printInfo { if (level == null) { return; } 		System.out.println("Level info:"); System.out.println("name: "+level.name); System.out.println("creator: "+level.creator); System.out.println("createTime: "+(DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL).format(level.createTime))); System.out.println("width: "+level.width); System.out.println("height: "+level.height); System.out.println("depth: "+level.depth); System.out.println("spawnpoint: ["+level.xSpawn+","+level.ySpawn+","+level.zSpawn+"]"); System.out.println("spawn rotation: "+level.rotSpawn); } 	// safe to use method, return value let's you know if anything was changed public boolean setTile(int x, int y, int z, int t) { if ( 			x >=0 && x < level.width && 			y >=0 && y < level.depth && 			z >=0 && z < level.height && 			t >= 0 && t <= 37 		) { if (t == 8 || t == 10) { level.setTile(x,y,z,t); } else if (t >= 0 && t <= 18) { level.setTileNoUpdate(x,y,z,t); } 			return true; } 		return false; } 	// gets you the level coordinates from the blocks array index public int[] getCoords(int index) { int x = index % width; index = (index-x) / width; int z = index % height; int y = (index-z) / height; return new int[] {x, y, z}; } 	public void clearBlocks { for (int i=0; i<level.blocks.length; i++) { level.blocks[i] = 0; } 	} 	public void floor(int y, int type) { for (int i=0; i<level.width; i++) { for (int j=0; j<level.height; j++) { setTile(i,y,j,type); } 		} 	} 	public void wallX(int x1, int x2, int z, int y, int height, int type) { for (int i=x1; i<=x2; i++) { for (int j=y; j<y+height; j++) { if (!setTile(i,j,z,type)) { System.out.println("Warning: a tile got ignored while building a wallX: ["+i+","+j+","+z+"]"); } 		} 		} 	} 	public void wallZ(int x, int z1, int z2, int y, int height, int type) { for (int i=z1; i<=z2; i++) { for (int j=y; j<y+height; j++) { if (!setTile(x,j,i,type)) { System.out.println("Warning: a tile got ignored while building a wallZ: ["+x+","+j+","+i+"]"); } 		} 		} 	} 	// substitute all of block type 'from' to 'to' :) returning the number of blocks altered 	public int substitute(byte from, byte to) { 		int count=0; 		for (int i=0; i 0) { 			filename = args[0]; 			le.load(filename); 			if (le.level == null) { 				System.out.println("Loading level "+filename+" failed"); 				return; 			} 		} else { 			le.level = new com.mojang.minecraft.level.Level; 		} 		// Do some fancy editing here 		// set a custom size: 256 wide, 128 high, 512 length 		le.setSize(256, 128, 512); 		// first, let's clear out the field le.clearBlocks; // add a bunch of walls to fill the lower part of the level for (int i=0; i<le.level.width; i++) { le.wallX(0,le.level.height-1,i,0,(int)le.level.getWaterLevel-1,3); } 		// lay the floor le.floor((int)le.level.getWaterLevel-1,2); // let the level find a spawn location for us 		le.level.findSpawn; // Leave our fingerprint le.level.creator = "Minecrafter"; le.level.name = "A Custom World"; le.level.createTime = System.currentTimeMillis; le.save(filename); le.printInfo; } }

To help with getting the correct bytes for different block types, you can also use this class public class Blocks {  	public static final byte air 				= (byte)0; public static final byte rock 				= (byte)1; public static final byte grass 				= (byte)2; public static final byte dirt 				= (byte)3; public static final byte stone 				= (byte)4; public static final byte wood 				= (byte)5; public static final byte shrub 				= (byte)6; public static final byte blackrock 			= (byte)7; public static final byte water 				= (byte)8; public static final byte waterstill 			= (byte)9; public static final byte lava 				= (byte)10; public static final byte lavastill 			= (byte)11; public static final byte sand 				= (byte)12; public static final byte gravel 			= (byte)13; public static final byte goldrock 			= (byte)14; public static final byte ironrock 			= (byte)15; public static final byte coal 				= (byte)16; public static final byte trunk 				= (byte)17; public static final byte leaf 				= (byte)18; public static final byte sponge 			= (byte)19; public static final byte glass 				= (byte)20; public static final byte red 				= (byte)21; public static final byte orange 			= (byte)22; public static final byte yellow 			= (byte)23; public static final byte lightgreen 			= (byte)24; public static final byte green 				= (byte)25; public static final byte aquagreen 			= (byte)26; public static final byte cyan 				= (byte)27; public static final byte lightblue 			= (byte)28; public static final byte blue 				= (byte)29; public static final byte purple 			= (byte)30; public static final byte lightpurple 			= (byte)31; public static final byte pink 				= (byte)32; public static final byte darkpink 			= (byte)33; public static final byte darkgrey 			= (byte)34; public static final byte lightgrey 			= (byte)35; public static final byte white 				= (byte)36; public static final byte yellowflower 			= (byte)37; public static final byte redflower 			= (byte)38; public static final byte mushroom 			= (byte)39; public static final byte redmushroom 			= (byte)40; public static final byte goldsolid 			= (byte)41; public static final byte iron 				= (byte)42; public static final byte staircasefull 			= (byte)43; public static final byte staircasestep 			= (byte)44; public static final byte brick 				= (byte)45; public static final byte tnt 				= (byte)46; public static final byte bookcase 			= (byte)47; public static final byte stonevine 			= (byte)48; public static final byte obsidian 			= (byte)49; }