Terrain Control

Terrain Control

235k Downloads

BO3 branches

rutgerkok opened this issue Β· 22 comments

commented

BO3s should have an option spawn with other BO3s connected to it. Those BO3s should also be able to spawn with BO3s connected, etc.

  • There needs to be a workaround for chunk limits.
  • Each branch must have a chance to be connected at a position, with a specified rotation.
  • Infinite loops need to be prevented. For rxample, there could be a MaxBranchDepth setting.

Sounds easier than it is. Here's a conversation between me and @LanToaster: (@Wickth was also reading)


LanToaster

Dec 30, 2012 at 11:26

I had an Idea (mainly a Workaround wich would/should work with BO3 right now) for Branching BO2s because branched BO2s never worked wich would/should/could also help with the Chunk limitation.

I thought of declaring a BranchBlock (wich in my Idea would just be a Block wich should never be used in my TerrainGeneration) on my Object and then letting other Obejects only spawn on this Block and override it with something else so not another Object would spawn there. (In my Case with a very Very High SpawnRate).

This would help and make large/branched structures able right now.
Of course due to the high Spawnrate it would cost much performance, but maybe the Idea could help with the BO3 Branching and Size problems.

rutgerkok

Dec 30, 2012 at 17:12

The problem with branches are the chunk limits. When you are populatin a chunk, only the chunks directly around are guaranteed to exist. So to get around this, we need to complete a partially spawned the BO3 later on.

I'm thinking of a Branch(x,y,z,anotherobject,anotherobjectrotation,anotherobjectchance[,...]) syntax, along with a hasParent setting.

Added Khoorn to the conversation.

LanToaster

Dec 30, 2012 at 18:45

IsnΒ΄t it Possible when placing an Object to Precalculate how big it is going to be and if it is Bigger than the Existing Chunks to save an Internal note on wich Chunks the Object needs to be added on later Creation?

rutgerkok

Dec 30, 2012 at 19:07

And then, when a chunk is generated check for each BO3 in nearby chunks? That could work.

LanToaster

Dec 30, 2012 at 22:23

Not essential "Each" you could generate and save a List for each "Unfinished" BO3, this could save some processing power

rutgerkok

Dec 31, 2012 at 09:34

That list would need to persist during server restarts, so you would need to save it or recalculate it.

If we are going with the recalculate option, when it generates a chunk, it checks whether the chunks next to the BO3 have a list of unfinished BO3s. If not, it calculates them.

That could work! Thanks!

But first I'm going to implement some other things.

LanToaster

2 days, 16 hours ago

Glad to be of Help :)


So we need to know the max size in chunks of each BO3 (easiest as a setting). When a chunk gets generated, all BO3s within the chunk size get spawned "virtually" - no blocks will be placed, no checks (except frequency/rarity/height) will be made (as a large number of chunks is not loaded, those checks cannot be made), just the position of all branches will be calculated. All BO3s that need to be spawned within the chunk are now spawned.

This means that BO3s with branches attached cannot have checks. This is also like how Mojang generates villages: the roads (which have houses attached) spawn no matter what, only the houses fail to spawn sometimes.

Would this be the right approach?

commented

As far as i Understand this, and i have sadly not much insight knowledge of the Coding, (not to say absolutly No Knowledge). This should theoreticly Work.

I dont really Understand the part witj "BO3s attached to BO3s". But i really think the Easiest way would be to save a Note in a CacheFile where an object needs to Spawn.

Or maybe a Different Approach would be to Force the Needed Chunks to Generate.
For that matter it would be a wise feature to Add a WorldSize so Chunks outside the WorldSize would get Deleted.

The Different Approach could be Easier because you can Check the Size of the Object and Generate the Chunks so they are ready for Block placement. But this could interfere withe Limited WorldSizes (In my Opinion not a Great drawback)

commented

Reworded "BO3s with BO3s attached" as "BO3s with branches attached".

I'm against cache files as long as they aren't absolutely needed. What I'm afraid for is that if someone changes a BO3 structure the cache file will cause strange results. And it's another file to delete if you are resetting your map (which I often have to do for development). Besides, I think that it can be quickly recalculated, maybe even faster than parsing the file.

