Dynamic Surroundings

Dynamic Surroundings

51M Downloads

BetterPortals compatibility

Johni0702 opened this issue ยท 2 comments

commented

(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:

// State that is gathered from the various sources
// to avoid requery. Used during the tick.
private static BiomeInfo playerBiome = null;
private static BiomeInfo truePlayerBiome = null;
private static int dimensionId;
private static String dimensionName;
private static DimensionData dimInfo = DimensionData.NONE;
private static BlockPos playerPosition;
private static TemperatureRating playerTemperature;
private static TemperatureRating biomeTemperature;
private static boolean inside;
private static ItemStack armorStack;
private static ItemStack footArmorStack;
private static boolean inVillage;
private static boolean isUnderground;
private static boolean isInSpace;
private static boolean isInClouds;
private static int lightLevel;
private static int tickCounter;
private static DayCycle dayCycle;
private static MinecraftClock clock = new MinecraftClock();
private static BattleScanner battle = new BattleScanner();

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.

private static Tracker tracker = new SimulationTracker();

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.

commented

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?

commented

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.