Declarative Immersives
hammy275 opened this issue ยท 7 comments
Right now, a large part of time taken making immersives is tediously positioning hitboxes. Instead, we should make it declarative, such as "put this pattern of hitboxes relative to the block here, following the block's direction".
Would follow the builder pattern of course, and the built objects would be stored with the immersive infos. From there, one can call functions such as .render()
or .tick()
on them when needed. This way, conditions can be handled (such as items only rendering when a chest is open).
Builders would create something that extends AbstractImmersive
when built. Everything that needs to be done to allow this to work can either be done in trackers (to keep track of what chests are open) and/or via callback functions (such as for animations as mentioned below).
For animated ones (enchanting table and beacon), the builder can be provided a function to offset positions.
The actual plan:
- Port immersives to the declarative system, adding features as necessary, removing mod compat and not caring for optimization along the way.
- Re-add missing mod compat immersives as separate immersives.
- Optimize now that we have a more stable API for declarative immersives to use.
- Re-add 3D Resource Pack stuff
- Take care of misc. stuff below if not already completed.
- Release an alpha version of 1.5.0 to make sure this system is as bug-free as possible (not part of this issue, but rather the associated milestone).
Misc. Uncomplete Things:
- Re-add VR motion for opening barrels.
Mod compat to re-add:
- Tinkers Construct workbenches (won't be added until I
git cherry-pick
to other branches, since Tinkers Construct last version is for 1.18.2) - Iron furnaces furnaces
- Forgot to do this before, but add Iron Furnaces furnace checker to the list of CHECKERS.
Implementation-wise, I'm going to have all immersives moved over to being declarative, then I'll go back and handle optimization.
Auto centering furnaces and brewing stands will be fun; perhaps I'll directly swap the immersive out when the setting changes?
I'm also going to be throwing away most, if not all, explicit mod compatibility, then adding it back in after the move.
Work is being done in https://github.com/hammy275/immersive-mc/tree/1.20.x-declarative-immersives
Thinking for auto-centering furnaces and brewing stands, we could instead support hitboxes being registered as Function
s which take the info instance and output position data that's run through the normal calculations.
With this kind of change, I may end up moving the entire declarative system to use suppliers of constant information under-the-hood, so this is easier to implement and keeps one underlying implementation.
EDIT: This is done, though comes at the current consequence of only calculating hitboxes when needed not possible. Once all planned immersives are made declarative, I'll split the suppliers to be either suppliers or a constant value. This way, we can still optimize for immersives that don't need to calculate hitboxes every tick (like the crafting table).
There are some immersives that I won't be moving to the declarative system:
- Chests (and trapped chests). I'm definitely not moving this over. I don't plan to support any sort of equivalent to what would be needed for double chests. Immersives are built to be a central block, with chest immersives being hacked on top. Since chests are staying this way, I'll be doing the same for Ender Chests, due to how similar they are to regular chests, and not wanting to duplicate code.
- Maybe repeaters. I'm back and forth as to whether I should add support for moving between hitboxes without a break in the system. On one hand, it's something that makes more sense as a
Tracker
(see doors, buttons, levers, etc.), but on the other hand, it would be nice to have this system in the immersive system, and it wouldn't be too difficult, where a toggle on the immersive itself to make it so hitboxes only activate when changed after entering the currently selected one. - ImmersiveHitboxes. The whole point of this is gesture management attached to the player. This is unlike most other immersives, where it's either "in the hitbox" or "has left click held while in the hitbox". Leaving this out of the declarative system as a result.
- Likely ImmersiveBeacon: The beacon is somewhat antithetical to the declarative immersive design for a few reasons (listed below). As a result, although it could be implemented as a declarative immersive, I feel it would be needlessly confusing. In short, there's a reason I'm not removing the old immersive system.
- The beacon has 5 different modes, depending on what level it is (0-4). Each one has variations on hitbox positions for the effect choice.
- The beacon can transition between the aforementioned levels effectively at random. The declarative immersive system really isn't built for this, meaning each hitbox would either need to be a hilariously long callback, abstracted out to another function, or each beacon level would have to be a separate immersive internally. None of these options seem ideal to me, as we don't want an immersive to be ridiculously long, it's declarative so everything can be in one place and easily readable, and going between different beacon levels would mean some way of moving data between different immersives, and would just generally feels hack-y. The separate immersive approach is likely what I would do if I decide to move the beacon to be a declarative immersive, though.
All others will be moved to the declarative system. The system should be the replacement for how Immersives are added internally, and the best way to make that happen is to port as many of the immmersives over as we can, adding features along the way.
For optimizations, instead of what's mentioned above, I'm thinking of adding optimization flags to the builders, where the immersive declares what optimizations can be applied to it (such as only changing based on the player direction changing).
I'm iffy on this one only because making the configuration manual like this seems prone to missing optimization opportunities or to introducing bugs by using an optimization when one shouldn't be used.
I did end up porting the Tinkers' Construct Crafting Station code up versions, though that was mainly because it adds a bunch more stuff to the declarative system. Should also make things work if Tinkers' Construct gets ported up versions, though (and doesn't change too much)!