비동기 멀티플레이어
ysdk.multiplayer
모듈을 사용하면 온라인 멀티플레이어와 유사한 경쟁 모드를 만들 수 있습니다. 이 모드를 사용하면 다음을 할 필요가 없습니다:
- 자체 서버 솔루션을 작성하고 유지 관리하지 않아도 됩니다.
- 상대방을 빠르게 찾기 위한 임계 플레이어 수를 확보할 필요가 없습니다.
SDK를 통해 실현할 수 있는 장르의 코어 메카닉 예시:
- 퍼즐: 비동기 세션은 인접한 게임 필드에서 재생되며, 시간이나 점수를 기반으로 한 경쟁을 추가할 수 있습니다. 적합한 게임의 예시: Klondike 온라인! (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
파라미터의 값을 0보다 큰 값으로 설정해야 합니다. 그렇지 않으면 멀티플레이어는 기록 전용으로 초기화됩니다.
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 КБ입니다.
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
값은 세션을 저장할 때 설정됩니다. 적어도 하나의 메타 매개변수가 정의되어야 합니다.
사용 예시
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);
// 현재 트랜잭션 및 게임 프리즈로 인해 지연된 트랜잭션도 포함됩니다.
});
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 Games에 게시하는 데 도움을 드릴 수 있습니다. 개발이나 테스트에 대해 궁금한 점이 있다면, Discord 채널에서 질문해 주세요.
지원 서비스는 얀덱스 게임에서 완성 된 게임을 게시 할 수 있습니다. 개발 또는 테스트에 대한 질문이 있는 경우
Yandex Games SDK 사용과 관련하여 문제가 발생하거나 질문이 있는 경우 다음 방법으로 지원팀에 문의하세요.
세션 식별자.
세션을 저장할 때 설정된 사용자 정의 매개변수 meta1
, meta2
, meta3
. 예를 들어, 게임 점수나 플레이어의 레벨.
상대 플레이어에 대한 정보:
avatar: string
— 사용자 아바타의 URL;name: string
— 플레이어 이름.
게임 세션을 설명하는 타이밍을 포함한 이벤트 배열:
id: string
— 이벤트의 고유 식별자;payload
— 이벤트 데이터: 게임 세계의 본질을 반영하고 변화의 이유를 나타내는 정보 (예: 캐릭터의 새로운 좌표나 마우스 버튼 클릭);time: number
— 일시 정지를 고려한 게임 시작 후 시간 (밀리초).
이벤트의 고유 식별자.
이벤트 데이터: 게임 세계의 본질을 반영하고 변화의 이유를 나타내는 정보 (예: 캐릭터의 새로운 좌표나 마우스 버튼 클릭).
일시 정지를 고려한 게임 시작 후 시간.