© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
AdmincraftA
Admincraft•12mo ago•
47 replies
Biquaternions

Performance tips for plugins?

Hi, I made a plugin that drops heads as one of its features, but apparently the part of "adding the skin to the head" has terrible performance for something surprisingly simple.
It's just get the item meta, set the skull owner and put it back. (and put it into the drops list)

I made the report on the fly on my local pc (windows), so it's very likely that it affected the results.

I made this code as an alternative, and while it gets good performance, it kinda looks horrible creating an async task and a sync one inside for each player death.
Not sure if someone has a better tip for this, or if I it will be negligeable once on linux (I won't be able to test this on linux for a couple of days).

    private fun handleHeadDrops(event: PlayerDeathEvent) {
        if (Random.nextDouble() > RootConfig.HEAD.CHANCE) return
        val location = event.player.location
        val world = event.player.world
        Bukkit.getScheduler().runTaskAsynchronously(this.plugin) { _ ->
            val head = ItemStack(Material.PLAYER_HEAD)
            val meta = (head.itemMeta as SkullMeta).apply { owningPlayer = event.player }
            head.itemMeta = meta

            Bukkit.getScheduler().runTask(this.plugin) { _ ->
                val item = world.dropItem(location, head)
            }
        }
    }
    private fun handleHeadDrops(event: PlayerDeathEvent) {
        if (Random.nextDouble() > RootConfig.HEAD.CHANCE) return
        val location = event.player.location
        val world = event.player.world
        Bukkit.getScheduler().runTaskAsynchronously(this.plugin) { _ ->
            val head = ItemStack(Material.PLAYER_HEAD)
            val meta = (head.itemMeta as SkullMeta).apply { owningPlayer = event.player }
            head.itemMeta = meta

            Bukkit.getScheduler().runTask(this.plugin) { _ ->
                val item = world.dropItem(location, head)
            }
        }
    }


This probably will sound silly, but I also don't know how the bukkit scheduler works internally, so idk if it's literally a scheduler, with a separate single thread to run scheduled tasks, or if it creates a different new thread everytime something is scheduled.

Report before: https://spark.lucko.me/wbbIOR4xc0
Report after adding the code above: https://spark.lucko.me/W9JAoVXoR9
spark
spark is a performance profiler for Minecraft clients, servers, and proxies.
spark
spark
spark is a performance profiler for Minecraft clients, servers, and proxies.
spark
Solution
I really like to use coroutines, like this
private fun handleHeadDrops_old(event: PlayerDeathEvent) {
    CoroutineScope(ioDispatcher).launch {
        val head = ItemStack(Material.PLAYER_HEAD)
        val meta = (head.itemMeta as SkullMeta).apply { owningPlayer = event.player }
        head.itemMeta = meta
        withContext(bukkitDispatcher) {
            event.drops.add(head)
        }
    }
}
private fun handleHeadDrops_old(event: PlayerDeathEvent) {
    CoroutineScope(ioDispatcher).launch {
        val head = ItemStack(Material.PLAYER_HEAD)
        val meta = (head.itemMeta as SkullMeta).apply { owningPlayer = event.player }
        head.itemMeta = meta
        withContext(bukkitDispatcher) {
            event.drops.add(head)
        }
    }
}
Jump to solution
AdmincraftJoin
10,704Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

Which Fabric mods and plugins to use for performance
AdmincraftAAdmincraft / questions
2y ago
Tips to performance test a paper fork
AdmincraftAAdmincraft / questions
11mo ago
Do "Raw Statistics Track" plugins cause performance problems?
AdmincraftAAdmincraft / questions
3y ago
Looking for Paper plugins for Builders
AdmincraftAAdmincraft / questions
3y ago