> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Quest Deploy/CDK 레퍼런스

GS2-Deploy의 스택을 생성할 때 사용하는 템플릿 포맷과, CDK를 이용한 각종 언어의 템플릿 출력 구현 예제




## 엔티티

Deploy 처리에서 조작 대상이 되는 리소스

### Namespace

네임스페이스<br>

네임스페이스는 하나의 프로젝트 내에서 동일한 서비스를 서로 다른 용도로 여러 개 이용하기 위한 엔티티입니다.<br>
GS2의 각 서비스는 네임스페이스 단위로 관리됩니다. 네임스페이스가 다르면 동일한 서비스라도 완전히 독립된 데이터 공간으로 취급됩니다.<br>

따라서 각 서비스의 이용을 시작하려면 먼저 네임스페이스를 생성해야 합니다.

#### Request

리소스 생성・갱신 요청

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| description | string |  | |  |  ~ 1024자 | 설명문 |
| transactionSetting | [TransactionSetting](#transactionsetting) |  | ✓|  |  | 트랜잭션 설정<br>퀘스트 보상 지급 시 트랜잭션 처리 방식을 제어하는 설정입니다. |
| startQuestScript | [ScriptSetting](#scriptsetting) |  | |  |  | 퀘스트를 시작했을 때 실행할 스크립트 설정<br>Script 트리거 참조 - [`startQuest`](../script/#startquest) |
| completeQuestScript | [ScriptSetting](#scriptsetting) |  | |  |  | 퀘스트를 클리어했을 때 실행할 스크립트 설정<br>Script 트리거 참조 - [`completeQuest`](../script/#completequest) |
| failedQuestScript | [ScriptSetting](#scriptsetting) |  | |  |  | 퀘스트에 실패했을 때 실행할 스크립트 설정<br>Script 트리거 참조 - [`failedQuest`](../script/#failedquest) |
| logSetting | [LogSetting](#logsetting) |  | |  |  | 로그 출력 설정<br>API 요청·응답 로그의 출력 대상이 되는 GS2-Log의 네임스페이스를 지정합니다. 퀘스트의 시작·클리어·실패 이벤트를 추적하는 데 사용됩니다. |

#### GetAttr

[!GetAttr](/articles/tech/deploy/#getattr) 태그로 취득 가능한 리소스 생성 결과

| | 타입 | 설명 |
| --- | --- | --- |
| Item | [Namespace](../sdk#namespace) | 생성한 네임스페이스

#### 구현 예제




**GS2-Deploy(YAML)**
```yaml

Type: GS2::Quest::Namespace
Properties:
  Name: namespace-0001
  Description: null
  TransactionSetting: 
    EnableAutoRun: true
    QueueNamespaceId: grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001
  StartQuestScript: null
  CompleteQuestScript: null
  FailedQuestScript: null
  LogSetting: 
    LoggingNamespaceId: grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001

```

**Go**
```go

import (
    "github.com/gs2io/gs2-golang-cdk/core"
    "github.com/gs2io/gs2-golang-cdk/quest"
    "github.com/openlyinc/pointy"
)


SampleStack := core.NewStack()
quest.NewNamespace(
    &SampleStack,
    "namespace-0001",
    quest.NamespaceOptions{
        TransactionSetting: core.NewTransactionSetting(
            core.TransactionSettingOptions{
                QueueNamespaceId: pointy.String("grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001"),
            },
        ),
        LogSetting: &core.LogSetting{
            LoggingNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001",
        },
    },
)

println(SampleStack.Yaml())  // Generate Template

```

**PHP**
```php

class SampleStack extends \Gs2Cdk\Core\Model\Stack
{
    function __construct() {
        parent::__construct();
        new \Gs2Cdk\Quest\Model\Namespace_(
            stack: $this,
            name: "namespace-0001",
            options: new \Gs2Cdk\Quest\Model\Options\NamespaceOptions(
                transactionSetting: new \Gs2Cdk\Core\Model\TransactionSetting(
                    new \Gs2Cdk\Core\Model\TransactionSettingOptions(
                        queueNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001"
                    )
                ),
                logSetting: new \Gs2Cdk\Core\Model\LogSetting(
                    loggingNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
                )
            )
        );
    }
}

print((new SampleStack())->yaml());  // Generate Template

```

**Java**
```java

class SampleStack extends io.gs2.cdk.core.model.Stack
{
    public SampleStack() {
        super();
        new io.gs2.cdk.quest.model.Namespace(
                this,
                "namespace-0001",
                new io.gs2.cdk.quest.model.options.NamespaceOptions()
                        .withTransactionSetting(new io.gs2.cdk.core.model.TransactionSetting(
                            new io.gs2.cdk.core.model.options.TransactionSettingOptions()
                                .withQueueNamespaceId("grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001")
                        ))
                        .withLogSetting(new io.gs2.cdk.core.model.LogSetting(
                            "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
                        ))
        );
    }
}

System.out.println(new SampleStack().yaml());  // Generate Template

```

**C#**
```csharp

public class SampleStack : Gs2Cdk.Core.Model.Stack
{
    public SampleStack() {
        new Gs2Cdk.Gs2Quest.Model.Namespace(
            stack: this,
            name: "namespace-0001",
            options: new Gs2Cdk.Gs2Quest.Model.Options.NamespaceOptions
            {
                transactionSetting = new Gs2Cdk.Core.Model.TransactionSetting(
                    options: new Gs2Cdk.Core.Model.TransactionSettingOptions
                    {
                        queueNamespaceId = "grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001"
                    }
                ),
                logSetting = new Gs2Cdk.Core.Model.LogSetting(
                    loggingNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
                )
            }
        );
    }
}

Debug.Log(new SampleStack().Yaml());  // Generate Template

```

**TypeScript**
```typescript

import core from "@/gs2cdk/core";
import quest from "@/gs2cdk/quest";

class SampleStack extends core.Stack
{
    public constructor() {
        super();
        new quest.model.Namespace(
            this,
            "namespace-0001",
            {
                transactionSetting: new core.TransactionSetting(
                    {
                        queueNamespaceId: "grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001"
                    }
                ),
                logSetting: new core.LogSetting(
                    "grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001"
                )
            }
        );
    }
}

console.log(new SampleStack().yaml());  // Generate Template

```

**Python**
```python

from gs2_cdk import Stack, core, quest

class SampleStack(Stack):

    def __init__(self):
        super().__init__()
        quest.Namespace(
            stack=self,
            name='namespace-0001',
            options=quest.NamespaceOptions(
                transaction_setting=core.TransactionSetting(
                    options=core.TransactionSettingOptions(
                        queue_namespace_id='grn:gs2:ap-northeast-1:YourOwnerId:queue:queue-0001',
                    )
                ),
                log_setting=core.LogSetting(
                    logging_namespace_id='grn:gs2:ap-northeast-1:YourOwnerId:log:namespace-0001',
                ),
            ),
        )

print(SampleStack().yaml())  # Generate Template

```


#### TransactionSetting

트랜잭션 설정<br>

트랜잭션 설정은 트랜잭션의 실행 방법·정합성·비동기 처리·충돌 회피 메커니즘을 제어하는 설정입니다.<br>
자동 실행(AutoRun), 원자적 실행(AtomicCommit), GS2-Distributor를 이용한 비동기 실행, 스크립트 결과의 일괄 적용, GS2-JobQueue를 통한 입수 액션의 비동기화 등을 조합하여 게임 로직에 맞는 견고한 트랜잭션 관리를 가능하게 합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| enableAutoRun | bool |  |  | false |  | 발행한 트랜잭션을 서버 사이드에서 자동으로 실행할지 여부 |
| enableAtomicCommit | bool | {enableAutoRun} == true |  | false |  | 트랜잭션의 실행을 원자적으로 커밋할지 여부<br>※ enableAutoRun이(가) true 이면 활성화 |
| transactionUseDistributor | bool | {enableAtomicCommit} == true |  | false |  | 트랜잭션을 비동기 처리로 실행할지 여부<br>※ enableAtomicCommit이(가) true 이면 활성화 |
| commitScriptResultInUseDistributor | bool | {transactionUseDistributor} == true |  | false |  | 스크립트의 결과 커밋 처리를 비동기 처리로 실행할지 여부<br>※ transactionUseDistributor이(가) true 이면 활성화 |
| acquireActionUseJobQueue | bool | {enableAtomicCommit} == true |  | false |  | 입수 액션을 실행할 때 GS2-JobQueue를 사용할지 여부<br>※ enableAtomicCommit이(가) true 이면 활성화 |
| distributorNamespaceId | string |  |  | "grn:gs2:{region}:{ownerId}:distributor:default" |  ~ 1024자 | 트랜잭션 실행에 사용하는 GS2-Distributor 네임스페이스GRN |
| queueNamespaceId | string |  |  | "grn:gs2:{region}:{ownerId}:queue:default" |  ~ 1024자 | 트랜잭션 실행에 사용하는 GS2-JobQueue의 네임스페이스GRN |

#### ScriptSetting

스크립트 설정<br>

GS2에서는 마이크로서비스의 이벤트에 연결하여 커스텀 스크립트를 실행할 수 있습니다.<br>
이 모델은 스크립트 실행을 트리거하기 위한 설정을 보유합니다.<br>

스크립트 실행 방식은 크게 두 가지로, 바로 "동기 실행"과 "비동기 실행"입니다.<br>
동기 실행은 스크립트 실행이 완료될 때까지 처리가 블록됩니다.<br>
대신 스크립트 실행 결과를 이용하여 API 실행을 중단시키거나 API 응답 내용을 제어할 수 있습니다.<br>

한편, 비동기 실행에서는 스크립트 완료를 기다리기 위해 처리가 블록되는 일이 없습니다.<br>
다만 스크립트 실행 결과를 이용하여 API 실행을 중단하거나 API 응답 내용을 변경할 수는 없습니다.<br>
비동기 실행은 API의 응답 흐름에 영향을 주지 않으므로 원칙적으로 비동기 실행을 권장합니다.<br>

비동기 실행에는 실행 방식이 두 가지 있으며, GS2-Script와 Amazon EventBridge가 있습니다.<br>
Amazon EventBridge를 사용함으로써 Lua 이외의 언어로 처리를 작성할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| triggerScriptId | string |  |  |  |  ~ 1024자 | API 실행 시 동기적으로 실행되는 GS2-Script의 스크립트GRN<br>"grn:gs2:"로 시작하는 GRN 형식의 ID로 지정해야 합니다. |
| doneTriggerTargetType | 문자열 열거형<br>enum {<br>"none",<br>"gs2_script",<br>"aws"<br>}<br> |  |  | "none" |  | 비동기 스크립트의 실행 방법<br>비동기 실행에서 사용할 스크립트의 종류를 지정합니다.<br>"비동기 실행의 스크립트를 사용하지 않음(none)", "GS2-Script를 사용함(gs2_script)", "Amazon EventBridge를 사용함(aws)" 중에서 선택할 수 있습니다.none: 없음 / gs2_script: GS2-Script / aws: Amazon EventBridge /  |
| doneTriggerScriptId | string | {doneTriggerTargetType} == "gs2_script" |  |  |  ~ 1024자 | 비동기 실행할 GS2-Script 스크립트GRN<br>"grn:gs2:"로 시작하는 GRN 형식의 ID로 지정해야 합니다.<br>※ doneTriggerTargetType이(가) "gs2_script" 이면 활성화 |
| doneTriggerQueueNamespaceId | string | {doneTriggerTargetType} == "gs2_script" |  |  |  ~ 1024자 | 비동기 실행 스크립트를 실행하는 GS2-JobQueue 네임스페이스GRN<br>비동기 실행 스크립트를 직접 실행하지 않고 GS2-JobQueue를 경유하는 경우 GS2-JobQueue의 네임스페이스GRN을 지정합니다.<br>GS2-JobQueue를 이용해야 할 이유는 많지 않으므로, 특별한 이유가 없다면 지정할 필요는 없습니다.<br>※ doneTriggerTargetType이(가) "gs2_script" 이면 활성화 |

#### LogSetting

로그 출력 설정<br>

로그 데이터의 출력 설정을 관리합니다. 이 타입은 로그 데이터를 출력하기 위해 사용되는 GS2-Log 네임스페이스의 식별자(Namespace ID)를 보관합니다.<br>
로그 네임스페이스ID(loggingNamespaceId)에는 로그 데이터를 수집하여 저장하는 GS2-Log의 네임스페이스를 GRN 형식으로 지정합니다.<br>
이 설정을 하면 설정된 네임스페이스 내에서 발생한 API 요청·응답 로그 데이터가 대상 GS2-Log 네임스페이스 쪽으로 출력됩니다.<br>
GS2-Log에서는 실시간으로 로그가 제공되어 시스템 모니터링, 분석, 디버깅 등에 활용할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| loggingNamespaceId | string |  | ✓ |  |  ~ 1024자 | 로그를 출력할 GS2-Log의 네임스페이스GRN<br>"grn:gs2:"로 시작하는 GRN 형식의 ID로 지정해야 합니다. |

---

### CurrentQuestMaster

현재 활성화된 퀘스트 모델의 마스터 데이터<br>

현재 네임스페이스 내에서 유효한 퀘스트 모델의 정의를 기술한 마스터 데이터입니다.<br>
GS2에서는 마스터 데이터 관리에 JSON 형식의 파일을 사용합니다.<br>
파일을 업로드함으로써 실제로 서버에 설정을 반영할 수 있습니다.<br>

JSON 파일을 작성하는 방법으로, 매니지먼트 콘솔 내에 마스터 데이터 에디터를 제공하고 있습니다.<br>
또한 게임 운영에 더 적합한 툴을 만들어 적절한 형식의 JSON 파일을 출력하는 방식으로도 서비스를 이용할 수 있습니다.
**ℹ️ Note**

JSON 파일 형식에 대해서는 [GS2-Quest 마스터 데이터 레퍼런스](api_reference/quest/master_data/)를 참조해 주세요.

#### Request

리소스 생성・갱신 요청

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| mode | 문자열 열거형<br>enum {<br>"direct",<br>"preUpload"<br>}<br> |  | | "direct" |  | 업데이트 모드direct: 마스터 데이터를 직접 업데이트 / preUpload: 마스터 데이터를 업로드한 후 업데이트 /  |
| settings | string | {mode} == "direct" | ✓※|  |  ~ 5242880 바이트 (5MB) | 마스터 데이터<br>※ mode이(가) "direct" 이면 필수 |
| uploadToken | string | {mode} == "preUpload" | ✓※|  |  ~ 1024자 | 사전 업로드로 획득한 토큰<br>업로드한 마스터 데이터를 적용하기 위해 사용됩니다.<br>※ mode이(가) "preUpload" 이면 필수 |

#### GetAttr

[!GetAttr](/articles/tech/deploy/#getattr) 태그로 취득 가능한 리소스 생성 결과

| | 타입 | 설명 |
| --- | --- | --- |
| Item | [CurrentQuestMaster](../sdk#currentquestmaster) | 갱신된 현재 활성화된 퀘스트 모델의 마스터 데이터

#### 구현 예제




**GS2-Deploy(YAML)**
```yaml

Type: GS2::Quest::CurrentQuestMaster
Properties:
  NamespaceName: namespace-0001
  Mode: direct
  Settings: {
    "version": "2019-05-14",
    "groups": [
      {
        "name": "main",
        "metadata": "MAIN",
        "quests": [
          {
            "name": "1-1",
            "metadata": "stage1-1",
            "contents": [
              {
                "metadata": "normal",
                "completeAcquireActions": [
                  {
                    "action": "Gs2Experience:AddExperienceByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "experienceName": "player",
                      "propertyId": "player",
                      "experienceValue": 30,
                      "truncateExperienceWhenRankUp": false,
                      "userId": "#{userId}"
                    }
                  },
                  {
                    "action": "Gs2Inventory:AcquireItemSetByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "inventoryName": "inventory-0001",
                      "itemName": "item-0001",
                      "acquireCount": 1,
                      "expiresAt": 0,
                      "createNewItemSet": false,
                      "itemSetName": "",
                      "userId": "#{userId}"
                    }
                  }
                ],
                "weight": 99
              },
              {
                "metadata": "rare",
                "completeAcquireActions": [
                  {
                    "action": "Gs2Experience:AddExperienceByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "experienceName": "player",
                      "propertyId": "player",
                      "experienceValue": 30,
                      "truncateExperienceWhenRankUp": false,
                      "userId": "#{userId}"
                    }
                  },
                  {
                    "action": "Gs2Inventory:AcquireItemSetByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "inventoryName": "inventory-0001",
                      "itemName": "item-0001",
                      "acquireCount": 1,
                      "expiresAt": 0,
                      "createNewItemSet": false,
                      "itemSetName": "",
                      "userId": "#{userId}"
                    }
                  }
                ],
                "weight": 1
              }
            ],
            "consumeActions": [
              {
                "action": "Gs2Stamina:ConsumeStaminaByUserId",
                "request": {
                  "namespaceName": "basic",
                  "staminaName": "quest",
                  "userId": "#{userId}",
                  "consumeValue": 5
                }
              }
            ],
            "failedAcquireActions": [
              {
                "action": "Gs2Stamina:RecoverStaminaByUserId",
                "request": {
                  "namespaceName": "basic",
                  "staminaName": "quest",
                  "userId": "#{userId}",
                  "recoverValue": 5
                }
              }
            ],
            "premiseQuestNames": [
              ]
          },
          {
            "name": "1-2",
            "metadata": "stage1-2",
            "contents": [
              {
                "metadata": "normal",
                "completeAcquireActions": [
                  {
                    "action": "Gs2Experience:AddExperienceByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "experienceName": "player",
                      "propertyId": "player",
                      "experienceValue": 30,
                      "truncateExperienceWhenRankUp": false,
                      "userId": "#{userId}"
                    }
                  },
                  {
                    "action": "Gs2Inventory:AcquireItemSetByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "inventoryName": "inventory-0001",
                      "itemName": "item-0001",
                      "acquireCount": 1,
                      "expiresAt": 0,
                      "createNewItemSet": false,
                      "itemSetName": "",
                      "userId": "#{userId}"
                    }
                  }
                ],
                "weight": 98
              },
              {
                "metadata": "rare",
                "completeAcquireActions": [
                  {
                    "action": "Gs2Experience:AddExperienceByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "experienceName": "player",
                      "propertyId": "player",
                      "experienceValue": 30,
                      "truncateExperienceWhenRankUp": false,
                      "userId": "#{userId}"
                    }
                  },
                  {
                    "action": "Gs2Inventory:AcquireItemSetByUserId",
                    "request": {
                      "namespaceName": "namespace-0001",
                      "inventoryName": "inventory-0001",
                      "itemName": "item-0001",
                      "acquireCount": 1,
                      "expiresAt": 0,
                      "createNewItemSet": false,
                      "itemSetName": "",
                      "userId": "#{userId}"
                    }
                  }
                ],
                "weight": 2
              }
            ],
            "consumeActions": [
              {
                "action": "Gs2Stamina:ConsumeStaminaByUserId",
                "request": {
                  "namespaceName": "basic",
                  "staminaName": "quest",
                  "consumeValue": 5,
                  "userId": "#{userId}"
                }
              }
            ],
            "failedAcquireActions": [
              {
                "action": "Gs2Stamina:RecoverStaminaByUserId",
                "request": {
                  "namespaceName": "basic",
                  "staminaName": "quest",
                  "userId": "#{userId}",
                  "recoverValue": 5
                }
              }
            ],
            "premiseQuestNames": [
              "1-1"
            ]
          }
        ]
      },
      {
        "name": "sub",
        "metadata": "SUB",
        "quests": [
          {
            "name": "1-1",
            "metadata": "stage1-1",
            "contents": [
              {
                "metadata": "normal",
                "completeAcquireActions": [
                  {
                    "action": "Gs2JobQueue:PushByUserId",
                    "request": {
                      "namespaceName": "queue-0001",
                      "userId": "#{userId}",
                      "jobs": [{'scriptId': 'script-0001', 'args': {}, 'maxTryCount': 3}]
                    }
                  }
                ],
                "weight": 1
              }
            ],
            "premiseQuestNames": [
              ]
          }
        ]
      }
    ]
  }
  UploadToken: null

```

**Go**
```go

import (
    "github.com/gs2io/gs2-golang-cdk/core"
    "github.com/gs2io/gs2-golang-cdk/quest"
    "github.com/gs2io/gs2-golang-cdk/experience"
    "github.com/gs2io/gs2-golang-cdk/inventory"
    "github.com/gs2io/gs2-golang-cdk/stamina"
    "github.com/openlyinc/pointy"
)


SampleStack := core.NewStack()
quest.NewNamespace(
    &SampleStack,
    "namespace-0001",
    quest.NamespaceOptions{},
).MasterData(
    []quest.QuestGroupModel{
        quest.NewQuestGroupModel(
            "main",
            quest.QuestGroupModelOptions{
                Metadata: pointy.String("MAIN"),
                Quests: []quest.QuestModel{
                    quest.NewQuestModel(
                        "1-1",
                        []quest.Contents{
                            quest.NewContents(
                                99,
                                quest.ContentsOptions{
                                    Metadata: pointy.String("normal"),
                                    CompleteAcquireActions: []core.AcquireAction{
                                        experience.AddExperienceByUserId(
                                            "namespace-0001",
                                            "player",
                                            "player",
                                            pointy.Int64(30),
                                            pointy.Bool(false),
                                        ),
                                        inventory.AcquireItemSetByUserId(
                                            "namespace-0001",
                                            "inventory-0001",
                                            "item-0001",
                                            1,
                                            pointy.Int64(0),
                                            pointy.Bool(false),
                                            pointy.String(""),
                                        ),
                                    },
                                },
                            ),
                            quest.NewContents(
                                1,
                                quest.ContentsOptions{
                                    Metadata: pointy.String("rare"),
                                    CompleteAcquireActions: []core.AcquireAction{
                                        experience.AddExperienceByUserId(
                                            "namespace-0001",
                                            "player",
                                            "player",
                                            pointy.Int64(30),
                                            pointy.Bool(false),
                                        ),
                                        inventory.AcquireItemSetByUserId(
                                            "namespace-0001",
                                            "inventory-0001",
                                            "item-0001",
                                            1,
                                            pointy.Int64(0),
                                            pointy.Bool(false),
                                            pointy.String(""),
                                        ),
                                    },
                                },
                            ),
                        },
                        quest.QuestModelOptions{
                            Metadata: pointy.String("stage1-1"),
                            ConsumeActions: []core.ConsumeAction{
                                stamina.ConsumeStaminaByUserId(
                                    "namespace-0001",
                                    "quest",
                                    5,
                                ),
                            },
                            FailedAcquireActions: []core.AcquireAction{
                                stamina.RecoverStaminaByUserId(
                                    "namespace-0001",
                                    "quest",
                                    5,
                                ),
                            },
                            PremiseQuestNames: []string{},
                        },
                    ),
                    quest.NewQuestModel(
                        "1-2",
                        []quest.Contents{
                            quest.NewContents(
                                98,
                                quest.ContentsOptions{
                                    Metadata: pointy.String("normal"),
                                    CompleteAcquireActions: []core.AcquireAction{
                                        experience.AddExperienceByUserId(
                                            "namespace-0001",
                                            "player",
                                            "player",
                                            pointy.Int64(30),
                                            pointy.Bool(false),
                                        ),
                                        inventory.AcquireItemSetByUserId(
                                            "namespace-0001",
                                            "inventory-0001",
                                            "item-0001",
                                            1,
                                            pointy.Int64(0),
                                            pointy.Bool(false),
                                            pointy.String(""),
                                        ),
                                    },
                                },
                            ),
                            quest.NewContents(
                                2,
                                quest.ContentsOptions{
                                    Metadata: pointy.String("rare"),
                                    CompleteAcquireActions: []core.AcquireAction{
                                        experience.AddExperienceByUserId(
                                            "namespace-0001",
                                            "player",
                                            "player",
                                            pointy.Int64(30),
                                            pointy.Bool(false),
                                        ),
                                        inventory.AcquireItemSetByUserId(
                                            "namespace-0001",
                                            "inventory-0001",
                                            "item-0001",
                                            1,
                                            pointy.Int64(0),
                                            pointy.Bool(false),
                                            pointy.String(""),
                                        ),
                                    },
                                },
                            ),
                        },
                        quest.QuestModelOptions{
                            Metadata: pointy.String("stage1-2"),
                            ConsumeActions: []core.ConsumeAction{
                                stamina.ConsumeStaminaByUserId(
                                    "namespace-0001",
                                    "quest",
                                    5,
                                ),
                            },
                            FailedAcquireActions: []core.AcquireAction{
                                stamina.RecoverStaminaByUserId(
                                    "namespace-0001",
                                    "quest",
                                    5,
                                ),
                            },
                            PremiseQuestNames: []string{
                                "1-1",
                            },
                        },
                    ),
                },
            },
        ),
        quest.NewQuestGroupModel(
            "sub",
            quest.QuestGroupModelOptions{
                Metadata: pointy.String("SUB"),
                Quests: []quest.QuestModel{
                    quest.NewQuestModel(
                        "1-1",
                        []quest.Contents{
                            quest.NewContents(
                                1,
                                quest.ContentsOptions{
                                    Metadata: pointy.String("normal"),
                                    CompleteAcquireActions: []core.AcquireAction{
                                        jobQueue.PushByUserId(
                                            "queue-0001",
                                            &[]jobQueue.JobEntry{ jobQueue.NewJobEntry("script-0001", "", 3, jobQueue.JobEntryOptions{},), },
                                        ),
                                    },
                                },
                            ),
                        },
                        quest.QuestModelOptions{
                            Metadata: pointy.String("stage1-1"),
                            PremiseQuestNames: []string{},
                        },
                    ),
                },
            },
        ),
    },
)

println(SampleStack.Yaml())  // Generate Template

```

**PHP**
```php

class SampleStack extends \Gs2Cdk\Core\Model\Stack
{
    function __construct() {
        parent::__construct();
        (new \Gs2Cdk\Quest\Model\Namespace_(
            stack: $this,
            name: "namespace-0001"
        ))->masterData(
            [
                new \Gs2Cdk\Quest\Model\QuestGroupModel(
                    name:"main",
                    options: new \Gs2Cdk\Quest\Model\Options\QuestGroupModelOptions(
                        metadata:"MAIN",
                        quests:[
                            new \Gs2Cdk\Quest\Model\QuestModel(
                                name: "1-1",
                                contents: [
                                    new \Gs2Cdk\Quest\Model\Contents(
                                        weight: 99,
                                        options: new \Gs2Cdk\Quest\Model\Options\ContentsOptions(
                                            metadata: "normal",
                                            completeAcquireActions: [
                                                new \Gs2Cdk\Experience\StampSheet\AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new \Gs2Cdk\Inventory\StampSheet\AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                ),
                                            ],
                                        ),
                                    ),
                                    new \Gs2Cdk\Quest\Model\Contents(
                                        weight: 1,
                                        options: new \Gs2Cdk\Quest\Model\Options\ContentsOptions(
                                            metadata: "rare",
                                            completeAcquireActions: [
                                                new \Gs2Cdk\Experience\StampSheet\AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new \Gs2Cdk\Inventory\StampSheet\AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                ),
                                            ],
                                        ),
                                    ),
                                ],
                                options: new \Gs2Cdk\Quest\Model\Options\QuestModelOptions(
                                    metadata: "stage1-1",
                                    consumeActions: [
                                        new \Gs2Cdk\Stamina\StampSheet\ConsumeStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            userId: "#{userId}",
                                            consumeValue: 5
                                        ),
                                    ],
                                    failedAcquireActions: [
                                        new \Gs2Cdk\Stamina\StampSheet\RecoverStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            userId: "#{userId}",
                                            recoverValue: 5
                                        ),
                                    ],
                                    premiseQuestNames: [],
                                ),
                            ),
                            new \Gs2Cdk\Quest\Model\QuestModel(
                                name: "1-2",
                                contents: [
                                    new \Gs2Cdk\Quest\Model\Contents(
                                        weight: 98,
                                        options: new \Gs2Cdk\Quest\Model\Options\ContentsOptions(
                                            metadata: "normal",
                                            completeAcquireActions: [
                                                new \Gs2Cdk\Experience\StampSheet\AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new \Gs2Cdk\Inventory\StampSheet\AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                ),
                                            ],
                                        ),
                                    ),
                                    new \Gs2Cdk\Quest\Model\Contents(
                                        weight: 2,
                                        options: new \Gs2Cdk\Quest\Model\Options\ContentsOptions(
                                            metadata: "rare",
                                            completeAcquireActions: [
                                                new \Gs2Cdk\Experience\StampSheet\AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new \Gs2Cdk\Inventory\StampSheet\AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                ),
                                            ],
                                        ),
                                    ),
                                ],
                                options: new \Gs2Cdk\Quest\Model\Options\QuestModelOptions(
                                    metadata: "stage1-2",
                                    consumeActions: [
                                        new \Gs2Cdk\Stamina\StampSheet\ConsumeStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            consumeValue: 5,
                                            userId: "#{userId}"
                                        ),
                                    ],
                                    failedAcquireActions: [
                                        new \Gs2Cdk\Stamina\StampSheet\RecoverStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            userId: "#{userId}",
                                            recoverValue: 5
                                        ),
                                    ],
                                    premiseQuestNames: [
                                        "1-1",
                                    ],
                                ),
                            ),
                        ]
                    )
                ),
                new \Gs2Cdk\Quest\Model\QuestGroupModel(
                    name:"sub",
                    options: new \Gs2Cdk\Quest\Model\Options\QuestGroupModelOptions(
                        metadata:"SUB",
                        quests:[
                            new \Gs2Cdk\Quest\Model\QuestModel(
                                name: "1-1",
                                contents: [
                                    new \Gs2Cdk\Quest\Model\Contents(
                                        weight: 1,
                                        options: new \Gs2Cdk\Quest\Model\Options\ContentsOptions(
                                            metadata: "normal",
                                            completeAcquireActions: [
                                                new \Gs2Cdk\JobQueue\StampSheet\PushByUserId(
                                                    namespaceName: "queue-0001",
                                                    jobs: [ new \Gs2Cdk\JobQueue\Model\JobEntry(scriptId: "script-0001", args: "", maxTryCount: 3)],
                                                    userId: "#{userId}"
                                                ),
                                            ],
                                        ),
                                    ),
                                ],
                                options: new \Gs2Cdk\Quest\Model\Options\QuestModelOptions(
                                    metadata: "stage1-1",
                                    premiseQuestNames: [],
                                ),
                            ),
                        ]
                    )
                )
            ]
        );
    }
}

print((new SampleStack())->yaml());  // Generate Template

```

**Java**
```java

class SampleStack extends io.gs2.cdk.core.model.Stack
{
    public SampleStack() {
        super();
        new io.gs2.cdk.quest.model.Namespace(
            this,
            "namespace-0001"
        ).masterData(
            Arrays.asList(
                new io.gs2.cdk.quest.model.QuestGroupModel(
                    "main",
                    new io.gs2.cdk.quest.model.options.QuestGroupModelOptions()
                        .withMetadata("MAIN")
                        .withQuests(Arrays.asList(
                            new io.gs2.cdk.quest.model.QuestModel(
                                "1-1",
                                Arrays.asList(
                                    new io.gs2.cdk.quest.model.Contents(
                                        99,
                                        new io.gs2.cdk.quest.model.options.ContentsOptions()
                                            .withMetadata("normal")
                                            .withCompleteAcquireActions(Arrays.asList(
                                                new io.gs2.cdk.experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30L,
                                                    false,
                                                    "#{userId}"
                                                ),
                                                new io.gs2.cdk.inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1L,
                                                    0L,
                                                    false,
                                                    "",
                                                    "#{userId}"
                                                )
                                            ))
                                    ),
                                    new io.gs2.cdk.quest.model.Contents(
                                        1,
                                        new io.gs2.cdk.quest.model.options.ContentsOptions()
                                            .withMetadata("rare")
                                            .withCompleteAcquireActions(Arrays.asList(
                                                new io.gs2.cdk.experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30L,
                                                    false,
                                                    "#{userId}"
                                                ),
                                                new io.gs2.cdk.inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1L,
                                                    0L,
                                                    false,
                                                    "",
                                                    "#{userId}"
                                                )
                                            ))
                                    )
                                ),
                                new io.gs2.cdk.quest.model.options.QuestModelOptions()
                                    .withMetadata("stage1-1")
                                    .withConsumeActions(Arrays.asList(
                                        new io.gs2.cdk.stamina.stampSheet.ConsumeStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            "#{userId}"
                                        )
                                    ))
                                    .withFailedAcquireActions(Arrays.asList(
                                        new io.gs2.cdk.stamina.stampSheet.RecoverStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            "#{userId}"
                                        )
                                    ))
                                    .withPremiseQuestNames(new ArrayList<String>())
                            ),
                            new io.gs2.cdk.quest.model.QuestModel(
                                "1-2",
                                Arrays.asList(
                                    new io.gs2.cdk.quest.model.Contents(
                                        98,
                                        new io.gs2.cdk.quest.model.options.ContentsOptions()
                                            .withMetadata("normal")
                                            .withCompleteAcquireActions(Arrays.asList(
                                                new io.gs2.cdk.experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30L,
                                                    false,
                                                    "#{userId}"
                                                ),
                                                new io.gs2.cdk.inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1L,
                                                    0L,
                                                    false,
                                                    "",
                                                    "#{userId}"
                                                )
                                            ))
                                    ),
                                    new io.gs2.cdk.quest.model.Contents(
                                        2,
                                        new io.gs2.cdk.quest.model.options.ContentsOptions()
                                            .withMetadata("rare")
                                            .withCompleteAcquireActions(Arrays.asList(
                                                new io.gs2.cdk.experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30L,
                                                    false,
                                                    "#{userId}"
                                                ),
                                                new io.gs2.cdk.inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1L,
                                                    0L,
                                                    false,
                                                    "",
                                                    "#{userId}"
                                                )
                                            ))
                                    )
                                ),
                                new io.gs2.cdk.quest.model.options.QuestModelOptions()
                                    .withMetadata("stage1-2")
                                    .withConsumeActions(Arrays.asList(
                                        new io.gs2.cdk.stamina.stampSheet.ConsumeStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            "#{userId}"
                                        )
                                    ))
                                    .withFailedAcquireActions(Arrays.asList(
                                        new io.gs2.cdk.stamina.stampSheet.RecoverStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            "#{userId}"
                                        )
                                    ))
                                    .withPremiseQuestNames(Arrays.asList(
                                        "1-1"
                                    ))
                            )
                        ))
                ),
                new io.gs2.cdk.quest.model.QuestGroupModel(
                    "sub",
                    new io.gs2.cdk.quest.model.options.QuestGroupModelOptions()
                        .withMetadata("SUB")
                        .withQuests(Arrays.asList(
                            new io.gs2.cdk.quest.model.QuestModel(
                                "1-1",
                                Arrays.asList(
                                    new io.gs2.cdk.quest.model.Contents(
                                        1,
                                        new io.gs2.cdk.quest.model.options.ContentsOptions()
                                            .withMetadata("normal")
                                            .withCompleteAcquireActions(Arrays.asList(
                                                new io.gs2.cdk.jobQueue.stampSheet.PushByUserId(
                                                    "queue-0001",
                                                    Arrays.asList(new io.gs2.cdk.jobQueue.model.JobEntry("script-0001", "", 3)),
                                                    "#{userId}"
                                                )
                                            ))
                                    )
                                ),
                                new io.gs2.cdk.quest.model.options.QuestModelOptions()
                                    .withMetadata("stage1-1")
                                    .withPremiseQuestNames(new ArrayList<String>())
                            )
                        ))
                )
            )
        );
    }
}

System.out.println(new SampleStack().yaml());  // Generate Template

```

**C#**
```csharp

public class SampleStack : Gs2Cdk.Core.Model.Stack
{
    public SampleStack() {
        new Gs2Cdk.Gs2Quest.Model.Namespace(
            stack: this,
            name: "namespace-0001"
        ).MasterData(
            new Gs2Cdk.Gs2Quest.Model.QuestGroupModel[] {
                new Gs2Cdk.Gs2Quest.Model.QuestGroupModel(
                    name: "main",
                    options: new Gs2Cdk.Gs2Quest.Model.Options.QuestGroupModelOptions
                    {
                        metadata = "MAIN",
                        quests = new Gs2Cdk.Gs2Quest.Model.QuestModel[]
                        {
                            new Gs2Cdk.Gs2Quest.Model.QuestModel(
                                name: "1-1",
                                contents: new Gs2Cdk.Gs2Quest.Model.Contents[]
                                {
                                    new Gs2Cdk.Gs2Quest.Model.Contents(
                                        weight: 99,
                                        options: new Gs2Cdk.Gs2Quest.Model.Options.ContentsOptions
                                        {
                                            metadata = "normal",
                                            completeAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                            {
                                                new Gs2Cdk.Gs2Experience.StampSheet.AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new Gs2Cdk.Gs2Inventory.StampSheet.AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                )
                                            }
                                        }
                                    ),
                                    new Gs2Cdk.Gs2Quest.Model.Contents(
                                        weight: 1,
                                        options: new Gs2Cdk.Gs2Quest.Model.Options.ContentsOptions
                                        {
                                            metadata = "rare",
                                            completeAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                            {
                                                new Gs2Cdk.Gs2Experience.StampSheet.AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new Gs2Cdk.Gs2Inventory.StampSheet.AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                )
                                            }
                                        }
                                    )
                                },
                                options: new Gs2Cdk.Gs2Quest.Model.Options.QuestModelOptions
                                {
                                    metadata = "stage1-1",
                                    consumeActions = new Gs2Cdk.Core.Model.ConsumeAction[]
                                    {
                                        new Gs2Cdk.Gs2Stamina.StampSheet.ConsumeStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            userId: "#{userId}",
                                            consumeValue: 5
                                        )
                                    },
                                    failedAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                    {
                                        new Gs2Cdk.Gs2Stamina.StampSheet.RecoverStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            userId: "#{userId}",
                                            recoverValue: 5
                                        )
                                    },
                                    premiseQuestNames = new string[] {}
                                }
                            ),
                            new Gs2Cdk.Gs2Quest.Model.QuestModel(
                                name: "1-2",
                                contents: new Gs2Cdk.Gs2Quest.Model.Contents[]
                                {
                                    new Gs2Cdk.Gs2Quest.Model.Contents(
                                        weight: 98,
                                        options: new Gs2Cdk.Gs2Quest.Model.Options.ContentsOptions
                                        {
                                            metadata = "normal",
                                            completeAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                            {
                                                new Gs2Cdk.Gs2Experience.StampSheet.AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new Gs2Cdk.Gs2Inventory.StampSheet.AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                )
                                            }
                                        }
                                    ),
                                    new Gs2Cdk.Gs2Quest.Model.Contents(
                                        weight: 2,
                                        options: new Gs2Cdk.Gs2Quest.Model.Options.ContentsOptions
                                        {
                                            metadata = "rare",
                                            completeAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                            {
                                                new Gs2Cdk.Gs2Experience.StampSheet.AddExperienceByUserId(
                                                    namespaceName: "namespace-0001",
                                                    experienceName: "player",
                                                    propertyId: "player",
                                                    experienceValue: 30,
                                                    truncateExperienceWhenRankUp: false,
                                                    userId: "#{userId}"
                                                ),
                                                new Gs2Cdk.Gs2Inventory.StampSheet.AcquireItemSetByUserId(
                                                    namespaceName: "namespace-0001",
                                                    inventoryName: "inventory-0001",
                                                    itemName: "item-0001",
                                                    acquireCount: 1,
                                                    expiresAt: 0,
                                                    createNewItemSet: false,
                                                    itemSetName: "",
                                                    userId: "#{userId}"
                                                )
                                            }
                                        }
                                    )
                                },
                                options: new Gs2Cdk.Gs2Quest.Model.Options.QuestModelOptions
                                {
                                    metadata = "stage1-2",
                                    consumeActions = new Gs2Cdk.Core.Model.ConsumeAction[]
                                    {
                                        new Gs2Cdk.Gs2Stamina.StampSheet.ConsumeStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            consumeValue: 5,
                                            userId: "#{userId}"
                                        )
                                    },
                                    failedAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                    {
                                        new Gs2Cdk.Gs2Stamina.StampSheet.RecoverStaminaByUserId(
                                            namespaceName: "basic",
                                            staminaName: "quest",
                                            userId: "#{userId}",
                                            recoverValue: 5
                                        )
                                    },
                                    premiseQuestNames = new string[]
                                    {
                                        "1-1"
                                    }
                                }
                            )
                        }
                    }
                ),
                new Gs2Cdk.Gs2Quest.Model.QuestGroupModel(
                    name: "sub",
                    options: new Gs2Cdk.Gs2Quest.Model.Options.QuestGroupModelOptions
                    {
                        metadata = "SUB",
                        quests = new Gs2Cdk.Gs2Quest.Model.QuestModel[]
                        {
                            new Gs2Cdk.Gs2Quest.Model.QuestModel(
                                name: "1-1",
                                contents: new Gs2Cdk.Gs2Quest.Model.Contents[]
                                {
                                    new Gs2Cdk.Gs2Quest.Model.Contents(
                                        weight: 1,
                                        options: new Gs2Cdk.Gs2Quest.Model.Options.ContentsOptions
                                        {
                                            metadata = "normal",
                                            completeAcquireActions = new Gs2Cdk.Core.Model.AcquireAction[]
                                            {
                                                new Gs2Cdk.Gs2JobQueue.StampSheet.PushByUserId(
                                                    namespaceName: "queue-0001",
                                                    jobs: new [] { new Gs2Cdk.Gs2JobQueue.Model.JobEntry(scriptId: "script-0001", args: "", maxTryCount: 3) },
                                                    userId: "#{userId}"
                                                )
                                            }
                                        }
                                    )
                                },
                                options: new Gs2Cdk.Gs2Quest.Model.Options.QuestModelOptions
                                {
                                    metadata = "stage1-1",
                                    premiseQuestNames = new string[] {}
                                }
                            )
                        }
                    }
                )
            }
        );
    }
}

Debug.Log(new SampleStack().Yaml());  // Generate Template

```

**TypeScript**
```typescript

import core from "@/gs2cdk/core";
import quest from "@/gs2cdk/quest";

class SampleStack extends core.Stack
{
    public constructor() {
        super();
        new quest.model.Namespace(
            this,
            "namespace-0001",
        ).masterData(
            [
                new quest.model.QuestGroupModel(
                    "main",
                    {
                        metadata: "MAIN",
                        quests: [
                            new quest.model.QuestModel(
                                "1-1",
                                [
                                    new quest.model.Contents(
                                        99,
                                        {
                                            metadata: "normal",
                                            completeAcquireActions: [
                                                new experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30,
                                                    false,
                                                    null,
                                                    "#{userId}"
                                                ),
                                                new inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1,
                                                    0,
                                                    false,
                                                    "",
                                                    null,
                                                    "#{userId}"
                                                ),
                                            ]
                                        }
                                    ),
                                    new quest.model.Contents(
                                        1,
                                        {
                                            metadata: "rare",
                                            completeAcquireActions: [
                                                new experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30,
                                                    false,
                                                    null,
                                                    "#{userId}"
                                                ),
                                                new inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1,
                                                    0,
                                                    false,
                                                    "",
                                                    null,
                                                    "#{userId}"
                                                ),
                                            ]
                                        }
                                    ),
                                ],
                                {
                                    metadata: "stage1-1",
                                    consumeActions: [
                                        new stamina.stampSheet.ConsumeStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            null,
                                            "#{userId}"
                                        ),
                                    ],
                                    failedAcquireActions: [
                                        new stamina.stampSheet.RecoverStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            null,
                                            "#{userId}"
                                        ),
                                    ],
                                    premiseQuestNames: []
                                }
                            ),
                            new quest.model.QuestModel(
                                "1-2",
                                [
                                    new quest.model.Contents(
                                        98,
                                        {
                                            metadata: "normal",
                                            completeAcquireActions: [
                                                new experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30,
                                                    false,
                                                    null,
                                                    "#{userId}"
                                                ),
                                                new inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1,
                                                    0,
                                                    false,
                                                    "",
                                                    null,
                                                    "#{userId}"
                                                ),
                                            ]
                                        }
                                    ),
                                    new quest.model.Contents(
                                        2,
                                        {
                                            metadata: "rare",
                                            completeAcquireActions: [
                                                new experience.stampSheet.AddExperienceByUserId(
                                                    "namespace-0001",
                                                    "player",
                                                    "player",
                                                    30,
                                                    false,
                                                    null,
                                                    "#{userId}"
                                                ),
                                                new inventory.stampSheet.AcquireItemSetByUserId(
                                                    "namespace-0001",
                                                    "inventory-0001",
                                                    "item-0001",
                                                    1,
                                                    0,
                                                    false,
                                                    "",
                                                    null,
                                                    "#{userId}"
                                                ),
                                            ]
                                        }
                                    ),
                                ],
                                {
                                    metadata: "stage1-2",
                                    consumeActions: [
                                        new stamina.stampSheet.ConsumeStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            null,
                                            "#{userId}"
                                        ),
                                    ],
                                    failedAcquireActions: [
                                        new stamina.stampSheet.RecoverStaminaByUserId(
                                            "namespace-0001",
                                            "quest",
                                            5,
                                            null,
                                            "#{userId}"
                                        ),
                                    ],
                                    premiseQuestNames: [
                                        "1-1",
                                    ]
                                }
                            ),
                        ]
                    }
                ),
                new quest.model.QuestGroupModel(
                    "sub",
                    {
                        metadata: "SUB",
                        quests: [
                            new quest.model.QuestModel(
                                "1-1",
                                [
                                    new quest.model.Contents(
                                        1,
                                        {
                                            metadata: "normal",
                                            completeAcquireActions: [
                                                new jobQueue.stampSheet.PushByUserId(
                                                    "namespace-0001",
                                                    [ new jobQueue.model.JobEntry( "script-0001", "", 3) ],
                                                    "#{userId}"
                                                ),
                                            ]
                                        }
                                    ),
                                ],
                                {
                                    metadata: "stage1-1",
                                    premiseQuestNames: []
                                }
                            ),
                        ]
                    }
                )
            ]
        );
    }
}

console.log(new SampleStack().yaml());  // Generate Template

```

**Python**
```python

from gs2_cdk import Stack, core, quest, job_queue

class SampleStack(Stack):

    def __init__(self):
        super().__init__()
        quest.Namespace(
            stack=self,
            name="namespace-0001",
        ).master_data(
            groups=[
                quest.QuestGroupModel(
                    name='main',
                    options=quest.QuestGroupModelOptions(
                        metadata = 'MAIN',
                        quests = [
                            quest.QuestModel(
                                name='1-1',
                                contents=[
                                    quest.Contents(
                                        weight=99,
                                        options=quest.ContentsOptions(
                                            metadata='normal',
                                            complete_acquire_actions=[
                                                experience.AddExperienceByUserId(
                                                    namespace_name='namespace-0001',
                                                    experience_name='player',
                                                    property_id='player',
                                                    experience_value=30,
                                                    truncate_experience_when_rank_up=False,
                                                    user_id='#{userId}'
                                                ),
                                                inventory.AcquireItemSetByUserId(
                                                    namespace_name='namespace-0001',
                                                    inventory_name='inventory-0001',
                                                    item_name='item-0001',
                                                    acquire_count=1,
                                                    expires_at=0,
                                                    create_new_item_set=False,
                                                    item_set_name="",
                                                    user_id='#{userId}'
                                                ),
                                            ],
                                        ),
                                    ),
                                    quest.Contents(
                                        weight=1,
                                        options=quest.ContentsOptions(
                                            metadata='rare',
                                            complete_acquire_actions=[
                                                experience.AddExperienceByUserId(
                                                    namespace_name='namespace-0001',
                                                    experience_name='player',
                                                    property_id='player',
                                                    experience_value=30,
                                                    truncate_experience_when_rank_up=False,
                                                    user_id='#{userId}'
                                                ),
                                                inventory.AcquireItemSetByUserId(
                                                    namespace_name='namespace-0001',
                                                    inventory_name='inventory-0001',
                                                    item_name='item-0001',
                                                    acquire_count=1,
                                                    expires_at=0,
                                                    create_new_item_set=False,
                                                    item_set_name="",
                                                    user_id='#{userId}'
                                                ),
                                            ],
                                        ),
                                    ),
                                ],
                                options=quest.QuestModelOptions(
                                    metadata='stage1-1',
                                    consume_actions=[
                                        stamina.ConsumeStaminaByUserId(
                                            namespace_name='basic',
                                            stamina_name='quest',
                                            user_id='#{userId}',
                                            consume_value=5
                                        ),
                                    ],
                                    failed_acquire_actions=[
                                        stamina.RecoverStaminaByUserId(
                                            namespace_name='basic',
                                            stamina_name='quest',
                                            user_id='#{userId}',
                                            recover_value=5
                                        ),
                                    ],
                                    premise_quest_names=[],
                                ),
                            ),
                            quest.QuestModel(
                                name='1-2',
                                contents=[
                                    quest.Contents(
                                        weight=98,
                                        options=quest.ContentsOptions(
                                            metadata='normal',
                                            complete_acquire_actions=[
                                                experience.AddExperienceByUserId(
                                                    namespace_name='namespace-0001',
                                                    experience_name='player',
                                                    property_id='player',
                                                    experience_value=30,
                                                    truncate_experience_when_rank_up=False,
                                                    user_id='#{userId}'
                                                ),
                                                inventory.AcquireItemSetByUserId(
                                                    namespace_name='namespace-0001',
                                                    inventory_name='inventory-0001',
                                                    item_name='item-0001',
                                                    acquire_count=1,
                                                    expires_at=0,
                                                    create_new_item_set=False,
                                                    item_set_name="",
                                                    user_id='#{userId}'
                                                ),
                                            ],
                                        ),
                                    ),
                                    quest.Contents(
                                        weight=2,
                                        options=quest.ContentsOptions(
                                            metadata='rare',
                                            complete_acquire_actions=[
                                                experience.AddExperienceByUserId(
                                                    namespace_name='namespace-0001',
                                                    experience_name='player',
                                                    property_id='player',
                                                    experience_value=30,
                                                    truncate_experience_when_rank_up=False,
                                                    user_id='#{userId}'
                                                ),
                                                inventory.AcquireItemSetByUserId(
                                                    namespace_name='namespace-0001',
                                                    inventory_name='inventory-0001',
                                                    item_name='item-0001',
                                                    acquire_count=1,
                                                    expires_at=0,
                                                    create_new_item_set=False,
                                                    item_set_name="",
                                                    user_id='#{userId}'
                                                ),
                                            ],
                                        ),
                                    ),
                                ],
                                options=quest.QuestModelOptions(
                                    metadata='stage1-2',
                                    consume_actions=[
                                        stamina.ConsumeStaminaByUserId(
                                            namespace_name='basic',
                                            stamina_name='quest',
                                            consume_value=5,
                                            user_id='#{userId}'
                                        ),
                                    ],
                                    failed_acquire_actions=[
                                        stamina.RecoverStaminaByUserId(
                                            namespace_name='basic',
                                            stamina_name='quest',
                                            user_id='#{userId}',
                                            recover_value=5
                                        ),
                                    ],
                                    premise_quest_names=[
                                        '1-1',
                                    ],
                                ),
                            ),
                        ]
                    ),
                ),
                quest.QuestGroupModel(
                    name='sub',
                    options=quest.QuestGroupModelOptions(
                        metadata = 'SUB',
                        quests = [
                            quest.QuestModel(
                                name='1-1',
                                contents=[
                                    quest.Contents(
                                        weight=1,
                                        options=quest.ContentsOptions(
                                            metadata='normal',
                                            complete_acquire_actions=[
                                                job_queue.PushByUserId(
                                                    namespace_name='queue-0001',
                                                    jobs=[{'scriptId': 'script-0001', 'args': {}, 'maxTryCount': 3}],
                                                    user_id='#{userId}'
                                                ),
                                            ],
                                        ),
                                    ),
                                ],
                                options=quest.QuestModelOptions(
                                    metadata='stage1-1',
                                    premise_quest_names=[],
                                ),
                            ),
                        ]
                    ),
                ),
            ],
        )

print(SampleStack().yaml())  # Generate Template

```


#### QuestGroupModel

퀘스트 그룹 모델<br>

퀘스트 그룹은 여러 퀘스트를 그룹화하기 위한 엔티티로, 퀘스트 진행은 그룹 내에서 동시에 하나만 실행할 수 있습니다.<br>
즉, 퀘스트를 병렬로 진행할 수 있도록 하려면 그룹을 분리해야 합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| questGroupModelId | string |  | ※ |  |  ~ 1024자 | 퀘스트 그룹 모델 GRN<br>※ 서버가 자동으로 설정 |
| name | string |  | ✓ |  |  ~ 128자 | 퀘스트 그룹 모델 이름<br>퀘스트 그룹 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 1024자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| quests | [List&lt;QuestModel&gt;](#questmodel) |  |  | [] | 0 ~ 1000 items | 그룹에 속한 퀘스트<br>이 퀘스트 그룹에 속한 퀘스트 모델의 목록입니다. 그룹 내에서는 동시에 하나의 퀘스트만 진행할 수 있습니다. |
| challengePeriodEventId | string |  |  |  |  ~ 1024자 | 도전 가능 기간 이벤트 GRN<br>이 그룹 내 퀘스트에 도전할 수 있는 기간을 설정하는 GS2-Schedule의 이벤트 GRN입니다. 지정한 경우, 이벤트가 활성화된 기간 동안에만 퀘스트를 시작할 수 있습니다. |

#### QuestModel

퀘스트 모델<br>

퀘스트 모델은 인게임 시작에 필요한 대가와 클리어했을 때 얻는 보상을 보유하는 엔티티입니다.<br>

클리어했을 때 얻는 보상은 여러 배리에이션을 준비할 수 있으며, 퀘스트 시작 시 추첨할 수 있습니다.<br>
예를 들어, 퀘스트 자체는 동일하더라도 레어 몬스터의 출현 여부에 따라 두 가지 콘텐츠 배리에이션을 만들 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| questModelId | string |  | ※ |  |  ~ 1024자 | 퀘스트 모델 GRN<br>※ 서버가 자동으로 설정 |
| name | string |  | ✓ |  |  ~ 128자 | 퀘스트 모델 이름<br>퀘스트 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 1024자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| contents | [List&lt;Contents&gt;](#contents) |  |  | [] | 1 ~ 10 items | 퀘스트 내용<br>이 퀘스트의 콘텐츠 배리에이션 목록입니다. 퀘스트 시작 시 가중치 추첨을 통해 하나의 배리에이션이 선택됩니다. 각 배리에이션마다 서로 다른 클리어 보상을 정의할 수 있어, 동일한 퀘스트라도 다른 결과(예: 레어 몬스터의 출현)를 구현할 수 있습니다. |
| challengePeriodEventId | string |  |  |  |  ~ 1024자 | 도전 가능 기간 이벤트 GRN<br>이 퀘스트에 도전할 수 있는 기간을 설정하는 GS2-Schedule 이벤트 GRN입니다. 지정한 경우, 이벤트가 활성화되어 있는 기간에만 퀘스트를 시작할 수 있습니다. 이 설정은 퀘스트 그룹의 도전 가능 기간보다 우선됩니다. |
| firstCompleteAcquireActions | [List&lt;AcquireAction&gt;](#acquireaction) |  |  | [] | 0 ~ 10 items | 최초 클리어 보상 입수 액션 리스트<br>이 퀘스트를 처음 클리어했을 때만 실행되는 입수 액션의 리스트입니다. 일반 클리어 보상에 더해 지급되는 보너스 보상으로, 최초 클리어 보너스를 구현하는 데 사용합니다. |
| verifyActions | [List&lt;VerifyAction&gt;](#verifyaction) |  |  | [] | 0 ~ 10 items | 검증 액션 리스트<br>이 퀘스트를 시작하기 위한 전제 조건이 되는 검증 액션의 리스트입니다. 모든 검증 액션이 성공해야만 퀘스트를 시작할 수 있습니다. 레벨 확인이나 아이템 소지 등의 요건을 강제하는 데 사용합니다. |
| consumeActions | [List&lt;ConsumeAction&gt;](#consumeaction) |  |  | [] | 0 ~ 10 items | 소비 액션 리스트<br>이 퀘스트의 시작 비용으로 실행되는 소비 액션입니다. 스태미나나 통화 등의 비용이 퀘스트 시작 시 소비됩니다. |
| failedAcquireActions | [List&lt;AcquireAction&gt;](#acquireaction) |  |  | [] | 0 ~ 100 items | 실패 시 입수 액션 리스트<br>퀘스트 실패 시 실행되는 입수 액션입니다. 실패 시 위로 보상이나 퀘스트 참가 비용의 일부 반환 등에 사용합니다. |
| premiseQuestNames | List&lt;string&gt; |  |  | [] | 0 ~ 10 items | 전제 퀘스트 이름 리스트<br>이 퀘스트에 도전하기 전에 클리어가 필요한 같은 그룹 내 퀘스트 이름의 리스트입니다. 연속되는 퀘스트 체인이나 분기되는 퀘스트 경로 작성에 사용합니다. |

#### Contents

콘텐츠<br>

퀘스트 콘텐츠의 하나의 배리에이션을 나타냅니다. 각 퀘스트는 서로 다른 보상을 가진 여러 콘텐츠 배리에이션을 가질 수 있으며, 퀘스트 시작 시 가중치 추첨을 통해 하나가 선택됩니다. 메타데이터는 사용자 ID 및 컨피그 값을 이용한 템플릿 변수 치환을 지원합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| metadata | string |  |  |  |  ~ 256자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| completeAcquireActions | [List&lt;AcquireAction&gt;](#acquireaction) |  |  | [] | 0 ~ 10 items | 클리어 보상 획득 액션<br>이 콘텐츠 배리에이션으로 퀘스트를 클리어했을 때 실행되는 획득 액션입니다. 플레이어가 퀘스트 클리어 시 받게 되는 실제 보상을 정의합니다. |
| weight | int |  |  | 1 | 1 ~ 2147483646 | 추첨 가중치<br>퀘스트 시작 시 이 콘텐츠 배리에이션의 무작위 선택에 사용되는 상대적 가중치입니다. 값이 클수록 이 배리에이션이 선택될 확률이 높아집니다. 예를 들어 가중치가 9인 배리에이션은 가중치가 1인 배리에이션보다 9배 선택되기 쉽습니다. |

#### AcquireAction

입수 액션

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| action | 문자열 열거형<br>enum {<br>}<br> |  | ✓ |  |  | 입수 액션에서 실행할 액션의 종류 |
| request | string |  | ✓ |  |  ~ 524288자 | 액션 실행 시 사용되는 요청의 JSON 문자열 |

#### ConsumeAction

소비 액션

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| action | 문자열 열거형<br>enum {<br>}<br> |  | ✓ |  |  | 소비 액션에서 실행할 액션의 종류 |
| request | string |  | ✓ |  |  ~ 524288자 | 액션 실행 시 사용되는 요청의 JSON 문자열 |

#### VerifyAction

검증 액션

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| action | 문자열 열거형<br>enum {<br>}<br> |  | ✓ |  |  | 검증 액션에서 실행할 액션의 종류 |
| request | string |  | ✓ |  |  ~ 524288자 | 액션 실행 시 사용되는 요청의 JSON 문자열 |

---



