Tweaking Stackable Chunks

Panserbjoern

Member
Contributor
Architecture
Hi all

I was very busy lately working on stackable chunks.

It's not trivial to extend the engine, to support stackable chunks. It was very important for me, that the engine supports both classic style chunks and stackable chunks at the same time. The new class ChunkType is responsible for that. You can define new chunk types with different properties.

Currently, there are 3 classic, non stackable chunk types:
  • Classic, 16 x 256 x 16
  • Small, 16 x 128 x 16
  • Tall, 16 x 512 x 16
And there is currently only one stackable chunk type:
  • Stackable, 16 x 16 x 16
The classic, non stackable chunk types work as you are accustomed to. They just differ in height. Please note, that i have only tested the PerlinTerrainGenerator with them. The FlatTerrainGenerator crashes, if you use it with another chunk type than Classic.

The stackable chunk type will not use any of the existing terrain generators! Currently it uses a simple generator for testing purposes. Also, the tesselator does not work correctly with stackable chunks.

When you create a new world, you can select the chunk type you want to use.

Check it out! :)

https://github.com/mbrotz/Terasology/tree/stackable-chunks


createworld.jpg stackablechunks.jpg


Panserbjoern
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
I don't see any reason to continue to support "classic" chunks. Can you explain why it is important to you? Or is this just a temporary measure?
 

Panserbjoern

Member
Contributor
Architecture
There are several reasons, why it is important for me.
  1. I want to have a working engine while switching from classic to stackable chunks. It's just very helpful to be able to compare results.
  2. I don't yet know, what size of chunks would be best for stacking. This way, i can experiment around freely, again with the ability to compare results from different chunk dimensions.
  3. It makes the engine very flexible. If someone has an idea for an entirely different game which does not require stackable chunks, it would be much easier to do so with support through the engine.
  4. I think, it does not hurt to continue support for classic chunks. Once we have fully switched to stackable chunks, the rest of terasology wont be impacted by the support for classic chunks.
And if stackable chunks turn out to be so much better/more efficient/cooler than classic chunks in every imaginable way, we can always remove support for classic chunks... :)
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
I think the first reason is fair.

On the second point, I would recommend 16x64x16, 16x128x16, or 16x256x16. There needs to be enough verticality to support the new sunlight algorithm - sunlight needs to fade in over a reasonable distance, and that distance needs to be less or equal to the chunk height. 64 is probably the practical minimum for this.

  1. It makes the engine very flexible. If someone has an idea for an entirely different game which does not require stackable chunks, it would be much easier to do so with support through the engine.
  2. I think, it does not hurt to continue support for classic chunks. Once we have fully switched to stackable chunks, the rest of terasology wont be impacted by the support for classic chunks.
There is a cost to flexibility, and a cost to having code that isn't actually being used (maintenance). The question would have to be whether the performance gain for having explicit flat-world support for the hypothetical situation that someone wants to use it, is worth it against the complexity cost of having it - especially because not having it doesn't prevent emulating it.

If the number of points which are impacted by flat vs stacked worlds are minimised I don't see an issue though - maybe you're already achieving this? If everything is working against world views, then having a flat world view and a stacked world view may be ok - you could even go further and just have the flat chunk provider with a single "above" chunk and a single "below" chunk which are put into the standard world view, and reused for every non-zero y chunk, and never saved. Then only the chunk provider would need to be changed I think. Everything else can assume the world is stacked with no issue (well, there's some soft issues around world generators, but that's more that some world generators would not produce sensible worlds for stacked chunks - but they should all still work with either). What we shouldn't have is checks for whether the world is stacked all over the place, or many different sets of classes for stacked vs unstacked.

If you are already achieving this, then that's cool. :) And it can wait for a second pass after stacked is working anyway. Thanks for elaborating on your reasoning.
 

Panserbjoern

Member
Contributor
Architecture
On the second point, I would recommend 16x64x16, 16x128x16, or 16x256x16. There needs to be enough verticality to support the new sunlight algorithm - sunlight needs to fade in over a reasonable distance, and that distance needs to be less or equal to the chunk height. 64 is probably the practical minimum for this.
What new sunlight algorithm are you talking about? Whats the difference to the current algorithm? It should be possible, to have the sunlight fade in over multiple chunks. Those chunks with higher y-coordinate could always be generated first. The sunlight could then fade top down from chunk to chunk.