Force chunk generation could easily cause an infinite loop (if there are so many structures) or severe lag (if a 10x10 area has to generate). Of course, this can be queued, but what if the server stops during the process? Corrupted map?

commented

Yes i was thinking about it before 2.4 ( You may see empty class ObjectCoordinatesStore )
But i think it must save something like "blocks need to spawn".
So how it will work:

  • Try to spawn BO3 without branches
  • If some blocks goes to unloaded chunks and BO3 have special setting - store unfinished blocks in world store.
  • When block placing in world - check if block have branch settings, and it it have try spawn branch ( going to step 1 with branch as main object). Also here we may check branch wave for MaxBranchDepth setting
  • When new chunk generated - check world block store and place unfinished blocks.It must be before place any resources.
  • Also we must have thread for save world stores to disk. This thing is the hardest part.

About recalculate - how you will do fast it if you have big object with branches on more than 3 chunks ?
And initially how you get object coordinate after server reload ?

commented

Random with seed is very good idea. I think we must use it in any case.

Also i dont like cache files too, so we need more thought :)

About your system.
I think there is big problem with spawning before check y coord.
This will looks like Mojang's mineshafts in air.

For avoiding place objects before player - we may use same method for MaxBranchDepth, but this will have name "MaxGrowCompletedChunks"

Your system is good. Looks like it may solve this feature. But after 1 hour of thinking i am still dont know how implement this :(
Maybe after sleep.

commented

I'm afraid I deleted the empty class.

So instead of storing unfinished BO3s, you are storing unspawned blocks. Sounds good. I'll try to explain my system, based on @LanToaster's suggestions.

My system

BO3Structure class

It can be quite fast to (re)calculate - as long as you aren't doing block checks, and are working on a BO3 level, not on a block level. I can imagine that a new instance of the class BO3Structure is created. The class has a constructor which takes the block x, y and z. It creates an instance of the Random generator, and sets the seed to something that is constant for the block location. It loops through the list of all the branches, and decides whether it will be spawned. If the branch syntax is Branch(x,y,x,branchobject,chance,otherbranch,chance...) it can quickly decide which branch to spawn. The height check can be done easily, all other checks are ignored. Each successful location is stored in a List<BO3Pos> (or something else which can quickly lookup objects in a certain chunk). BO3Pos would keep a reference to the BO3, the rotation and the x, y and z. If a branch also has branches, it is added to the list.

Spawning

Now the more difficult part. When populating a chunk, we need to loop through all BO3s that have a isStructure flag set to true. (Or something similar.) Calculate the nearest chunk it will spawn in - we can use code similar to the structure code of Mojang. Then check if the size of the structure would make it possibly spawn in the current chunk. If yes, use a cached BO3Structure or calculate a new one. Now you can know for sure which BO3s need to be spawned. If the BO3 doesn't have branches, all checks can be done, and the BO3 can fail to be placed if needed. If the BO3 does have branches, it needs to spawn no matter what (just like Mojang's road) to avoid missing parts in the structure.

Pros and cons

Your system is much easier to implement and it also allows individual BO3s to be as large as you want. My system doesn't use cache files, but it is much more difficult to implement. Your system can make a 8-chunks long village suddenly appear in the face of a player, my system spawns parts of the village as the player approaches. Your system is almost fully fledged out - my system has a lot of gaps. (For example: how to make a BO3Structure cache without it being a giant memory leak.) And both systems can't do all the block and light checks.

Edit 12 hours after I have posted this: replaced List with List<BO3Pos>.

commented

