-
Notifications
You must be signed in to change notification settings - Fork 0
Zones
RPGMood divides the world into zones. Whenever a player crosses into a new zone, they get a colored Title + Subtitle and a sound. As of v1.10.0, every zone is an organically-grown zone cluster — there is no more hand-curated zones.yml and no WORLDGUARD/BIOME zone type; wilderness is entirely cluster-driven (see Compatibility for the WorldGuard softdepend removal).
Cave biomes and certain vanilla structures layer a lighter-weight subzone Title on top of whichever zone cluster you're standing in — see Subzones below.
The first time a player reaches a chunk that isn't already part of a known cluster, RPGMood performs a bounded, synchronous flood-fill: starting from that chunk, it claims every already-loaded neighboring chunk (4-connected) that samples to the same biome group as the seed chunk, up to dynamic_zones.max_cluster_chunks chunks (default 576 — about 24×24 chunks, ~384×384 blocks). The flood-fill never forces new chunk generation — it only ever considers chunks that are already loaded, so a cluster's exact shape can vary slightly depending on how much terrain around the seed happens to be loaded at the moment it's created.
A newly-created cluster:
- Gets a permanent, unique 3-part name —
{adjective} {descriptor} {noun}(e.g. "Elden Misty Meadows"), picked deterministically from a per-biome pool seeded by the cluster's own id. If a biome's entire adjective × descriptor × noun space is somehow already exhausted elsewhere on the server, RPGMood falls back to a numeric suffix (Elden Misty Meadows 2) — a last resort that should essentially never happen given the size of the combinatorial pool. - Is persisted to
plugins/RPGMood/dynamiczones.ymlthe moment it's created (id, world, biome group, display name, center point, and its full list of member chunks) — unlike the old fixed-grid dynamic zones, cluster names now survive a server restart. - Never grows, shrinks, or merges once created. A chunk that loads in later and would otherwise qualify either already belongs to another cluster, or becomes the seed of a brand-new one of its own.
- Gets a biome-appropriate Subtitle, picked from a built-in pool per biome (not configurable via YAML — see
ZoneManager.javaif you want to add more), with the same combined-pool/rotation behavior dynamic zones always had.
Creating a brand-new cluster is throttled per-player via dynamic_zones.creation_throttle_ms (default 750ms) — this only gates creating a cluster for a never-before-seen chunk; resolving a chunk that's already part of a known cluster is never throttled, so fast travel (elytra) through already-explored territory is unaffected. If a player reaches a genuinely new chunk while still inside the throttle window, RPGMood just holds their last-confirmed zone for that tick rather than resolving nothing — no zone-change fires from that gap.
Each biome group has its own pools of adjectives, descriptors, and nouns. A cluster's name combines one of each, picked deterministically from a hash of the cluster's own id (so it's reproducible if ever recomputed) and then permanently reserved so no two clusters on the server end up with the same name. This is a 3-part combination — an evolution of the plugin's original 2-part (adjective + noun) dynamic-zone names, which is why older zone names look shorter than newly-generated ones.
A cluster's real biome (used for mob-scaling bonuses, /rpgmood zones's biome column, farming's soil fertility, etc.) is always its actual sampled biome group. The pool a name/Subtitle is borrowed from can differ for biomes with no dedicated pool of their own (e.g. Savanna, Cherry Grove, Wooded Badlands, or a datapack/mod biome RPGMood has never seen) — in that case RPGMood borrows the closest-themed existing pool by real temperature/humidity rather than always silently defaulting to Plains.
Entering a new zone cluster shows a Title (the cluster's name) + Subtitle (a biome-flavored line) and plays a fixed ambient wind sound (ambient.weather.wind_light) — that's it. As of v1.10.0, there are no more per-zone particles or per-zone custom music — both were configured per-entry in the now-removed zones.yml (a particles field and an optional music key) and have no equivalent in the cluster system. If you're upgrading from a pre-1.10 install and remember zone entry spawning a particle burst or playing a unique track per zone, that behavior is gone, not misconfigured.
A zone's title is colored by the mob scaling level at that spot (a Zombie's
equivalent level there), using the same 5-tier palette RPGLoot uses for item rarity — gray →
yellow → purple → green → gold as danger rises. Since every zone is now a cluster, this applies
uniformly everywhere — a zone's title text is whatever the name generator assigned it, but its
color always reflects the actual current danger, so retuning mob_scaling updates zone colors
everywhere without touching any zone data at all. The same 5 RGB colors are reused verbatim by
the Squaremap integration below and by the sidebar scoreboard.
Cave biomes and a handful of vanilla structures get their own Title/Subtitle inside whichever zone cluster you're standing in — a lighter-weight, side-effect-free sibling to the cluster system above. Standing in a Lush Caves/Dripstone Caves/Deep Dark pocket, or within subzones.structures.chunk_radius chunks (default 1, a 3×3 area) of a Village/Pillager Outpost/Desert Pyramid/Jungle Temple/Woodland Mansion/Ocean Monument/Nether Fortress/Stronghold, shows a two-line Title: the subzone name large, the current zone cluster's name smaller underneath as context.
Detected via Paper's Chunk#getStructures() (already-generated structure data the chunk already carries — no expensive radius search like MobScalingService's structure-bonus lookup) and real 3D biome reads for the cave biomes, plus a Y-level fallback (subzones.caves.deep_threshold_y, default 0) for plain stone underground with no special biome: "Shallow Caves" above that Y level, "Deep Caves" at or below it, once the player is at least subzones.caves.underground_surface_margin blocks (default 8) below the surface heightmap.
Purely a flavor layer: no XP, no achievement progress, and no /rpgmood zones entries come from subzones — zone discovery, the leaderboard, and achievement behavior are completely unchanged by them.
Reskin the title text per-subzone in plugins/RPGMood/subzones.yml — the entries keys themselves (LUSH_CAVES, VILLAGE, STRONGHOLD, etc.) are fixed identifiers RPGMood already knows how to detect; only the title values are meant to be edited. When multiple structure subzones are in range at once, a fixed priority order breaks the tie (rarer/more notable wins): Stronghold > Woodland Mansion > Ocean Monument > Nether Fortress > Pillager Outpost > Jungle Temple > Desert Pyramid > Village.
Subzones have their own lightweight throttling, independent of the full zone-cluster dwell/cooldown described below: a re-check every subzones.check_throttle_ms (default 500ms, filters border flicker across two consecutive confirmed reads instead of a scheduled dwell timer), and a subzones.title_suppress_minutes (default 3) "seen recently" memory per subzone before its Title can show again for that player.
If squaremap is installed, RPGMood registers a "RPGMood Zones" map layer and draws every zone cluster as a borderless, semi-transparent rectangle on the web map — filled with the same 5-tier danger color used for zone titles, with the cluster's display name shown on hover (squaremap's marker API has no always-visible floating label, only hover/click tooltips). No effect at all if squaremap isn't installed — the plugin-specific classes are only ever loaded when the squaremap plugin is actually present.
Since clusters are immutable once created, there's no periodic refresh task: markers are registered once at startup for every existing cluster, and once more, incrementally, each time a brand-new cluster is created. /rpgmood reload clears and re-adds every marker from current cluster data as a cheap self-healing step.
Configurable via square_map.layer_priority (default 3) and square_map.zone_fill_opacity (default 0.18) — see Configuration → square_map.
Three independent mechanisms keep zone feedback from becoming annoying, regardless of how you're moving (on foot, at a border, on horseback, in a boat/minecart, or flying with an elytra):
A zone change isn't confirmed the instant you cross a boundary — RPGMood waits 1.5 seconds (3 seconds while gliding or riding a vehicle) and re-checks whether you're still in that zone before firing any feedback. If you crossed back out before the wait is over (pacing on a border, clipping a biome corner while flying, blasting through on a fast horse), nothing fires at all. This is the main fix for border flicker and fast pass-throughs.
settings.zone_change_cooldown in config.yml (default 45 seconds) throttles how often a single player can trigger zone feedback at all, on top of the dwell time above.
Even after the dwell time and cooldown both pass, the big Title/Subtitle only shows if you haven't seen that same zone's title in the last 5 minutes — independent of the ambient cooldown above. The sound isn't affected by this and still plays normally. While gliding or riding a vehicle, the title (when shown) also uses a shorter fade-in/stay/fade-out so it doesn't linger over your view during fast, precision movement.
Players who find the on-screen titles specifically annoying (as opposed to the whole ambience system) can run /rpgmood toggle titles to disable just that part — sound keeps working. Subzone titles respect this same toggle. See Commands.
Every zone-change event that clears the cooldown also counts toward that player's /rpgmood leaderboard zones total — see Commands.
Optional, on by default, toggled per-player with /rpgmood toggle scoreboard (writes player_scoreboard.<uuid> in config.yml) — see Commands → /rpgmood toggle.
A small panel rebuilt on every confirmed zone change and every scaled-mob kill:
Zone: Elden Meadows
Danger: Lv 12
Kills: 4
-
Zone — your current zone's display name, same string
/rpgmood infoshows. - Danger — the Zombie-equivalent mob scaling level right where you're standing.
-
Kills — scaled-mob kills so far this session only. Not persisted — it resets to 0 on rejoin. Distinct from any of the permanent, persisted stats (
/rpgmood leaderboard,/rpgmood level) — this counter exists purely to give a running sense of "how much have I fought since I logged in."
Purely visual (no persisted state beyond the on/off preference) and independent of the Title/Subtitle system above — /rpgmood toggle titles doesn't affect it, and disabling /rpgmood toggle scoreboard doesn't affect titles/sound. Only the master /rpgmood toggle and this dedicated scoreboard toggle control it.
Removed in v1.9.0: the temporary danger-colored zone-change BossBar that shipped alongside this scoreboard in v1.8.0 is gone, replaced by the subzone Title choreography above. The sidebar scoreboard itself is unaffected and still shows zone/danger/kills exactly as before.
RPGMood remembers every zone you've ever triggered zone-entry feedback in — /rpgmood zones lists them, persisted per-player to plugins/RPGMood/zonediscovery.yml. Full command reference: Commands → /rpgmood zones.
A zone counts as discovered the moment it clears the same dwell time and cooldown as any other zone-change feedback — not from merely passing through before those settle. The first time you discover a given zone, you also earn a flat 15 XP toward your progression level (/rpgmood level, separate from mob difficulty levels).
Each entry records the zone's display name, first-seen date, and an optional favorite star (/rpgmood zones fav <name>, matched case-insensitively). The list also shows biome and current danger level, and the distance to your nearest other known zone.
Since v1.10.0, every zone is a zone cluster with a stored representative location (the seed chunk's center), so danger level and "distance to nearest known zone" are computable for every discovered zone — there's no longer a category of zone that can't provide this (the old caveat about hand-curated zones.yml zones having no single fixed point no longer applies, since that system doesn't exist anymore).