There is a cost to flexibility, and a cost to having code that isn't actually being used (maintenance). The question would have to be whether the performance gain for having explicit flat-world support for the hypothetical situation that someone wants to use it, is worth it against the complexity cost of having it - especially because not having it doesn't prevent emulating it.
I agree with that.

If the number of points which are impacted by flat vs stacked worlds are minimised I don't see an issue though - maybe you're already achieving this? [...] What we shouldn't have is checks for whether the world is stacked all over the place, or many different sets of classes for stacked vs unstacked.
That's exactly what i have in mind. The class ChunkType handles most of the differences between flat vs stacked. There are still some things that should be changed to be handled through the chunk type, though.

For now, i will implement a specialized tesselator for stackable chunks. I've never implemented a tesselation algorithm, though...

If everything is working against world views, then having a flat world view and a stacked world view may be ok - you could even go further and just have the flat chunk provider with a single "above" chunk and a single "below" chunk which are put into the standard world view, and reused for every non-zero y chunk, and never saved.
I've adapted the world view to support both flat and stackable chunks. Having the world view use some "virtual" above and below chunks is an interesting idea. Currently in flat worlds it does not have chunks above and below y = 0.

Then only the chunk provider would need to be changed I think. Everything else can assume the world is stacked with no issue (well, there's some soft issues around world generators, but that's more that some world generators would not produce sensible worlds for stacked chunks - but they should all still work with either).
Maybe it can be handled by the world view itself. If it is a flat world, the world view just uses a virtual chunk for all chunks with y != 0.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
What new sunlight algorithm are you talking about? Whats the difference to the current algorithm? It should be possible, to have the sunlight fade in over multiple chunks. Those chunks with higher y-coordinate could always be generated first. The sunlight could then fade top down from chunk to chunk.
Sunlight propagation is the main issue with implementing vertical chunks. Sunlight currently assumes that there is only 1 vertical chunk, with sunlight at full strength above that. If the sunlight is blocked, then a shadow is pushed down to the bottom of the chunk. We fundamentally cannot have infinite sun-shadow - if I climb up to 0, 10000, 0 and add a block, we cannot afford to load and update every chunk all the way down to 0, -10000, 0 or whatever.

Ideally lighting propagation should be resolvable within just a chunk and its immediate neighbours - this plays into chunk generation and loading, with chunks being considered ready for use when they are loaded and complete, and surrounded with loaded chunks.

The proposed algorithm is that sunlight fades back in over the vertical distance the same height as a chunk - that is a fully sunlit block has a light value of 127. If you have a solid floor 1 block thick, then beneath that sunlight will be 0, and then tick up by 1 each block further down until it is full. The effective sunlight value (from 0 to 15, just like normal light) will be calculated off of this such that a reasonable light value must be reached before the sunlight starts becoming visible.

Additionally, the regeneration of sunlight would not occur beyond a certain depth below ground level, as indicated by the world's heightmap data (whether a noise function or an actual heightmap, depending on the generation technique).

Because the sunlight regenerates locally, there are no infinite roll-on effects.

For now, i will implement a specialized tesselator for stackable chunks. I've never implemented a tesselation algorithm, though...
You shouldn't have to create another tesselator. It should already work with vertical chunks.
 

Panserbjoern

Member
Contributor
Architecture
Immortius

It took me a while to figure out why the chunk tesselator wasn't working with stackable chunks. You said, it should work, so i assumed that the bug was somwhere else. I finally found it. It was because i forgot to update the calculation of the chunks AABB.

Now everything is tesselated correctly! :)
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
I guess I really meant to say stacking should just work with the tessellator, the size changes are another story. Sorry if that caused confusion. :/
 

Panserbjoern

Member
Contributor
Architecture
You didn't cause any confusion! You were right when you said that the tesselator should work for stackable chunks. The bug was in the methods Chunk.getAABB() and Chunk.getSubMeshAABB(). I just forgot to handle stackable chunks in those methods. But it took me a while to figure it out. :)
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
I don't know where Panserbjoern got to with this, but I've started work on both vertical chunking and world load and render optimisation. This is currently in the Terasology branch "develop-vertical-chunking".