So what we will do with it ?
I still does not have idea how do it without cache file :(

commented

I think that I will create a new branch for the branches, and just poke around. No idea if it will work, but it's worth trying.

I think there is big problem with spawning before check y coord.

Maybe you misread my post? I said that height checks can be done easily, but all other checks can't, as they require the chunk to be loaded. πŸ˜ƒ Checking y < maxHeight doesn't require the chunk to be loaded, checking world.getMaterial/LightLevel(x,y,z) does. Edit: my bad, see @Wickth's comment just below.

  • There needs to be a method getStructureStart(chunkx, chunkz) which will return a CustomObjectStructure, or null if there is no starting structure in the chunk. (There can only be one structure start in a chunk, but I don't think that that is a problem.)
  • CustomObjectStructure will just store a (optimized?) list of CustomObjectPos. CustomObjectPos won't store blocks, only the BO2/BO3 and it's position+rotation.
  • CustomObjectStructure needs to have a method spawnObjectsForChunk(chunkx,chunkz)
  • CustomObjectGen needs to loop over all nearby chunks and call getStructureStart. For each CustomObjectStructure it receives it will call it's spawnObjectsForChunk. See the Vein code for an example.
  • CustomObjectStructure will be cached, but it won't be saved.
commented

I mean check ground level. So example for easy understand :

  1. We have normal tree with size = 1.5 chunk
  2. And we in chunk contains only leaves ( 1/3 of this tree)
  3. How to choose y coordinate of this leaves, if tree trunk must start from ground in not generated chunk

Yes you may control it be setting min/max height of object if terrain is flat. But usually it is not...

commented

Ah, now I understand. Hmm, will think about this. I wonder how Mojang has solved this for the villages.

commented

Maybe the structure shouldn't store y coords if it is a on-the-ground structure? Then a structure can either have fixed y coords, or flexible y coords. (No combinations can be made.)

commented

Hmm ... ok if we back to tree example, it is mean leaves blocks in first chunk appears after generation in second chunk right ?

And what we should do if we have half completed object in many chunk and next chunks is not suitable by object biome specs ?

commented

Hmm ... ok if we back to tree example, it is mean leaves blocks in first chunk appears after generation in second chunk right ?

And there you have found a flaw in my system. We need to know the height for the structure to start, while that chunk isn't generated yet.

So either you would need to have y coords which don't depend on the terrain everywhere in your BO3 structure , or you would need to use the highest block everywhere in the BO3 structure.

And what we should do if we have half completed object in many chunk and next chunks is not suitable by object biome specs ?

Place it anyway if it has any more branches attached to it, don't place it if it hasn't. Just like villages, roads (which have houses attached) can extend to another biome if needed, but houses (which have nothing attached) cannot.

 

You're finding more and more flaws in my system, so maybe we just need to go with your system.

commented

On the other hand, all of Mojang's structures have the same limitations. Swamp huts and jungle temples are small and won't need branches, pyramids have a fixed height, villages all generate on the highest block and strongholds and mineshafts ignore the terrain completely.

I'll create a new branch soon to work on the branches.

commented

Created a new branch, work has begun!

I try to implement it without the cache files. Let's see if I can succeed.

commented

Ok πŸ˜„

I am some busy again now πŸ˜•

Damned real life work. Need make plans for rebuild our server room in this year ....

commented

The branch trees are now being built. Now they just need to spawn. πŸ˜„

The easiest way to do this would be to create a CustomStructure(object,object,object) resource, that can only be once in each BiomeConfig. The resource will check all surrounding chunks to see if there are structure starts (based on the biome in that chunk, not the current chunk that is being populated). If yes, it generates the correct part of the structure.

All those structures will need to be cached. The cache will be cleaned up periodically.

@Wickth Do you know how the BO2 branches worked? I can of course downgrade TC and try to find it out on my own, but if the answer already lies somewhere in your head, it will save me a lot of time. πŸ˜ƒ

commented

Yeap.
See this old version - https://github.com/Wickth/TerrainControl/blob/057eca414c6669e7004ac236c19e3ea8b2144714/common/src/com/khorn/terraincontrol/customobjects/CustomObjectGen.java#L172

Each world had special arraylists with bo2 branches in one group

So for spawn one bo2 all block coordinates copied to internal list, if coordinate had branch tag - check araylist with branches and add block coordinates from branch to internal list.

After this - check internal list for collisions, rotate and spawn.

commented

I haven't got the BO2 branches to work yet - it are largely incompatible systems. However, the BO3 branches are now up and running. It can currently only spawn at a random y, spawning the structure at the ground is not possible yet.

commented

Even if start point is in not complete chunk ? πŸ˜›

Sorry my brains explode in whit week and i cant check code 😟

commented

Now they are also able to spawn on the ground. πŸ˜ƒ

commented

Yep, but the restriction "all objects must be on the ground if the first one is" is still there. πŸ˜₯

commented

Structure of orange wool

Structures can be made of objects up to 16x256x16 blocks.