3.3.1
[3.3.1] - 2026-10-26
Added
Tune background cache refill automatically from server headroom and player demand (
autoTune, ADR-087, ADR-123, ADR-124).advanced/performance.ymlshipsautoTune: true. While players teleport and the server has spare tick time, CPU and memory, regions refill on every tick withinasyncAllottedTime,syncAllottedTimeandactiveChunkCapinstead of waiting forperiod. When tick time, CPU, chunk-load latency or tenured heap usage rises, or when caches are already full, background refill scales down beforeminTPS,maxMSPTormaxHeapPercenttrips, while players waiting for a teleport keep the full configured budgets; constrained refill is shared across regions by distinct active players (ADR-124), and on Folia tick-region shares are probed per cell group and background work prefers tick regions with headroom and fewer players up to a 60 s or 8-deferral aging bound (ADR-123)./rtp infoshows effective budgets, per-region refill shares and top consumers, and/rtp testincludes thecompute-governorcheck for reduced or floor-held budgets and stale metrics; settingautoTune: falseuses the fixed values and refills once perperiod.Action and Claim addons report setup health through BIT (ADR-121).
/rtp test action-setupidentifies rejected definitions, command or trigger registration failures, missing batch scheduling and name collisions. On Bukkit-family servers,/rtp test claim-integrationsreports disabled, absent, late-enabled and incompatible claim integrations. Each addon publishes a separate code catalog and stable identity lock; first-boot severity overrides for addon codes take effect after addon registration.Refuse steep landing spots (ADR-119).
linearandjumpverts accept two new optional keys.maxSlopeis the largest floor-height step, in blocks, allowed between the landing spot and the groundslopeRadiusblocks away (default2, range1-8) to the north, south, east and west. Spots on cliff edges or steep hillsides are skipped and the search moves on to the next spot. The check follows the floor the player would stand on, so it also works in caves and the Nether. Regions withoutmaxSlopebehave as before and keep their saved region data. Setting or changing either key rebuilds that region's saved data once. Steep worlds with a lowmaxSlopereject more chunks. Not available onfixed, which places players in mid-air.Keep players off mountainsides and cliff edges (ADR-120).
linearandjumpverts acceptmaxHillAngle, the steepest hill in degrees a player may land on.config.ymlships it as"off"underdefaults.vert, and the config menu offers"off",30,45and60; any number from 0 to 89 also works. On a 26.3 test world,30refused about 1 in 5 land spots,45about 1 in 12 and60about 1 in 60. RTP checks the ground 16 blocks away in 8 directions and within 8 blocks of the spot, inside the 3x3 chunks around it, using blocks only, so it works the same with custom generators such as Iris and Terra and on every platform. The check itself loads no chunks: it reads region files during the background search, then rechecks the chunks the server already holds around the spot. Only spots that pass the other checks look at their surroundings, and only at the chunks needed to decide. With the check on, the background search does about 3 times the work per spot and tries more spots, because refused spots are picked again; spots rejected after the server has read their chunk add chunk loads."off",-1and a missing key behave as before and keep the region's saved data.Action definitions report findings and support strict registration (ADR-121). Each finding logs its stable code, source file and YAML path, allowed values, and a suggestion when available.
advanced/bit.ymlshipsstrictActions: false, which logs structural action codes as warnings and keeps loading compatible; setting it totrueprevents registration of an action with any effectiveERROR, while other actions continue to load, and per-code overrides take precedence. UnknownACTION:names are omitted, unknown trigger types are skipped instead of falling back toSTEP_IN, and a missing trigger type still defaults toSTEP_IN; the checks use the standalonebit-apimodule./rtp testreports registered BIT probe results (ADR-121). The SAFEallgroup includesapi-compat,commands,scheduler,events,economy-isolation,disconnect-job,networkandsafety-verifier, and can be filtered withtier=orsubsystem=./rtp test statusshows registered state without rerunning checks, andjson=trueselects machine-readable output. Chat starts with a component-count summary, then lists only distinctFAIL,WARNandINFOfindings; repeated codes are counted, whilePASSandSKIPcomponents appear only in the summary. The server log keeps the full table with paths and messages.allis distinct from the Bukkit-onlyfullsweep; existing probe summaries remain unchanged for automation./rtp test teleportchecks the teleport pipeline without a real player (ADR-121)./rtp test teleport [region=<name>] [count=1-16] [json=true](permissionrtp.test.mutating) sends temporaryrtp-bit-*test players through real location selection, including real chunk loading, and reports whether the teleport was reached, any left-over teleport state, and timeouts. Test players get no cooldowns, teleport history, usage-limit counts, economy charges, landing-heatmap entries or plugin events, and never appear in online-player lists. Every report says that the final teleport was simulated. The check runs only when named, never as part ofallortier=ibit.Generate a mock teleport landing heatmap (
/rtp test teleport-heatmap, ADR-121). Operators withrtp.test.mutatingcan sample a region with bounded mock teleports and export the landing coordinates and distribution as CSV and PNG files. The probe runs only when named and does not alter the existing landing heatmap.Teleport probes report mock and player results through
/rtp test(ADR-121). Stress, queue-starvation, disconnect-midflight, Folia ownership and the pipeline half of async-reply now run as registered BIT components using mock players or UUIDs. Stress and async-reply retain separateplayer=<name>components for live platform behavior; hologram remains player-only. Component findings are included in the BIT report, and every timeout recordsBIT_COMPONENT_TIMEOUTwhile existing[RTP test/<probe>]output remains unchanged.RTP reports startup check health (ADR-121). After startup, RTP runs SAFE action-definition and region-file self-tests off-thread and logs one health summary. A missing optional host Zstandard runtime is informational and leaves the component healthy because RTP can use its safe live-load fallback; a present engine that fails its canary remains degraded.
Action runtime health is visible in BIT status (ADR-121).
/rtp test statusreports missing scoreboard objectives, gates that always or never pass, unresolved placeholders, unknownACTION:commands, and sessions that remain active beyond their reaper window.advanced/bit.ymladdsgateOutcomeSamples, which defaults to200evaluations.A bad config no longer breaks a running server on
/rtp reload(ADR-121).- What is checked. On startup, by
/rtp test subsystem=config, and before every/rtp reload, editor Hot-Apply,/rtp configedit,/rtp config importor/rtp admin setup confirm, RTP checks every config file. It reports:- YAML that does not parse;
- values outside the type, allowed values or range in the shipped comments;
@config/@economy/@safetyreferences that do not resolve;- regions, worlds, schematics and effect groups that point at something missing;
- impossible settings such as a
radiusthat is not larger thancenterRadiusor ashrinkTolarger thaninitialSize; - message files with missing keys.
- How findings are reported. Each finding names its file and key and suggests the closest valid value. The checks read files only and never load chunks.
- What is rejected. If a reload, Hot-Apply, config command, import or setup confirm finds an error, nothing is applied and the server keeps its current configuration. The sender is told which file and key to fix (new
reloadRejectedandeditorApplyRejectedmessages, translated in every bundled language). - New setting:
strictConfig. Problems that earlier releases accepted are logged as warnings for now, so a reload is not rejected. SetstrictConfig: trueinadvanced/bit.ymlto treat them as errors. Broken YAML and impossible settings are always errors.
- What is checked. On startup, by
Publish condensed metric history across backends in network mode (ADR-040). Setting
metrics.networkTimeSeries.publish: trueinadvanced/network.yml(defaultfalse) writes completed metric buckets (tier, default24h@1m) to the shared SQL tablertp_metric_bucketor Redis sorted setsrtp:metric:<backend_id>:<metric_key>with(sample_count, mean, min, max, p95)and the active networkgeneration. Writes are batched (perPassWriteCap, default64rows per pass) and swept per backend afterretentionDays(default7days). Cross-backend chart snapshots include the(min, max)band alongsidemean. When network mode is off andpublish: true, RTP logs one warning at startup and stays dormant.Choose whether bare
/rtpopens the destination picker (openOnBareRtp).addons/guimenu.ymladdsopenOnBareRtp: true(also disabled whenmenuStyleis"none"or"off"). SettingopenOnBareRtp: falsemakes bare/rtpteleport immediately in the player's current world while keeping/rtp gui(rtp.gui) and/rtp menu(rtp.menu) active to open the destination picker.Set the region radius and bare-
/rtpmenu behavior in the setup wizard (/rtp admin setup, ADR-038)./rtp admin setupadds a region outer radius step (/rtp admin setup radius <distance>, with presets2.5km,5km,10km,25km,4096band500c, plus a custom distance prompt) and anopenGuiOnRtptoggle on the gameplay page (addons/guimenu.ymlopenOnBareRtp).
Changed
BIT codes now have namespace-local identities (ADR-121). The stable identity is
(namespace, id, key), so separate code owners with distinct prefixes can use the same number without reserving global ranges. The log table printsnamespace:id, JSON includesnswhile retaining schema 1 for its first release, and a committed release lock prevents renames, renumbering, reuse or unreviewed default-severity changes; retired codes remain documented. A new startup check,bit-namespaces, reportsBIT_NAMESPACE_CONFLICTwhen two plugins reserve the same code prefix.Runtime-read duration settings accept explicit units. Values such as
30s,5m,2h,1d12h,40tand500mswork insafety.yml,advanced/performance.yml,advanced/network.ymland proxynetwork-proxy.yml; bare numbers retain each setting's existing unit. Invalid backend values use their documented fallback with a warning, while invalid proxy network durations reject the configuration.Both jars share one version number (ADR-117). The separate
liteVersionline is retired; full and Lite builds report the same version.For addon developers (ADR-115, ADR-116, ADR-040, ADR-120, ADR-121). The common server bridge and platform-family enum are now available from the standalone
server-apiartifact inio.github.dailystruggle.server.api(RTPServerAccessorextendsServerAccessorandRTPSchedulerextendsTaskScheduler), andrtp-apire-exportsserver-api,menu-api,units-apiandtags-apialongside the standalonebit-api,config-bit-apiandpredict-apimodules (ConfigParser,MultiConfigParser,LanguageBootstrap,FactoryandFactoryValuealso live inyaml-apiunder their existing packages). UpdatePlatformFamilyimports fromio.github.dailystruggle.rtp.api.serverand rebuild binaries compiled against the old enum package. Built-in effects now route throughServerAccessors(wrapEffectPlayer,wrapEffectLocation,resolveEffectPlayerAt,dispatchConsoleCommand),HandleRegistryandHandleProviderinio.github.dailystruggle.effectsapi.common.spiare deprecated (@Deprecated(forRemoval = true)) as forwarding shims overServerAccessors, and the Bukkit effect classes (io.github.dailystruggle.effectsapi.bukkit.*andio.github.dailystruggle.effectsapi.EffectsAPI) have moved fromeffects-apiinto:rtp-bukkit:rtp-bukkit-commonsoeffects-apicarries no platform code.RTPServerAccessorprovides the defaultOptional<Boolean> hasScoreboardObjective(String)method,RTPScheduleraddsisGenerationSaturated(RTPWorld),RTPWorldaddsprobeChunkSquarefor off-thread same-region-file square probes, andrtp-apiadds@PublicApiMetricTimeSeriesPublisherandMetricBucketRowinio.github.dailystruggle.rtp.api.metrics.
Fixed
Moving during the
/rtpwarmup now cancels the teleport. Walking farther thancancelDistanceduringteleportDelaywas ignored for/rtp, because the player's starting position was never recorded, so the teleport went ahead anyway.Plain-number
teleportCooldownandteleportDelayvalues were treated as milliseconds instead of seconds. Bare numbers such asteleportCooldown: 300orteleportDelay: 5were read as milliseconds after duration-unit parsing landed, andteleportDelaywas skipped when all arrival chunks were already loaded. Bare numbers now mean seconds again, and the warmup runs even when no chunks need loading.Per-region
cooldownoverrides were blocked by a longer globalteleportCooldown. Naming a region with/rtp region:<name>now uses that region'scooldownoverride on its own, and a bare/rtpinto a world's default region passes once either the global cooldown or the region's override has elapsed.Walk-in trigger
batchIntervalwaves never fired (ADR-093). The wave timer was registered before the platform scheduler was set on startup, so players waiting in a wave trigger zone were never teleported. The timer now starts when RTP enables and stops on disable.Countdown boss bars stayed on screen after a cancelled teleport. Cancelling a teleport with
/rtp cancelor by moving during warmup left the countdown addon's queue or warmup bar running until it reached zero. Both bars are now cleared immediately on cancel.minePlots claim check now detects plots. With
rerollMinePlots: true, the check never found a plot, so players could land inside minePlots plots. It looked minePlots up under the wrong plugin name and guessed at its classes. It is now built against minePlots' published API (plugin-api4.6.2,PlotServiceApi.getPlotfrom the Bukkit ServicesManager) instead of looking classes up by name, and rejects the spot if minePlots is enabled but that service is missing or the lookup fails. It is tested against the published API, not yet on a live minePlots server, so treat it as best effort.UltimateClaims, PlotSquared, HuskClaims and KingdomsX claim checks fixed. UltimateClaims claims were never found: the check called a lookup UltimateClaims does not have, and could load a chunk off the main thread. On PlotSquared worlds every unclaimed plot was rejected; now owned plots and roads are rejected and unclaimed plots are allowed. The HuskClaims and KingdomsX checks could pick the wrong method depending on the server and then reject everything or nothing. Residence, CrashClaim, HuskTowns, SaberFactions/FactionsUUID and FactionsBridge were checked against their plugins' source and now look methods up by exact signature. These checks are tested against copies of each plugin's API, not on live servers, so treat them as best effort.
Claim checks no longer switch themselves off (ADR-118). If a claim plugin is enabled but its API doesn't match what the claim addon expects, every destination is now rejected and one error is logged, instead of the integration turning off and letting players land in claims. Update the claim plugin or the addon, or turn the integration's
integrations.ymlflag off, to resume teleports.A deleted Rift demo group no longer comes back after a restart. The Rift addon wrote its demo group to the old
effects/folder, and every start moved that copy intodefinitions/effects/, so deletingdefinitions/effects/rift.ymlwhile the server was stopped brought it back on the next start, even with the addon removed. The addon now writesdefinitions/effects/rift.ymldirectly and deletes an uneditedeffects/rift.ymlleft by an earlier version.The Rift effect no longer cancels
/rtpor buries the player. The fall into the rift counted as moving and trippedcancelDistance, so every delayed/rtpwithRIFTcancelled itself. While the rift is open, only sideways movement now counts, so walking away still cancels. When the rift closes, a player still inside it (teleport cancelled, or the rift's seconds shorter thanteleportDelay) is put back on the block they stood on instead of being left inside the restored terrain.Built-in effects that were missing on some platforms are now registered there.
TITLEnow works on Paper, Spigot and Folia.GLIDEnow works on Fabric 26.x and NeoForge.DROP_INVENTORYandDROP_EXP/DROP_EXPERIENCEnow work on NeoForge. Before, these tokens were skipped without a message.FIREWORKandNOTEare still Bukkit-family only.GLIDEon Fabric no longer drops the player. Without an elytra the game ended the glide on the next tick, so the player was lifted and then fell, taking fall damage. The glide is now kept going until the player lands, andLANDINGTIMEOUTstill forces a landing. Fabric and NeoForge don't yet place players who are still gliding when the server stops.TITLEshows the configured text. Text arguments were replaced by their empty defaults while the effect was built, soTITLE.<title>.<subtitle>showed a blank title on every platform. The same applied to text arguments of addon effects./rtp config languageonly tab-completed 5 of the 12 bundled locales. It now suggests all 12 (en,de,es,fr,it,ja,ko,nl,pl,pt,ru,zh).RECTANGLEregions withrotation: 90mapped locations to the wrong coordinates, andsetBiomeGetteroverrides on Fabric and NeoForge were ignored. Rotated rectangles now round-trip coordinates and heights, and biome checks on Fabric and NeoForge read the registeredsetBiomeGetteroverride first.Background cache fill on NeoForge 1.21.1 could stall player joins. Login-cache promotions and startup ticket re-validation could start unbounded chunk generations at once, and non-hill chunk tickets held a 3x3 radius instead of a single chunk. Generation-causing loads now share a bounded budget, and single-chunk tickets use radius 0 unless
maxHillAngleneeds the 3x3 square.
Platforms
Dependencies
- CombatLogX Optional
- Factions Optional
- GriefDefender Optional
- GriefPrevention Optional
- HuskTowns Optional
- Lands Optional
- PvPManager Optional
- RedProtect Optional
- SimpleCombatLog Optional
- Towny Optional
- Vault Optional
- WorldGuard Optional