ArdaRegions

ArdaRegions

区域管理模组,允许你为自定义多边形命名,并让玩家知道他们正在探索何处。

游戏机制

ArdaRegions

面向 Minecraft 服务器的区域发现与追踪模组。在地图上定义区域,让玩家通过探索来发现它们。

功能简介

区域

通过区域地图面板在游戏内定义多边形区域。每个区域都有 ID、显示名称、可选描述、Y 轴范围、所属世界,以及可选的父/子层级结构。区域可以被标记为可发现或不可发现(默认可发现)。父区域可以包含子区域;模组通过层级链解决嵌套重叠问题。

区域数据存储在世界存档下的 H2 数据库中(world/arda-regions/db/)。管理员可以维护多个区域数据库,并在地图编辑器中切换。

发现

当玩家进入一个尚未发现且可发现的区域时,系统会记录该区域,并向玩家显示一个发现弹窗,包含区域名称和描述。

发现进度按玩家存储在单独的 H2 数据库中(可配置)。HUD 使用来自服务器的游戏/发现区域快照,该快照可能与地图编辑器中当前打开的数据库不同——这样管理员可以编辑一个数据集,而玩家继续使用另一个数据集进行定位和发现。

玩家在游戏中还会在左上角 HUD 看到自己的当前位置(层级链中最深的区域)。

地图面板

使用 /ardaregions panel(管理员)打开交互式区域地图。在面板中你可以:

  • 平移和缩放地图
  • 绘制和编辑区域多边形
  • 创建、更新和删除区域
  • 管理父区域和可发现标志
  • 在以下底图之间切换:
    • BlueMap——从服务器提供的预渲染瓦片
    • 图像图层——来自配置的自定义 PNG 叠加层
    • 无——仅多边形,无底图
  • 切换活动的编辑数据库和世界进行编辑

3D 区域视图(管理员)

管理员可以在世界中可视化区域轮廓:

  • /ardaregions viewcurrent——当前区域
  • /ardaregions view <区域ID>——指定区域
  • /ardaregions viewall——所有区域
  • /ardaregions viewnone——隐藏轮廓

这些命令在连接到服务器时在客户端上运行(它们通过服务器检查 ardaregions.admin 权限)。

环境要求

  • Minecraft 1.20.1
  • Fabric Loader(≥ 0.16.0)
  • Fabric API
  • Fabric Permissions API(随模组捆绑;用于权限检查,回退到 OP 等级 2)

可选组件

  • LuckPerms(或任何实现 Fabric Permissions API 的模组)——推荐用于在不授予 OP 的情况下授予 ardaregions.admin 权限
  • BlueMap——渲染您的世界,然后处理瓦片以供游戏内地图使用(见下文)

设置

1. 在服务器上安装

  1. 将 ArdaRegions 的 jar 文件添加到服务器的 mods/ 目录。
  2. 启动服务器。首次运行时,它会创建:
    • world/arda-regions/db/——H2 数据库(区域、编辑器上下文、发现记录)
    • world/serverconfig/arda-regions/gameplay.json——游戏设置(发现数据库名称)

2. 在客户端安装

  1. 将 ArdaRegions 添加到客户端的 mods/ 目录。
  2. 启动客户端并加入运行该模组的服务器。

区域地图、发现 HUD 和客户端管理命令需要服务器和客户端都安装模组。

3. 地图瓦片和图像叠加层(可选)

BlueMap 底图

  1. 安装并运行 BlueMap,使其渲染您的世界。
  2. 在服务器上运行 /ardaregions processbluemaptiles(管理员)。这会将 BlueMap 的瓦片输出转换为服务器工作目录下 ardaregions/ 中的 ArdaRegions 瓦片。当在地图面板中选择 BlueMap 时,客户端会流式加载这些瓦片。
  3. 您也可以在客户端运行 /ardaregions processbluemaptiles,通过服务器请求处理。

图像叠加图层

在客户端的 config/arda-regions/map-layers.json 中添加一个或多个图层(服务器端配置时可将图层同步到客户端)。旧版 map-overlay.json 仍会被读取并自动迁移。

示例:

{
  "layers": [
    {
      "id": "overview",
      "name": "总览",
      "imagePath": "overview.png",
      "worldSize": 53887,
      "worldX": -19584.0,
      "worldZ": -10240.0,
      "autoCalibrateBounds": false
    }
  ]
}
  • imagePath——相对于 config/arda-regions/ 的 PNG 文件
  • worldSize——图像在世界中的像素对应的方块宽度(X 轴)
  • worldX / worldZ——图像左上角的世界坐标
  • autoCalibrateBounds——如果为 true,则可在有已处理的 BlueMap 瓦片时从其中推导边界

使用 /ardaregions panel 中的地图图层下拉菜单切换底图。

4. 权限

ArdaRegions 通过 Fabric Permissions API 检查权限。如果没有权限模组,则使用 OP 等级 2 作为管理操作的回退权限。

使用 LuckPerms(或类似模组),授予:

权限节点 用途
ardaregions.admin 区域地图面板、3D 视图命令、瓦片处理、重置其他玩家进度、地图内区域编辑