At this point I have basic support for vertical chunks covered - in the Flat world, you can dig down or build up as high as desired. Chunk sizes have been changed to 32x64x32 for the moment, which result in better rendering performance for a given view - ignoring vertical chunks. I may switch to 32x128x32, depending on the results of performance testing.

A few major bits of work still required:
  • Remove Second Pass Chunk Generation. While convenient, it requires a lot of memory and work to support this pass - it requires a 5x5x5 cube of chunks to just get the center chunk fully generated. By removing this pass a chunk can be fully generated on its own, which both simplifies chunk generation and saves a lot of memory, particularly for larger view distances. This does mean working out how to get tree generation working in the primary pass - which will be interesting.
  • Update existing world generators to support vertical chunks. Currently the Perlin world generator squishes the world down to fit in the 64 block height of a single chunk, and then repeats - so the world has a ceiling which is a copy of the world, and if you dug through the mantle you would find another copy of the world. Trees need fixing. The ocean probably needs work.
  • Light and Sunlight propagation needs to be fixed as well. This isn't too bad - the algorithm for light is unchanged, just need to check it doesn't stop at min or max height. For sunlight, the key is for it to regenerate over vertical distance, so that any chunk two or more steps away from a given chunk has no impact.
Along with the vertical chunking is other tuning and optimisation of the chunk generation process. I've corrected a number of issues with chunk generation and unload resulting in a much smoother experience and better performance in general. I will continue testing this as the work continues.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Thinking about how to get trees working without the second pass chunk generation stage makes me think it is time to address improvements to the world generation model. Some musings and thoughts:

  • Firstly, it still seems sensible to have multiple classes doing passes over the chunk, each concerned with a separate feature - basic terrain followed by flowers followed by trees followed by whatever else. This allows some mixing and matching, and separates concerns. However...
  • Using the chunk itself to convey information from pass to pass won't cut it. A tree needs to be able to grow into a chunk from "off-chunk", this means it needs to be deterministic where it will grow from and how it will grow. This means the tree growth algorithm cannot require scanning a chunk for the surface or a block type - the information must be available from elsewhere.
  • This supports the need for a separate, conceptual model of the world, which is rasterised by the chunk generation passes. This model needs will need to be interrogated by systems outside the world generator as well - it provides information useful for map generation, spawn location determination and other needs. (Thought: an alternate way of handling the world would be to remove per-block modifications entirely, and do modifications to the conceptual model. This would be a different sort of game though).
One way of doing the conceptual model would be a network of information providers. Each provides will provide certain information, and require certain information. Providers can "stack" - a provider may provide information that overrides the information that it requires. A vague example may be something like:

* Heightmap - provides surface and basic air/solid information
* CaveSystem - requires basic air/solid information, provides basic air/solid information modified to add caves.
* Climate - provides humidity and temperature info
* BiomeSystem - requires surface, humidity, temperature and air/solid information, provides biome information.
* TreeSystem - uses surface, air/solid and biome information, provides tree locations and sizes.
* Cities - uses much of the above, provides city locations, may alter surface and air/solid info (to flatten landscape), remove trees.

Then each chunk pass would require various types of information.

Important - the conceptual model would not refer to specific block types. That should be determined by chunk passes. Ultimately chunk passes should determine appropriate blocks through the components of the blocks (after block improvement work).

A model for this would be to model each information element as an interface:

Code:
public interface SurfaceProvider extends MapDataProvider {
 
    int getSurfaceFor(int x, int y);
 
}
 
public interface TreeProvider extends MapDataProvider {
 
    TreeInfo getTreesInArea(Region3i);
 
}
Implementations would implement the interfaces for the data they provide, and have setters for the data they require

Code:
public class FairyCircleProvider implements TreeProvider, StandingStoneProvider {
 
    @Requires
    public void setSurfaceProvider(SurfaceProvider provider) {
        // ...
    }
 
    // ...
}
Some care would need to be taken around the population of the required providers - generally the last provider registered for each interface would be used, with that provider chaining back to earlier providers of that type.

Likewise chunk passes would have setters for the data they require.

Some potential benefits:
* Allows chunk passes to be replaced without changing conceptual data - could use the same provider to produce trees, and then either a non-growing or growing chunk pass to add them.
* Adds some scope for mods adding providers or chunk passes to modify the world. So a mod could simply add fairy circles or giant cairns on top of an existing world generator.

