Skip to content

Feature: Optimize handleMove #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: v3
Choose a base branch
from

Conversation

adabugra
Copy link

This PR optimizes the handleMove method in the BukkitActionController class by introducing chunk caching and movement tick skipping. These enhancements reduce unnecessary calculations and improves performance.

Tests (~550 online/real players):

Before:
image

After:
image

@Cryptite
Copy link
Contributor

Excellent, I too was about to start looking into it as well, as it was often the laggiest method running for me too.

// Add the chunk to the cache
loadedChunks
.computeIfAbsent(world, w -> new HashSet<>())
.add(chunkKey(chunk.getX(), chunk.getZ()));
Copy link
Contributor

@Cryptite Cryptite Feb 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would advise just using Chunk.getChunkKey() and storing the long this provides instead of a String. It is much more efficient than constructing a string on every single chunk load, unload, and player movement.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think getChunkKey is an api that is available since 1.8, let alone in spigot/bukkit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's available in the paper-api since I think about 1.12, but all the same, here's the method:

static long getChunkKey(int x, int z) {
    return (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
} 

for (Npc<World, Player, ItemStack, Plugin> npc : this.npcTracker.trackedNpcs()) {
// check if the player is still in the same world as the npc
Position pos = npc.position();
if (!npc.world().equals(player.getWorld()) || !npc.world().isChunkLoaded(pos.chunkX(), pos.chunkZ())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all honestly, I think a better call here would be for NPCs to store state as to whether they are in a loaded chunk or not, rather than rely on every single small player movement to check if they are in a loaded chunk.

@Cryptite
Copy link
Contributor

Cryptite commented Apr 4, 2025

Any updates on this one?

@derklaro
Copy link
Collaborator

@adabugra are you still working on this? else I (or someone else) could maybe take this over

@adabugra
Copy link
Author

adabugra commented Jun 16, 2025

@adabugra are you still working on this? else I (or someone else) could maybe take this over

I will look into this when I have time. What changes are needed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants