From b9b350ef3a1966d5ae3577dc261b2de9d44150d0 Mon Sep 17 00:00:00 2001 From: Player Name Date: Sun, 28 Jun 2026 00:14:12 +0200 Subject: [PATCH] Revert "Simpler renderer but same issue" This reverts commit 78f287e5ca27ec4a8d17cf6fd50869d6f6348ce3. --- .../core/game/node/entity/player/Player.java | 3 +- .../game/world/update/MapChunkRenderer.kt | 83 +++++++++++++------ .../game/world/update/flag/PlayerFlags.java | 13 +-- 3 files changed, 61 insertions(+), 38 deletions(-) diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index 2303a150b..cb94a83bd 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -93,7 +93,6 @@ import static core.api.utils.PermadeathKt.permadeath; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_DEATHS; import static core.tools.GlobalsKt.colorize; -import static java.util.Collections.emptySet; import static org.rs09.consts.Items.BONES_526; /** @@ -857,7 +856,7 @@ public class Player extends Entity { getZoneMonitor().getZones().clear(); playerFlags.setLastSceneGraph(null); playerFlags.setUpdateSceneGraph(false); - playerFlags.setLastViewport(emptySet()); + playerFlags.setLastViewport(new RegionChunk[13][13]); renderInfo.getLocalNpcs().clear(); renderInfo.getLocalPlayers().clear(); renderInfo.setLastLocation(null); diff --git a/Server/src/main/core/game/world/update/MapChunkRenderer.kt b/Server/src/main/core/game/world/update/MapChunkRenderer.kt index 9b9f66a74..d87a7b295 100644 --- a/Server/src/main/core/game/world/update/MapChunkRenderer.kt +++ b/Server/src/main/core/game/world/update/MapChunkRenderer.kt @@ -23,37 +23,66 @@ object MapChunkRenderer { */ @JvmStatic fun render(player: Player) { - val lastSet = player.playerFlags.lastViewport - val currentSet = HashSet() - for (dcx in -buildAreaDepth..buildAreaDepth) { - for (dcy in -buildAreaDepth..buildAreaDepth) { - val loc = player.location.transform(dcx * 8, dcy * 8, 0) - currentSet.add(loc.chunk) + val last = player.playerFlags.lastViewport + val updated: MutableList = ArrayList() + val current: MutableList> = ArrayList() + + for (dcx in -buildAreaDepth..+buildAreaDepth) { + val addX = ArrayList() + for (dcy in -buildAreaDepth..+buildAreaDepth) { + val newloc = player.location.transform(dcx*8, dcy*8, 0) + addX.add(newloc.chunk) + } + current.add(addX) + } + + var sizeX = last.size + for (x in 0 until sizeX) { + val sizeY: Int = last[x].size + for (y in 0 until sizeY) { + val previous = last[x][y] ?: continue + if (containsChunk(current, previous)) { + updated.add(previous) + continue + } + if (previous.region is DynamicRegion) { + continue //dynamic regions do not need a clear packet and briefly flash their cached states (e.g. POH with only hotspots) if you do send one + } + PacketRepository.send(ClearRegionChunk::class.java, ClearChunkContext(player, previous)) } } - - // Compute diffs - val entered = currentSet - lastSet - val stayed = currentSet intersect lastSet - val exited = lastSet - currentSet - - // 1. New chunks → synchronize - for (c in entered) { - c.synchronize(player) - } - - // 2. Existing chunks → update - for (c in stayed) { - c.update(player) - } - - // 3. Exited chunks → clear - for (c in exited) { - if (c.region !is DynamicRegion) { - PacketRepository.send(ClearRegionChunk::class.java, ClearChunkContext(player, c)) + sizeX = current.size + for (x in 0 until sizeX) { + val sizeY: Int = current[x].size + for (y in 0 until sizeY) { + val chunk = current[x][y] + if (updated.contains(chunk)) { + chunk.update(player) + } else { + println("Syncing ${chunk.currentBase}") + chunk.synchronize(player) + } + last[x][y] = chunk } } + } - player.playerFlags.lastViewport = currentSet + /** + * Checks if the chunks list contains the specified region chunk. + * @param list The list to search. + * @param c The region chunk. + * @return `True` if so. + */ + private fun containsChunk(list: MutableList>, c: RegionChunk): Boolean { + val sizeList = list.size + for (x in 0 until sizeList) { + val chunkSize: Int = list[x].size + for (y in 0 until chunkSize) { + if (list[x][y] === c) { + return true + } + } + } + return false } } \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/PlayerFlags.java b/Server/src/main/core/game/world/update/flag/PlayerFlags.java index 86feac373..41d0cb441 100644 --- a/Server/src/main/core/game/world/update/flag/PlayerFlags.java +++ b/Server/src/main/core/game/world/update/flag/PlayerFlags.java @@ -1,13 +1,7 @@ package core.game.world.update.flag; import core.game.world.map.Location; -import core.game.world.map.Region; import core.game.world.map.RegionChunk; -import core.game.world.update.MapChunkRenderer; - -import java.util.Set; - -import static java.util.Collections.emptySet; /** * A class holding a player's updating flags. @@ -23,7 +17,7 @@ public final class PlayerFlags { /** * The last viewport. */ - private Set lastViewport = emptySet(); + private RegionChunk[][] lastViewport = new RegionChunk[13][13]; /** * The location the player was standing on when last scene graph update @@ -76,7 +70,7 @@ public final class PlayerFlags { * Gets the lastViewport. * @return The lastViewport. */ - public Set getLastViewport() { + public RegionChunk[][] getLastViewport() { return lastViewport; } @@ -84,7 +78,8 @@ public final class PlayerFlags { * Sets the lastViewport. * @param lastViewport The lastViewport to set. */ - public void setLastViewport(Set lastViewport) { + public void setLastViewport(RegionChunk[][] lastViewport) { this.lastViewport = lastViewport; } + } \ No newline at end of file