Outstanding questions:
* A common use case would be a world feature that overrides other features in its area - like a city removing the trees, standing stones, and any other features in its area. Can this be addressed in a simple way without requiring a city to know about all features that may be placed before it, or those feature providers knowing about cities? What of features a city might build around but not remove? Is it even worth trying to deal with this?
 

Skaldarnar

Development Lead
Contributor
Art
World
SpecOps
Outstanding questions:
* A common use case would be a world feature that overrides other features in its area - like a city removing the trees, standing stones, and any other features in its area. Can this be addressed in a simple way without requiring a city to know about all features that may be placed before it, or those feature providers knowing about cities? What of features a city might build around but not remove? Is it even worth trying to deal with this?
As to my understanding the chunk passes turn the conceptional data into "real" blocks/game objects, right? It seems to me that removing some trees of wood biome or flatten some terrain parts are quite unproblematic, whereas other terrain features are more sensible to changes. For example, a city should be either build around Stonehenge (and not changing it) or remove it completely, but not cutting it in half.
Another word to river bodies (to me the conceptual data seems to be perfect to model those): if a structure like a city or castle needs to modify the terrain in an area where a river body is present, it should preserve the it in a way such that the water can keep "flowing" (I hope you get what I want to express :D).

All that said, I would suggest some kind of indicator how much a structure/world feature is "bound together" (e.g. stone circles should be either complete or not there at all, rivers should stay connected, but their path can change, forests can be changed without restrictions, ...). Does that sound reasonable (and doable)?

PS: Immortius, where is that nice screenshot you posted on IRC yesterday? :p
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
As to my understanding the chunk passes turn the conceptional data into "real" blocks/game objects, right? It seems to me that removing some trees of wood biome or flatten some terrain parts are quite unproblematic, whereas other terrain features are more sensible to changes. For example, a city should be either build around Stonehenge (and not changing it) or remove it completely, but not cutting it in half.
Another word to river bodies (to me the conceptual data seems to be perfect to model those): if a structure like a city or castle needs to modify the terrain in an area where a river body is present, it should preserve the it in a way such that the water can keep "flowing" (I hope you get what I want to express :D).

All that said, I would suggest some kind of indicator how much a structure/world feature is "bound together" (e.g. stone circles should be either complete or not there at all, rivers should stay connected, but their path can change, forests can be changed without restrictions, ...). Does that sound reasonable (and doable)?
Yeah. I envision a conceptual level, a feature like a stone circle or tree would be a single element, so you could filter it out individually and completely. Something like a forest or biome would be a region that could be modified more fine grained.

PS: Immortius, where is that nice screenshot you posted on IRC yesterday? :p
This one? The height is working well, but it looks odd when you find a particularly pointy bit of terrain and the lower chunks don't render (need better depth-fogging).
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
Screenie splashed all over our social networks - nice work! :D

Curiously, would an event-based generation system work for "smaller" world features like trees and cities? Where individual blocks matter, unlike rivers, ravines, and such.

Big stuff generates during the main phase dealing with the different "maps" that eventually rasterize into blocks. Smaller stuff like trees get placed in a central block/"egg"/entity/pixel on a map/given coordinate, that doesn't trigger and generate until it is sufficiently visible to a player, yet can "process" in the background as if they exist, if appropriate - mainly thinking cities there. Surely entity based.

Trees are probably easier to imagine that way, since we currently have organically growing trees, you could place one in a delayed fashion and let it generate in fast-forward mode when appropriate - likely when an outer band within player visibility has generated so the chunks are available. Cities would be trickier as they could span a much larger area, but then if we have the "plot plan" then individual buildings could generate when appropriate, like trees. Could possibly even generate within sight of the player if made a stylistic choice (stuff pops into existence layer by layer)

Background processing for cities could do stuff like send out caravans that are visible on a "world trade map" but have no block-based representation unless a player is within range. Maybe an event-based approach could also help different features cancel each other out when appropriate - such as a city "egg" suppressing the generation of faery circles, yet OKing individual trees if they're placed in a fashion that doesn't clash with the city's "plot map"

