# PlayDrop의 게임 수명 주기: 로딩, 준비, 일시 정지, 오디오

PlayDrop SDK를 초기화하고, 첫 플레이 가능 프레임에서 준비를 알리고, 깔끔하게 일시 정지·재개하고, 호스트 오디오 정책을 따르고, 네이티브·오프라인 플레이용 파일을 미리 로드하세요.

Source: https://www.playdrop.ai/ko/create/learn/lifecycle

PlayDrop은 게임 주위에 자체 로딩 화면, 일시 정지 메뉴, 음소거 컨트롤 등 여러 창을 띄웁니다. 수명 주기 API는 게임이 이 창들과 보조를 맞추게 합니다. PlayDrop이 게임을 일시 정지하는 동안에는 멈추고, PlayDrop의 오디오 정책이 허용할 때만 소리를 냅니다.

## 초기화한 다음 준비 알리기

SDK를 로드하고, 초기 상태를 읽고, 변경 사항을 구독하고, 첫 화면을 준비한 다음에야 `ready()`를 호출하세요. 그때까지 PlayDrop은 로딩 화면을 계속 보여 줍니다.

```html
<script src="https://assets.playdrop.ai/sdk/playdrop.js"></script>
<script type="module">
  const sdk = await playdrop.init();
  let paused = sdk.host.isPaused;
  setAudio(sdk.host.audioAllowed);
  sdk.host.onAudioAllowedChange(setAudio);
  sdk.host.onPause(() => { paused = true; });
  sdk.host.onResume(() => { paused = false; last = performance.now(); });

  try {
    await loadFirstLevel();
  } catch (error) {
    sdk.host.error("Could not load the first level");
    throw error;
  }
  drawFirstFrame();
  sdk.host.ready();
</script>
```

에셋을 로드하기 전이 아니라, 설계한 첫 화면이 보이고 입력이 작동할 때 `ready()`를 호출하세요. `sdk.host.error(message)`는 게임을 시작할 수 없다고 PlayDrop에 알립니다. `setLoadingState`와 `firstFrameReady`는 같은 단계의 이전 이름이니 `ready()`를 사용하세요.

## 단계: 미리 보기, 플레이, 에디터

`sdk.host.phase`는 `preview`, `play` 또는 `editor`이며, `onPhaseChange`가 단계 전환을 알려 줍니다. 미리 보기와 캡처는 실제 세션 없이 게임을 보여 주므로, `play` 밖에서는 저장, 점수, 업적, 구매를 절대 기록하지 마세요. `sdk.host.mode`는 보통 `play`이고, 로컬 Dev 프레임에서는 `dev`입니다.

## 일시 정지와 재개

`onPause(reason)`와 `onResume(reason)`은 플레이어가 일시 정지 메뉴를 열거나, 탭을 숨기거나, 로그인하거나, 무언가를 구매할 때, 또는 광고나 PlayDrop 창이 게임을 가릴 때 실행됩니다. `reason`은 `tab_hidden`, `auth_prompt`, `purchase_flow`, `host_overlay`, `detail_hidden`, `route_change`, `native_background` 중 하나이며, `sdk.host.isPaused`는 현재 상태입니다.

일시 정지된 동안에는 시뮬레이션과 타이머를 멈추세요. 재개할 때는 게임이 앞으로 건너뛰지 않도록 프레임 시계를 초기화하세요.

```js
let last = performance.now();
function frame(now) {
  const dt = paused ? 0 : Math.min((now - last) / 1000, 0.05);
  last = now;
  if (!paused) update(dt);
  render();
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
```

Esc 키와 컨트롤러의 메뉴 버튼은 PlayDrop의 일시 정지 메뉴에 속하므로 게임에서 바인딩하지 마세요. 네트워크 게임에서는 일시 정지 중에도 방 연결을 유지하세요. 한 플레이어가 일시 정지했다고 다른 플레이어가 멈추면 안 됩니다.

## 오디오

