Open StavWasPlayZ opened 3 weeks ago
This is just my opinion, but if you are going to propose a change to Forge and have code ready to put into it, I think you might as well create a PR for it. It will be easier for me, as a code reviewer, to actually read what you are trying to do, as it is easier for me to understand from code diffs rather from explanatory paragraphs. Though since rendering is not my area of expertise, I'd like @LexManos or @basdxz to comment on this one.
I really apologize if it came out as an inconvenience. It was more so my intention to discuss and get feedback on that API before actually putting my time implementing it.
I did, however, attach a diff - albeit produced on my own mod project, so as to actually test these ideas in production.
The only real difference is that it contains mixins instead of patches.
No need to apologize, I just think it is easier that way.
I'm making this first an issue to discuss if the following is ok/relevant to be considered into Forge.
I'm willing to convert it into a PR if all is fine.
TL;DR: A new
ExctractRenderStateEvent.Pre/Post
should be implemented to compensate for the lack of an entity reference in the reformedRenderLivingEvent
, as well as to adapt for Minecraft's new render states abstraction.There is also the possibility to provide an API for modders to add custom rendering state fields to different entities and states.
ExctractRenderStateEvent
In 1.21.2, a refactoring change has made it so that rendering-related fields in
EntityRenderer
s are now separated into another data class -EntityRenderState
.Hence, the new
EntityRenderer#render
method is now defined with the following signature:In this form, the entity is now omitted from context.
There is no way, as of current, to trace back to the original entity that possesses the renderer OR its state (as far as I'm aware).
This consequently affects
RenderLivingEvent
- which no longer passes anentity
reference.Here is an example method from 1.21.1 that used this reference, for instance:
This method operates a bunch of checks on the player, that if passed - applies a certain
ArmPose
to them before rendering is applied.This is now impossible.
The solution I came with (diff) was to hook an event to the end of the
EntityRenderer#extractRenderState
methods - where the initialization of the state's fields are to be completed, and we can manipulate them so as to not be overwritten or be too late into rendering.Since the way this method works is by chaining a bunch of overrides-calls-super, we can't determine where the method really ends - so I placed the hook at the end of the
EntityRenderer#createRenderState
, which is basically the wrapper method mostly referred to for this operation anyways.Also added Pre/Post phases, just because we can.
Custom Render State Fields API
The approach to add one's own render state field and then use it for rendering without an
entity
reference aligns with that of the new Minecraft API.This was my initial solution to the problem as well.
My implementation (same diff) involves defining the following class, to identify custom fields:
Which would then be put into a client-only registry - mine uses a simple
HashMap
:Example custom field:
And at the end of vanilla's render state initialization (aka where the
ExctractRenderStateEvent.Post
will be hooked), we can perform the following operation:Where
get/setCustomField
are new methods patched into theEntityRenderState
class:This would allow us to define and use custom render fields, and access a set of defined entity-related data.
Example usage: