This has come up now and then and has been discussed a bit on IRC for the last couple days.
We currently have the BlockFamily concept for related blocks of varying rotation or so, out of a single .block definition. To my knowledge we don't have plain support for blocks that simply vary their texture of choice for variety.
I'd like to see that get added so we can vary both base blocks (dirt, grass, stone, etc in the world) and fancier blocks that have a relationship (like different growth stages of corn without individual .blocks or quantity-showing bookcases)
Some use cases to illustrate the concept and different implementations:
Subtly varying dirt - non-consistent
With extremely similar dirt textures we could simply render a texture at random for each dirt block id. Likely them getting redrawn differently for other players or later sessions wouldn't matter much. Challenge: how to actually pick a texture at random and keep drawing that one texture every time it is still valid (something about generating a chunk mesh once then reusing it - on regeneration pick a random texture again?)
Strategies for this have also come up in the past, like a request for Wang Tiling logic, maybe that could be useful?
Distinct stone - consistent
@Soos621 is working towards a system to engrave stone, and on the way there made some new stone textures with occasional cracks and such. These distinctions are enough that redrawing the textures randomly would be jarring. @shartte suggested basing the texture choice on the position of the block, which remains consistent. Yay!
But then if you break and replace a block, you'd get the same block variant every time. This might not matter in some cases, but could be annoying in other cases. Yet generating and placing unique block ids for every variant of stone instead is overkill at the world gen stage. How about a hybrid approach where base world blocks generate with a family id that get rendered consistently from random variants. If a player breaks any block from that grouping they get a single stackable id that when placed in the world takes a specific id to the block with the exact texture (Stone42). Break it and get the family parent block again, place it get a new variant randomly.
That might also be weird in some cases. Maybe they only get picked randomly once, then when broken drop the exact block that is no longer stackable with other family member blocks. Or maybe you can only get the exact variants by using the console or an actual in-game process, like an engraving process where you get to pick an exact variant (could simply be a filtered BlockPicker window?)
Corn plants - growth stages
Fairly simple example with existing files - the 7 corn .blocks (and other plants) in the Crops module. They share a single prefab for actual logic, but take pointless individual .block files with nothing unique in them. Would be much nicer to write a sequence into a single .block file ("make Corn 1-7 with textures Corn 1-7)
Quantified bookcases - collapses into complex block
Imagine generating a large library full of bookcases. We have a set of 8 or 16 quantified bookcase textures floating around in the forum somewhere (one texture with one book, one with two, one with three, etc). World gen again simply places a single family parent id block, the exact texture picked at random, library looks great and random. As bookcases can be interacted with like chests player can 'e' click them, but to save on entities leave them without persistent entities to start with (on_interaction I think?). On the first interaction collapse the family parent block (via some event) into the correct quantified block, like Bookcase7 if it has 7 showing blocks, and swap it to a persistent entity now containing an inventory with 7 random books chosen at that point.
That would allow us to generate "cheap" world that's distinct, yet doesn't collapse into complexity until needed. In fact, couldn't you do the same with chests and such in dungeons to keep them cheap and "secret" all the way till a player actually attempts to open one? Been talking with @Florian on some inventory / GUI interaction logic including whether the client should have all the data locally (adds more network data and risks cheating if able to scan the content of potentially trapped or locked chests before trying to open them) or not. One additional useful option?
Animated blocks
This might be out of scope as animation is far tricker when you have to regenerate the chunk mesh (I think?) every frame. But I wanted to mention it anyway for consideration in coming up with .block definition support to cover a set of textures / block tiles to be used in an animation. A potential strategy came up on IRC to actually toggle between a set of prepared chunk meshes (equal to the length of the animation) to avoid having to regenerate, but I'm just going on my sketchy memory here
The involved 3D wizardry is beyond me, not that I would have time for this anyway, so looking for anybody interested in taking this to the design phase for more details or outright implementation. Thoughts? Or is this something that would benefit from waiting till we make blocks more like prefabs? @Immortius question on that part
We currently have the BlockFamily concept for related blocks of varying rotation or so, out of a single .block definition. To my knowledge we don't have plain support for blocks that simply vary their texture of choice for variety.
I'd like to see that get added so we can vary both base blocks (dirt, grass, stone, etc in the world) and fancier blocks that have a relationship (like different growth stages of corn without individual .blocks or quantity-showing bookcases)
Some use cases to illustrate the concept and different implementations:
Subtly varying dirt - non-consistent
With extremely similar dirt textures we could simply render a texture at random for each dirt block id. Likely them getting redrawn differently for other players or later sessions wouldn't matter much. Challenge: how to actually pick a texture at random and keep drawing that one texture every time it is still valid (something about generating a chunk mesh once then reusing it - on regeneration pick a random texture again?)
Strategies for this have also come up in the past, like a request for Wang Tiling logic, maybe that could be useful?
Distinct stone - consistent
@Soos621 is working towards a system to engrave stone, and on the way there made some new stone textures with occasional cracks and such. These distinctions are enough that redrawing the textures randomly would be jarring. @shartte suggested basing the texture choice on the position of the block, which remains consistent. Yay!
But then if you break and replace a block, you'd get the same block variant every time. This might not matter in some cases, but could be annoying in other cases. Yet generating and placing unique block ids for every variant of stone instead is overkill at the world gen stage. How about a hybrid approach where base world blocks generate with a family id that get rendered consistently from random variants. If a player breaks any block from that grouping they get a single stackable id that when placed in the world takes a specific id to the block with the exact texture (Stone42). Break it and get the family parent block again, place it get a new variant randomly.
That might also be weird in some cases. Maybe they only get picked randomly once, then when broken drop the exact block that is no longer stackable with other family member blocks. Or maybe you can only get the exact variants by using the console or an actual in-game process, like an engraving process where you get to pick an exact variant (could simply be a filtered BlockPicker window?)
Corn plants - growth stages
Fairly simple example with existing files - the 7 corn .blocks (and other plants) in the Crops module. They share a single prefab for actual logic, but take pointless individual .block files with nothing unique in them. Would be much nicer to write a sequence into a single .block file ("make Corn 1-7 with textures Corn 1-7)
Quantified bookcases - collapses into complex block
Imagine generating a large library full of bookcases. We have a set of 8 or 16 quantified bookcase textures floating around in the forum somewhere (one texture with one book, one with two, one with three, etc). World gen again simply places a single family parent id block, the exact texture picked at random, library looks great and random. As bookcases can be interacted with like chests player can 'e' click them, but to save on entities leave them without persistent entities to start with (on_interaction I think?). On the first interaction collapse the family parent block (via some event) into the correct quantified block, like Bookcase7 if it has 7 showing blocks, and swap it to a persistent entity now containing an inventory with 7 random books chosen at that point.
That would allow us to generate "cheap" world that's distinct, yet doesn't collapse into complexity until needed. In fact, couldn't you do the same with chests and such in dungeons to keep them cheap and "secret" all the way till a player actually attempts to open one? Been talking with @Florian on some inventory / GUI interaction logic including whether the client should have all the data locally (adds more network data and risks cheating if able to scan the content of potentially trapped or locked chests before trying to open them) or not. One additional useful option?
Animated blocks
This might be out of scope as animation is far tricker when you have to regenerate the chunk mesh (I think?) every frame. But I wanted to mention it anyway for consideration in coming up with .block definition support to cover a set of textures / block tiles to be used in an animation. A potential strategy came up on IRC to actually toggle between a set of prepared chunk meshes (equal to the length of the animation) to avoid having to regenerate, but I'm just going on my sketchy memory here
The involved 3D wizardry is beyond me, not that I would have time for this anyway, so looking for anybody interested in taking this to the design phase for more details or outright implementation. Thoughts? Or is this something that would benefit from waiting till we make blocks more like prefabs? @Immortius question on that part