异步多人游戏

通过 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)。

概念

  1. 用户 A 游戏时,SDK 记录关键事件(按键、状态变化)及其时间。
  2. 这些事件作为时间线(事务列表)保存在服务器上。
  3. 用户 B 启动游戏时,已保存的时间线中的对手将加载到他的会话中。
  4. SDK 实时重现对手的动作,营造同时游戏的感觉。

初始化和加载会话

要开始使用异步多人游戏,请调用方法 ysdk.multiplayer.sessions.init()。该方法进行初始初始化和加载对手的游戏会话。

该方法返回已加载会话的数组。

接受以下参数:

参数

类型

描述

count

number

确定要加载的会话数量。响应中的最大会话数为 10 个。

isEventBased

boolean

通过事件初始化工作的标志。

maxOpponentTurnTime

number

限制对手回合时间,并以毫秒为单位设置 multiplayer-sessions-transaction 事件发送之间的最大间隔。如果指定了该参数,则每个持续时间超过 maxOpponentTurnTime 的对手回合将被缩短到指定值。默认情况下,对手的回合时间是无限制的。

maxOpponentTurnTime 工作示例

在已记录的会话中,对手以 2–10 秒的间隔进行操作,maxOpponentTurnTime 参数值为 5000 毫秒。在这种情况下,无论该对手的回合原始持续时间如何,所有操作都将在不晚于 5 秒内发生。

meta

object

用于筛选的自定义参数 meta1、meta2、meta3。它们的形式为对象 { min: %number%, max: %number% },并在保存会话时设置。例如,如果 meta1 中存储了游戏分数,meta2 中存储了玩家等级,您可以加载这些参数接近于当前用户的已保存会话。

重要

加载会话时,必须至少设置三个 meta 参数中的一个,并且 count 参数的值要大于零。否则,多人游戏将仅初始化为记录。

 1ysdk.multiplayer.sessions.init({
 2    count: 2, // 要加载的对手会话数量(最多为10)。
 3    isEventBased: true, // 通过事件初始化工作的标志。
 4    maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
 5    meta: {
 6        meta1: {
 7            min: 0,
 8            max: 6000
 9        },
10        meta2: {
11            min: 2,
12            max: 10
13        }
14    }
15}).then((opponents) => console.log(opponents));
 1const work = async () => {
 2    const opponents = await ysdk.multiplayer.sessions.init({
 3        count: 2, // 要加载的对手会话数量(最多为10)。
 4        isEventBased: true, // 通过事件初始化工作的标志。
 5        maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
 6        meta: {
 7            meta1: {
 8                min: 0,
 9                max: 6000
10            },
11            meta2: {
12                min: 2,
13                max: 10
14            }
15        }
16    });
17
18    console.log(opponents);
19};
20
21work();

回答格式

 1[
 2    {
 3        id: string;
 4        meta: {
 5            meta1: number;
 6            meta2: number;
 7            meta3: number;
 8        };
 9        player: {
10            avatar: string;
11            name: string;
12        };
13        timeline: [
14            {
15                id: string;
16                payload: object | string | undefined;
17                time: number;
18            },
19            ...
20        ];
21    },
22    ...
23]

参数

类型

描述

id

string

会话标识符。

meta

object

自定义参数 meta1、meta2、meta3。例如,游戏中的分数或玩家等级。

player

object

对手玩家信息:

  • avatar: string —— 用户头像的URL;
  • name: string —— 玩家的姓名。

timeline

array

描述游戏会话的事件时间线数组:

  • id: string —— 事件的唯一标识;
  • payload —— 事件数据:反映游戏世界中变化原因的信息(例如,角色的新坐标或鼠标点击);
  • time: number —— 游戏开始后的时间,考虑暂停(毫秒)。

游戏会话记录

注意

最大的单个会话记录大小为200 KB。

使用 SDK 记录用户的游戏会话(带有时间戳的事件序列)。事件可以是拼图游戏中棋子在棋盘上的移动,也可以是跑酷游戏中键盘或鼠标按键的动作。

在用户输入连续的游戏中,例如跑酷游戏,可以在特定时间间隔内人工生成事件,记录角色状态的指标——坐标、能量水平等。这也可以是游戏中的随机事件——奖励、地震。

游戏中发生的事件作为事务保存。每个事务都有:

参数

类型

描述

id

number

事件的唯一标识符。

payload

object

事件数据:反映游戏世界本质变化原因的信息(例如角色的新坐标或鼠标按键动作)。包含键值对的对象。

time

number

游戏开始的时间,包含暂停的修正。

在游戏过程中,通过方法 commit() 保存 payload。这样会形成一个事务列表——游戏会话的时间线 (timeline)。

在游戏结束时,通过方法 push() 将会话保存到服务器。保存后,会话可以在下一个游戏中加载并回放。

ysdk.multiplayer.sessions.commit()

方法 commit() 固定当前游戏会话的事务。事件数据(payload)传递给它。

重要

交易的其他参数——标识符 (id) 和游戏开始时间 (time)——是在 SDK 中计算的,因此及时发送 payload 非常重要。

示例

1// 第一次交易。
2ysdk.multiplayer.sessions.commit({ x: 1, y: 2, z: 3, health: 67 });
3
4// .......
5
6// 下一次交易。
7ysdk.multiplayer.sessions.commit({ x: 4, y: -2, z: 19, health: 15 });
8
9// .......

ysdk.multiplayer.sessions.push()

方法 push() 用于将时间线保存到远程服务器。游戏结束时调用。

保存会话时设置 meta1、meta2、meta3 的值。至少必须定义一个 meta 参数。

示例

ysdk.multiplayer.sessions.push({ meta1: 12, meta2: -2 });

使用会话

要选择如何处理加载的对手会话,请在方法 init() 中传递所需的 isEventBased 标志值:

值

描述

isEventBased: true

通过事件处理。

isEventBased: false

自行处理。

客户端通过 ysdk.on() 订阅事件 multiplayer-sessions-transaction 和 multiplayer-sessions-finish,而 SDK 自行加载共有会话并根据其中指定的时间戳发出事件:

  • 在游戏过程中,对手的交易会在从会话开始记录时间的时刻到达 multiplayer-sessions-transaction 处理器,但会考虑对手回合时间限制(maxOpponentTurnTime,方法 init() 的参数)。

  • 当会话结束时,将调用 multiplayer-sessions-finish 处理器,并提供游戏结束的对手的标识符。

 1ysdk.multiplayer.sessions.init({
 2    count: 2, // 要加载的对手会话数量(最多为10)。
 3    isEventBased: true, // 通过事件初始化工作的标志。
 4    maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
 5    meta: {
 6        meta1: {
 7            min: 0,
 8            max: 6000
 9        },
10        meta2: {
11            min: 2,
12            max: 10
13        }
14    }
15});
16
17// 在此处我们接收当前需要执行的事务数组:
18// 当前事务以及由于游戏可能出现卡顿而延迟的事务。
19ysdk.on('multiplayer-sessions-transaction', ({ opponentId, transactions }) => {
20    console.log(opponentId, transactions);
21    // 在游戏场景中应用 transaction.payload 的数据。
22});
23
24ysdk.on('multiplayer-sessions-finish', (opponentId) => console.log(opponentId));

多人游戏的启动和暂停由游戏玩法标记方法控制:

1// 启动多人模式。
2ysdk.features.GameplayAPI.start();
3
4// 暂停多人模式。
5ysdk.features.GameplayAPI.stop();

多人游戏初始化方法 init() 返回加载的对手会话数组,包含带有事务的时间线。

自行获取和处理数据:

 1const start = (opponent) => {
 2    console.log('player', opponent.player);
 3    console.log('timeline', opponent.timeline);
 4
 5    // 实现使用时间轴和播放器数据的机制。
 6};
 7
 8const work = async () => {
 9    const opponents = await ysdk.multiplayer.sessions.init({
10        count: 2, // 要加载的对手会话数量(最多为10)。
11        isEventBased: false, // 通过事件初始化工作的标志。
12        maxOpponentTurnTime: 200, // 限制对手的回合时间(毫秒)。
13        meta: {
14            meta1: {
15                min: 0,
16                max: 6000
17            },
18            meta2: {
19                min: 2,
20                max: 10
21            }
22        }
23    });
24
25    console.log('opponents', opponents);
26
27    for (let i = 0; i < opponents.length; i++) {
28        start(opponents[i]);
29    }
30};
31
32work();

备注

技术支持团队将协助您将已完成的游戏发布到 Yandex 游戏平台。关于开发和测试方面的具体问题,其他开发人员将在Discord 频道中进行回答。

如果您遇到 Yandex Games SDK 方面的问题或有其他问题想要咨询,请联系支持部门:

写入聊天信息

会话标识符。

自定义参数 meta1、meta2、meta3,它们在保存会话时设置。例如,游戏分数或玩家等级。

对手玩家的信息:

  • avatar: string —— 用户头像的URL;
  • name: string —— 玩家姓名。

描述游戏会话的事件时间轴数组:

  • id: string —— 事件的唯一标识符;
  • payload —— 事件数据:反映游戏世界变化本质、原因的信息(例如,角色的新坐标或鼠标点击);
  • time: number —— 从游戏开始到事件发生的时间(毫秒),考虑了暂停的影响。

事件的唯一标识符。

事件数据:反映游戏世界变化本质、原因的信息(例如,角色的新坐标或鼠标点击)。

从游戏开始到事件发生的时间,考虑了暂停的影响。

上一篇
下一篇