BetterPortals compatibility
Johni0702 opened this issue ยท 2 comments
(1.12.2)
When used with BetterPortals, the weather particles are only visible in the main world (see Johni0702/BetterPortals#36).
From looking over the code (there may be more, I've only skimmed it), there seem to be at least two issues which would need resolving for the particles to properly render on both sides of the portal:
All the static state here seems to only be updated on world ticks, not before every frame. If there's nothing too expensive in them, then updating them before every frame will probably solve the issue. If that is too expensive (or if you prefer), please consider keeping one of those per world (e.g. WeakHashMap), instead of only one overall.
As I understand it, having only one of these would imply the same weather in all dimensions. If so, please consider keeping one of these per world as well.
EnvironStateHandler caches state for the current player about the world he is in. I only do it once per client tick because doing before every frame could get expensive.
The weather tracker for either pure client side weather generation (the simulation tracker), or having it driven from the server side (the server side tracker). This guy is responsible for handling rain intensity, lightning, etc. (Most installs are for simulated because my mod is rarely installed on the server.)
How do you go about rendering the other world when looking through the portal? Where is that data sources from client side?
BP spawns fake players on the server and tunnels their packets to the client. There it swaps out ordinarily unique state (e.g. mc.player
, mc.world
, etc.) as needed during packet handing, world ticking and rendering.
For rendering it hooks into the call to EntityRenderer.renderWorld
, computes which worlds need to be rendered from which perspective and then renders them with sequential calls to EntityRenderer.renderWorld
.
This also means that all the usual world-related rendering events are fired for all the visible worlds (and potentially multiple times per frame).
Ticking all client worlds without depending on BP's API is a bit trickier because mods rely on the ClientTickEvent
to be fired exactly once per tick (so only with the primary world active).
Forge doesn't fire the WorldTickEvent
on the client at all, so BP can't either.
One could use a WeakHashMap
(adding worlds via WorldEvent.Load
) but then one needs to be very careful to not accidentally leak memory and one can end up ticking worlds which are no longer used and just haven't been GCed yet.
Really the only way of doing this is getting called from (Client)World.tick
in some other way, i.e. ASM which I'd argue might even be the most idiomatic way of doing stuff per-worldtick (at least until WorldTickEvent
works, which isn't happening).
If you'd rather use BP's API (wouldn't recommend, especially since you've already got ASM going anyway): ClientWorldsManagerKt.getWorldsManager(mc).getWorlds()
, though beware that mc.world
and all other global state will ofc still be the primary one.