异步多人游戏
通过 ysdk.multiplayer
模块,您可以创建类似在线多人游戏的竞技模式。这样您无需:
- 编写和维护自己的服务器解决方案;
- 拥有快速寻找对手所需的临界玩家数量。
可以通过 SDK 实现核心机制的游戏类型示例:
- 益智游戏: 异步会话可以在相邻的游戏板上播放,可以增加按时间或分数的竞争。适合的游戏示例:空当接龙在线! (来自 KosmosGames),Match Arena - 消消乐! (来自 PecPoc Piggy)。
- 跑酷和赛车游戏: 对手的会话可以显示为“阴影”,与玩家一起在关卡中移动 (鬼魂驾驶机制)。适合的游戏示例:疯狂赛车 2 (来自 JL studio) 中的“极速竞赛”模式,疯狂摩托 (来自 haoda games)。
- 策略和自动战斗游戏: 可以实现与其他玩家战术对抗的战斗。适合的游戏示例:Ludus (来自 Positron Dynamics),Like a King (来自 Vladimir Saponenko),TOYS: Crash Arena (来自 Mad Pixel)。
概念
- 用户 A 游戏时,SDK 记录关键事件(按键、状态变化)及其时间。
- 这些事件作为时间线(事务列表)保存在服务器上。
- 用户 B 启动游戏时,已保存的时间线中的对手将加载到他的会话中。
- SDK 实时重现对手的动作,营造同时游戏的感觉。
初始化和加载会话
要开始使用异步多人游戏,请调用方法 ysdk.multiplayer.sessions.init()
。该方法进行初始初始化和加载对手的游戏会话。
该方法返回已加载会话的数组。
参数 count
确定要加载的会话数量。响应中的最大会话数为 10 个。
用于筛选的参数有 meta1
、meta2
、meta3
。它们的形式为对象 { min: %number%, max: %number% }
,并在保存会话时设置。例如,如果 meta1
中存储了游戏分数,meta2
中存储了玩家等级,您可以加载这些参数接近于当前用户的已保存会话。
重要
加载会话时,必须至少设置三个 meta
参数中的一个,并且 count
参数的值要大于零。否则,多人游戏将仅初始化为记录。
ysdk.multiplayer.sessions.init({
count: 2, // 要加载的对手会话数量(最多为10)。
isEventBased: true, // 通过事件初始化工作的标志。
maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
}).then(opponents => console.log(opponents));
const work = async () => {
const opponents = await ysdk.multiplayer.sessions.init({
count: 2, // 要加载的对手会话数量(最多为10)。
isEventBased: true, // 通过事件初始化工作的标志。
maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
console.log(opponents);
}
work();
回答格式
[
{
id: string;
meta: {
meta1: number;
meta2: number;
meta3: number;
};
player: {
avatar: string;
name: string;
};
timeline: [
{
id: string;
payload: object | string | undefined;
time: number;
},
...
];
},
...
]
参数 |
类型 |
描述 |
|
string |
会话标识符。 |
|
object |
自定义参数 |
|
object |
对手玩家信息:
|
|
array |
描述游戏会话的事件时间线数组:
|
游戏会话记录
注意
最大的单个会话记录大小为200 KB。
使用 SDK 记录用户的游戏会话(带有时间戳的事件序列)。事件可以是拼图游戏中棋子在棋盘上的移动,也可以是跑酷游戏中键盘或鼠标按键的动作。
在用户输入连续的游戏中,例如跑酷游戏,可以在特定时间间隔内人工生成事件,记录角色状态的指标——坐标、能量水平等。这也可以是游戏中的随机事件——奖励、地震。
游戏中发生的事件作为事务保存。每个事务都有:
id
—— 事件的唯一标识符;payload
—— 事件数据:反映游戏世界本质变化原因的信息(例如角色的新坐标或鼠标按键动作);time
—— 游戏开始的时间,包含暂停的修正。
在游戏过程中,通过方法 commit() 保存 payload
。这样会形成一个事务列表——游戏会话的时间线 (timeline
)。
在游戏结束时,通过方法 push() 将会话保存到服务器。保存后,会话可以在下一个游戏中加载并回放。
ysdk.multiplayer.sessions.commit()
方法 commit()
固定当前游戏会话的事务。事件数据(payload)传递给它。
重要
交易的其他参数——标识符 (id
) 和游戏开始时间 (time
)——是在 SDK 中计算的,因此及时发送 payload
非常重要。
使用示例
// 第一次交易。
ysdk.multiplayer.sessions.commit({ x: 1, y: 2, z: 3, health: 67 });
// .......
// 下一次交易。
ysdk.multiplayer.sessions.commit({ x: 4, y: -2, z: 19, health: 15 });
// .......
ysdk.multiplayer.sessions.push()
方法 push()
用于将时间线保存到远程服务器。游戏结束时调用。
保存会话时设置 meta1
、meta2
、meta3
的值。至少必须定义一个 meta 参数。
使用示例
ysdk.multiplayer.sessions.push({ meta1: 12, meta2: -2 });
使用会话
要选择如何处理加载的对手会话,请在方法 init() 中传递所需的 isEventBased
标志值:
true
—— 通过事件处理;false
—— 自行处理。
客户端通过 ysdk.on()
订阅事件 multiplayer-sessions-transaction
和 multiplayer-sessions-finish
,而 SDK 自行加载共有会话并根据其中指定的时间戳发出事件:
-
在游戏过程中,对手的交易会在从会话开始记录时间的时刻到达
multiplayer-sessions-transaction
处理器,但会考虑对手回合时间限制(maxOpponentTurnTime
,方法 init() 的参数)。 -
当会话结束时,将调用
multiplayer-sessions-finish
处理器,并提供游戏结束的对手的标识符。
ysdk.multiplayer.sessions.init({
count: 2, // 要加载的对手会话数量(最多为10)。
isEventBased: true, // 通过事件初始化工作的标志。
maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
// 在此处我们接收当前需要执行的事务数组:
// 当前事务以及由于游戏可能出现卡顿而延迟的事务。
ysdk.on('multiplayer-sessions-transaction', ({ opponentId, transactions }) = > {
console.log(opponentId, transactions);
// 在游戏场景中应用 transaction.payload 的数据。
});
ysdk.on('multiplayer-sessions-finish', (opponentId) => console.log(opponentId));
多人游戏的启动和暂停由游戏玩法标记方法控制:
// 启动多人模式。
ysdk.features.GameplayAPI.start();
// 暂停多人模式。
ysdk.features.GameplayAPI.stop();
多人游戏初始化方法 init() 返回加载的对手会话数组,包含带有事务的时间线。
自行获取和处理数据:
const start = (opponent) => {
console.log('player', opponent.player);
console.log('timeline', opponent.timeline);
// 实现使用时间轴和播放器数据的机制。
}
const work = async () => {
const opponents = await ysdk.multiplayer.sessions.init({
count: 2, // 要加载的对手会话数量(最多为10)。
isEventBased: false, // 通过事件初始化工作的标志。
maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
console.log('opponents', opponents);
for (let i = 0; i < opponents.length; i++) {
start(opponents[i]);
}
}
work();
备注
技术支持团队将协助您将已完成的游戏发布到 Yandex 游戏平台。关于开发和测试方面的具体问题,其他开发人员将在Discord 频道中进行回答。
如果您遇到 Yandex Games SDK 方面的问题或有其他问题想要咨询,请联系支持部门:
会话标识符。
自定义参数 meta1
、meta2
、meta3
,它们在保存会话时设置。例如,游戏分数或玩家等级。
对手玩家的信息:
avatar: string
— 用户头像的URL;name: string
— 玩家姓名。
描述游戏会话的事件时间轴数组:
id: string
— 事件的唯一标识符;payload
— 事件数据:反映游戏世界变化本质、原因的信息(例如,角色的新坐标或鼠标点击);time: number
— 从游戏开始到事件发生的时间(毫秒),考虑了暂停的影响。
事件的唯一标识符。
事件数据:反映游戏世界变化本质、原因的信息(例如,角色的新坐标或鼠标点击)。
从游戏开始到事件发生的时间,考虑了暂停的影响。