I wanted a way for players on my Paper server to know when they were going beyond where people have previously explored. To do this, I wrote the New Chunks Alert plugin, which uses events and O(1) operations to notify players when they've loaded a brand new chunk. The plugin features a customizable cooldown, built-in memory managment, and a performance-minded design.
You can download the
.jar from the plugin's
CurseForge page
to add it to your server. Find the source code on the
GitHub repository.
p.s. don't @ me ik there's spaces in the title of this one unlike my other plugins it's not an inconsistency: i am testing if it helps for search indexing.
For players on a server with New Chunk Alerts installed: run
/newchunkalerts or /nca to toggle the
alerts.
For server administrators: the plugin has no dependencies beyond Paper
and can be used after dropping the .jar into the
plugins directory. The first time the server is started
with New Chunk Alerts installed, a configuration file will be
generated at plugins/NewChunkAlerts/config.yml. This
config file will keep track of the list of players that have disabled
alerts, as well as a few configuration options relating to the
behavior of the plugin. Find out more about the config options below.
Initially, I couldn't figure out whether to use Bukkit's
ChunkLoadEvent or the Paper API's
PlayerChunkLoadEvent.
If I were to use only the
ChunkLoadEvent, retrieving the players surrounding the
chunk in order to notify them would be an expensive task. The
getPlayersViewingChunk() method would be a nice way to
cheaply and quickly notify players, but it is not a reliable enough
indicator of nearby players since it will always return an empty list
at generation time, and it's dependent on each client's set render
distance. I think. Ergo, we'd have to check the location of every
player in the world. Not ideal.
However, I also couldn't use exclusively the
PlayerChunkLoadEvent because it offers no useful
information about the recency of the chunk's generation (getInhabitedTime()
doesn't tell us anything about the chunk's generation).
I needed a combination of both events, with some way to keep track of
chunks that have triggered the ChunkLoadEvent for the
first time and have not yet triggered the
PlayerChunkLoadEvent and notified a player.
I used a Deque that maintains the order in which chunks
are generated, backed by a HashMap that maintains a
mapping from each chunk to its generation time. This allows us to
maintain the order of chunks while also achieving O(1) lookup and
insertion times. Even the cleanup functionality is a summation of O(1)
operations, so it's bound by the number of expired chunks it must
remove.
Keeping the plugin low-profile and maintaining a small memory footprint was a top priority.
The default values of these variables should work for the majority of servers, but feel free to tweak them as you see fit.
- chunk-queue-cleanup-cooldown-ms (default equivalent to
15s): The number of milliseconds the plugin waits before repeating
cleanup of the chunk queue. Decreasing this will simply make the
plugin check for expired chunks more often.
- chunk-queue-entry-expiration-time-ms (default
equivalent to 3m): The number of milliseconds to retain a chunk in the
queue after it is generated. Making this number too small will cause
the plugin to "forget" new chunks before the player has time to
trigger a PlayerChunkLoadEvent and be alerted. The
default for this configuration option should be just fine for most
servers. However, if the plugin doesn't seem to be working and players
move very slowly on the server or have very low render distances,
increasing this number and restarting the server may fix it.
- max-queued-chunks (default = 100,000): The maximum
number of chunks to allow in the queue. Once the queue exceeds this
size, the oldest chunks in the queue are removed until the size of the
queue is once again under this value. Try increasing this number if
your server is extremely large and players are not correctly receiving
alerts.
- notification-cooldown-ms (default equivalent to 1m):
The minimum number of milliseconds the plugin must wait before sending
another notification to the same player.
If you find a bug or have a feature request, please submit an issue on the issue tracker. If you'd like to contribute to the project, please fork the repository and submit a pull request.