Class ChunkTracker

java.lang.Object
com.hypixel.hytale.server.core.modules.entity.player.ChunkTracker
All Implemented Interfaces:
Component<EntityStore>, Cloneable

public class ChunkTracker extends Object implements Component<EntityStore>
The chunk tracker, tracks the chunks players have loaded and sends chunks that are in view distance and unloads loaded chunks that are now out of view distance.

Chunk sending is rate limited to prevent sending unnecessary chunks when the player is moving.

  • Field Details

    • METRICS_REGISTRY

      @Nonnull public static final MetricsRegistry<ChunkTracker> METRICS_REGISTRY
      The metrics registry for the chunk tracker.
    • MAX_SECTIONS_PER_SECOND_LOCAL

      public static final int MAX_SECTIONS_PER_SECOND_LOCAL
      See Also:
    • MAX_SECTIONS_PER_SECOND_LAN

      public static final int MAX_SECTIONS_PER_SECOND_LAN
      See Also:
    • MAX_SECTIONS_PER_SECOND

      public static final int MAX_SECTIONS_PER_SECOND
      See Also:
    • MAX_SECTIONS_PER_TICK

      public static final int MAX_SECTIONS_PER_TICK
      See Also:
    • MAX_UNLOAD_SECTION_INTS

      public static final int MAX_UNLOAD_SECTION_INTS
      Maximum ints per batched UnloadChunks packet. A large move (or teleport) can unload far more than one packet should carry, so flushUnloads(PlayerRef) slices the scratch buffers into packets of at most these many ints. Must match the MaxLength on the packet's Sections / Columns fields and stay a multiple of the entry stride (3 for sections, 2 for columns).
      See Also:
    • MAX_UNLOAD_COLUMN_INTS

      public static final int MAX_UNLOAD_COLUMN_INTS
      See Also:
    • MAX_ABSENT_Y_INTS

      public static final int MAX_ABSENT_Y_INTS
      Maximum Ys per batched SetAbsentChunks packet. Must match the MaxLength on SetAbsentChunks.Ys; flushPendingAbsent(PlayerRef) slices a column's pending list into packets of at most this many so a tall cubic column can't produce an over-long packet.
      See Also:
    • MIN_LOADED_RADIUS

      public static final int MIN_LOADED_RADIUS
      The minimum loaded chunks radius.
      See Also:
    • MAX_HOT_LOADED_RADIUS

      public static final int MAX_HOT_LOADED_RADIUS
      The maximum hot loaded chunks radius.
      See Also:
    • MAX_FAILURE_BACKOFF_NANOS

      public static final long MAX_FAILURE_BACKOFF_NANOS
      The maximum failure backoff time in nanoseconds.
  • Constructor Details

    • ChunkTracker

      public ChunkTracker()
      Empty Constructor for a ChunkTracker instance. Reads the max view offsets from the live server config.
    • ChunkTracker

      public ChunkTracker(@Nonnull Supplier<SphereOffsets> sphereOffsetsSupplier)
      Constructor accepting the max view SphereOffsets supplier, so callers (notably tests) can build a ChunkTracker without depending on the server singleton.
      Parameters:
      sphereOffsetsSupplier - supplies the current maximum view offsets for the spiral iterator.
  • Method Details

    • getComponentType

      public static ComponentType<EntityStore, ChunkTracker> getComponentType()
      Returns:
      the component type for the ChunkTracker component.
    • clear

      public void clear()
      Called to clear all loaded and loading chunks without sending unload packets.
    • tick

      public void tick(@Nonnull Player playerComponent, @Nonnull PlayerRef playerRefComponent, @Nonnull TransformComponent transformComponent, float dt, @Nonnull CommandBuffer<EntityStore> commandBuffer)
      Called to tick the chunk tracker component for the given player entity.
      Parameters:
      dt - The delta time since the last tick.
      commandBuffer - The CommandBuffer<EntityStore> for component access.
    • isLoaded

      public boolean isLoaded(long indexChunk)
      Determines whether the given chunk is loaded.
      Parameters:
      indexChunk - The index of the chunk to check
      Returns:
      true if the chunk is loaded, false otherwise
    • isLoaded

      public boolean isLoaded(int x, int y, int z)
    • removeForReload

      @Deprecated(forRemoval=true) public void removeForReload(long chunkIndex)
      Deprecated, for removal: This API element is subject to removal in a future version.
    • removeForReload

      public void removeForReload(int x, int y, int z)
    • shouldBeVisible

      public boolean shouldBeVisible(long chunkCoordinates)
      Determines whether the given chunk coordinates should be visible.
      Parameters:
      chunkCoordinates - The chunk coordinates to check.
      Returns:
      true if the chunk should be visible, false otherwise.
    • shouldBeVisible

      public boolean shouldBeVisible(int x, int y, int z)
      Determines whether the given section coordinates should be visible from the player's current position, using the same sphere predicate that drives section load/unload.
      Parameters:
      x - The section X coordinate to check.
      y - The section Y coordinate to check.
      z - The section Z coordinate to check.
      Returns:
      true if the section is inside the player's sphere, false otherwise.
    • getChunkVisibility

      @Nonnull public ChunkTracker.ChunkVisibility getChunkVisibility(long indexChunk)
      Fetches the visibility state of a chunk column using a flat 2D disc test around the player. This is the column-level (legacy) view of visibility and does not match the sphere predicate that drives section load/unload. For per-section visibility use getSectionVisibility(int, int, int) instead.
      Parameters:
      indexChunk - The index of the chunk to check.
      Returns:
      the ChunkTracker.ChunkVisibility state of the chunk.
    • getSectionVisibility

      @Nonnull public ChunkTracker.ChunkVisibility getSectionVisibility(int x, int y, int z)
      Fetches the visibility state of a chunk section. The 3D analog of getChunkVisibility(long). Uses the sphere predicate that drives section load/unload for the COLD test and a Euclidean sphere of radius maxHotLoadedRadius for the HOT test.
      Parameters:
      x - The section X coordinate.
      y - The section Y coordinate.
      z - The section Z coordinate.
      Returns:
      the ChunkTracker.ChunkVisibility state of the section.
    • getMaxSectionsPerSecond

      public int getMaxSectionsPerSecond()
      Returns:
      the maximum sections per second allowed to be sent to the player.
    • setMaxSectionsPerSecond

      public void setMaxSectionsPerSecond(int maxSectionsPerSecond)
      Called to set the maximum sections per second allowed to be sent to the player.
      Parameters:
      maxSectionsPerSecond - The maximum sections per second.
    • setDefaultMaxSectionsPerSecond

      public void setDefaultMaxSectionsPerSecond(@Nonnull PlayerRef playerRef)
      Called to set the default maximum sections per second based on the player connection type.
      Parameters:
      playerRef - The PlayerRef component of the player.
    • getMaxSectionsPerTick

      public int getMaxSectionsPerTick()
      Returns:
      the maximum sections per tick allowed to be sent to the player.
    • setMaxSectionsPerTick

      public void setMaxSectionsPerTick(int maxSectionsPerTick)
      Called to set the maximum sections per tick allowed to be sent to the player.
      Parameters:
      maxSectionsPerTick - the maximum sections per tick allowed to be sent to the player.
    • getMinLoadedRadius

      public int getMinLoadedRadius()
      Returns:
      the minimum loaded chunks radius.
    • setMinLoadedRadius

      public void setMinLoadedRadius(int minLoadedRadius)
      Called to set the minimum loaded chunks radius.
      Parameters:
      minLoadedRadius - the minimum loaded chunks radius.
    • getMaxHotLoadedRadius

      public int getMaxHotLoadedRadius()
      Returns:
      the maximum hot loaded chunks radius.
    • setMaxHotLoadedRadius

      public void setMaxHotLoadedRadius(int maxHotLoadedRadius)
      Called to set the maximum hot loaded chunks radius.
      Parameters:
      maxHotLoadedRadius - the maximum hot loaded chunks radius.
    • getLoadedSectionsCount

      public int getLoadedSectionsCount()
      Returns the number of sections loaded by the player that owns this tracker.
      Returns:
      The number of sections loaded by the player
    • forEachLoadedSection

      public void forEachLoadedSection(@Nonnull TriIntConsumer consumer)
      Visits each section the client has received from this tracker, calling consumer.accept(x, y, z) once per section under the tracker's read lock.

      The consumer must not mutate the tracker (directly or via a method that takes the write lock). The lock is not reentrant.

      Parameters:
      consumer - Called once per loaded section.
    • getLoadingSectionsCount

      public int getLoadingSectionsCount()
      Returns the number of sections being loaded by the player that owns this tracker.
      Returns:
      The number of sections being loaded by the player
    • getLoadedChunksDebug

      @Nonnull public String getLoadedChunksDebug()
      Formats a debug string containing tracker state and two top-down grids: loaded section counts per column and hot section counts per column. Each cell holds a 2-digit number plus a trailing space; untracked columns render as " . ". The grids are centred on the player's column.
      Returns:
      a debug string suitable for the server dump.
    • setReadyForChunks

      public void setReadyForChunks(boolean readyForChunks)
      Called to set whether the chunk tracker is ready to send chunks.
      Parameters:
      readyForChunks - whether the chunk tracker is ready to send chunks.
    • isReadyForChunks

      public boolean isReadyForChunks()
      Returns:
      true if the chunk tracker is ready to send chunks, false otherwise.
    • copyFrom

      public void copyFrom(@Nonnull ChunkTracker chunkTracker)
      Called to copy the state from another ChunkTracker instance.

      Only ChunkTracker.ColumnState.READY columns and their loaded section sets are carried over. Those represent state the client already has. In-flight columns/sections are dropped because the source tracker still owns their async load chains; the spiral re-walk triggered by resetting sentViewRadiusSq will re-issue any loads we need.

      Parameters:
      chunkTracker - The other ChunkTracker instance to copy from.
    • tryLoadColumnAsync

      public void tryLoadColumnAsync(@Nonnull ChunkStore chunkStore, @Nonnull PlayerRef playerRefComponent, long chunkIndex, @Nonnull TransformComponent transformComponent, @Nonnull ComponentAccessor<EntityStore> componentAccessor)
      Called to try and load a chunk asynchronously for the given player.
      Parameters:
      chunkStore - The chunk store.
      playerRefComponent - The PlayerRef component of the player.
      chunkIndex - The index of the chunk to load.
      transformComponent - The TransformComponent of the player.
      componentAccessor - The ComponentAccessor<EntityStore> for component access.
    • tryLoadSectionAsync

      public void tryLoadSectionAsync(@Nonnull ChunkStore chunkStore, @Nonnull PlayerRef playerRefComponent, int x, int y, int z, @Nonnull TransformComponent transformComponent, @Nonnull ComponentAccessor<EntityStore> componentAccessor)
      Called to try and load a section asynchronously for the given player. Mirrors tryLoadColumnAsync(ChunkStore, PlayerRef, long, TransformComponent, ComponentAccessor) but for a single section identified by its (x, y, z) chunk-section coordinates.

      Caller is expected to have placed y in the parent ChunkTracker.TrackedColumn.loadingSections set before invoking; this method takes responsibility for the transition from that set once the load completes (success: move to loadedSections; failure / null ref: drop so it can be retried next tick).

      Parameters:
      chunkStore - The chunk store.
      playerRefComponent - The PlayerRef component of the player.
      x - The section's x position.
      y - The section's y position.
      z - The section's z position.
      transformComponent - The TransformComponent of the player.
      componentAccessor - The ComponentAccessor<EntityStore> for component access.
    • clone

      @Nonnull public Component<EntityStore> clone()
      Specified by:
      clone in interface Component<EntityStore>
      Returns:
      a clone instance of the original component instance.

    • calculateSectionPriority

      public float calculateSectionPriority(int x, int y, int z)
    • calculateColumnPriority

      public float calculateColumnPriority(int x, int z)