`init()` 후에 `sdk.host.audioAllowed`를 한 번 읽고, 그다음부터는 `onAudioAllowedChange`를 따르세요. 이 값은 플레이어의 음소거, 단계, 일시 정지를 합친 결과이며, 탭이 숨겨져 일시 정지된 동안에는 음악이 재생 위치를 유지할 수 있도록 true로 남습니다. 이유나 호스트 볼륨도 필요하면 `onAudioPolicyChange`가 `{ enabled, reason, volume }`을 알려 줍니다.

```js
const audio = new AudioContext();
function setAudio(allowed) {
  (allowed ? audio.resume() : audio.suspend()).catch(() => {});
}
```

오디오는 호스트가 허용할 때까지 음소거 상태로 시작하며, 브라우저는 여전히 소리를 재생하기 전에 플레이어의 조작을 요구합니다. 게임 내 볼륨 설정은 추가 제한으로 유지하세요. 호스트 음소거가 항상 우선합니다. 거부된 `play()`와 `resume()` promise를 처리하세요.

## 앱에서 미리 로드하고 오프라인으로 플레이하기

네이티브 앱은 게임이 시작되기 전에 파일을 내려받아 오프라인 플레이용으로 보관할 수 있습니다. [catalogue.json](https://www.playdrop.ai/ko/create/learn/catalogue-json)에 선언하세요.

```json
{
  "prefetch": { "required": ["game.js", "assets/level-1.png"], "optional": ["assets/music.mp3"] },
  "offlineSupported": true
}
```

시작 페이지는 항상 포함됩니다. `required` 파일은 플레이 전에, `optional` 파일은 그 후에 가져옵니다. `offlineSupported: true`를 설정하면 필수 파일이 저장된 뒤 앱이 게임을 오프라인으로 제공할 수 있습니다. 잘못된 값은 무시되며 업로드를 막지 않습니다. 웹사이트는 평소처럼 게임을 불러옵니다. [인스턴트](https://www.playdrop.ai/ko/create/learn/instant-games) 게임에서는 필수 파일의 크기가 시작 크기가 됩니다.

기기 데이터 지원을 알리는 호스트에서는 오프라인에서 기록한 저장, 점수, 업적이 기기에 남아 있다가 온라인이 되면 동기화되며, 오프라인 순위표에는 플레이어 본인의 최고 기록만 표시됩니다. 브라우저에는 오프라인 대기열이 없으므로 실패한 저장을 처리하세요. 게임이 인터넷에서 불러오는 것은 여전히 연결이 필요합니다.

## 햅틱

네이티브 앱에서 `sdk.haptics.selection()`, `impact("light" | "medium" | "heavy")`, `notification("success" | "warning" | "error")`는 짧은 진동 피드백을 줍니다. `sdk.haptics.supported`는 호스트가 이를 지원하는지 알려 줍니다. 웹에서는 아무 동작도 하지 않으며, 음소거와는 무관합니다.

## 관련 가이드

- [전체 화면과 안전 영역](https://www.playdrop.ai/ko/create/learn/viewport): PlayDrop 게임이 화면을 꽉 채우게 하고, SDK가 측정한 reservedCorners로 HUD를 CSS 안전 영역 안에 두고 호스트 컨트롤과 겹치지 않게 하세요.
- [클라우드 저장](https://www.playdrop.ai/ko/create/learn/cloud-saves): sdk.me.appData와 sdk.me.updateAppData로 게스트와 로그인한 플레이어의 진행 상황을 저장하고 불러오세요. 쓰기, 미리 보기, 오프라인 플레이 규칙도 담았습니다.
- [인스턴트 게임](https://www.playdrop.ai/ko/create/learn/instant-games): PlayDrop 게임이 인스턴트가 되는 조건: 세로 플레이, 게스트 접근, 최대 10 MiB의 시작 파일, 2초 안에 시작. 일반 게임과의 차이도 알아보세요.
- [클라이언트 SDK](https://www.playdrop.ai/ko/create/learn/sdk): PlayDrop 브라우저 SDK 참조: 초기화, 호스트 수명 주기, 플레이어 신원과 저장, 기기와 컨트롤러, 소셜, 멀티플레이어, 상점, 광고, 순위표, 업적, 에셋, AI.
