ChunkGenerators & BlockPopulators FAQ

Discussion in 'Plugin Development' started by Dinnerbone, Jun 23, 2011.

Not open for further replies.
1. Offline

#91
2. Offline

md_5

Can Mike Primm please explain, I cant figure what each byte[][] coord maps to

#92
3. Offline

Mike Primm

OK - new format reflects the new structure of the chunks in vanilla:

1) Chunks are taller - now 256 - and represented by a stack of 16 x 16 x 16 cubiods called sections. As each section is 16 blocks high, there potentially 16 in the current chunks. The index of the section containing the blocks with a given Y coordinate is (Y / 16) or (Y >> 4).
2) To save memory, and improve performance, whole sections that are empty can be undefined - this is part of how maps were migrated, as existing maps were limited to 128, and thus only could have content in the first 8 sections (0-7).
3) Within a given section, the native order of the blocks in the vanilla code was altered: for a given coordinate within the section (X = 0-15, as before; (Y & 0xF) = YY = 0-15; Z = 0-15, as before), the index is ((Y & 0xF) << 8) | (Z << 4) | X.

So, the resulting return values have the following structure:

result[section-index][block-index-within-the-section]

The suggestion is to allocate the first level array based on the world height divided by 16:

byte[][] result = new byte[16][];

Then, the sections (each of which are 16 * 16 * 16 blocks) can be allocated as needed (that is, when you set one of their blocks to non-empty). Here are a pair of simple access wrappers that both illustrate the mapping, and the 'allocate sections when needed' characteristic:

Code:
```
int getBlockID(byte[][] cdata, int x, int y, int z) {
int sy = y >> 4;
if (cdata[sy] == null) {
return 0;
}
return (int)cdata[sy][((y & 0xF) << 8) | (z << 4) | x) & 0xFF;
}

void setBlockID(byte[][] cdata, int x, int y, int z, int blkid) {
int sy = y >> 4;
if(cdata[sy] == null) {
cdata[sy] = new byte[4096];
}
cdata[sy][((y & 0xF) << 8) | (z << 4) | x) = (byte)blkid;
}

```
My apologies on the lack of clarity in the javadoc - I'll write up an updated version sometime today.

#93
4. Offline

zipron

could someone maybe help me with the beginnings of the ChunkGenerator? I'm not having troubles for two days and actually I only want to create a flatland generator...

Oh And I'm using bukkit for 1.2

Kind regards,
zipron

#94
5. Offline

6. Offline

zipron

Already fixed, and the worldgen is only part of the plugin I'm making

zip

#96
7. Offline

Celtic Minstrel

Okay, did you read the post just above yours?

8. Offline

zipron

Yes I did, however, it still didn't work, then I got the issue (very noobish) but I had an outdated dev build =)

Zip

#98
9. Offline

Celtic Minstrel

Oh wait, you said you fixed your issue. Never mind then, carry on!

10. Offline

zipron

Question: is there anywhere some documentation but the API where you can learn about populators? I would really like to expiriment with some wgen plugins but it just don't seem that there are any good guides about it?

zip

11. Offline

Celtic Minstrel

I'm pretty sure it's as simple as "Here's a chunk; modify it as you please".

12. Offline

zipron

