宝箱出现在哪里
这一页讲 location.yml。它是整个插件最容易配错的地方,也是"命令能打开但世界里看不到"问题的根源。
先理解文件结构
location.yml 分成两大块:
location: # 第一块:定义位置
...
generator: # 第二块:定义规则
normal: # 固定刷新
...
random: # 随机刷新
...
两块的分工:
location只回答"有哪些位置可以用",它不决定任何宝箱generator回答"哪个宝箱用哪些位置、多久刷一次"
只写 location 不写 generator,宝箱不会出现。
固定刷新
定义位置
location:
spawn_area:
- 'world, 100, 65, 200, north'
- 'world, 105, 65, 210, south'
nether_area:
- 'world_nether, 50, 40, 50, east'
这里定义了两个坐标组:spawn_area 有 2 个位置,nether_area 有 1 个位置。
每一行的格式是固定的五段:
'世界名, X, Y, Z, 朝向'
| 段 | 说明 |
|---|---|
| 世界名 | 世界文件夹的名字,不能空 |
| X / Y / Z | 必须是整数,不能带小数点 |
| 朝向 | 只能是 north south east west random |
必须写满五段。下面这些写法都是错的:
# 错:少了朝向
- 'world, 100, 65, 200'
# 错:坐标带小数
- 'world, 100.5, 65, 200, north'
# 错:朝向不在允许的取值里
- 'world, 100, 65, 200, up'
# 错:世界名空着
- ', 100, 65, 200, north'
写错的行会被跳过,控制台输出 无法解析坐标 location.<组名>[<序号>]='...',这个位置就不会有宝箱。序号从 0 开始,所以 [1] 指的是这个组的第二行。
固定坐标里写 random,插件在读取配置的那一刻随机一次,然后一直用这个结果。不是每次刷新都重新随机。
想换一个朝向的话执行 /tsl reload,会重新随机。
绑定宝箱
generator:
normal:
period: 1800000
treasure:
def:
spawn_area: "true"
nether_area: "check player level > 10"
读法:宝箱 def 会在 spawn_area 出现(无条件),也会在 nether_area 出现(但只有等级大于 10 的玩家能看到)。
三个名字必须对得上:
def↔treasures/def.yml的文件名spawn_area、nether_area↔location里定义的组名
对不上的话控制台会提示 宝箱 def 引用了不存在的坐标组 xxx。
条件写法
条件用的是 Kether 脚本。最常用的几种:
treasure:
normal_chest:
# 所有人都能看到
spawn_area: "true"
elite_chest:
# 等级大于 10
spawn_area: "check player level > 10"
vip_chest:
# 有指定权限
spawn_area: "check player perm vip.chest"
写 "true" 时插件会跳过脚本执行直接通过,所以不用担心性能。
条件脚本执行失败时,这个坐标组按不通过处理(也就是不显示)。开 /tsl debug 能看到每个条件的判定结果。
刷新周期
generator:
normal:
# 全局周期:30 分钟
period: 1800000
# 某些组用自己的周期
cooldown:
spawn_area: 300000 # 5 分钟
nether_area: 3600000 # 1 小时
单位是毫秒。换算表:
| 想要的间隔 | 填 |
|---|---|
| 1 分钟 | 60000 |
| 5 分钟 | 300000 |
| 30 分钟 | 1800000 |
| 1 小时 | 3600000 |
| 6 小时 | 21600000 |
| 24 小时 | 86400000 |
cooldown 里配了的组用自己的值,没配的用 period。
填 0 或负数表示关闭这个全局周期任务,控制台会输出 周期任务 normal-refresh 已禁用。
此时只有配了 cooldown 的坐标组还会自动刷新,其他组要等玩家重新进服或者手动 /tsl reload。这是一个有效用法,如果你想让每个组完全独立控制,就这么配。
公共宝箱
默认情况下每个玩家能各开一次同一个位置的宝箱。想改成"先到先得":
generator:
normal:
public:
def:
- spawn_area
意思是:宝箱 def 在 spawn_area 这些位置上是公共的。谁先开了,这个位置对所有玩家消失,等下次刷新才回来。
public 里引用了不存在或者空的坐标组,控制台会输出 公共宝箱 def 引用了不存在或为空的坐标组 xxx。
随机刷新
随机刷新是给野外探索用的:你划一个范围,插件在里面随机挑位置。每个玩家挑到的位置是独立的。
基本写法
generator:
random:
period: 1800000
treasure:
- location: "world: 50,100 ~ -50,-100: ground#255: random"
max: 5
chest: def
注意这里是列表(每条前面有 -),和固定刷新的写法完全不同。
location 怎么读
world: 50,100 ~ -50,-100: ground#255: random
↑ ↑ ↑ ↑
世界名 矩形区域 高度规则 朝向
用冒号分成四段:
| 段 | 说明 |
|---|---|
| 世界名 | 在哪个世界随机 |
X1,Z1 ~ X2,Z2 | 矩形范围的两个对角,只要 X 和 Z,不要 Y |
| 高度规则 | 怎么决定 Y 坐标,见下面 |
| 朝向 | north south east west random |
上面这个例子表示:在 world 世界里,X 从 -50 到 50、Z 从 -100 到 100 的这块区域内随机。
写 50,100 ~ -50,-100 和写 -50,-100 ~ 50,100 完全一样,插件会自己算出最小值和最大值。
高度规则:ground
ground#255
从 Y=255 开始往下扫,找到第一个不是空气的方块,把宝箱放在它上面一格。
适合地表寻宝。宝箱会自然地落在地面、山坡、屋顶上。
高度规则:range
range#0~40
在 Y=0 到 40 之间随便挑一个高度。不管那个位置是石头还是空气。
加上材质过滤会更实用:
range#0~40#air,stone,water
只有当那个位置的方块是空气、石头或水时才接受这个坐标。适合在山体内部或者矿洞里生成。
range#0~40 不检查目标位置有什么,宝箱可能出现在实心岩石中间,玩家根本走不过去。
要么加材质过滤只接受 air,要么用 ground 规则。
其他参数
- location: "world: 50,100 ~ -50,-100: ground#255: random"
max: 5
chest: def
if: "check player level > 5"
| 参数 | 说明 |
|---|---|
max | 这条规则想生成几个,支持 3~5 范围写法 |
chest | 宝箱 ID,也就是文件名 |
if | 可选条件,只有满足的玩家才生成。默认 "true" |
if 在默认配置里没有,需要自己加。
多条规则会合并
treasure:
- location: "world: 50,100 ~ -50,-100: ground#255: random"
max: 5
chest: def
- location: "world: 50,100 ~ -50,-100: range#0~40#air: random"
max: 4
chest: def
同一个 chest 写多条规则时,结果是加起来的,不是覆盖。上面这样配,def 最多能拿到 5 + 4 = 9 个位置。
所有规则之间会按坐标去重,同一个位置不会被算两次。
随机数量不够怎么办
控制台可能出现这样的告警:
[Treasure] 随机宝箱 def 的规则生成数量不足: 请求=5, 生成=2, 尝试=250/250,
原因=候选坐标重复、材质不匹配、区块未加载或地形不可用,
重复=0, 未加载区块=248, 越界=0, 材质不匹配=0, 未找到支撑=0, 检查失败=0
后面那串统计能直接告诉你原因:
| 统计项 | 含义 | 怎么解决 |
|---|---|---|
| 未加载区块 | 那块地方没有玩家,区块没加载 | 把范围缩小到玩家活动区域附近 |
| 材质不匹配 | range 的材质过滤没命中 | 放宽材质列表,或者改用 ground |
| 越界 | 高度超出世界上下限 | 检查 range 的高度范围 |
| 未找到支撑 | ground 往下扫没找到方块 | 该区域可能是虚空,换地方 |
| 重复 | 随机到了已经用过的坐标 | 范围太小,扩大区域 |
未加载区块 是最常见的。随机生成需要读取方块信息,没加载的区块读不到,只能跳过。
玩家进服时会建立一次随机缓存,之后按 generator.random.period 整批重新抽。
重新抽的时候,还没被领取的旧位置也会一起换掉:插件先把旧位置恢复成真实方块,再显示新位置。
三种来源的优先级
同一个玩家的宝箱可能来自三个地方,如果它们撞到同一个坐标,按这个优先级只保留一个:
| 优先级 | 来源 | 从哪来 |
|---|---|---|
| 最高 | 临时 | Kether 动作 tsl-put 放的 |
| 中 | 固定 | generator.normal |
| 最低 | 随机 | generator.random |
判断"撞到同一个坐标"只看世界和 XYZ,不看朝向。
显示距离和刷新时机
配好位置之后,玩家还要满足两个条件才能看到宝箱:
- 在同一个世界
- 距离在
config.yml的view.distance之内(默认 16 格)
显示会在这些时候更新:
| 时机 | 延迟 | 行为 |
|---|---|---|
| 进服 | 约 3 秒 | 全部重发 |
| 传送 | 1 tick | 全部重发 |
| 切换世界 | 1 tick | 全部重发 |
定时(view.refresh,默认 30 秒) | — | 只补发有变化的 |
/tsl update | 立即 | 全部重发 |
玩家进服时插件要先算出这个玩家能看到哪些位置,这个过程需要一点时间。算完之前不会显示,算完之后会自动补上。
如果等了几秒还是没有,用 /tsl update 强制刷一次;还是不行就去看 排查手册。
一份带注释的完整示例
# ========== 定义位置 ==========
location:
# 出生点附近的 3 个位置
spawn_area:
- 'world, 100, 65, 200, north'
- 'world, 110, 65, 200, south'
- 'world, 120, 65, 200, random'
# 下界的 1 个位置
nether_area:
- 'world_nether, 50, 40, 50, east'
# ========== 定义规则 ==========
generator:
normal:
# 默认 30 分钟刷新
period: 1800000
# 出生点的宝箱 5 分钟就刷
cooldown:
spawn_area: 300000
# 出生点的宝箱先到先得
public:
daily:
- spawn_area
# 绑定关系
treasure:
# daily 宝箱放在出生点,所有人可见
daily:
spawn_area: "true"
# elite 宝箱放在下界,需要 20 级
elite:
nether_area: "check player level > 20"
random:
# 1 小时重新抽一次随机点
period: 3600000
treasure:
# 在主世界地表随机 5 个 daily 宝箱
- location: "world: 200,200 ~ -200,-200: ground#128: random"
max: 5
chest: daily
这份配置假设你有 treasures/daily.yml 和 treasures/elite.yml 两个文件。