PLUGIN PROPOSAL · LEAVES 1.21.8

《任意门》插件策划案 DOKODEMO DOOR — PAIRED CROSS-WORLD PORTALS

两扇门,一次绑定,双向互通。为 Leaves 1.21.8 打造的配对式跨世界传送门插件——像原版下界门一样自然走进去,但连接的是任意两个世界的任意两扇门。

目标核心 Leaves 1.21.8(Paper API 兼容) 运行环境 Java 21 类型 Bukkit/ Paper 插件 版本目标 V1.0 定位 生存 / RPG 服务器
两个发光的任意门跨越主世界与下界,被紫色粒子流连接
概念图:主世界与下界各立一扇任意门,紫颂粒子在两门之间穿行——这就是插件的全部体验
CHAPTER 01

项目概述

原版下界门是 Minecraft 里最优雅的传送设计:走进去,穿过一片紫色幕布,从另一端出来。但它有两条硬边界——只能连接主世界与下界的固定比例坐标,且两端位置不可选择。服主想让玩家在主世界出生点与千里之外的基地之间自由往返,只能借助 Multiverse-Portals 这类管理员工具:敲命令、选区域、填坐标,创建过程与游戏体验完全割裂。

《任意门》(DokodemoDoor,下称 DDoor)把下界门的沉浸感还给了玩家自己:在任意两个世界各放一扇普通的门,手持一把"门之钥"依次右键两扇门,它们从此配对互通。此后走进任意一扇门,就从另一扇门前走出——没有命令,没有菜单,和推开哆啦A梦的任意门一样直白。

设计三原则

PRINCIPLE 01
零门槛创建
不放告示牌、不敲命令、不选区域。玩家只需要"放门 + 右键"两个动作。创建权可按权限组放开或收紧,默认对全体玩家开放。
PRINCIPLE 02
原生化沉浸
触发方式是"走进门框"而非右键点击;配对成功与传送瞬间都有粒子、音效、短暂视觉过渡的完整反馈,玩家感知不到插件的存在,只感知到"门变魔法了"。
PRINCIPLE 03
服务器友好
移动事件节流检测、按距离分级的粒子渲染、异步落盘的存储层,性能开销控制在无感知级别;冷却、世界黑名单、门数量上限为服主兜底防滥用。

目标与边界

本插件的唯一核心命题是点对点配对传送。围绕它做深做透,同时明确不做什么:

命名说明:插件 ID 定为 DokodemoDoor,命令前缀 /ddoor。中文语境统一称"任意门",面向英文社区的名称与 SpigotMC 发布名建议用 AnyDoor Portals,便于搜索。
CHAPTER 02

竞品分析与差异化

传送门类插件在 Bukkit 生态已发展十余年,头部方案可归为三派:以 Multiverse-Portals 为代表的"选区派",以 MyWorlds 为代表的"告示牌派",以及以 AdvancedPortals 为代表的"命令标签派"[2][3][4]。三派的共同短板是一致的:以"目的地"为中心建模——每个门指向一个坐标或另一个门,创建权基本只对管理员开放,创建流程脱离游戏操作本身[5]

维度Multiverse-PortalsMyWorldsAdvancedPortals任意门 DDoor
创建方式木棍选区 + 命令告示牌写规则命令 / GUI 配标签放门 + 钥匙右键
创建者仅管理员仅管理员管理员为主玩家自助(可配置)
连接模型门 → 目的地坐标门 ↔ 门(牌面声明)门 → 目的地/标签门 ↔ 门(实体配对)
跨世界传送支持支持支持支持
触发体验走进区域即传走进门方块即传走进区域/触发词走进门框即传
视觉沉浸无反馈原版门方块一般粒子 + 音效 + 过渡
前置依赖Multiverse-Core同族插件群无硬依赖零硬依赖
玩家上手成本极低(两个动作)
四款传送门方案能力对比
评分为策划评估值(满分 5),依据为各插件公开文档与功能清单
图 2-1:竞品六维能力雷达图——DDoor 在"玩家自助"与"沉浸反馈"两个维度形成代差,其余维度持平