lol yea but I mean how the methods work =(

13. Offline

14. Offline

15. Offline

Littlefryingpan

This was really helpful. For some reason I keep getting errors on the following things though:

In the Moon Chunk Generator class I get an error at the beginning of the class on "MoonChunkGenerator" (public class MoonChunkGenerator extends ChunkGenerator)

When I hover over it it says: "The type MoonChunkGenerator must implement the inherited abstract method ChunkGenerator.generate(World, Random, int, int)"

Another error I get is in the same class on the line that says: "public byte[][] generateBlockSections(World world, Random random, int cx, int cz, BiomeGrid biomes" The error is on the text BiomeGrid, hovering over it it says "BiomeGrid cannot be resolved to a type"

Sorry about posting this here, I am fairly new to Java so I am not very good with this sort of stuff yet.
Thanks,

Littlefryingpan
Just forgot to update my version of Bukkit. Problem solved.

16. Offline

Mike Primm

You're building with a downlevel bukkit.jar - you'll need to update to at least the 1.2.3-R0.2 one.

17. Offline

Littlefryingpan

Well, I feel dumb, could have sworn that I updated Bukkit, but I guess I copied the old one back to the same folder.
That fixed the problem.
Thanks Mike.

18. Offline

Mike, Nice example THX

19. Offline

AmoebaMan

I'm coding a small plugin that basically needs to do two things:
1. Alter the size and rarity of natural spawning ore veins
2. Whenever a vein is generated (I assume this is done by a BlockPopulator) retrieve and store the locations of the ore blocks.
Is there an easy way to do this without writing my own generator from scratch?

20. Offline

Celtic Minstrel

You can write your own ore BlockPopulator and add it to the default generator. I don't think you can remove the default ore populator, though.

21. Offline

22. Offline

23. Offline

FnordianLoop

odd this plugin example gives me an error on /moon
Code:
```10:50:56 [SEVERE] null
org.bukkit.command.CommandException: Unhandled exception executing command 'moon
' in plugin BukkitFullOfMoon v0.1.0
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:42)
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:16
6)
at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:4
73)
at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.
java:821)
at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:781)

at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:764)
at net.minecraft.server.Packet3Chat.handle(Packet3Chat.java:33)
at net.minecraft.server.NetworkManager.b(NetworkManager.java:229)
at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:113)
8)
at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:554)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:452)
Caused by: java.lang.NoSuchMethodError: org.bukkit.Server.createWorld(Ljava/lang
/String;Lorg/bukkit/World\$Environment;Lorg/bukkit/generator/ChunkGenerator;)Lorg
/bukkit/World;
at com.dinnerbone.bukkit.moon.BukkitMoon.getMoon(BukkitMoon.java:38)
at com.dinnerbone.bukkit.moon.MoonCommandExec.onCommand(MoonCommandExec.
java:13)
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:40)
... 12 more```

24. Offline

xpansive

Sorry, I didn't test it... It appears as if it is still using the old world creation methods.

25. Offline

FnordianLoop

thanks for looking into it xpansive. Dinnerbone, I'd be eternally grateful if you could fix this little snafu.

26. Offline

Tim Visee

Hi thanks for this but I've a problem. I searched on this topic if I could find how to generate mountains in my world generator. What I just want is generate small hills with a heigh difference of 5 or something, so yes really small smooth hills like the flatlands biome in minecraft. I tested the following code (the noice generator with the 'height' variable part);
PHP:
``` private NoiseGenerator generator;     private NoiseGenerator getGenerator(World world) {        if (generator == null) {            generator = new SimplexNoiseGenerator(world);        }         return generator;    }     private int getHeight(World world, double x, double y, int variance) {        NoiseGenerator gen = getGenerator(world);         double result = gen.noise(x, y);        result *= variance;        return NoiseGenerator.floor(result);    } public byte[] generate(World world, Random random, int cx, int cz) {        byte[] result = new byte[32768];         for (int x = 0; x < 16; x++) {            for (int z = 0; z < 16; z++) {                int height = getHeight(world, cx + x * 0.0625, cz + z * 0.0625, 2) + 60;                for (int y = 0; y < height; y++) {                    result[(x * 16 + z) * 128 + y] = (byte)Material.SPONGE.getId();                }            }        }         return result;    } ```
but this doesn't look really smooth I want to spread it out to make it smoother but when I change some numbers in here;
PHP:
```  int height = getHeight(world, cx + x * 0.0625, cz + z * 0.0625, 2) + 60; ```
it won't work too. Could anyone help me with a explenation for noice generators to generate smooth hills? That would be really cool!
Tim Visée

I already found the solution. You could find the solution here;

EDIT by Moderator: merged posts, please use the edit button instead of double posting.

Last edited by a moderator: May 17, 2016
27. Offline

I have been spinning around a problem that I think is actually buried in Bukkit. Specifically I was working on my CityWorld generator and was getting crazy NULL reference exception that I could not find. Eventually (about four hours later) I traced it down to the returning of certain Biomes via generateBlockSections. It seems that if you return SCRUBLAND eventually a null exception is thrown way down deep in Bukkit.

From my glancing at the bukkit code via JD, it looks like the following biomes are not "referenced" in CraftBlock.class' static initializer...
• ICE_DESERT
• RAINFOREST
• SAVANNA
• SEASONAL_FOREST
• SHRUBLAND
• TUNDRA

I might be wrong but not using those biomes definitely make things work better.
I am heading over to post an official bug report but figured I would alert the fellow world generators of the potential issue.

[BUG - https://bukkit.atlassian.net/browse/BUKKIT-1684]

28. Offline

Tim Visee

Hmm, strange in my world generator (Dungeon Maze, released soon) I didn't have this problem, well I think, not sure. When I really don't have this problem I don't know what happend

29. Offline

Celtic Minstrel

They may be old biomes from before they redid the biome code...

30. Offline