玩家无需管理员权限即可随时对自己运行 /ardaregions resetprogress。

5. 高级:单独的发现数据库

在 world/serverconfig/arda-regions/gameplay.json 中:

{
  "discoveryDatabaseBase": "ardaregions"
}

discoveryDatabaseBase 是 H2 文件的基础名称(位于 world/arda-regions/db/ 下),玩家发现记录存储在其中。这与地图编辑器当前打开的区域数据库无关。请谨慎更改;现有发现记录将保留在旧文件中,直到手动迁移。

命令

运行 /ardaregions 且不带参数可查看命令列表。仅管理员的条目只在有权限时显示。

命令 位置 权限 描述
/ardaregions panel 客户端 管理员 打开交互式区域地图
/ardaregions processbluemaptiles 客户端或服务器 管理员 将 BlueMap 瓦片处理为 ArdaRegions 瓦片
/ardaregions resetprogress 客户端或服务器 — 重置自己的发现记录
/ardaregions resetprogress <玩家> 客户端或服务器 管理员 重置另一玩家的发现记录
/ardaregions view <区域ID> 客户端 管理员 显示单个区域的 3D 轮廓
/ardaregions viewall 客户端 管理员 显示所有区域轮廓
/ardaregions viewnone 客户端 管理员 隐藏区域轮廓
/ardaregions viewcurrent 客户端 管理员 显示当前区域轮廓

在专用服务器上,panel 和 view* 会响应提醒您在客户端使用;resetprogress 和 processbluemaptiles 可在服务器控制台或游戏内使用。

API

ArdaRegions 为其他模组提供了 API:区域查询、玩家探索、地图编辑器上下文,以及 Fabric 事件(发现、增删改、客户端发现弹窗)。

获取 API

入口点(推荐)——在您的 fabric.mod.json 中:

"entrypoints": {
  "arda-regions:api": [
    "your.mod.YourApiEntrypoint"
  ]
}
import mc.ardacraft.ardaregions.api.ArdaRegionsAPI;
import mc.ardacraft.ardaregions.api.ArdaRegionsApiEntrypoint;

public class YourApiEntrypoint implements ArdaRegionsApiEntrypoint {
    @Override
    public void onApiReady(ArdaRegionsAPI api) {
        // 存储 api;使用 getRegionAPI()、getExplorationAPI()、getMapEditorContextAPI()、事件
    }
}

或稍后: ArdaRegionsAPI.getInstance()——如果模组未加载则抛出异常。推荐使用入口点,以便在 API 就绪时立即接收。

区域 API(IRegionAPI)

来自 api.getRegionAPI()。

方法 描述
getRegion(String regionId) 按 ID 获取区域,或返回空
getAllRegions() 获取所有区域
getRegionsByWorld(String worldId) 获取世界中的区域(注册表键,例如 minecraft:overworld)
getChildRegions(String parentId) 获取区域的直接子区域
getParentRegion(String regionId) 获取区域的父区域,或返回空
regionExists(String regionId) 区域是否存在
isPointInRegion(String regionId, double x, double z, int y, String world) 点是否位于区域内

探索 API(IPlayerExplorationAPI)

来自 api.getExplorationAPI()。

方法 描述
getDiscoveredRegions(UUID playerId) 已发现区域的 ID 集合
hasDiscovered(UUID playerId, String regionId) 玩家是否发现了该区域
getDiscoveryCount(UUID playerId) 已发现区域的数量
getDiscoveredRegionsAsObjects(UUID playerId) 已发现区域作为 ApiRegion 对象

数据类型

全部位于 mc.ardacraft.ardaregions.api.data。不可变。

ApiRegion——id、name、parentId、childrenIds、polygons、metadata。
getDescription() 在存在时返回 metadata.get("description") 字符串。
discoverable 存储在元数据中为布尔值(缺失时默认可发现)。

ApiPolygon——vertices(ApiPoint2D 列表)、minY、maxY、world。
isWithinYBounds(int y) 用于 Y 轴检查。

ApiPoint2D——x、z(double)。获取器:getX()、getZ()。

事件

Fabric Event<T>。使用 event.register(callback) 注册。

事件 回调 触发时机
getRegionDiscoveredEvent() (UUID playerId, String regionId) 玩家发现区域(服务器)
getRegionCreatedEvent() (ApiRegion region) 管理员创建区域
getRegionUpdatedEvent() (ApiRegion oldRegion, ApiRegion newRegion) 管理员更新区域
getRegionDeletedEvent() (String regionId) 管理员删除区域
getClientDiscoveryPopupEvent() (String regionId, String regionName, String description, float alpha) 客户端显示发现弹窗(仅客户端)

示例:

api.getRegionDiscoveredEvent().register((playerId, regionId) -> {
    // ...
});

致谢

感谢所有帮助开发此模组的人:

  • Xone——测试、找 Bug、纹理和图形
  • Fornad——测试、找 Bug、首位用户
  • 整个 ArdaCraft 团队——支持本项目
  • Blue(BlueMap)——帮助集成 BlueMap 的图块集