The problem is that "minVeinSize" is 2 and while "maxVeinSize" is 3 you calculate it as "minVeinSize + random.nextInt(maxVeinSize - minVeinSize)", which always gives 2 because Random.nextInt(n) returns a value between 0 inclusive and n exclusive (in other words, 0 to (3-2)-1, which is 0). The ore generator doesn't generate anything if the "size" is 2 or less. If you actually want a range of 2 to 3 you need to add one to "maxVeinSize - minVeinSize" (so it is now "minVeinSize + random.nextInt(maxVeinSize - minVeinSize + 1)". This also means you can set the min/max equal without causing an exception. The same is true of the y-range calculation, which should be "maxY - minY + 1" (this is why diamond generates up to layer 15, not 16, despite the code specifying a range of 0-16).
Thus, you should increase the size to at least 3, and just remove the random factor since the actual size of a vein varies a lot anyway; for example, diamond ore has a "size" of 7 (in 1.7.10) and generates anywhere from 1 to 10 blocks in a vein, averaging about 5.16, based on a simulation of 1 million fully generated veins; a "size" of 3 generates veins with 1-4 blocks, averaging 0.46 (about 2/3 of attempts don't generate anything at all with most of the rest being single blocks; if you actually want single blocks you should place them like emerald ore, which randomly places 3-8 blocks across its range, replacing the call to WorldGenMinable.generate with World.setBlock):
This is how I'd rewrite the code, I cleaned it up by removing unnecessary stuff (it looks like you used a default template; e.g. "defaultChunkSize" is only ever going to be 16, and should be declared as a field if you do use it as it also affects the conversion from chunk to block coordinates):
private final WorldGenMinable phantomOreGeneratorSurface = new WorldGenMinable(ModItems.PHANTOM_ORE, 3, Blocks.stone);
private final WorldGenMinable phantomOreGeneratorNether = new WorldGenMinable(ModItems.PHANTOM_ORE, 3, Blocks.netherrack);
private void addOre(WorldGenMinable oreGenerator, Random random, World world, int posX, int posZ, int minY, int maxY, int spawnChance)
for (int i = 0; i < spawnChance; i++)
int xPos = posX + random.nextInt(16);
int yPos = minY + random.nextInt(maxY - minY);
int zPos = posZ + random.nextInt(16);
oreGenerator.generate(world, random, xPos, yPos, zPos);
There is one other issue - ores only replace stone by default and you have to specify otherwise; you did by specifying "Blocks.stone" but unless you modified the Nether to have stone instead of Netherrack it won't generate (vanilla actually attempts to generate ores in the End but since they can't replace End stone it doesn't do anything). This in included in the code above; pass in the appropriate generator to the "addOre" method when calling it (I made them fields, as vanilla does, so the same instance can be used over and over instead of creating a whole new object each time, which will increase memory allocation rates and cause GC issues if overused. In my own mod I actually use my own ore generator which is a rewritten version of vanilla's and only needs a single object to generate any ore by passing everything in as parameters).
Another thing to be aware of - while not necessary for WorldGenMinable you usually need to add 8 to the coordinates after multiplying the chunk coordinates by 16 (i.e. "chunkX * 16 + 8"), as otherwise you'll cause runaway worldgen, which can cause major performance issues (WorldGenMinable adds the offset internally, but many of the vanilla generators do not).