Architecture Decision Records¶
This directory contains Architecture Decision Records (ADRs) for the RTP project.
An ADR captures a significant architectural decision: the context that forced it, the decision made, the alternatives considered, and the consequences. They are numbered sequentially and never deleted — superseded records are marked as such.
Index¶
| # | Title | Status |
|---|---|---|
| ADR-000 | Development Workflow (meta: how a developer ought to work in this repo and why - full lifecycle from intake through self-maintenance, D-005 guard rail, divergence handling, optional AI tooling) | Accepted |
| ADR-001 | Archimedean Spiral 1D Mapping for Location Selection | Accepted |
| ADR-002 | H2/SQLite for Spatial Memory Persistence Over Flat-File Cache | Accepted |
| ADR-003 | rtp-plugin as a Separate Bridge Module from rtp-core | Accepted |
| ADR-004 | CountBoundTaskPipe Instead of TimeBoundTaskPipe on Folia Regional Threads | Accepted |
| ADR-005 | Removal of PaperLib in Favour of Native Paper APIs | Accepted |
| ADR-006 | Async Queue Pre-Generation Over On-Demand Async Selection | Accepted |
| ADR-007 | Per-User Isolated Queues Alongside the Global Queue | Accepted (operational details superseded by ADR-043) |
| ADR-008 | MemoryTracker as Active Task GC with WeakReference Deallocation | Accepted |
| ADR-009 | Configurable Spatial Distributions: Flat, Normal, Exponential | Accepted |
| ADR-010 | Versioned Platform Adapter Submodules | Accepted |
| ADR-011 | rtp-api as a Separately Published Addon Interface |
Accepted |
| ADR-012 | ChunkReservation as an Internal Chunk Ticket Abstraction |
Accepted |
| ADR-013 | Addons as External Gradle Projects Rather Than Built-In Optional Modules | Accepted (partially superseded by ADR-019) |
| ADR-015 | Stale-Chunk Guard for Count-Bound Pipes | Accepted |
| ADR-016 | Anvil Read-Only Subsystem (Prefilter, Backed Chunk View, Shared Module) | Accepted |
| ADR-017 | Block Tags and Block-State Predicates in Safety Lists | Accepted |
| ADR-018 | AGENTS.md Public Release Structure: Thin Router + Canonical Sources |
Accepted |
| ADR-019 | Claim-Plugin Integrations Folded Into rtp-plugin; Example Addon Retained |
Accepted |
| ADR-020 | Language Bootstrap and Locale-Aware ConfigParser | Accepted |
| ADR-021 | Legacy Minecraft and Java Support Are Out of Scope | Accepted |
| ADR-022 | Region Shape Cache Key: Seed + Canonical Config Hash | Accepted |
| ADR-023 | Login Reserve Cache for Join-Time RTP | Accepted |
| ADR-024 | RTP Lite Assembly Variant | Accepted |
| ADR-025 | Replace SimpleYaml with an Internal SnakeYAML-Backed YAML Wrapper | Proposed |
| ADR-026 | External Hook API Surface | Accepted |
| ADR-028 | L3 Backlog Cache (backlogLocations) |
Accepted |
| ADR-032 | Teleport Pipeline Latency Histogram: 256-Sample Wait-Free Ring, Never Reset | Proposed |
| ADR-034 | Memory Shape Catalog and Polygon Shape | Accepted |
| ADR-035 | Interactive Menus via Written Book (Book-First, Chat Fallback) | Proposed |
| ADR-036 | Network Mode: Multi-Server, Multi-Proxy RTP | Accepted (2026-05-14) |
| ADR-037 | Harden RTP Config Commands (Prerequisite for /rtpadmin Setup Wizards) |
Accepted |
| ADR-038 | /rtpadmin Setup Wizards (Book-Menu Driven, Config-Transaction Backed) |
Proposed |
| ADR-039 | /rtpadmin Diagnostic Surfaces (Biome Map, Bad-Selection Heatmap, Metrics Readouts) |
Proposed |
| ADR-040 | Cross-Backend Metric Time-Series Publication via MemoryTracker Tier Promotion |
Proposed |
| ADR-041 | /rtp config Command and Save Mechanics: Implementation Strategy (companion to ADR-037) |
Proposed |
| ADR-043 | rtp.personalqueue Permission Semantics: Bucket-Only Opt-In (supersedes operational details of ADR-007) |
Accepted |
| ADR-046 | maps-api Module for Runtime Cartography Chart Generation |
Accepted |
| ADR-047 | Declarative Chart Composition Bridge (ChartSpec + ChartSpecResolver + MapDispatch) |
Accepted |
| ADR-048 | Move menu page builders into rtp-api behind RTPServerAccessor (four default methods + MenuPlatformView snapshot record; no new Gradle module) |
Proposed |
| ADR-049 | Lift network-mode plumbing (NetworkModeBootstrap + 12 helpers) from rtp-plugin/bukkit/network/ to rtp-core; new PlayerLifecycleHook SPI on RTPServerAccessor; supersedes rtp-fabric-ADR-013 |
Accepted |
| ADR-053 | Pipeline Latency Percentiles and Slow-Teleport Audit (extends ADR-032; /rtp info readout) |
Accepted |
| ADR-054 | RTPRunnable Self-Scheduling Thread Routing (target/location + schedule() entity/region/async dispatch) |
Accepted |
| ADR-057 | Platform-agnostic addon SPI (RTPAddon + AddonRegistry ServiceLoader discovery; replaces Bukkit JavaPlugin addon loading) |
Accepted |
| ADR-058 | Region-Specific Schematic (.schem) Paste at the Arrival Location (SchematicPaster SPI + swappable per-adapter getter; load-async/paste-on-region-thread) |
Accepted |
| ADR-059 | Relative Ground-Distance Safety Predicate (synthetic _groundDistance block-state property consumed by the ADR-017 numeric-range grammar; ground leaves/roots safe, tall-tree canopy unsafe) |
Proposed |
| ADR-060 | Emergency-Platform Block-Restoration Timeout (safety.yml platformRestoreSeconds, -1 disables; per-coordinate diff capture; DB-persisted, chunk-loaded countdown reaper; row removed on completion) |
Accepted |
| ADR-061 | Open-Core Dual Licensing (MIT for rtp-api, rtp-core, and the RTP lite binary; PolyForm Noncommercial for Pro-only source) |
Accepted |
| ADR-062 | Biome-Probability Weighting for Location Selection (Anvil-sourced per-region biome occupancy map + bounded weighted draw; steering distinct from existing bad-sector avoidance) | Accepted |
| ADR-063 | Biome-First Menu with Auto-Region Selection by Biome Availability (observed-biome list from MemoryShape.getObservedBiomes(), BiomeColorSource row coloring, shared /rtp biome:<x> auto-region for CLI/menu parity, no player-controlled disk writes) |
Accepted |
| ADR-064 | Config-Comment Format: Summary Line as Menu Hover Text (fixed two-part template — standalone first-line summary + prose + @type/@options/@range/@unit/@default/@source directives; canonical style guide docs/dev/CONFIG_COMMENT_STYLE.md) |
Accepted |
| ADR-065 | World-Override Regions and the /rtp World Menu (shared world:<x> override builds a cached <region>_<world> region so rtp world:nether and rtp region:r world:nether actually land in the target world; adds the front-page world picker row) |
Accepted |
| ADR-066 | Foreign Config Importer (rtp config import <plugin>: one-shot, non-destructive, dry-run/confirm migration aid; generic ConfigImporter seam in rtp-core reading competitor YAML via the in-house parser; BetterRTP/EzRTP/JakesRTP sources; MAPPED/APPROXIMATED/DEFERRED/DROPPED classification; SetAsRespawn/LockAfter deferred until parity lands) |
Accepted |
| ADR-067 | Automatic PRESCAN, Adaptive Scan Rate Control, and .mca-Header Generation Check (three disk-/generation-neutral safety-map tiers: scheduled PRESCAN-only auto-scan that never promotes to FULLSCAN, opportunistic bounded on-load PRESCAN clipped to region boundaries, and live verification fallback; two-axis MSPT-headroom + queue-pressure per-tick budget; check-then-allocate predictive bound using per-class ChunkLoadProfile floors; Option B per-chunk generated/ungenerated read from the cached region-file sector-offset table via an anvil-api helper, reusing ScanTask's existing region-file binning; all behaviour configurable via performance.yml keys, off by default) |
Proposed |
| ADR-068 | Cross-Server Persisted Teleport Limits (two orthogonal axes: durability local always-on + optional proxy durable store, file-backed YAML/JSON in lite and Redis/SQL in Pro; swappable transport reusing NetworkTransport; push-on-connect snapshot instead of poll-per-teleport; relative-duration wire format to neutralize clock skew; usage-cap persistence parity with the already-persisted cooldown; fail-open-to-local) |
Accepted |
| ADR-070 | Platform-neutral /rtp command root (CoreRtpRoot) for Brigadier-bridged platforms (collapses the duplicated Fabric / NeoForge roots into thin subclasses of one rtp-core root; accessor-backed ServerAccessorCommandParameters for player/world; new default RTPServerAccessor.getOnlinePlayerNames() SPI; Bukkit root left bespoke) |
Accepted |
| ADR-071 | Config Organization and Discoverability (keep split-by-concern files; virtual Teleport/Safety/Economy/... grouping in menu+docs rather than physical YAML merges; relevance ordering of keys; staged messages.yml plan: section refinement now, planned messages/-directory split later via a merge-loader that keeps the closed MessagesKeys enum + legacy flat-file fallback; read-legacy-warn-prefer-new migration on key moves; first action de-duplicates config.yml's network.redis against the authoritative network.yml) |
Proposed |
| ADR-072 | Teleport View-Distance Clamp and Steady Restore (per-player delivery view distance clamped to the viewDistanceTeleport preload radius, floored at MIN_VD=2, on arrival; one new performance.yml#viewDistanceRestoreInterval total-time ramp key, default 200 ticks, 0 disables; single-chunk increments deferring to any larger concurrent view distance; platform-neutral getViewDistance/setViewDistance SPI; RTP.scheduler-driven, session-scoped, no DB persistence) |
Accepted |
| ADR-073 | Config Default Inheritance via @<file> References (region/world settings may resolve to a global default owned by a named file instead of a literal; the @<file> token names the owning file so each default stays in its concern file - price -> @economy, shape/vert/cache caps/spatialResolution/world requirePermission -> @config#defaults; type-bearing shape/vert inherit as whole named blocks, type-free scalars inherit individually; shipped regions/worlds defaults use the reference; read-time fail-safe resolution with warn-on-missing/unknown-file; non-rewriting opt-in migration + version bumps; menu inherit/override toggle; extends ADR-071, builds on the ADR-034 shape catalog) |
Proposed |
| ADR-074 | Operator-Facing RTP Throughput and Cost Metrics (end-to-end command latency + cost-per-valid-location reusing the ADR-032 ring; always-paired usage/refill EWMA rates over a shared named window with backlog fill %/state label to disambiguate hysteresis-driven zero refill; usage/refill ratio headline; green/amber/red color coding via the ADR-053 threshold mechanism; extends ADR-032/ADR-053) | Proposed |
| ADR-075 | Platform-Neutral Player-Move Event SPI (normalized block-granularity move signal in rtp-api, dispatched by rtp-core, implemented per adapter - Bukkit PlayerMoveEvent, Fabric/NeoForge server-tick position diff; opt-in per-player subscription so cost scales with watched players not total; enables cross-platform region confinement/tether and future move-driven features without a WorldGuard dependency) |
Accepted (2026-07-25) |
| ADR-076 | Config Folder Consolidation (reduce the operator-facing top level from 12 to a small tiered surface: everyday YAMLs at root + addons/ + definitions/ grouping the MultiConfigParser sets regions/worlds/effects + one advanced/ door absorbing schematics/messages alongside the tuning YAMLs; the lang/ locale value tree stays at root, and rename-maps become co-located dotfile siblings mirroring the default tree; database/ stays at root as runtime state; supersedes ADR-071's top-level layout only, all other ADR-071 rules retained; read-legacy folder-relocation migration + version bumps) |
Accepted (2026-07-26) |
Subproject ADRs¶
ADRs whose scope is confined to a single subproject (module / addon) live next to that subproject's source under <subproject>/docs/adr/ rather than in this directory. They follow the same numbering sequence and template as the project-wide ADRs above. Catalog of known subproject ADR directories:
| Subproject | Path | ADRs |
|---|---|---|
LeafRTPPartyAddon |
addons/LeafRTPPartyAddon/docs/adr/ |
leafrtp-party-addon-ADR-001 Party Teleport via Shared Prepared Destination (reuse the supply pipeline, do not search per member) (Proposed) |
LeafRTPTetherAddon |
addons/LeafRTPTetherAddon/docs/adr/ |
leafrtp-tether-addon-ADR-001 Tether: Cross-Platform Region Confinement Composed From RTP Primitives (No WorldGuard Trap) (Proposed) |
commands-api |
api/commands-api/docs/adr/ |
commands-api-ADR-001 Brigadier Bridge via commands-api Adapter Layer (Proposed); commands-api-ADR-002 Message-delivery seam via a MessageSink SPI (Accepted); commands-api-ADR-003 Registration seam via a CommandRegistrar (Bukkit), neutral command roots (Accepted) |
effects-api |
api/effects-api/docs/adr/ |
effects-api-ADR-001 Glide Effect in effects-api (Proposed); effects-api-ADR-002 Type-Driven Adaptive Reading Order (Accepted; amended by ADR-004); effects-api-ADR-003 Platform Split Bukkit/Fabric (Accepted); effects-api-ADR-004 ValueCoercer SPI: Per-Platform Type Binding for the Adaptive Reading Order (Accepted) |
rtp-fabric |
platforms/rtp-fabric/docs/adr/ |
rtp-fabric-ADR-001 Fabric Multiversion Submodule Layout (Accepted); rtp-fabric-ADR-002 Fabric Platform Is In Scope (Accepted; renumbered from ADR-022 on 2026-05-05 to resolve a numbering collision); rtp-fabric-ADR-003 Non-persistent chunk tickets via DistanceManager.addRegionTicket (Accepted); rtp-fabric-ADR-004 DistanceManager API split at MC 1.21.5 (Accepted); rtp-fabric-ADR-005 Fabric anvil pre-filter parity (Accepted); rtp-fabric-ADR-006 Chunk-ticket radius is 3, not 31 (Accepted); rtp-fabric-ADR-007 Decouple FabricVersionAdapter from Mojmap type names (Accepted); rtp-fabric-ADR-008 Non-blocking chunk generation via ServerChunkCache#getChunkFuture (Accepted); rtp-fabric-ADR-009 Obf/unobf common module split (Accepted); rtp-fabric-ADR-010 Typed block-tag snapshot via per-version SPI; reflection demoted to fallback (Accepted); rtp-fabric-ADR-011 Effective-permission enumeration on Fabric (LuckPerms-Fabric primary, registry-probe fallback; covers rtp.effect.* + rtp.onevent.* + numeric tails) (Accepted 2026-05-22); rtp-fabric-ADR-012 Menu renderer parity on Fabric (chat-first via obf/unobf carrier split; book renderer deferred; PromptAnvilInput substituted by chat-prompt callback) (Proposed 2026-05-22); rtp-fabric-ADR-013 Network-mode backend parity on Fabric (reimplementation as FabricNetworkModeBootstrap + FabricJoinTriggerSource; pulls pure-I/O helpers up to a shared utility; reuses ADR-011 resolver for reservation-token auth) (Proposed 2026-05-22); rtp-fabric-ADR-014 Early/experimental MC 26.2 pre-release adapter (rtp-fabric-v26_2_R1, cloned from v26_1_R1; deobf/JDK-25; startsWith("26.2") dispatch) (Accepted 2026-05-31); rtp-fabric-ADR-015 Maps API parity (vanilla filled-map path; FabricMapBinding + FabricVersionAdapter.renderMapChart seam, 26.2_R1 carrier) (Accepted 2026-05-31) |
maps-api |
api/maps-api/docs/adr/ |
maps-api-ADR-001 Module Bootstrap, Package Layout, and Palette Policy (Accepted); maps-api-ADR-002 GUI-Slot Map Delivery and a Future Off-Main Raw-Packet Render Path (Proposed) |
metrics-api |
api/metrics-api/docs/adr/ |
metrics-api-ADR-001 Module Extraction from rtp-core (Accepted) |
rtp-neoforge |
platforms/rtp-neoforge/docs/adr/ |
rtp-neoforge-ADR-001 NeoForge Platform Is In Scope (Per-MC-Version Submodule Layout, Mojmap-at-Runtime) (Accepted 2026-06-01) |
rtp-proxy |
platforms/rtp-proxy/docs/adr/ |
See subdirectory index. Highlights: rtp-proxy-ADR-001 SPI Shape (Proposed); rtp-proxy-ADR-002 network.yml Schema (Accepted 2026-05-14, amended 2026-05-18); rtp-proxy-ADR-003 In-Memory Binding (Proposed); rtp-proxy-ADR-004 Weighted-Average Selector (Proposed); rtp-proxy-ADR-005 Redis Binding (Accepted 2026-05-18); rtp-proxy-ADR-006 Velocity Bootstrap (Accepted 2026-05-18); rtp-proxy-ADR-007 Postgres Binding (Proposed, superseded-sketch by ADR-011); rtp-proxy-ADR-008 Bungee Bootstrap (Proposed); rtp-proxy-ADR-009 Generic SQL Binding (Proposed, superseded-sketch by ADR-011); rtp-proxy-ADR-010 Security Hardening (Accepted 2026-05-18); rtp-proxy-ADR-011 SQL Network State Binding (Accepted 2026-05-18); rtp-proxy-ADR-012 Proxy Role: Participant Default (Proposed); rtp-proxy-ADR-013 RTPProxyAccessor Registration (Proposed); rtp-proxy-ADR-014 Backend-Owned /rtp with Network Wait-Queue (L6) (Accepted 2026-05-21, supersedes rtp-proxy-ADR-006 Command Hosting); rtp-proxy-ADR-015 Shared Network Waitlist and Dynamic Batched Dispatch (Proposed 2026-05-21); rtp-proxy-ADR-016 Plugin-Message Default Transport (tier-1, non-durable, ships in lite; amends ADR-036) (Accepted 2026-06-12) |
When adding a new subproject ADR, also add a row here so the global index remains a one-stop catalog.
Template¶
Use ADR-TEMPLATE.md when recording a new decision.