Colyseus Metadata 详解
Colyseus 是一个专注于实时多人在线游戏和应用的框架,它的 metadata 功能为每个房间提供了一个灵活且有用的机制,用来存储和共享与房间相关的非实时信息。这些信息可以用来描述房间、标记房间状态、或提供额外的房间配置选项。
什么是 metadata?
- metadata 是一个自定义的键值对数据结构,通常以 JSON 对象的形式存储。
- 它与房间的核心状态(
state
)分开,用于存储非实时的、描述性的房间信息。 - metadata 的主要作用是帮助服务器端和客户端对房间进行筛选、分类和描述。
metadata 的典型用途
-
房间描述
- 存储房间的名称、类型、或分类。
- 例如,房间的游戏模式(如“团队模式”或“自由模式”)、地图信息或其他描述性内容。
-
房间过滤
- 结合 Colyseus 的 matchmaking 功能,可以使用 metadata 定义筛选条件。
- 例如:找到所有支持“4人组队”的房间。
-
玩家信息
- 存储房间当前玩家的数量、最大玩家限制,甚至可以包含玩家等级范围等信息。
-
游戏配置
- 存储与游戏逻辑相关的初始化参数,例如游戏时间限制、难度级别等。
-
动态状态标识
- 指示房间是否开放加入或是否正在游戏中。
- 例如,通过
isActive: true
表明房间正在等待玩家加入。
如何在 Colyseus 中使用 metadata
1. 在房间定义中设置 metadata
import { Room } from "colyseus";
export class MyRoom extends Room {
onCreate(options: any) {
// 设置房间的 metadata
this.setMetadata({
roomName: "My Cool Room",
gameMode: "deathmatch",
maxPlayers: 10,
});
}
}
2. 在运行时更新 metadata
Colyseus 提供了 setMetadata
和 patchMetadata
方法,可以动态更新房间的 metadata。
this.setMetadata({
roomName: "Updated Room Name",
gameMode: "capture the flag",
});
或者更新部分字段:
this.patchMetadata({
gameMode: "team battle",
});
3. 在客户端读取 metadata
当客户端通过 Colyseus 的 matchmaking 查找房间时,可以获取房间的 metadata。例如:
const rooms = await client.getAvailableRooms("my_room_type");
rooms.forEach((room) => {
console.log("Room ID:", room.roomId);
console.log("Metadata:", room.metadata);
});
4. 使用 metadata 筛选房间
可以通过 matchMaker
在服务器端根据 metadata 筛选房间:
matchMaker.query({
gameMode: "deathmatch",
maxPlayers: { $gte: 5 },
});
metadata 与 state 的区别
特性 | metadata | state |
---|---|---|
用途 | 描述性、静态数据 | 游戏状态、动态数据 |
更新频率 | 较低,适合偶尔更新 | 实时更新 |
存储位置 | 房间实例 | 房间的同步状态 |
使用场景 | 房间筛选、描述信息 | 玩家位置、分数等实时信息 |
同步到客户端 | 通过房间列表返回,不自动推送 | 自动同步到客户端 |
注意事项
-
大小限制
- metadata 通常存储于服务器的内存中,不适合存储大量数据。
- 如果 metadata 太大,可能会影响房间查询性能。
-
非实时性
- metadata 不会像 state 那样实时同步。更新后的 metadata 需要客户端通过新的房间查询获取。
-
与 matchMaker 结合使用
- 使用 metadata 和 matchMaker 筛选房间时,请确保查询字段和 metadata 字段一致。
示例:metadata 在多人游戏中的应用
假设你正在开发一款多人射击游戏,以下是可能的 metadata 设置:
this.setMetadata({
roomName: "Team Deathmatch Room",
gameMode: "team deathmatch",
map: "desert",
maxPlayers: 10,
currentPlayers: 4,
isActive: true, // 是否开放加入
});
客户端可以使用 metadata 筛选条件:
const rooms = await client.getAvailableRooms("game_room", {
gameMode: "team deathmatch",
map: "desert",
isActive: true,
});
通过 metadata,开发者可以轻松实现房间的分类和筛选,同时减少对实时状态的依赖,使得房间管理更加高效灵活。