Clarifications: Voxels, Blocks, Locations, and access interfaces

There has been a lot of confusion and wasted time regarding the topics of Blocks, Voxels and Locations, so I’m making this post to clear it all up, or at least try to.

Blocks

Blocks in Minecraft aren’t Blocks in Bukkit. In Minecraft, Blocks are singletons used to define the logic of all blocks of a type. For example, defining whether or not a block burns. These are not bound to any location and the same instance is used for all logic calls.

In Bukkit, a Block is simply a Material and a Location. The Material refers to the logic and is a singleton (much like the Minecraft Blocks), and the Location provides the position in the world. You can have many Blocks of the same type and even of the same Location.

Sponge adopts the Minecraft way of defining Blocks for ease of implementation.

Locations and Vectors

Location in Bukkit is mostly just a fancy name for a Vector3d, which is a 3 component vector with double precision floating point numbers for numerical storage. Bukkit Locations do add pitch and yaw information, which actually makes it a simplified Transform, but these should be separate, since they aren’t alway needed. Sponge will use Vector3d as a replacement for Location, as well as Vector3i. Entities and other objects that require decimal precision for their position will use Vector3d, while objects that only need integer coordinates (such as Voxel that will be explained bellow) will use Vector3i. Sponge also adds classes for Vector2i, Vector2f, Vector2d and Vector3f. The number suffix is the dimension of the vector, while the letter suffix is the numerical storage type (int, float or double).

Voxels

To replace the Bukkit concept of Block, Sponge introduces Voxels, which are in essence the same thing as Bukkit Blocks. A Voxel is the smallest unit of a Minecraft world. They have a reference to the Block singleton that defines the logic, and a Vector3i that gives them a Location. These are simply there for convenience and are created on demand. They are not by themselves responsible for any logic at a their location.

Access interfaces

An access interface is a common interface for objects that allow access to other objects of a shared type in similar ways. For example, a World and a Chunk give you access to a Voxel at a location and a list of all Entities they contain. For abstraction purposes, we can regroup World and Chunk under interfaces for these accesses. They’re right now two major access interfaces: VoxelVolume and EntityUniverse.

VoxelVolume

A VoxelVolume is, as the name suggests, a Volume that contains Voxels. It can be bounded or unbounded. World is an example of an unbounded VoxelVolume, while Chunk is a bounded VoxelVolume. A Voxel is also a VoxelVolume. This might sound like a weird idea, since a Voxel is just a single Voxel, but, it’s actually the unit VoxelVolume, and including it under the interface can be very useful for abstracting certain algorithms. For example, if we have an algorithm that counts Voxels of a given Block type in a VoxelVolume, both Chunk and Voxel should be valid inputs, as both contain materials that can be counted (even if it’s just one). Another way to support this reasoning that a list with 1 item is still a list, and so a VoxelVolume with 1 Voxel is still a VoxelVolume. Other objects will be added that implement the interface, to provide bounded Views of unbounded Volumes, Buffers and thread-safe world editing. These will be detailed in another post.

EntityUniverse

Basically, anything that can return a list of entities should be an EntityUniverse. The terms simply means a universe in which entities can be found. World is a good example of such a thing. The term Universe was favoured over Volume since it’s formless and doesn’t actually suggest any formal concept of space.

Sumary

  • Bukkit Material = Sponge Block = Minecraft Block

  • Bukkit Block = Sponge Voxel

  • Bukkit Location = Sponge Vector{2/3}{i/f/d} = Minecraft Vector (in 1.8)

  • VoxelVolume = volume of Voxels

  • EntityUniverse = container of entities

28 Likes

How will tile entities fit within the Voxel-Block model, will it be part of the block class as the contents of a tile entity could effect its logic. Or will it be off the voxel class as it only relates to that voxel? If it will be off the voxel class will the logic be split between tile entity class and the block class. Or will the tile entity class only contain data(maybe is just an NBT tag)?

1 Like

I’m not very familiar with tile entities, but as I understand they’re just a special case of Block, so they will probably be handled much like Blocks for this part of the API.

TileEntities are entities that are created when a chunk is created. They are not Block objects at all.

There is one instance per Block of that type.

@Zidane could comment more. A tile entity would have to be linked to a voxel. Maybe that is core enough for it to be part of the entity object. However, most likely they could do it with a TileComponent or something like that.

When you interact with a block, it sends that info to the tile entity if it exists.

I think TileEntities were stored along with the chunk like any other entities.

1 Like

tile entities are block addidtions e.g. the command of commandblocks or the text of signs are saved there

I think it should be possible to change Tiles. We could just add this to the world class.

  • hasTile(x,y,z) : Boolean
  • getTileAt(x,y,z) : org.spongepowered.tile.Tile

Thanks for the explanation! I’ve added BiomeArea to my World Generator API fork, to keep things consistent. I’m looking forward to seeing how you handle mutation.

1 Like

@DDoS, will the use of this type (Voxel Block) reduce the performance of the server? Or this type can increase performance?

It really depends on what the plugin dev does, using Blocks should come at no real performance cost versus Bukkit Materials. Voxels will have the cost of object creation, but any good dev would avoid using them if large amount would end up getting created. The VoxelVolume interface could actually lead to less overhead for large scale Voxel operation and improve performance.

I really wouldn’t worry to much about it.

1 Like

This is going to be one of the most major transitions that plugin devs will have to deal with porting from bukkit next to the new way entities are handled but from the looks of it if you code it right this is a much more efficient system. It will certainly take me a while to get used to using all these new libs though.