Hello everyone,
i will try to present my proposed change to store biome information per-block with the other chunk data (block ids, etc.).
The problem I am trying to solve: Through profiling, I found that 95%+ of the time spent in generating a chunk mesh is spent in calculating the temperature/humidity of a block for giving foliage and other blocks a hue.
Proposed Solution: Since there is most likely a correlation between temperature/humidity and biome, I'd like to determine the biome for every block when the world is being generated and store that information with the rest of the chunk. In the rendering stage, the humidity/temperature of the biome is then used for rendering.
To do this, I introduced the concept of a Biome in the engine (interface), which has to provide temperature and humidity values, as well as an ID and a human readable name. Largely this concept is stolen from the AnotherWorld BiomeRegistry. The change set also includes the necessary changes to bring the Core and AnotherWorld biomes into the Biome class hierarchy provided by the engine. In a chunk, Biomes are stored as 16-bit integers. The mapping between Biome IDs (assumed to be module + ":" + biomeId) and those "short ids" is managed by the BiomeManager and stored to the save manifest. The change also includes the necessary changes to transmit the biome data to the client in a networked environment, as well as transmitting "BiomeUpdateEvents" to clients. The F3 debug overlay also now shows the biome the player is standing on. The Biome auto discovery requires a module to provide an implementation of "BiomeRegistrator", which then is called back with an instanceof a "BiomeRegistry". The module then uses this biome registry to register the biomes it provides. I made the move away from auto-discovering Biome classes, since Core defines its Biome in an enumeration. I also conflated the Biomes in AnotherWorld into a single class and simply instantiated it for each Biome and then registered the instances (as can be seen in the AnotherWorldBiomes class).
In the medium to long term, it'd make more sense to encode fixed biome colors rather than colors deduced from humidity and temperature. For example one could devise a Wasteland biome with dark brown foliage colors, which shares the same humidity and temperature as a desert, which still has green cacti.
Biomes are stored per-block instead of per-block-column (as for example in Minecraft), since this would allow deep underground caverns, dungeons, or sky islands to be a separate biome from the overworld.
In the future, Biome could have more gameplay implications and may be used by modules to attach gameplay behaviour to areas generated by the World Generator, all while not directly depending on the world generation itself.
For example:
- spawn entities or structures only in certain biomes
- allow terraforming the world with advanced technology or magic (effectively changing the biome of surrounding blocks)
- allow wildly magical areas through world-generation (think purple grass) without having to provide different grass blocks (to look nice, this requires biome color interpolation)
You can find the source code here:
https://github.com/shartte/Terasology/tree/biome-per-block
https://github.com/shartte/GrowingFlora/tree/biome-per-block
https://github.com/shartte/AnotherWorld/tree/biome-per-block
https://github.com/shartte/WoodAndStone/tree/biome-per-block
I uploaded a ZIP Dist here: http://www.hartte.de/ts/Terasology.zip
If you'd like to check out the performance improvements without having to compile it yourself.
This thread is intended to serve as a discussion for the merits of this change. There are certainly several alternatives, which could also be discussed here.
Regards
Sebastian
i will try to present my proposed change to store biome information per-block with the other chunk data (block ids, etc.).
The problem I am trying to solve: Through profiling, I found that 95%+ of the time spent in generating a chunk mesh is spent in calculating the temperature/humidity of a block for giving foliage and other blocks a hue.
Proposed Solution: Since there is most likely a correlation between temperature/humidity and biome, I'd like to determine the biome for every block when the world is being generated and store that information with the rest of the chunk. In the rendering stage, the humidity/temperature of the biome is then used for rendering.
To do this, I introduced the concept of a Biome in the engine (interface), which has to provide temperature and humidity values, as well as an ID and a human readable name. Largely this concept is stolen from the AnotherWorld BiomeRegistry. The change set also includes the necessary changes to bring the Core and AnotherWorld biomes into the Biome class hierarchy provided by the engine. In a chunk, Biomes are stored as 16-bit integers. The mapping between Biome IDs (assumed to be module + ":" + biomeId) and those "short ids" is managed by the BiomeManager and stored to the save manifest. The change also includes the necessary changes to transmit the biome data to the client in a networked environment, as well as transmitting "BiomeUpdateEvents" to clients. The F3 debug overlay also now shows the biome the player is standing on. The Biome auto discovery requires a module to provide an implementation of "BiomeRegistrator", which then is called back with an instanceof a "BiomeRegistry". The module then uses this biome registry to register the biomes it provides. I made the move away from auto-discovering Biome classes, since Core defines its Biome in an enumeration. I also conflated the Biomes in AnotherWorld into a single class and simply instantiated it for each Biome and then registered the instances (as can be seen in the AnotherWorldBiomes class).
In the medium to long term, it'd make more sense to encode fixed biome colors rather than colors deduced from humidity and temperature. For example one could devise a Wasteland biome with dark brown foliage colors, which shares the same humidity and temperature as a desert, which still has green cacti.
Biomes are stored per-block instead of per-block-column (as for example in Minecraft), since this would allow deep underground caverns, dungeons, or sky islands to be a separate biome from the overworld.
In the future, Biome could have more gameplay implications and may be used by modules to attach gameplay behaviour to areas generated by the World Generator, all while not directly depending on the world generation itself.
For example:
- spawn entities or structures only in certain biomes
- allow terraforming the world with advanced technology or magic (effectively changing the biome of surrounding blocks)
- allow wildly magical areas through world-generation (think purple grass) without having to provide different grass blocks (to look nice, this requires biome color interpolation)
You can find the source code here:
https://github.com/shartte/Terasology/tree/biome-per-block
https://github.com/shartte/GrowingFlora/tree/biome-per-block
https://github.com/shartte/AnotherWorld/tree/biome-per-block
https://github.com/shartte/WoodAndStone/tree/biome-per-block
I uploaded a ZIP Dist here: http://www.hartte.de/ts/Terasology.zip
If you'd like to check out the performance improvements without having to compile it yourself.
This thread is intended to serve as a discussion for the merits of this change. There are certainly several alternatives, which could also be discussed here.
Regards
Sebastian