雷达图暴露出一个市场空档:现有方案把"传送"当作基础设施来做,没人把它当作玩家玩法来做。玩家自助创建意味着门本身成为可规划、可交易、可展示的生存内容——基地入口的对开门、跨服活动的往返门、村落之间的公交网络,都会从玩家社区里自然生长出来,这是三款头部插件都无法提供的服务器生态价值。

另一个被忽视的差异是心智模型。"门 A 指向门 B"和"门 A 与门 B 是一对"听起来相似,实际体验完全不同:前者要求玩家理解"目的地"这个抽象概念并在创建时做出单向决策;后者只需要玩家拿起钥匙把两扇门"锁"在一起——配对成功后双向自动生效,没有方向可以搞错。

CHAPTER 03

核心玩法设计

3.1 配对模型

插件的最小单元不是"门",而是"门对"(DoorPair)。一扇门在被钥匙选中之前只是一扇普通门;被选中的门进入"待配对"状态并开始 60 秒倒计时;倒计时内选中第二扇门,两门缔结为一对,此后任意时刻踏入其中一扇,都会从另一扇门前走出。

3.2 三步上手法

创建一对任意门需要三个动作,全程无需打开任何界面:

INTERACTIVE DEMO 01 任意门创建全流程 · 点击"执行下一步"逐帧体验
OVERWORLD · 主世界
门 A
手持:门之钥 ×1
跨世界
NETHER · 下界
门 B
手持:门之钥 ×1
第 1 步:在主世界放置一扇门
* 演示已就绪,点击「执行下一步」开始 *
操作提示:真实游戏内为——放置任意材质的门 → 手持门之钥右键第一扇门 → 60 秒内右键第二扇门 → 完成。门之钥绑定成功后消耗 1 把。
玩家手持发光的金色门之钥,走向一扇散发紫色粒子的独立门
图 3-1:绑定瞬间——手持门之钥右键门方块,门框亮起紫颂粒子进入待配对状态

3.3 传送体验

传送的触发方式刻意选择了物理走进而非右键交互:玩家推门而入的动线与原版下界门完全一致,肌肉记忆零迁移成本。传送发生时按固定时序播放三段反馈——门口紫颂粒子收拢为漩涡(200ms)→ 屏幕短暂渐暗(可配置,默认 300ms)→ 落点粒子绽放并播放 BLOCK_CHORUS_FLOWER_TELEPORT 音效。整套反馈控制在半秒内完成,节奏快于下界门的原版过场。

落点计算遵循门前安全原则:传送目的地固定为对侧门"面向外"的一格,插件自动校验该格及其头顶两格无碰撞方块、脚下有承托面;校验失败时向门左右两侧逐格探测,全部失败则拒绝传送并提示对侧异常,玩家不会被传进方块或虚空。

3.4 视觉与听觉设计

状态视觉音效渲染策略
待机(已配对)门框边缘稀疏紫颂粒子缓慢上浮无(保持安静)仅 32 格内玩家可见,2 粒/次 · 4 tick 间隔
待配对门框粒子明亮密集 + 门顶悬浮倒计时琥珀音(上界铜钟轻击)同上,密度翻倍
传送瞬间粒子收拢漩涡 → 落点绽放紫颂果传送音事件驱动,单次触发
配对成功两门同时光柱爆发悦灵投掷音 + 经验球音事件驱动,单次触发

所有粒子使用 Paper API 的 player.spawnParticle() 按接收者发送,而非世界级广播——一个 30 人的服务器上,只有站在门附近的少数玩家收到粒子包,这是性能设计的细节之一(详见第 5 章)。

CHAPTER 04

功能需求详述

功能按五个模块拆解:配对系统是数据基石,传送引擎是体验核心,门之钥是经济阀门,管理界面是运维入口,防护体系是兜底安全。每个模块先给交互原型,再给逻辑细节。

4.1 门方块识别与配对系统

材质支持:凡继承 org.bukkit.block.data.type.Door 的方块全部支持——涵盖 1.21.8 全部 11 种木门、铁门与铜门系(含氧化变体)。门允许放在任意位置,无需贴墙。铁门无法徒手打开的问题不影响本插件:传送判定基于"玩家身体进入门框空间",与门的开合状态无关,玩家可以直接穿门而过(这也让铁门成为最推荐的任意门材质——防误触又防盗)。

