Minecraft inspired world generator.

Hello everyone :confused:

So the other day I downloaded MineCraft to give it a whirl. Well, turns out that I fell in love with that beautiful 16 bit texture game :slight_smile: So much infact, that I decided to try my hand at writing a world generator, much like that in MineCraft.

I donā€™t intend to make a game out of this, just a PoC; to prove that I can do it :smiley:

Note: I havenā€™t written any python scripts in the last 3 or so months, so bare with me. This is my first time touching the 2.5 api :o

When I finish this, Iā€™ll release it to the community (as always) so that 100 ā€œ1337 noob minecraft clone-but-somehow-better-and-donā€™t-forget-the-massive-MMO-engine-that-will-be-better-than-world-of-warcraftā€ projects can blossom and flood these forums!

So now, onto the screenshots of my ā€œengineā€ so far! (Itā€™s kinda hard to get multi-angle shots, because everytime I restart the engine it regenerates)




(oops, hit limit :frowning: )

So basically the way my script is working is like this:

First I tell it to generate a list of coordinates ranging from 0 to the max width (mine is 16 right now, but I can change on number and itā€™ll generate whatever I want at any time :smiley: ), then repeat that for each of the directions (x,y,z). This map is 16x16x5. You have to be careful though when making large maps, I tried 128x128x128 and nearly crashed my computer (as it was creating 2,097,152 cubes!). Then itā€™s generating the odds of placing each tile (on sea level the borders will always be water). So therefore if itā€™s next to water it has a higher chance of generating water or sand than grass or dirt; and so on and so forth.

When generating the hight it looks for which tile is below it. If itā€™s dirt it will ALWAYS generate either more dirt or grass.

Thatā€™s basically the way Iā€™ve made it work. Obviously itā€™s a lot more complex than I can put into words. So youā€™ll just have to look at the code once itā€™s released.

Wellā€¦ thatā€™s it. Iā€™d appreciate any feedback :smiley:

wow thats really really cool! keep up the great work! im a minecraft fan as well, although im not an addict.

This is very cool but simple you could design a game like minecraft in bleder just add ur own spin to it and Iā€™d buy it haha

Thanks guys! I plan on working on LoD next actually. Once I get the tile generator algorithm to my likings.

Good - I thought, what if it had a chance to generate rocks when thereā€™s tiles suspended over water? That would be good.

What do you mean by that? Right now NOTHING can get generated over water.

Very cool! I made one that can support 2000+ cubes with completely random terrain generation and terrain type at 60 fps. Far from 5+ million blocks in minecraft but it is cool.

@Killer - This is the best thing that I could find that shows what I meant:


As you can see, the rocks hang and ā€˜caveā€™ over the water - in your example, it would be rock blocks that would form a cave, or just blocks that are pillars or hang from the ground over the water. Whilst this is a real life occurance, it would be cool to see in your Minecraft-like world. If itā€™s not possible or is too much work (it would be for me, Iā€™d think, LOL), then thatā€™s fine. It would just be a cool thing to see. I already see that you have sand, so the beach is already a great feature.

@Laxwolf - Hey, thatā€™s cool - I have yet to make a Minecraft-like system, but it sounds like itā€™d be fun to have around (though I did do voxels). P.S. Keep up your work - that Limbo-like game on Youtube looked awesome.

Hereā€™s a quick test of visual culling.

Basically you can make the scale of the cube whatever youā€™d like, and itā€™ll generate a map inside of it.

The problem right now is the deletion of old map elements. It needs to automatically remove tiles that are no longer inside the cubeā€¦ Iā€™m going to have to sleep this one out, maybe Iā€™ll strike an idea tomorrow :slight_smile:

Hereā€™s a couple of theories on this culling idea:

  1. Keep an array of created blocks when you generate the map. Every time you generate the map, loop through the array and delete the blocks that are outside of the range of the block.
  2. Actually create all of the blocks for the whole world, turn them all invisible (ahead of time, to save CPU), and set visible the blocks that are in range - thatā€™s how I did the voxels in my loop logic demo. Keep an array of such blocks (you can just loop through each block in the world, or, better yet, a Near sensorā€™s output, though Iā€™m not sure if that would be CPU-efficient enough), and loop through those blocks - if they are outside of the range, set them invisible. Otherwise, set them visible.

Thanks so much! Iā€™m guessing voxels is a feature in 2.5 +
Also, if you want natural caves, created a random-loc spawning cube and make it go in a random direction. Make the blocks you have get destroyed when they get hit by the cube. Also experiment with random scaling and directions for more unique caves. You might have to extend your cube downwards, though.

Also the only blocks that need to be visible or even instanced are the ones that come into contact with ā€œairā€

Nice work. LoD should take care of the blocks you want to delete.

@Siegel: Not really, because I want this to be just like the real deal, so therefore itā€™ll generate everything from bedrock to mountain peaks. Hell, maybe Iā€™ll even make a quick FPS setup so you can walk around the generated world.

@Josip: Well, I donā€™t really have LoD and donā€™t think Iā€™ll add it. Instead Iā€™m going to add visual culling (see the video above) so only objects inside the cube get effected.

@SolarLune: Didnā€™t you watch the video? Right now the way itā€™s setup is I have an object named ā€œCullingā€. When you run the game it runs two python functions. One of them is called generateMap( xWidth, yWidth, height, margin ). That basically generates a MASSIVE python list with every possible coordinate for our map. Then I run a function called generateTileMap(map). This basically takes all the coordinates and generates a dictionary with every map tile and their respective coordinates in it. Then from there, every 100 frames itā€™s checking the coordinates/size of the culling cube (so if you resize smaller, itā€™ll display less objects, larger itā€™ll display more) and it will generate enough cubes to fit inside the culling cube.

So now I have a few questions to the bigger python gurus than me :smiley: (or maybe Iā€™m just stupid)

How do I make global variables. So I can access them across different scripts? I used to be able to use GameLogic.myVariable, but obviously in 2.5 there is no GameLogic. This will help a TON if I can figure that out.

Also, is setting objects to ā€œInvisibleā€ as efficient as actually not having an object? Ie: What will use more CPU, a block thatā€™s physically in the scene just set to invisible, or an imaginary cube that was never in the scene?

Thanks guys!

Weeee got global variables working! Just using bge.myVar. Is this the best way to approach it?

@Agoose: Thanks! While it may be relevant, Iā€™m not a fan of looking through someone elseā€™s code. Iā€™ve almost got mine complete. I enjoy problem solving and simply feel more fulfilled when itā€™s 100% my own code :slight_smile:

i cannot wait to see this!

Well good, cause you wont need to wait any longer :smiley: hereā€™s my finished visual culling:

woah, video got stretched during upload? Weirdā€¦

Also, global Variables.
If you use bge.myvar, it is not saved with the save game actuator.
if you use bge.globalDict[ā€œmyvarā€] then you can save it with the save-game actuator

Why would I want to save it? I only need it for the game. If I wanted to do a save/load of maps Iā€™d simply write a save/load script in python.

I think you misunderstood what I meant. I wouldnā€™t be surprised if the same system is being used in the original minecraft. I assume you are generating some sort of array/s with each index represents a block as to its position in the grid and its block type so allot of the blocks will be empty referred to as air by Notch. So getting to my point if you have it that only blocks that are next to air be visible or even instanced and have that do a check every time a block is destroyed to update whatā€™s next to air and whatā€™s not that way you are not wasting any resources on blocks that are hidden behind other blocks. Imagine a 3x3x3 grid the block in the very center cannot and will not be seen until one of the blocks directly next to it is destroyed so there is no point in instancing it until that happens you can even get away without instancing it if blocks diagonal to it are destroyed. I hope I managed to explain it properly and you can see the massive increase in performance you could potentially get considering the amount of blocks potentially involved. I can do some images to further explain if you want just let me know.