Skip to content

Instantly share code, notes, and snippets.

@Commoble
Last active December 10, 2023 22:31
Show Gist options
  • Save Commoble/1e44951973ccc518248ccc0ee3880bf9 to your computer and use it in GitHub Desktop.
Save Commoble/1e44951973ccc518248ccc0ee3880bf9 to your computer and use it in GitHub Desktop.
What's the difference between the different VoxelShape getters in forge for minecraft 1.16.4?
/**
AbstractBlock::getShape(BlockState, IBlockReader, BlockPos, ISelectionContext)
The primary shape for "selection" raytraces, like clicking a block.
Defaults to a full cube. Delegated to by AbstractBlockState::getShape(IBlockReader, BlockPos, ISelectionContext)
Most of the other shape getters either default to this or default to empty,
so just overriding this shape getter is sufficient if finer variations aren't needed.
AbstractBlock::getCollisionShape(BlockState, IBlockReader, BlockPos, ISelectionContext)
The primary shape for collision raytraces.
Delegated to by AbstractBlockState::getCollisionShape(IBlockReader, BlockPos, ISelectionContext)
By default, this checks whether the block blocks movement,
using AbstractBlock::getShape if it does, or an empty shape if it doesn't.
Movement-blocking is set via the Block.Properties.
AbstractBlock::getCollisionShape(BlockState, IBlockReader, BlockPos)
Same name as the above in MCP due to misnaming, used for a completely different mechanic
Defaults to the other getCollisionShape, delegated to by AbstractBlockState::getRenderShape(IBlockReader, BlockPos)
This seems to be used when the block is checked to determine whether it has a big enough side
to support another block (like when a torch is placed on a wall)
this is overridden by e.g. leaves to make them unable to support anything,
and by soul sand and snow layers to make them support more things than their regular collision shapes would
AbstractBlock::getRendershape(BlockState, IBlockReader, BlockPos)
Defaults to Block::getShape. Delegated to by AbstractBlockState::getRenderShapeTrue(IBlockReader, BlockPos).
This one is used for several things.
Firstly, it's used to determine whether to cull faces of adjacent blocks.
Secondly, it's checked in Block::isOpaqueCube, which is used for many things unrelated to rendering things, like pathfinding
Giving a block the notSolid() Block.Property causes the render shape to be ignored in most cases
(effectively being the same as having an empty render shape)
Transparent full-cube blocks like glass should be set to notSolid() to avoid culling adjacent faces (the x-ray effect)
AbstractBlock::getRayTraceShape(BlockState, IBlockReader, BlockPos, ISelectionContext)
Defaults to getCollisionShape (the one used for collisions),
delegated to by AbstractBlockState::getRaytraceShape(IBlockReader, BlockPos, ISelectionContext)
Used for determining the collision shape with respect to the camera in 3rd-person camera mode
AbstractBlock::getRaytraceShape(BlockState, IBlockReader, BlockPos)
This is almost the same name as the above function but completely different, blame MCP
Defaults to an empty shape. Delegated to by AbstractBlockState::getRaytraceShape(IBlockReader, BlockPos)
This one is a bit strange, but it's sort of like a normal map override for raytraces against the other shape types.
When a block is raytraced against, the primary shape (getShape or getCollisionShape) is raytraced against first.
IF the raytrace result against the primary shape is non-null, the raytrace shape is raytraced against.
IF the raytrace result against the raytrace shape is ALSO non-null
and the raytrace shape raytrace hit is closer to the raytrace origin than the primary shape raytrace hit
i.e. the raytrace hit the raytrace shape before the primary shape
then we still use the raytrace result that hit the primary shape,
but with the Direction of the face of the raytrace shape that was hit.
getRaytraceShape is therefore only used when
the primary shape exists and is hit
the raytrace shape exists and is hit
the raytrace shape is hit before the primary raytrace shape
otherwise, only result of the raytrace against the primary shape is used
/**
@Tacitor
Copy link

Tacitor commented Oct 25, 2020

Thank you this was very helpful. I don't think I would have been able to get my block to work without this. Additionally, I would add that Block::getShape also deals with the block's particles, at least that's what I got from testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment