# Lifecycle

### 소개

앱이 시작되어, 실행되고 종료될 때까지를 하나의 **생애 주기(Lifecycle)**&#xB77C;고 합니다. 관련 함수들을 이용하여 **앱이 시작될 때, 실행 중일 때 그리고 종료될 때** 등의 상황에서 필요한 동작들을 실행해 전체적인 앱의 생애주기를 만들 수 있습니다.

<table><thead><tr><th width="167">이름</th><th>설명</th></tr></thead><tbody><tr><td>onInit</td><td>App이 최초로 시작될 때 한 번 호출되는 함수입니다.</td></tr><tr><td>onJoinPlayer</td><td>onInit이 호출된 후, 접속해 있는 모든 플레이어를 해당 이벤트를 통해 입장 시키고, 이후 입장하는 플레이어가 있을 때 마다 동작합니다.</td></tr><tr><td>onStart</td><td>모든 플레이어가 onJoinPlayer를 통해 입장한 후 한 번 호출 됩니다.</td></tr><tr><td>onUpdate</td><td>약 20ms 마다 주기적으로 실행되는 함수입니다.</td></tr><tr><td>onLeavePlayer</td><td>퇴장하는 플레이어가 있을 때 마다 동작합니다. 이후, 다른 App이 실행되거나 설치한 Game Block이 파괴될 때 모든 플레이어를 이 함수를 통해 퇴장시킵니다.</td></tr><tr><td>onDestroy</td><td>다른 App이 실행되거나 설치한 Game Block이 파괴될 때 동작합니다.</td></tr></tbody></table>

### App 생애 주기(Lifecycle) 이해하기

Lifecycle 함수들은 생애 주기에 맞게 기능을 만들 수 있는 필수적인 함수입니다. \
아래 그림과 같이 앱이 실행될 때는 **Enter 단계**의 함수들이 동작하고, 앱이 실행 중 일때는 **Update 단계**의 함수들이 주기적으로 동작하며, 앱이 종료될 때는 **Exit 단계**의 함수들이 동작하게됩니다.

앱이 실행되어 종료될 때 까지 각 단계의 함수들을 잘 활용해 생애 주기에 맞게 App을 만들어보세요.

<figure><img src="/files/pEGxhKsvVLRlmHIEfPVx" alt=""><figcaption></figcaption></figure>

<mark style="background-color:yellow;">**Lifecycle 함수 한 눈에 보기**</mark>

```jsx
// App 실행 시에 최초로 호출되는 이벤트 (유저 진입 전)
// Normal App과 Sidebar App은 Script 적용 후 맵이 실행될 때 호출 [ Enter ]
App.onInit.Add(function(){
});

// 모든 플레이어를 이 이벤트를 통해 App에 진입시킴 [ Enter ]
// 이후 플레이어가 입장 할 때마다 호출 [ Events ]
App.onJoinPlayer.Add(function(player) {
});

// 플레이어 모두 진입 시 최초로 시작되는 이벤트 [ Enter ]
App.onStart.Add(function(){
});

// 20ms 마다 호출되는 이벤트
// dt: deltatime(전 프레임이 완료되기까지 걸린 시간) [ Update ]
App.onUpdate.Add(function(dt){
});

// 이벤트 콜백 처리 후 다시 onUpdate

// App 종료 시 모든 플레이어를 App에서 나가게 함 [ Exit ]
App.onLeavePlayer.Add(function(player){
});

// App 종료 시 마지막으로 호출 [ Exit ]
// Normal App과 Sidebar App은 별도의 종료
App.onDestroy.Add(function(){
});
```

## 1️⃣ Enter 단계 함수

App의 실행과 함께 호출되는 **라이프사이클 Enter 단계**에서 호출되는 함수를 안내합니다.

### onInit

{% hint style="info" %}
&#x20;App.onInit.Add(function(){})
{% endhint %}

App이 최초로 시작될 때 한 번 호출됩니다.

**파라미터**

* 없음

**예제**

onInit 에서 채팅 출력해보기. ( 미니게임으로 만들어 확인해보세요. )

```jsx
App.onInit.Add(function(){
	App.sayToAll("-- onInit --")
	App.sayToAll("   ready..  ")
	App.sayToAll("------------")
});
```

###

### onJoinPlayer

{% hint style="info" %}
App.onJoinPlayer.Add(function(player){})
{% endhint %}

onInit이 호출된 후, 접속해 있는 모든 플레이어를 해당 이벤트를 통해 입장시키고, 이후 입장하는 플레이어가 있을 때 마다 동작합니다.

**파라미터**

<table><thead><tr><th width="118.33333333333331">이름</th><th width="112">타입</th><th>설명</th></tr></thead><tbody><tr><td>player</td><td>Player</td><td>player는 입장하는 플레이어를 가르킴<br>파라미터의 이름은 임의로 변경가능</td></tr></tbody></table>

**예시**

플레이어 입장시 메시지 출력해보기

```jsx
App.onJoinPlayer.Add(function(player){
	App.showCenterLabel(`${player.name}님이 입장하셨습니다.`)
});
```

###

### onStart

{% hint style="info" %}
App.onStart.Add(function(){})
{% endhint %}

모든 플레이어가 onJoinPlayer를 통해 입장한 후 한 번 호출 됩니다.

**파라미터**

* 없음

**예제**

onStart에서 채팅 출력해보기 ( 미니게임으로 만들어 확인해보세요. )

```jsx
App.onStart.Add(function(){
	App.sayToAll("-- App Start --")
});
```

<mark style="background-color:yellow;">**Enter 단계 함수의 흐름 이해하기**</mark>

**Lifecycle Enter 단계**의 흐름을 코드로 확인해보세요.\
아래 코드를 미니게임으로 만들어 실행해보세요!

```jsx
// main.js
App.onInit.Add(function(){
	App.sayToAll("-- onInit --")
	App.sayToAll("   ready..  ")
	App.sayToAll("------------")
});

App.onJoinPlayer.Add(function(player){
	App.sayToAll(`${player.name}님이 입장하셨습니다.`)
});

App.onStart.Add(function(){
	App.sayToAll("-- App Start --")
});
```

<div align="left"><figure><img src="/files/cnlqy3aECilzCJ5PASqS" alt=""><figcaption><p>Enter 단계 함수들이 순서대로 동작하는 모습.</p></figcaption></figure></div>

## 2️⃣ Update

Update에는 약 20ms 마다 주기적으로 실행되는 함수 onUpdate가 있습니다.

onJoinPlayer, onLeavePlayer 등의 이벤트가 발생하면 해당 이벤트 처리 후 다시 onUpdate가 주기적으로 실행됩니다.

### onUpdate

{% hint style="info" %}
App.onUpdate.Add(function(dt){})
{% endhint %}

약 20ms 마다 주기적으로 실행되는 함수입니다.

**파라미터**

<table><thead><tr><th width="93.33333333333331">이름</th><th width="110">타입</th><th>설명</th></tr></thead><tbody><tr><td>dt</td><td>Number</td><td>deltatime (전 프레임이 완료되기까지 걸린 시간, 약 20ms)<br>dt 파라미터의 이름은 임의로 변경 가능</td></tr></tbody></table>

**예시**

onUpdate 함수를 이용해 10초 카운트다운 만들어보기

<div align="left"><figure><img src="/files/qESXf66b6MlCyMYMAHrT" alt=""><figcaption></figcaption></figure></div>

```jsx
let countdown = 10;
let timer = 0;
App.onUpdate.Add(function(dt){
	timer += dt;
	if(timer >=1){
		if(countdown >= 0)
		{
			App.showCenterLabel(countdown--);
		}
		else{
			App.showCenterLabel("Time Over");
		}
		timer = 0;
	}
})
```

## 3️⃣ Exit 단계 함수

앱이 종료될 때 실행되는 함수 입니다.

### onLeavePlayer

{% hint style="info" %}
&#x20;App.onLeavePlayer.Add(function(player){})
{% endhint %}

퇴장하는 플레이어가 있을 때 마다 동작합니다. 이후, 다른 App이 실행되거나 설치한 Game Block이 파괴될 때 모든 플레이어를 이 함수를 통해 퇴장시킵니다.

**파라미터**

<table><thead><tr><th width="99.33333333333331">이름</th><th width="97">타입</th><th>설명</th></tr></thead><tbody><tr><td>player</td><td>Player</td><td>player 파라미터는 퇴장하는 플레이어를 가르킴<br>player 파라미터의 이름은 임의로 변경 가능</td></tr></tbody></table>

**예시**

플레이어 퇴장 시 메시지 출력해보기

```jsx
// 플레이어가 퇴장할 때 실행
App.onLeavePlayer.Add(function(player){
	App.showCenterLabel(`${player.name}님이 퇴장하셨습니다.`)
});
```

###

### onDestroy

{% hint style="info" %}
App.onDestroy.Add(function(){})
{% endhint %}

다른 App이 실행되거나, 설치한 Game Block이 파괴될 때 동작합니다.

**파라미터**

* 없음

**예제**

Game Block 파괴 시 메시지 출력해보기 ( 미니게임 )

<div align="left"><figure><img src="/files/4xHqePgwle0lW2UGD4j4" alt=""><figcaption></figcaption></figure></div>

```jsx
// Game Block 파괴 시 실행
App.onDestroy.Add(function(){
	App.showCenterLabel("게임 블록이 파괴되었습니다.")
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-kr.zep.us/zep-script-api/zepscriptapi/scriptapp/lifecycle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