结构校验:单扇门取 BlockData#getHalf() 的 LOWER 半格作为门的锚定坐标;双扇对开门(两格宽)识别后合并为一个逻辑门,配对时右键任意半扇均生效。校验失败的边缘情况(悬浮半扇门、上半格残留)在钥匙右键时给出精确提示。

绑定流程状态:钥匙右键门 → 校验(该门是否已配对 / 玩家门对数量是否达上限 / 世界是否允许)→ 通过后进入待配对态并记入会话缓存(60 秒 TTL,玩家下线即清除)→ 右键第二扇门 → 双重校验 + 距离与同门检查 → 配对落库、双门播放光柱、消耗钥匙。

字段类型说明
door_idUUID门的唯一标识,锚定坐标生成
nameString门名,默认"某某的门",可由所有者改名(≤16 字符)
ownerUUID创建者,拥有改名 / 解绑权
world / x / y / zString / int锚定方块坐标(下半门格)
facingEnum门朝向,决定传送落点在门外哪一侧
paired_idUUID配对门 ID,未配对为空
created_at / useslong创建时间戳 / 累计穿越次数(供统计与 PAPI)

4.2 传送引擎

传送引擎是插件的性能与体验命脉。每次玩家移动都会触发一次六环节检测链,任何一环拦截即终止并反馈原因。下方原型完整模拟了这条检测链——先打开任意拦截开关,再点"走进任意门",观察失败发生在哪一环:

INTERACTIVE DEMO 02 传送检测链 · 打开拦截开关后走进门,观察拦截环节
处于传送冷却中 无使用权限 对侧门已被破坏 对侧世界被禁用 对侧落点不安全
冷却检查同一玩家 3 秒内不可连续传送
🔑权限检查门对权限 / 玩家使用权限
🚪对侧门有效性配对门方块是否仍然存在
🌍目标世界可用世界已加载且不在黑名单
🛟落点安全校验落点无碰撞且脚下有承托
执行传送异步加载区块 → 传送 → 反馈
等待测试…
传送冷却:3.0s
真实实现中整条检测链在主线程执行、耗时微秒级;跨世界传送时才使用 getChunkAtAsync 异步加载目标区块,避免主线程卡顿。

检测链的工程含义需要逐环说明:

flowchart TD
    A[PlayerMoveEvent 玩家移动] --> B{位置进入门框空间?}
    B -- 否 --> Z[正常返回 · 事件透传]
    B -- 是 --> C{区块级节流缓存
该玩家本 tick 已检测?} C -- 是 --> Z C -- 否 --> D[O 1 内存索引查门
blockKey → doorId] D --> E{是已配对的门?} E -- 否 --> Z E -- 是 --> F[冷却检查] F -- 拦截 --> M1[ActionBar 提示 冷却中] F -- 通过 --> G[权限检查] G -- 拦截 --> M2[聊天提示 无权限] G -- 通过 --> H[对侧门方块存在?] H -- 否 --> M3[提示 对侧门已失效
本门降级未配对态] H -- 是 --> I[目标世界可用?] I -- 否 --> M4[提示 目标世界禁用] I -- 是 --> J[落点安全校验] J -- 失败 --> M5[左右逐格探测
全败则提示异常] J -- 通过 --> K[teleportAsync 传送
粒子 + 音效 + 渐暗反馈] K --> L[写入穿越统计
异步落库] style K fill:#b388ff,color:#0a0e1a,stroke:#b388ff style A fill:#131a2e,color:#e8eaf6,stroke:#4a5580 style Z fill:#131a2e,color:#9aa3c7,stroke:#4a5580
图 4-1:传送检测链完整流程——高频入口(移动事件)只做两次哈希比较即返回,重逻辑全部后置

4.3 门之钥与经济系统

玩家自助创建必须有资源阀门,否则门对数量会在一周内指数膨胀。阀门就是门之钥(Door Key)——自定义命名物品(紫水晶簇纹理 + 紫色名称 + 自定义 NBT/组件标记),默认配方如下,可在配置中整体替换或关闭(改为管理员发放):