Maybe all that is still too similar to the two-phased approach where you're waiting for a specific set of chunks to generate. But then maybe it could allow for better functionality in loading/unloading things during normal gameplay after an area has done its initial generation? At that point of course you'd need to be storing block state (well, not for caravans) - unless you can simply revert to seed values if the area is otherwise untouched by the player (could be tracked by a chunk-level flag that would likely be useful for other stuff as well)
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Curiously, would an event-based generation system work for "smaller" world features like trees and cities? Where individual blocks matter, unlike rivers, ravines, and such.

Big stuff generates during the main phase dealing with the different "maps" that eventually rasterize into blocks. Smaller stuff like trees get placed in a central block/"egg"/entity/pixel on a map/given coordinate, that doesn't trigger and generate until it is sufficiently visible to a player, yet can "process" in the background as if they exist, if appropriate - mainly thinking cities there. Surely entity based.

Trees are probably easier to imagine that way, since we currently have organically growing trees, you could place one in a delayed fashion and let it generate in fast-forward mode when appropriate - likely when an outer band within player visibility has generated so the chunks are available. Cities would be trickier as they could span a much larger area, but then if we have the "plot plan" then individual buildings could generate when appropriate, like trees. Could possibly even generate within sight of the player if made a stylistic choice (stuff pops into existence layer by layer
I would prefer to avoid it generating features outside of the generation pipeline if at all possible. Past initial generation, block changes are much more expensive - lighting has to be updated, events sent to generated entities, and all on the main thread currently. For performance, being able to plonk down complete structures during generation, on a background thread, is pretty big. We should certainly look into improving performance at runtime though, maybe with some sort of large scale batch updates with single events per block type (like for chunk load/unload). And certainly further work to switch to using bytecode manip and runtime generation of classes over reflection would help with the temporary block entities.

This doesn't mean there cannot be an entity for a city before it is generated into a chunk, with that used for gameplay (diplomatic relationships, simulating trade and so forth), but care would have to be taken with how that feeds into the generation. Cities are NOT small features - they span multiple chunks, potentially too many to ever be in memory at one time. If I sweep past a city and generate some out part, and then enter the city proper sometime later, the chunks need to synch up.

This does make it hard to do cities that evolve over time. This could be done by completely regenerating the chunks on return... although that would wipe any player changes. Could be explained away as the citizens repairing the city. If entities are feeding into the generation, this can persist important things like player relationships with stores and so forth.

Background processing for cities could do stuff like send out caravans that are visible on a "world trade map" but have no block-based representation unless a player is within range.
This doesn't have anything to do with world generation, since caravans are completely dynamic and not block-based. It is absolutely doable too.

Maybe an event-based approach could also help different features cancel each other out when appropriate - such as a city "egg" suppressing the generation of faery circles, yet OKing individual trees if they're placed in a fashion that doesn't clash with the city's "plot map"
I don't really see it helping. The difficulty is, when you have two types of features X and Y, how to know whether Y overrides or coexists with X. It is fine if X knows about Y, or if Y knows about X, but if neither know about each other it it gets messy. That is mostly a modding consideration though - there's no reason a city wouldn't know about trees, and so remove overlapping trees - or even add trees into internal park areas.
 

Marcin Sciesinski

Code ALL the Ages!
Contributor
World
Architecture
Yes, initially the trees were being generated post-worldgen, which was causing a lag. When I moved the generation to the second-pass there was a huge improvement in the performance.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
A not-very-interesting update:

I have been working away at the sunlight algorithm. I have the core algorithm down pat, and an optimised algorithm for initially connecting chunks. Unfortunately the performance is still too low to satisfy me - the lighting merge when connecting chunks is easily one of the most expensive activities frame-to-frame while chunks are being generated or loaded, although just optimised enough that it doesn't affect the framerate on my machine. Still, next I'm going to look at improving the chunk generation/load pipeline so the initial connect can be either be done off-thread, or otherwise in a more efficient manner.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Another update:

Sunlight algorithms are now reasonably performant - I haven't done any threading, but managed to tweak things to the point where it is acceptable. There is potential for threading in light merge itself, or possibly even usage of CUDA, but will leave this for the moment.

So the remaining bits to be done are:
  • New world generation framework with the split between the abstract world and rasterization.
  • Basic terrain generation under the new framework
  • Tree generation under the new framework
  • Update player spawning to determine the spawn location using the abstract world (avoid spawning in water or underground)
  • Feed the surface height information into sunlight propagation to prevent underground sunlight
At that point I will merge. Following from this:
  • Update AnotherWorld for the new system.
  • Change the chunk load/generation to prioritise which chunks are loaded/generated based on closeness to players at the time a thread becomes available
  • Implement some support for entity creation during chunk generation.
  • Further optimisation of light merge.
And at some point after the merge, TeraMath integration.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Progress Update:

This has been pretty slow going unfortunately. I discarded the previously mentioned generation framework - it was too slow working directly against noise algorithms (replicating the perlin generator) and wasn't particularly open to optimisation - since it was based on chained function calls, the same data would be requested multiple times. It also was unable to take advantage of batch generation of all the data needed for a chunk.

I have been working on a new framework, and would like some feedback on the current design. It is aiming to maintain the good conceptual features of what I was originally working on (layered approach, open for extensions and modifications, allowing looking beyond the current chunk for information, ability to deterministically specify features so multi-chunk spanning features can be generated correctly without requiring all chunks to be generated together), while allowing for optimisation and batching.

Core to the generation framework are Facets. Each facet holds data on one layer of the world - surface height, temperature, biomes, plants, the locations of stone circles, whatever is needed or desired. They do so for a specific region - whatever region is being requested (typically a chunk).

These facets are generated by a series of FacetProviders. Each FacetProvider either Requires, Updates or Produce one or more facets - these relationships are specified using annotations. Produces means that facet provider create the initial form of a facet. Requires means the provide needs a facet, generally in its complete form - an example would be a BiomeFacetProvider that uses temperature, humidity and surface height information to produce a BiomeFacet. Updates means the provider takes a previously created Facet and modifies it. These three relationships help order the facet providers - so if a module introduces a facet provider to create stone circles which flattens the surface where they occur, this can be inserted correctly before the a provider that needs to use the final surface height. Additionally if a single facet is required, on the facets and facet provides in the chain resulting in that facet will be run. It also allows for discarding facets from memory if they are no longer needed.

Finally WorldRasterizers take the facets and apply these to chunks, using whatever logic they need. This is where blocks are selected and placed - everything before this is more abstract information.



Facets can be whatever is needed, but I envision generally they are either "field" facets containing data for each location in the region, or "feature" facets contain information on features that overlap or are near to the region. Facets additionally can be 2D or 3D - 2D is good for surface information, and potentially for dungeon layers and that sort of thing.

One final feature is that a Requires annotation allows a border to be specified for a facet - so if you need a little information from outside the region itself you can expand the region a little. For instance, to determine where plants are placed you may need to know whether the ground is solid one block below each position - so you can @Require(@Facet(value = SolidityFacet.class, @FacetBorder(bottom = 1)). This is accumulated, so if you require solidity with a bottom of 1, and a facet provider contributing to Solditity requires another facet, the border is passed on to that facet as well.

What this doesn't yet provide is a way to sample non-adjacent sections of the world - this can be handled somewhat by specialised Facets (a facet could provide data on some much broader area of the world), so I was thinking of leaving this unless a solid need for it arises.


At the moment I'm fleshing out the implementation for this, and putting together a simple world generator based on the old perlin world generator - it loses some of the features of perlin at the moment though as several parts of the perlin world gen assume you can scan the entire world from top to bottom. I will look into how this can be addressed.
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
Sounds like a great approach to me, but you probably would like some more technically detailed feedback than that :)

Pinging begla Panserbjoern Marcin Sciesinski msteiger Skaldarnar Nym Traveel Laurimann MPratt Brokenshakles Perdemot Ten'son' ... via convo too just in case that gets another attempt or two for a constructive reply :geek:

Immortius would there be any value in merging in the vertically stacked chunks before the new world gen approach is ready, so that the code doesn't go dusty and in case it helps get some more eyes on getting existing world gens updated just for height ? Or is that what you aim for with addressing the Perlin approach? Certainly the tree setup hits challenges

You might want/need to do the whole thing in one go, but I thought I'd bring up the option in case it would help the transition to have a sort of cheaty option to only generate real chunks in the normal 0-256 height and filling anything below with mantle and anything above with air

Edit: On a side note I find it interesting how the facets are almost like Gradle dependencies and the project tree. Right down to "figure out the configuration first then do the action" so to say. Maybe a silly observation, but it is past midnight so ..
 
Top