Add custom blocks
knokko opened this issue ยท 5 comments
There have been quite some requests to add custom blocks to this plug-in. Unfortunately, it seems quite hard to actually implement this, and some tricks are not available for all minecraft versions and/or have unacceptable performance problems.
If we were to implement this, it would involve quite some research to determine the best strategy, and quite some work to implement it.
There is a potential additional source of custom blocks: Mushrooms. Block States on giant mushroom blocks that never appear in survival give ~160 free resource slots, meaning at minimum 160 custom blocks from that alone. Other options may exist as well.
I saw an interesting video the other day demonstrating this, see https://www.youtube.com/watch?a&v=UpVXOCHMj7c
Keep in mind this has potential conflicts with more recent versions of Minecraft, where you can place mushroom blocks and get the variants. So be sure to add some safe default logic (e.g. when placing mushroom blocks, check nearby, and set to unused variants)
Outside of that, see below:
The current de facto method seems to be either Item Frames (1.16+ supports invisible and "fixture" flags to prevent manipulation) or Armor Stands.
The block underneath/inside the entity sets the break sound/speed/particle. However for that, there are some other options. For example, applying a negative fatigue potion effect and manually calculating/tracking mining times. With this approach you could use a barrier block and have full control over and dig speed mining particles, the latter by sending break particle packets to the client. This would give you full flexibility on aesthetics.
For gravity-affected blocks, create an invisible sand/gravel entity and set the armor stand as a passenger. This should give the desired effect.
One significant drawback I can see is no meshing and/or culling would take place. Entities cost more computationally overall, so performance on large-scale builds would be significantly impacted.
Most solutions require either entities or tile entities, which will have an unacceptable impact on performance if too many are placed.
The most promising option is probably using mushroom blocks, but that also has some challenges and drawbacks:
- Won't work on minecraft 1.12 and perhaps not on minecraft 1.13 (I haven't checked this exactly).
- The number of custom blocks I can add like this is somewhat limited (~160)
- I need to suppress blockstate updates of these mushroom blocks
- In the later minecraft versions, I need to prevent players from placing the variants that I claimed (so this is not entirely 0-cost)
Last time I tried that, it was affected by the entity render distance: If I moved too far away, I would see an empty mob spawner. Perhaps it works better in other minecraft versions, but I only tried it in mc 1.12.
Also, I am a bit concerned about the performance of this trick: mob spawners are tile entities, and I think they update every tick. Also, players have to render the 'mob' inside every frame. This will probably cause problems when players start building castles with it...
I've done an experiment, and at least for 1.14+, armor stand mob spawners work. Here's the steps I've done:
- Override spawner block model. Scale down .01 to prevent texture artifacts. This change is not noticeable but makes all the difference.
- Override spawner item model using CustomModelData floating-point-casted int prop (limit ~16 million custom blocks this way) for hand/inventory models to create visual consistency
- Create a block model designed for armor stand heads. Numbers are to account for spawner entity position/rotation
- Give the player a heavily-customized spawner
- Marker: 1, Invisible: 1, RequiredPlayerRange: 0, SpawnRange: 1, SpawnCount: 0, MaxNearbyEntities: 0
- Armor Items: [{}, {}, {}, item with custom block model NBT]
- Example command I used to test
- On place, force a block update of some kind otherwise this happens. This is because the client has a few render ticks before the state is applied from the item on block place, so it rotates a little bit before it realizes it isn't supposed to. It looks fine on reconnect/chunk reload.
Here's a visual on what this looks like.
Credit to Sarc on YouTube for coming up with most of it, but I made a few small tweaks.
Today, me and Guaz had a discussion about the inefficiency of most other custom block plug-ins (basically unacceptable lagg). That seems to be because they need to (1) keep track of the positions of all custom blocks, to prevent them from turning into mushroom blocks upon block state updates. (2) Also, we need to prevent real mushroom blocks from taking the texture of a custom block. The biggest performance bottleneck seems to be (1), but perhaps I would be able to do better than them.
I am planning to experiment with this before the Custom Items 9.0 release.