A modern replacement for BlockFace and Directional
Is your feature request related to a problem?
In order to represent the direction a block is facing, Paper makes use of the BlockFace enum, which contains 19 variants. The problem here is that many of these variants are rarely valid, a stair only has 4 valid faces, yet it uses BlockFace which can represent facing directions as specific as "WEST_NORTH_WEST" and simply throws an exception if an invalid BlockFace is passed.
"Make invalid states unrepresentable" is a phrase that is sometimes used. Using stairs as an example here, the core idea is that the API should not be able to represent a state that the stair could never be in, instead of using a BlockFace (which could represent an invalid state), you'd use a more specific enum which only represents the states valid for stairs. There are a number of advantages to this approach, for instance:
- It's more clear to developers what rotations are valid as it becomes part of the function signature as opposed to some doc comment (often elsewhere) or even worse a wiki page they may not read.
- It's less error prone, if you have a type which only accepts the 4 cardinal directions, if you try and pass "UP" then it becomes a compile error, not a runtime exception which may go unnoticed during development.
Describe the solution you'd like.
A gradual replacement of BlockFace with more specific facing direction representations, such as a BlockFace4, BlockFace5, and BlockFace6, etc. If implemented correctly these could even be made to allow BlockFace6 to extend BlockFace4 so they can be passed as is, making it convenient for developers. How exactly this API would be structured would have to be part of further discussion.
Describe alternatives you've considered.
Doing nothing, which while fine, unless I am mistaken, it is at least in part Paper's goal long term to clean up the API and fix the mistakes of the past, this would simply be another aspect of that.
I understand that due to the scale this would probably not be a priority for the Paper team, likely to see gradual implementation, and not result in the quick removal of BlockFace due to the wide use of BlockFace.
Other
I initially discussed this in #paper-dev in order to test the waters and see if people were open to the idea, and it seems like they were, so I'm bringing the idea here more formally.
If the idea has support from developers (within and outside of the Paper team), I'm interested in further discussion and at minimum assisting with implementation.