비동기 멀티플레이어

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).

개념

  1. 사용자 A가 게임을 하고, SDK는 주요 이벤트(키 입력, 상태 변화)를 기록하고 그 시간을 고정합니다.
  2. 이러한 이벤트는 서버에 타임라인(트랜잭션 목록)으로 저장됩니다.
  3. 사용자 B가 게임을 시작하면, 그의 세션에는 이미 저장된 타임라인에서 상대방들이 로드됩니다.
  4. 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;
      },
      ...
    ];
  },
  ...
]

매개변수

유형

설명

id

string

세션 식별자.

meta

object

사용자 지정 매개변수 meta1, meta2, meta3. 예: 게임 점수 또는 플레이어 레벨.

player

object

상대방 플레이어 정보:

  • avatar: string — 사용자 아바타의 URL;
  • name: string — 플레이어 이름.

timeline

array

게임 세션을 설명하는 타이밍이 있는 이벤트 배열:

  • id: string — 이벤트의 고유 식별자;
  • payload — 이벤트 데이터: 게임 세계의 본질, 변경 이유를 반영하는 정보(예: 캐릭터의 새 좌표 또는 마우스 버튼 클릭);
  • time: number — 게임 시작 후 일시정지 조정을 고려한 시간(밀리초).

게임 세션 기록

제한

한 세션에서 기록 가능한 최대 크기는 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-transactionmultiplayer-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 — 일시 정지를 고려한 게임 시작 후 시간 (밀리초).

이벤트의 고유 식별자.

이벤트 데이터: 게임 세계의 본질을 반영하고 변화의 이유를 나타내는 정보 (예: 캐릭터의 새로운 좌표나 마우스 버튼 클릭).

일시 정지를 고려한 게임 시작 후 시간.