INTERACTIVE DEMO 03 门之钥合成配方 · 悬停查看物品详情
紫晶
1紫水晶碎片minecraft:amethyst_shard
铁锭
1铁锭minecraft:iron_ingot
紫晶
1紫水晶碎片minecraft:amethyst_shard
铁锭
1铁锭minecraft:iron_ingot
末影
之眼
1末影之眼minecraft:ender_eye
铁锭
1铁锭minecraft:iron_ingot
紫晶
1紫水晶碎片minecraft:amethyst_shard
铁锭
1铁锭minecraft:iron_ingot
紫晶
1紫水晶碎片minecraft:amethyst_shard
门之钥
2 门之钥 · 右键两扇门完成配对ddoor:key(自定义组件标记)
配方成本定位:约等于一组铁 + 4 紫水晶碎片 + 2 末影之眼换 2 对门——前期略有门槛,中期社区交易品,后期日常消耗
配方通过 prepareCraftEvent 动态注入,无需修改玩家客户端;产物带自定义数据组件标记,杜绝铁砧改名伪造。

数量上限体系:按权限组配置门对上限(默认普通玩家 3 对、赞助组 10 对、管理员无限),达到上限时钥匙右键给出明确提示。上限检查发生在配对落库前,避免半途消耗钥匙。

Vault 经济挂钩(软依赖):可选拆分为两档收费——创建费(配对成功时扣)与使用费(每次穿越扣,默认关闭)。未安装 Vault 时相关配置自动失效,插件功能不受影响。

4.4 管理 GUI 与命令

服主入口为 /ddoor 命令树与一个箱子风格 GUI。GUI 主体是门对列表(每对门一个门图标),点击选中后在右侧详情栏执行操作——以下是可交互原型,点击门图标试试:

INTERACTIVE DEMO 04 任意门管理面板 · /ddoor gui · 点击门图标查看详情与操作
任意门管理 · 共 16 对
未选中门对
点击左侧任意门图标查看详情
GUI 顶部一行为功能格(翻页 / 筛选仅我创建的 / 关闭),底部两行为玩家快捷栏映射;真实实现基于 InventoryHolder 自定义容器,杜绝与其它插件的 GUI 冲突。

4.5 防护与反滥用

风险场景防护机制默认策略
高频穿越刷事件按玩家维度的传送冷却 + 检测链区块级节流冷却 3s,节流 1 次/tick
门被破坏后的悬空配对BlockBreakEvent / EntityExplodeEvent / 活塞推动事件统一监听,门方块消失即解绑并通知所有者即时解绑
恶意传送到敌对领地世界黑名单 + WorldGuard 软依赖(目标区域含 PVP/保护旗标时拒绝)黑名单空,WG 检查开启
骑乘载具穿门逃逸骑乘状态(马/矿车/船)默认禁止传送,提示先下车禁止
创造模式刷钥匙钥匙带数据组件指纹,取自生存背包外的钥匙(创造取出)标记不消耗但仅管理员可用管理员豁免
门对刷量权限组数量上限 + 解绑冷却(同一门 10s 内不可重复绑定)普通 3 对/人
CHAPTER 05

技术方案

5.1 架构总览

四层结构:监听层只做事件接入与前置节流,核心层承载全部业务判断,表现层与数据层通过队列解耦。全部软依赖(Vault / PlaceholderAPI / WorldGuard)以独立挂钩类接入,主代码零编译期耦合——未安装任何挂钩时插件完整可用。

flowchart TB
    subgraph LISTEN["监听层 · 事件接入"]
        L1["DoorInteractListener
钥匙右键 · 配对会话"] L2["MoveListener
PlayerMoveEvent 双重节流"] L3["BlockWatcher
破坏 / 爆炸 / 活塞"] end subgraph CORE["核心层 · 主线程"] PAIR["PairManager
配对会话与门对生命周期"] ENG["TeleportEngine
六环检测链"] REG[("PortalRegistry
Long2Object 坐标索引")] end subgraph VISUAL["表现层"] PT["ParticleScheduler
按玩家距离分级渲染"] SND["SoundCue 音效"] end subgraph DATA["数据层 · 异步"] Q["异步写队列"] DB[("SQLite WAL / MySQL")] end subgraph HOOK["软依赖挂钩 · 可选"] V["Vault"] WG["WorldGuard"] PAPI["PlaceholderAPI"] end L1 --> PAIR L2 --> ENG L3 --> REG ENG --> REG PAIR --> Q ENG --> PT ENG --> SND Q --> DB ENG -.-> V ENG -.-> WG PAPI -.-> REG style ENG fill:#b388ff,color:#0a0e1a,stroke:#b388ff style REG fill:#131a2e,color:#e8eaf6,stroke:#4a5580 style DB fill:#131a2e,color:#e8eaf6,stroke:#4a5580
图 5-1:插件四层架构——监听层薄、核心层重、表现与数据层全部异步化

5.2 存储设计

默认 SQLite(WAL 模式,零配置开箱即用),可切换 MySQL 适配群组服。单表 ddoor_doors,门对通过 paired_id 互相引用。启动时全量加载进内存索引后,运行期只读内存、只写队列——所有变更先进异步写队列批量落库,关服时统一刷盘,玩家传送路径上没有任何同步 IO。

内存索引是性能关键:以世界名 + 方块坐标打包的 long 作 key 的哈希表(Long2ObjectOpenHashMap 或等价结构),任意"这个坐标是不是任意门"的查询都是 O(1)。50 对门与 5000 对门的查询成本完全相同,数据量不构成性能变量。

5.3 性能设计:驯服 PlayerMoveEvent

传送插件的性能原罪是 PlayerMoveEvent——每个玩家每秒触发约 20 次,直接在事件里查门必然拖垮 TPS。本方案在事件入口设置两道闸门:

两道闸门都通过(玩家确实走进了门框)才进入重量级检测链。粒子渲染同样按需供给:以每个门为中心、以最近玩家距离决定渲染频率——32 格内满频,32~64 格减半,64 格外暂停;粒子包只发给 32 格内的玩家而非全世界广播。叠加 Leaves 自身的异步区块与实体追踪优化[1],插件侧开销在 100 玩家在线的压测目标下应低于 0.3ms/tick。

5.4 兼容性边界

5.5 工作量估算

各模块开发工作量估算
单位:人日 · 单人开发 · 含单元测试与联调
图 5-2:22 人日总量——传送引擎与防护边界是两大投入重心,合计占近半工作量
CHAPTER 06

命令与权限设计

命令树刻意收窄:玩家的核心动线(放门、绑定、穿越)完全不经过命令,命令只服务于管理与补救场景。

6.1 命令表

命令功能权限默认
/ddoor打开管理 GUI(玩家视角仅见自己的门)ddoor.gui全体
/ddoor link命令式绑定(免钥匙的管理替代路径)ddoor.link.commandOP
/ddoor list [页]列出自己的门对;带 -a 列全服ddoor.list / .others全体 / OP
/ddoor tp <门名>传送到指定门(管理员巡查用)ddoor.tpOP
/ddoor rename <门名> <新名>重命名门ddoor.rename门所有者
/ddoor unlink <门名>解除一扇门的配对ddoor.unlink门所有者
/ddoor delete <门名>删除门的记录(不可恢复)ddoor.deleteOP
/ddoor key [数量] [玩家]发放门之钥ddoor.adminOP
/ddoor stats全服门对统计(总量 / 今日穿越 / TOP 门对)ddoor.adminOP
/ddoor reload重载配置(不动数据)ddoor.adminOP

6.2 权限表

权限节点含义默认
ddoor.use穿越任意门全体 true
ddoor.create使用钥匙配对(消耗钥匙)全体 true
ddoor.limit.<n>门对数量上限(如 ddoor.limit.10)无此权限时取配置 default-limit
ddoor.bypass.cooldown免传送冷却OP
ddoor.bypass.world免世界黑名单限制OP
ddoor.admin管理全部门对 + 发钥匙 + reloadOP
CHAPTER 07

配置文件设计

一份 config.yml 覆盖全部可调项,注释即文档;另配 messages.yml(全量消息文案,支持 MiniMessage 格式码)与 lang/ 多语言目录,默认内置中文与英文。

# ================= DDoor 任意门 =================

key:
  item: AMETHYST_SHARD        # 钥匙基底物品
  name: "门之钥"               # 显示名(支持 MiniMessage)
  custom-model-data: 21001     # 材质包可覆盖的模型标记
  craftable: true               # 是否启用合成配方
  recipe-output: 2             # 单次合成产出数量

teleport:
  cooldown-seconds: 3          # 玩家级传送冷却
  fade-effect: true             # 传送瞬间屏幕渐暗过渡
  anti-fall-ticks: 40          # 落点抗性时长(防加载延迟摔伤)
  deny-vehicles: true           # 骑乘状态禁止传送

pairing:
  session-timeout-seconds: 60 # 待配对会话 TTL
  default-limit: 3            # 无 ddoor.limit.<n> 时的门对上限
  unlink-cooldown-seconds: 10 # 同一门解绑后的再绑定冷却

visual:
  idle-particle: true           # 待机粒子开关
  particle-range: 32           # 粒子渲染半径(格)
  sound-on-teleport: true

worlds:
  mode: blacklist              # blacklist / whitelist 二选一
  list: ["spawn_protected"]    # 世界名列表

economy:
  enabled: false                # 需要 Vault;未安装自动失效
  create-cost: 0.0             # 配对成功收取
  use-cost: 0.0               # 每次穿越收取

storage:
  type: sqlite                 # sqlite / mysql
  mysql: { host: "localhost", port: 3306, database: "ddoor",
          username: "root", password: "" }

hooks:
  worldguard-check: true        # 目标区域含保护/PVP 旗标时拒绝
  placeholderapi: true

PlaceholderAPI 提供四个占位符:%ddoor_uses%(玩家累计穿越次数)、%ddoor_pairs%(持有门对数)、%ddoor_limit%(上限)、%ddoor_total%(全服门对数,管理员向)。

CHAPTER 08

开发计划

单人业余时间开发,按四周四个里程碑推进,每个里程碑结束都产出可跑的版本——M1 结束时核心玩法已可自用测试,不必等全部完成。

M0第 1 周前半

工程骨架与数据层

Maven 工程接入 paper-api 1.21.8,落实现 ddoor_doors 表、SQLite/MySQL 双驱动、内存索引与异步写队列;命令框架与消息系统骨架。

产出:可启动的空插件 + 存储层单元测试通过
M1第 1 周后半 ~ 第 2 周

核心闭环 MVP

门方块识别(含双扇门合并)、钥匙右键配对会话、传送引擎基础版(六环检测链 + 落点安全校验)、同世界与跨世界传送。此时插件已可上测试服体验。

产出:测试服部署,核心玩法全流程可玩
M2第 3 周

体验与防护完整

粒子三态渲染与音效、冷却/世界规则/载具拦截全链路、破坏爆炸活塞联动解绑、钥匙配方注入与数量上限、Vault 经济挂钩。

产出:V1.0 候选版,邀请 5~10 名玩家灰度
M3第 4 周

管理与发布

管理 GUI、命令树补全、PAPI 占位符、中英双语文案、bStats 统计、100 玩家模拟压测(重点验证移动事件节流)、发布文档与更新日志。

产出:V1.0 正式版,可提交 SpigotMC / MC 百科发布
CHAPTER 09

风险与应对

风险概率影响应对
PlayerMoveEvent 高频压力拖累 TPS中高服务器卡顿双重节流闸门设计(见 5.3);M3 压测以 100 玩家为基准线,未达标则追加"每 tick 每 player 一次"的严格缓存
门方块被活塞/爆炸/流体移除的边缘态悬空配对数据物理事件全监听即时解绑;另设每小时全量对账任务兜底清理失配记录
玩家滥用门对穿越 PVP/领地边界玩法公平受损WorldGuard 软依赖检查目标区域旗标 + 世界黑名单双保险;服主反馈案例持续补充默认策略
1.21.x 版本快速迭代导致 API 变动维护成本只用稳定 Bukkit/Paper 公开 API,零 NMS 依赖;跟随 Leaves 版本节奏回归测试
门对数据长期膨胀存储与索引增长权限组上限控增量;提供 30 天未使用门对的归档/清理命令供服主运营
钥匙被复制/伪造刷门对经济失衡钥匙绑定不可复制的数据组件标记,铁砧改名/克隆均无效;上限机制兜底
发布策略建议:V1.0 先在自有服务器(米优服)实跑两周收集真实使用数据,重点观察门对创建速率与穿越频次分布,再决定 V1.1 的方向排序——若跨服需求呼声最高,则优先 Velocity 支持;若沉浸感反馈集中,则优先门内景渲染(让任意门内也能看见对面的伪透视效果)。