GS2-Mission SDK for Game Engine API 레퍼런스
모델
EzComplete
미션 달성 상황
특정 미션 그룹에 대한 사용자의 미션 달성 상황과 보상 수령 상황을 추적합니다. 달성 완료된 태스크명과 보상 수령 완료된 태스크명을 각각 별도의 목록으로 관리하여, 달성된 태스크와 실제로 보상을 수령한 태스크를 구분합니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹명 이 달성 상황 레코드가 속한 미션 그룹의 이름입니다. 사용자별·미션 그룹별로 하나의 달성 상황 레코드가 존재합니다. | ||
| completedMissionTaskNames | List<string> | [] | 0 ~ 1000 items | 달성 완료된 태스크명 목록 사용자가 달성한(달성 조건을 충족한) 미션 태스크의 이름입니다. 카운터가 목표값에 도달하거나 검증 액션이 성공한 시점에 이 목록에 추가됩니다. 보상 수령 여부는 관계없습니다. | ||
| receivedMissionTaskNames | List<string> | [] | 0 ~ 1000 items | 보상 수령 완료된 태스크명 목록 사용자가 달성 보상을 이미 수령한 미션 태스크의 이름입니다. 보상을 받으려면 태스크가 달성 완료 목록에 포함되어 있어야 합니다. |
EzCounter
카운터
카운터는 미션 진행 상황을 게임 플레이어별로 보관하는 엔티티입니다.
카운터의 값은 연결된 태스크의 기간별로 집계됩니다.
따라서 하나의 카운터는 여러 개의 값을 가집니다.
예를 들어, 퀘스트 클리어 횟수 카운터라면 이번 달 클리어 횟수, 이번 주 클리어 횟수, 오늘 클리어 횟수와 같은 식입니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 카운터 모델 이름 이 카운터 인스턴스의 기반이 되는 카운터 모델의 이름입니다. 스코프와 리셋 타이밍을 정의하는 카운터 모델 정의에 연결됩니다. | ||
| values | List<EzScopedValue> | [] | 0 ~ 32 items | 값 이 카운터의 스코프별 값 리스트입니다. 각 엔트리는 특정 스코프(리셋 타이밍 또는 검증 액션 조건)의 카운터 값과 다음 리셋 시각을 보관합니다. 하나의 카운터가 여러 스코프의 값을 동시에 보관합니다. |
EzCounterScopeModel
카운터 리셋 타이밍 모델
카운터의 스코프를 정의하고, 카운터 값의 리셋 방법과 타이밍을 결정합니다. 스코프는 리셋 타이밍(매일, 매주, 매월, 일정 일수마다, 또는 리셋 없음) 또는 검증 액션 조건 중 하나입니다. 각 카운터는 여러 스코프를 가질 수 있으며, 서로 다른 기간의 값을 추적할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| scopeType | 문자열 열거형 enum { “resetTiming”, “verifyAction” } | “resetTiming” | 스코프의 종류 카운터 스코프의 정의 방법을 결정합니다. “resetTiming” 은 정기적인 리셋 스케줄을 사용하고, “verifyAction” 은 검증 액션으로 카운터 값이 적용되는지 여부를 판정합니다.
| |||||||||||||||||||
| resetType | 문자열 열거형 enum { “notReset”, “daily”, “weekly”, “monthly”, “days” } | “notReset” | 리셋 타이밍 이 스코프의 카운터 값이 리셋되는 타이밍을 결정합니다. 리셋하지 않음(영구 누계), 매일, 매주, 매월, 일정 일수마다 중에서 선택합니다. scopeType 이 “resetTiming” 인 경우에만 사용됩니다.
| |||||||||||||||||||
| resetDayOfMonth | int | {resetType} == “monthly” | ✓※ | 1 ~ 31 | 리셋할 날짜 카운터 값이 리셋되는 월의 날짜입니다. 지정한 값이 해당 월의 일수를 초과하는 경우, 그 달의 마지막 날로 처리됩니다. resetType 이 “monthly” 인 경우에만 사용됩니다. ※ resetType이(가) “monthly” 이면 필수 | |||||||||||||||||
| resetDayOfWeek | 문자열 열거형 enum { “sunday”, “monday”, “tuesday”, “wednesday”, “thursday”, “friday”, “saturday” } | {resetType} == “weekly” | ✓※ | 리셋할 요일 카운터 값이 리셋되는 요일입니다. resetType 이 “weekly” 인 경우에만 사용됩니다.
※ resetType이(가) “weekly” 이면 필수 | ||||||||||||||||||
| resetHour | int | {resetType} in [“monthly”, “weekly”, “daily”] | ✓※ | 0 ~ 23 | 리셋 시각 카운터 값이 리셋되는 시각(0~23)입니다. 매일, 매주, 매월 리셋 타입과 조합하여 사용됩니다. ※ resetType이(가) “monthly”,“weekly”,“daily"이면 필수 | |||||||||||||||||
| conditionName | string | {scopeType} == “verifyAction” | ✓※ | ~ 128자 | 조건명 이 검증 액션 조건 스코프를 식별하는 고유한 이름입니다. 카운터 내에서 대응하는 스코프 값을 조회하는 데 사용됩니다. scopeType 이 “verifyAction” 인 경우에만 사용됩니다. ※ scopeType이(가) “verifyAction” 이면 필수 | |||||||||||||||||
| condition | EzVerifyAction | {scopeType} == “verifyAction” | ✓※ | 조건 이 스코프의 카운터 값이 적용되는지 여부를 판정하는 검증 액션입니다. scopeType이 “verifyAction"인 경우에만 사용됩니다. ※ scopeType이(가) “verifyAction” 이면 필수 | ||||||||||||||||||
| anchorTimestamp | long | {resetType} == “days” | ✓※ | 경과 일수를 계산하는 기준 일시 UNIX 시간(밀리초) ※ resetType이(가) “days” 이면 필수 | ||||||||||||||||||
| days | int | {resetType} == “days” | ✓※ | 1 ~ 2147483646 | 리셋하는 일수 기준 일시부터 카운트되는 카운터 값의 리셋 간격 일수입니다. resetType이 “days"인 경우에만 사용됩니다. ※ resetType이(가) “days” 이면 필수 |
EzCounterModel
카운터 모델
카운터 모델은 미션 태스크의 달성 조건으로 설정할 수 있는 엔티티입니다.
카운터 값은 여러 미션 그룹에서 참조할 수 있기 때문에, 하나의 카운터를 위클리 미션과 데일리 미션 같은 여러 미션 그룹의 달성 조건으로 설정할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 카운터 모델명 카운터 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| metadata | string | ~ 1024자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||
| scopes | List<EzCounterScopeModel> | [] | 1 ~ 20 items | 카운터의 리셋 타이밍 목록 이 카운터의 스코프(리셋 타이밍 또는 검증 액션 조건)를 정의합니다. 하나의 카운터에 여러 스코프를 설정할 수 있으며, 서로 다른 기간의 값(예: 데일리, 위클리, 누계를 동시에)을 추적할 수 있습니다. | ||
| challengePeriodEventId | string | ~ 1024자 | 카운터를 조작할 수 있는 기간을 설정한 GS2-Schedule 이벤트 GRN
이 카운터의 증감이 가능한 기간을 정의하는 GS2-Schedule 이벤트를 지정합니다. 설정하지 않은 경우, 카운터는 언제든지 조작할 수 있습니다. |
EzMissionGroupModel
미션 그룹 모델
미션 그룹은 카운터의 리셋 타이밍으로 태스크를 그룹화하는 엔티티입니다.
예를 들어, 데일리 미션으로 하나의 그룹, 위클리 미션으로 하나의 그룹이 됩니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 미션 그룹 모델 이름 미션 그룹 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||||||||||||
| metadata | string | ~ 1024자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||||||||||||||||||
| tasks | List<EzMissionTaskModel> | [] | 0 ~ 1000 items | 미션 태스크 리스트 이 그룹에 속하는 미션 태스크입니다. 각 태스크는 달성 조건(카운터의 임계값 또는 검증 액션)과 달성 시 부여되는 보상을 정의합니다. | ||||||||||||||||||
| resetType | 문자열 열거형 enum { “notReset”, “daily”, “weekly”, “monthly”, “days” } | “notReset” | 리셋 타이밍 미션 그룹의 달성 상황이 리셋되는 타이밍을 결정합니다. 리셋하지 않음(영구), 매일, 매주, 매월, 기준 일시부터 일정 일수마다 중에서 선택합니다.
| |||||||||||||||||||
| resetDayOfMonth | int | {resetType} == “monthly” | ✓※ | 1 ~ 31 | 리셋하는 날짜 미션 그룹이 리셋되는 월의 날짜입니다. 지정한 값이 해당 월의 일수를 초과하는 경우, 그 달의 마지막 날로 처리됩니다. resetType이 “monthly"인 경우에만 사용됩니다. ※ resetType이(가) “monthly” 이면 필수 | |||||||||||||||||
| resetDayOfWeek | 문자열 열거형 enum { “sunday”, “monday”, “tuesday”, “wednesday”, “thursday”, “friday”, “saturday” } | {resetType} == “weekly” | ✓※ | 리셋하는 요일 미션 그룹이 리셋되는 요일입니다. resetType이 “weekly"인 경우에만 사용됩니다.
※ resetType이(가) “weekly” 이면 필수 | ||||||||||||||||||
| resetHour | int | {resetType} in [“monthly”, “weekly”, “daily”] | ✓※ | 0 ~ 23 | 리셋 시각 미션 그룹이 리셋되는 시각(0~23)입니다. 매일, 매주, 매월 리셋 타입과 조합하여 사용됩니다. ※ resetType이(가) “monthly”,“weekly”,“daily"이면 필수 | |||||||||||||||||
| completeNotificationNamespaceId | string | ~ 1024자 | 미션 태스크를 달성했을 때의 푸시 통지 이 그룹 내의 미션 태스크가 달성되었을 때 푸시 통지를 전송하는 데 사용되는 GS2-Gateway의 네임스페이스 GRN입니다. 게임 클라이언트에 실시간으로 통지할 수 있습니다. |
EzMissionTaskModel
미션 태스크 모델
미션 태스크는 연결된 카운터의 값이 일정 수준을 초과하면 보상을 받을 수 있는 조건을 정의하는 엔티티입니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 미션 태스크 모델 이름 미션 태스크 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||
| metadata | string | ~ 1024자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||||||||
| verifyCompleteType | 문자열 열거형 enum { “counter”, “verifyActions” } | “counter” | 달성 조건 종류 미션 태스크의 달성 판정 방법을 지정합니다. “counter"는 관련된 카운터의 스코프 값이 목표 임곗값에 도달했는지 확인합니다. “verifyActions"는 검증 액션을 사용하여 달성 조건을 확인합니다.
| |||||||||
| targetCounter | EzTargetCounterModel | {verifyCompleteType} == “counter” | ✓※ | 목표 카운터 미션 태스크의 달성 판정에 사용되는 카운터, 스코프, 목표값을 정의합니다. 카운터의 스코프 값이 지정된 목표값에 도달하거나 초과한 경우, 태스크가 달성된 것으로 간주됩니다. ※ verifyCompleteType이(가) “counter” 이면 필수 | ||||||||
| verifyCompleteConsumeActions | List<EzVerifyAction> | {verifyCompleteType} == “verifyActions” | [] | 0 ~ 10 items | 태스크 달성 판정에 사용하는 검증 액션 미션 태스크의 달성 판정에 사용되는 검증 액션의 목록입니다. 모든 검증 액션이 성공한 경우 태스크가 달성된 것으로 간주됩니다. verifyCompleteType이 “verifyActions"인 경우에만 사용됩니다. ※ verifyCompleteType이(가) “verifyActions” 이면 활성화 | |||||||
| completeAcquireActions | List<EzAcquireAction> | [] | 0 ~ 100 items | 미션 달성 시 보상 플레이어가 미션 달성 보상을 받을 때 실행되는 입수 액션의 목록입니다. | ||||||||
| challengePeriodEventId | string | ~ 1024자 | 보상을 받을 수 있는 기간을 설정한 GS2-Schedule 이벤트 GRN
미션 태스크의 보상을 받을 수 있는 기간을 정의하는 GS2-Schedule 이벤트를 지정합니다. 설정하지 않은 경우, 달성 후 언제든지 보상을 받을 수 있습니다. | |||||||||
| premiseMissionTaskName | string | ~ 128자 | 이 태스크에 도전하기 위해 달성해 두어야 하는 태스크의 이름 이 태스크의 보상을 받기 전에 달성해 두어야 하는, 같은 그룹 내의 전제 미션 태스크를 지정합니다. 단계적인 미션 체인을 만드는 데 사용합니다. |
EzTargetCounterModel
목표 카운터
미션의 달성 목표가 되는 카운터의 정보
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| counterName | string | ✓ | ~ 128자 | 카운터 모델명 카운터 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||||||||
| scopeType | 문자열 열거형 enum { “resetTiming”, “verifyAction” } | “resetTiming” | 스코프 종류 미션 달성 판정에 사용하는 카운터 스코프의 종류를 지정합니다. “resetTiming"은 특정 리셋 기간의 카운터 값을 평가하고, “verifyAction"은 이름이 지정된 조건의 값을 평가합니다.
| |||||||||||||||
| resetType | 문자열 열거형 enum { “notReset”, “daily”, “weekly”, “monthly”, “days” } | {scopeType} == “resetTiming” | 목표 리셋 타이밍 목표값과 비교할 카운터의 리셋 타이밍 스코프를 지정합니다. 예를 들어 “daily"를 선택하면 데일리 카운터 값을 확인합니다. 생략한 경우, 미션 그룹의 리셋 타이밍이 사용됩니다.
※ scopeType이(가) “resetTiming” 이면 활성화 | |||||||||||||||
| conditionName | string | {scopeType} == “verifyAction” | ✓※ | ~ 128자 | 조건 이름 목표값과 비교할 검증 액션 조건 스코프의 이름입니다. 카운터 모델의 스코프에서 정의된 conditionName과 일치해야 합니다. scopeType이 “verifyAction"인 경우에만 사용됩니다. ※ scopeType이(가) “verifyAction” 이면 필수 | |||||||||||||
| value | long | ✓ | 0 ~ 9223372036854775805 | 목표값 미션 태스크가 달성된 것으로 간주되기 위해, 카운터의 스코프 값이 도달하거나 초과해야 하는 임곗값입니다. |
EzConfig
컨피그 설정
트랜잭션의 변수에 적용하는 설정 값
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| key | string | ✓ | ~ 64자 | 이름 | ||
| value | string | ~ 51200자 | 값 |
EzAcquireAction
입수 액션
EzConsumeAction
소비 액션
EzVerifyAction
검증 액션
작업을 실행하기 전에 조건을 검증하는 액션을 정의합니다.
미수령 보너스 구제에서 구제를 허용하기 전에 전제 조건(사용자 자격, 리소스 이용 가능 여부 등)을 확인하는 데 사용됩니다.
action 필드는 검증 액션의 종류를 지정하고, request 필드에는 그에 대응하는 요청 매개변수가 포함됩니다.
EzScopedValue
스코프 값
특정 스코프 내의 카운터 값을 나타냅니다. 각 스코프 값은 특정 리셋 타이밍(예: 매일, 매주, 매월) 또는 검증 액션 조건의 누적 카운트를 보유합니다. 리셋 타이밍이 도래하면 값은 0으로 리셋됩니다. 카운터 값에는 상한이 있으며, 증가하더라도 최댓값을 초과하지 않습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| scopeType | 문자열 열거형 enum { “resetTiming”, “verifyAction” } | “resetTiming” | 스코프 종류 이 스코프 값이 리셋 타이밍 스케줄에 기반한 것인지, 검증 액션 조건에 기반한 것인지를 나타냅니다.
| |||||||||||||||
| resetType | 문자열 열거형 enum { “notReset”, “daily”, “weekly”, “monthly”, “days” } | {scopeType} == “resetTiming” | ✓※ | 리셋 타이밍 이 스코프 값의 리셋 타이밍입니다. 카운터 값이 리셋될 때까지의 누적 기간을 결정합니다. scopeType이 “resetTiming"인 경우에만 적용됩니다.
※ scopeType이(가) “resetTiming” 이면 필수 | ||||||||||||||
| conditionName | string | {scopeType} == “verifyAction” | ✓※ | ~ 128자 | 조건 이름 이 스코프 값이 대응하는 검증 액션 조건의 이름입니다. 이 값이 어느 조건 스코프에 속하는지 식별하는 데 사용됩니다. scopeType이 “verifyAction"인 경우에만 적용됩니다. ※ scopeType이(가) “verifyAction” 이면 필수 | |||||||||||||
| value | long | 0 | 0 ~ 9223372036854775805 | 카운트 이 스코프의 누적 카운터 값입니다. 카운터가 증가하면 늘어나고 감소하면 줄어듭니다. 값은 최댓값으로 상한이 설정되며, 0 미만으로 내려가지 않습니다. |
EzVerifyActionResult
검증 액션 실행 결과
EzConsumeActionResult
소비 액션 실행 결과
EzAcquireActionResult
획득 액션 실행 결과
EzTransactionResult
트랜잭션 실행 결과
서버 사이드에서 트랜잭션 자동 실행 기능을 이용하여 실행된 트랜잭션의 실행 결과
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| transactionId | string | ✓ | 36 ~ 36자 | 트랜잭션 ID | ||
| verifyResults | List<EzVerifyActionResult> | 0 ~ 10 items | 검증 액션의 실행 결과 목록 | |||
| consumeResults | List<EzConsumeActionResult> | [] | 0 ~ 10 items | 소비 액션의 실행 결과 목록 | ||
| acquireResults | List<EzAcquireActionResult> | [] | 0 ~ 100 items | 획득 액션 실행 결과 리스트 |
메서드
batchReceiveRewards
여러 개의 달성 미션 보상을 한꺼번에 수령합니다
같은 그룹 내의 여러 미션 태스크의 보상을 한 번의 호출로 수령합니다.
미션 UI의 “일괄 수령” 버튼에 대응합니다. 플레이어가 각 미션의 “수령하기"를 하나씩 탭하는 대신, 한꺼번에 수령할 수 있습니다.
지정된 모든 태스크는 달성 완료 상태이며 아직 수령하지 않은 상태여야 합니다. 모든 태스크의 보상이 하나의 트랜잭션으로 합쳐집니다.
예를 들어 “전투에서 3회 승리”(보상: 젬 50개)와 “골드 500 수집”(보상: 가챠 티켓 1장)을 달성한 경우, 두 태스크 이름을 함께 지정하여 호출하면 젬 50개 + 가챠 티켓 1장이 한 번의 조작으로 지급됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹명 이 달성 상황 레코드가 속한 미션 그룹의 이름입니다. 사용자별·미션 그룹별로 하나의 달성 상황 레코드가 존재합니다. | ||
| missionTaskNames | List<string> | ✓ | 1 ~ 100 items | 태스크 이름 리스트 | ||
| gameSession | GameSession | ✓ | GameSession | |||
| config | List<EzConfig> | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |
Result
| 타입 | 설명 | |
|---|---|---|
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 미션 달성 보상을 수령하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var result = await domain.BatchReceiveRewardsAsync(
missionTaskNames: new List<string> {
"mission-task-0001",
"mission-task-0002",
},
config: null
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var future = domain.BatchReceiveRewardsFuture(
missionTaskNames: new List<string> {
"mission-task-0001",
"mission-task-0002",
},
config: null
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Complete(
"mission-group-0001" // missionGroupName
);
const auto Future = Domain->BatchReceiveRewards(
[]
{
auto v = TOptional<TArray<FString>>();
v->Add("mission-task-0001");
v->Add("mission-task-0002");
return v;
}() // missionTaskNames
// config
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).complete(
"mission-group-0001"
)
var async_result = await domain.batch_receive_rewards(
[
"mission-task-0001",
"mission-task-0002",
], # mission_task_names
null # config
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultevaluateComplete
미션 달성 상태를 재평가합니다
지정된 그룹 내의 모든 카운터 값을 미션 태스크 조건과 대조하여 달성 상태를 갱신합니다.
일반적으로 미션 달성 판정은 카운터가 가산될 때마다 자동으로 이루어집니다. 그러나 카운터가 이미 가산된 후에 기존 그룹에 새로운 미션 태스크를 추가한 경우, 새로운 태스크는 자동으로 평가되지 않습니다.
이러한 상황에서 이 API를 호출하면, 플레이어의 기존 카운터 값이 새로운 태스크의 조건을 이미 충족하고 있는지를 소급하여 확인할 수 있습니다.
예: 데일리 미션에 “전투에서 1회 승리"를 새로 추가한 경우. 오늘 이미 전투에서 승리한 플레이어는 조건을 충족하는 카운터 값을 가지고 있지만, 시스템은 아직 이를 인식하지 못한 상태입니다. EvaluateComplete 를 호출하면 확인이 이루어져 달성 완료로 표시됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹명 이 달성 상황 레코드가 속한 미션 그룹의 이름입니다. 사용자별·미션 그룹별로 하나의 달성 상황 레코드가 존재합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzComplete | 재평가 후의 달성 상황 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var result = await domain.EvaluateCompleteAsync(
);
var item = await result.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var future = domain.EvaluateCompleteFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Complete(
"mission-group-0001" // missionGroupName
);
const auto Future = Domain->EvaluateComplete(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// 변경된 값 / 결과 값을 취득
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).complete(
"mission-group-0001"
)
var async_result = await domain.evaluate_complete(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultgetComplete
특정 미션 그룹에 대한 플레이어의 달성 상태를 취득합니다
지정된 미션 그룹 내에서 플레이어가 어떤 미션 태스크를 달성했고 어떤 보상을 수령했는지를 취득합니다.
특정 그룹의 미션 목록 화면을 표시할 때 사용합니다. 예를 들어 각 데일리 미션과 그 상태를 다음과 같이 표시할 수 있습니다:
- “전투에서 3회 승리” — 달성, 보상 수령 완료(체크 표시)
- “골드 500 수집” — 달성, 보상 수령 가능!(수령 버튼)
- “아이템 10회 사용” — 진행 중: 7/10(진행률 바)
ListMissionTaskModels 나 GetMissionGroupModel 과 조합하면 태스크 정의(목표, 임계값, 보상)를 얻을 수 있고, GetCounter 와 조합하면 진행률 바 표시용 현재 카운터 값을 얻을 수 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹명 이 달성 상황 레코드가 속한 미션 그룹의 이름입니다. 사용자별·미션 그룹별로 하나의 달성 상황 레코드가 존재합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzComplete | 달성 상황 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Complete(
"mission-group-0001" // missionGroupName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).complete(
"mission-group-0001"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Complete(
"mission-group-0001" // missionGroupName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Mission::Model::FComplete> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).complete(
"mission-group-0001"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listCompletes
전체 그룹에 대한 플레이어의 미션 달성 상황 조회
모든 미션 그룹의 달성 상황과 보상 수령 상황을 조회합니다.
각 항목에는 플레이어가 어떤 미션 태스크를 달성했는지(카운터의 임계값을 충족했는지)와 어떤 보상을 수령했는지가 포함됩니다.
미션 개요 화면을 만들 때 사용합니다. 예를 들어, 미수령 보상이 있는 그룹에 배지나 알림 점을 표시할 수 있습니다:
「데일리 미션(보상 2건 수령 가능!)」「위클리 미션(완료)」「업적(신규 1건!)」
미션 태스크에는 두 가지 상태가 있습니다:
- 달성(Completed): 카운터가 임계값을 충족한 상태(예: 「배틀에서 5회 승리」에서 5회 이상 승리한 경우)
- 수령(Received): 달성한 태스크의 보상을 플레이어가 수령한 상태
「달성 완료이지만 미수령」 상태의 태스크는 플레이어가 보상을 획득했지만 아직 수령하지 않았음을 의미합니다. UI에서는 이 상태를 강조 표시해야 합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| pageToken | string | ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 | |||
| limit | int | 30 | 1 ~ 1000 | 취득할 데이터 건수 |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzComplete> | 달성 상황 리스트 |
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.CompletesAsync(
).ToListAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Completes(
);
List<EzComplete> items = new List<EzComplete>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Completes(
);
TArray<Gs2::UE5::Mission::Model::FEzCompletePtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeCompletes(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeCompletes(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeCompletes(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeCompletes(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeCompletes(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeCompletes(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
receiveRewards
달성한 미션의 보상을 수령합니다
플레이어가 달성한 미션 태스크의 보상을 수령합니다.
태스크는 달성 완료(카운터가 임계값을 충족한 상태) 상태이며 아직 수령하지 않은 상태여야 합니다.
호출하면 설정된 보상이 플레이어에게 지급됩니다. 예를 들어 젬 100개, 가챠 티켓, 골드 500과 같은 보상입니다.
미션 UI의 “수령하기” “받기” 버튼에 대응합니다. 일반적인 흐름은 다음과 같습니다:
- 플레이어가 달성 완료되어 수령 가능한 보상이 있는 미션을 확인합니다
- 플레이어가 “수령하기” 버튼을 탭합니다
- 게임이 ReceiveRewards 를 호출합니다
- 보상이 지급되고 태스크가 “수령 완료"로 표시됩니다
태스크가 아직 달성되지 않았거나 보상을 이미 수령한 경우에는 오류가 반환됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹명 이 달성 상황 레코드가 속한 미션 그룹의 이름입니다. 사용자별·미션 그룹별로 하나의 달성 상황 레코드가 존재합니다. | ||
| missionTaskName | string | ✓ | ~ 128자 | 태스크 이름 태스크 고유의 이름입니다. 영숫자와 -(하이픈), _(언더스코어), .(마침표)를 사용하여 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| config | List<EzConfig> | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |
Result
| 타입 | 설명 | |
|---|---|---|
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 미션 달성 보상을 수령하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var result = await domain.ReceiveRewardsAsync(
missionTaskName: "mission-task-0001",
config: null
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Complete(
missionGroupName: "mission-group-0001"
);
var future = domain.ReceiveRewardsFuture(
missionTaskName: "mission-task-0001",
config: null
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Complete(
"mission-group-0001" // missionGroupName
);
const auto Future = Domain->ReceiveRewards(
"mission-task-0001" // missionTaskName
// config
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).complete(
"mission-group-0001"
)
var async_result = await domain.receive_rewards(
"mission-task-0001", # mission_task_name
null # config
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultdecreaseCounter
카운터를 감소시키기
지정한 카운터의 값을 감소시킵니다. 감소시킬 값을 지정합니다.
현재 시점에서 유효한 스코프만 감소 대상이 됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| counterName | string | ✓ | ~ 128자 | 카운터 모델 이름 이 카운터 인스턴스의 기반이 되는 카운터 모델의 이름입니다. 스코프와 리셋 타이밍을 정의하는 카운터 모델 정의에 연결됩니다. | ||
| value | long | ✓ | 1 ~ 9223372036854775805 | 감산할 값 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzCounter | 감산된 카운터 |
| changedCompletes | List<EzComplete> | 갱신된 달성 상황 리스트 |
Error
이 API에는 특별한 예외가 정의되어 있습니다.
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.
일반적인 에러의 종류와 핸들링 방법은 여기 문서를 참고해 주세요.
| 타입 | 베이스 클래스 | 설명 |
|---|---|---|
| ConflictException | ConflictException | 카운터 상승 처리가 충돌했습니다. 재시도가 필요합니다 |
구현 예제
try {
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "counter-0001"
);
var result = await domain.DecreaseCounterAsync(
value: 1L
);
var item = await result.ModelAsync();
var changedCompletes = result.ChangedCompletes;
} catch(Gs2.Gs2Mission.Exception.ConflictException e) {
// The counter ascent process has conflicted. Retry required.
} var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "counter-0001"
);
var future = domain.DecreaseCounterFuture(
value: 1L
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Mission.Exception.ConflictException)
{
// The counter ascent process has conflicted. Retry required.
}
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result;
var changedCompletes = future.Result.ChangedCompletes; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Counter(
"counter-0001" // counterName
);
const auto Future = Domain->DecreaseCounter(
1L // value
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Mission::Error::FConflictError::Class))
{
// The counter ascent process has conflicted. Retry required.
}
return false;
}
// 변경된 값 / 결과 값을 취득
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();
const auto ChangedCompletes = Result->ChangedCompletes;var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).counter(
"counter-0001"
)
var async_result = await domain.decrease_counter(
1 # value
)
if async_result.error != null:
if async_result.error is Gs2MissionConflictException:
# 카운터 상승 처리가 충돌했습니다. 재시도가 필요합니다
pass
push_error(str(async_result.error))
return
var result = async_result.resultdeleteCounter
카운터를 완전히 삭제
플레이어의 지정된 카운터와 그 모든 스코프 값을 삭제합니다.
ResetCounter(특정 스코프만 리셋)와 달리, 플레이어가 한 번도 진행 상황을 가진 적이 없었던 것처럼 카운터 전체를 삭제합니다.
특정 카운터에 대한 플레이어의 진행 상황을 완전히 초기화하고 싶을 때 사용합니다. 예를 들어, 미션의 완전 리셋 기능을 구현하는 경우 등입니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| counterName | string | ✓ | ~ 128자 | 카운터 모델 이름 이 카운터 인스턴스의 기반이 되는 카운터 모델의 이름입니다. 스코프와 리셋 타이밍을 정의하는 카운터 모델 정의에 연결됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzCounter | 삭제한 카운터 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "counter-0001"
);
var result = await domain.DeleteCounterAsync(
); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "counter-0001"
);
var future = domain.DeleteCounterFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
} const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Counter(
"counter-0001" // counterName
);
const auto Future = Domain->DeleteCounter(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
const auto Result = Future->GetTask().Result();var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).counter(
"counter-0001"
)
var async_result = await domain.delete_counter(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultgetCounter
특정 카운터에 대한 플레이어의 값 조회
플레이어의 특정 카운터의 현재 값을 모든 스코프 값을 포함하여 조회합니다.
예를 들어 「battle_wins」 카운터의 경우, 일간=3, 주간=12, 누계=87 과 같은 값이 반환됩니다.
특정 목표에 대한 미션 진행 상황을 표시할 때 사용합니다. 예를 들어 데일리 미션 옆에 진행률 바 「오늘의 배틀 승리 수 3/5」와 같이 표시할 수 있습니다.
각 스코프 값은 서로 다른 기간에 걸쳐 추적된 카운터를 나타내며, 단기적인 진행 상황과 장기적인 진행 상황을 모두 표시할 수 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| counterName | string | ✓ | ~ 128자 | 카운터 모델 이름 이 카운터 인스턴스의 기반이 되는 카운터 모델의 이름입니다. 스코프와 리셋 타이밍을 정의하는 카운터 모델 정의에 연결됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzCounter | 카운터 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "quest_complete"
);
var item = await domain.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "quest_complete"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Counter(
"quest_complete" // counterName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).counter(
"quest_complete"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "quest_complete"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "quest_complete"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Counter(
"quest_complete" // counterName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Mission::Model::FCounter> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).counter(
"quest_complete"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listCounters
플레이어의 현재 카운터 값 조회
플레이어의 모든 카운터 값을 조회합니다.
각 카운터는 특정 플레이어 액션(배틀 승리 횟수, 아이템 수집 수, 골드 획득량 등)을 추적하며, 각 스코프(일간·주간·월간·누계)별 값을 가집니다.
플레이어의 미션 진행 상황 개요를 표시할 때 사용합니다. 예를 들어 「오늘의 배틀 승리 수: 3」이나 「퀘스트 누적 클리어 수: 42」와 같이 상태나 미션 화면에서 표시할 수 있습니다.
카운터 값은 플레이어가 게임 내에서 액션을 수행했을 때(다른 서비스의 보상 액션을 통해) 자동으로 가산되며, 미션 태스크의 임계값과 자동으로 대조됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| pageToken | string | ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 | |||
| limit | int | 30 | 1 ~ 1000 | 취득할 데이터 건수 |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzCounter> | 카운터 리스트 |
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.CountersAsync(
).ToListAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Counters(
);
List<EzCounter> items = new List<EzCounter>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Counters(
);
TArray<Gs2::UE5::Mission::Model::FEzCounterPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeCounters(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeCounters(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeCounters(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeCounters(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeCounters(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeCounters(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
resetCounter
카운터의 특정 스코프 리셋
지정된 스코프의 카운터 값만 리셋합니다.
예를 들어, 주간이나 누계 값에 영향을 주지 않고 일간 스코프만 리셋할 수 있습니다.
특정 기간의 진행 상황을 수동으로 리셋하고 싶을 때 사용합니다. 예를 들어, 플레이어가 특수 아이템을 사용해 데일리 미션을 재도전할 때 「데일리 챌린지」 카운터를 리셋하는 경우입니다.
지정된 스코프 타입과 일치하는 스코프별 값만 리셋되며, 그 외의 스코프별 값은 변경되지 않습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| counterName | string | ✓ | ~ 128자 | 카운터 모델 이름 이 카운터 인스턴스의 기반이 되는 카운터 모델의 이름입니다. 스코프와 리셋 타이밍을 정의하는 카운터 모델 정의에 연결됩니다. | ||
| scopes | List<EzScopedValue> | ✓ | 1 ~ 20 items | 스코프 리스트 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzCounter | 삭제한 카운터 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "counter-0001"
);
var result = await domain.ResetCounterAsync(
scopes: new List<Gs2.Unity.Gs2Mission.Model.EzScopedValue> {
new Gs2.Unity.Gs2Mission.Model.EzScopedValue() {
ResetType = "daily",
},
new Gs2.Unity.Gs2Mission.Model.EzScopedValue() {
ResetType = "weekly",
},
}
);
var item = await result.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Counter(
counterName: "counter-0001"
);
var future = domain.ResetCounterFuture(
scopes: new List<Gs2.Unity.Gs2Mission.Model.EzScopedValue> {
new Gs2.Unity.Gs2Mission.Model.EzScopedValue() {
ResetType = "daily",
},
new Gs2.Unity.Gs2Mission.Model.EzScopedValue() {
ResetType = "weekly",
},
}
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Counter(
"counter-0001" // counterName
);
const auto Future = Domain->ResetCounter(
[]
{
auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Mission::Model::FEzScopedValue>>>();
v->Add(
MakeShared<Gs2::UE5::Mission::Model::FEzScopedValue>()
->WithResetType(TOptional<FString>("daily"))
);
v->Add(
MakeShared<Gs2::UE5::Mission::Model::FEzScopedValue>()
->WithResetType(TOptional<FString>("weekly"))
);
return v;
}() // scopes
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// 변경된 값 / 결과 값을 취득
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();var domain = ez.mission.namespace_(
"namespace-0001"
).me(game_session).counter(
"counter-0001"
)
var async_result = await domain.reset_counter(
[
Gs2MissionEzScopedValue.new()
.with_reset_type("daily"),
Gs2MissionEzScopedValue.new()
.with_reset_type("weekly"),
] # scopes
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultgetCounterModel
특정 카운터 정의의 상세 정보를 취득합니다
카운터 이름을 지정하여 스코프와 리셋 조건을 포함한 상세 정보를 취득합니다.
카운터가 무엇을 추적하고 그 값이 어떻게 관리되는지를 파악할 때 사용합니다. 예를 들어 미션의 진행에 어떤 액션이 기여하는지를 플레이어에게 표시하는 경우 등입니다.
응답에는 이 카운터에 정의된 스코프 목록이 포함되며, 각 스코프에는 리셋 타입(일별·주별·월별·없음)과 리셋 타이밍이 설정되어 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| counterName | string | ✓ | ~ 128자 | 카운터 모델명 카운터 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzCounterModel | 카운터 모델 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).CounterModel(
counterName: "counter-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).CounterModel(
counterName: "counter-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->CounterModel(
"counter-0001" // counterName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).counter_model(
"counter-0001"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).CounterModel(
counterName: "counter-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).CounterModel(
counterName: "counter-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->CounterModel(
"counter-0001" // counterName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Mission::Model::FCounterModel> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.mission.namespace_(
"namespace-0001"
).counter_model(
"counter-0001"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listCounterModels
카운터 정의 목록을 취득합니다
네임스페이스에 정의된 모든 카운터 모델을 취득합니다.
카운터는 플레이어의 행동을 추적하고 미션 달성 판정에 사용되는 값입니다. 예를 들어 “battle_wins” 카운터는 전투 승리 횟수를 추적하고, “gold_collected” 카운터는 획득한 골드의 합계를 추적합니다.
각 카운터 모델에서는 하나 이상의 “스코프"를 정의합니다. 스코프는 카운터 값이 어떤 기간 단위로 추적되는지를 결정합니다:
- 하나의 카운터로 일별·주별·월별·누계 값을 동시에 추적할 수 있습니다
- 예를 들어 “battle_wins” 카운터는 오늘의 승리 수(일별 스코프), 이번 주의 승리 수(주별 스코프), 누계 승리 수(누계 스코프)를 가질 수 있습니다
- 서로 다른 미션 태스크가 같은 카운터의 서로 다른 스코프를 참조할 수 있습니다(예: “오늘 전투에서 3회 승리"는 일별 스코프를, “누계 100회 승리"는 누계 스코프를 사용)
카운터 값은 일반적으로 다른 GS2 서비스의 보상 액션으로서 자동으로 가산됩니다(예: 퀘스트 클리어 시나 아이템 구매 시)만, 게임 서버에서 수동으로 가산할 수도 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzCounterModel> | 카운터 모델 리스트 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.CounterModelsAsync(
).ToListAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.CounterModels(
);
List<EzCounterModel> items = new List<EzCounterModel>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->CounterModels(
);
TArray<Gs2::UE5::Mission::Model::FEzCounterModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeCounterModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeCounterModels(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeCounterModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeCounterModels(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeCounterModels(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeCounterModels(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getMissionGroupModel
특정 미션 그룹의 상세 정보를 취득합니다
미션 그룹 이름을 지정하여 리셋 타입, 리셋 타이밍 설정, 그리고 포함된 미션 태스크 목록을 포함한 상세 정보를 취득합니다.
특정 그룹 내의 미션 목록을 표시할 때 사용합니다. 예를 들어 플레이어가 “데일리 미션” 탭을 탭했을 때, 이 API를 호출하여 모든 데일리 미션 태스크와 그 상세 정보를 취득합니다.
응답에는 그룹에 정의된 미션 태스크가 포함되며, 각 태스크에는 대상 카운터 조건과 보상 설정이 있습니다.
GetComplete 와 조합하면 각 태스크에 대한 플레이어의 진행 상황과 달성 상태를 표시할 수 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹 모델 이름 미션 그룹 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzMissionGroupModel | 미션 그룹 모델 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->MissionGroupModel(
"mission-group-0001" // missionGroupName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).mission_group_model(
"mission-group-0001"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->MissionGroupModel(
"mission-group-0001" // missionGroupName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Mission::Model::FMissionGroupModel> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.mission.namespace_(
"namespace-0001"
).mission_group_model(
"mission-group-0001"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listMissionGroupModels
미션 그룹 목록을 취득합니다
네임스페이스에 정의된 모든 미션 그룹을 취득합니다.
미션 그룹은 개별 미션을 하나로 묶는 카테고리입니다. 예를 들어 “데일리 미션”, “위클리 미션”, “스토리 미션”, “업적 미션"과 같은 것입니다.
각 그룹에는 리셋 타입이 있으며, 그룹 내 미션이 언제 리셋되는지를 결정합니다:
- notReset: 리셋하지 않음(“스테이지 10 클리어”, “캐릭터 100체 수집"과 같은 영구적인 업적)
- daily: 매일 리셋(예: “오늘 전투에서 3회 승리”)
- weekly: 매주 리셋(예: “이번 주 5일 로그인”)
- monthly: 매월 리셋(예: “이번 달 골드 10,000 소비”)
미션의 메인 목록 화면을 만들 때 사용합니다. 예를 들어 “데일리”, “위클리”, “업적” 탭을 표시하는 화면입니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzMissionGroupModel> | 미션 그룹 모델 리스트 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.MissionGroupModelsAsync(
).ToListAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.MissionGroupModels(
);
List<EzMissionGroupModel> items = new List<EzMissionGroupModel>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->MissionGroupModels(
);
TArray<Gs2::UE5::Mission::Model::FEzMissionGroupModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeMissionGroupModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeMissionGroupModels(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeMissionGroupModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeMissionGroupModels(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeMissionGroupModels(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeMissionGroupModels(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getMissionTaskModel
특정 미션 태스크의 상세 정보를 취득합니다
지정된 미션 그룹 내의 특정 미션 태스크를 이름을 지정하여 취득합니다.
특정 미션의 상세 화면을 표시할 때 사용합니다. 목표, 현재 진행 상황, 보상, 달성 여부를 표시할 수 있습니다.
응답에는 다음이 포함됩니다:
- 대상 카운터 이름과 임계값(플레이어가 달성해야 하는 목표)
- 보상 액션(수령 시 플레이어가 획득하는 것)
- 전제 태스크(먼저 달성이 필요한 태스크)가 있는 경우 그 정보
- 달성 판정의 검증 타입
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹 모델 이름 미션 그룹 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionTaskName | string | ✓ | ~ 128자 | 미션 태스크 모델 이름 미션 태스크 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzMissionTaskModel | 미션 태스크 모델 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
).MissionTaskModel(
missionTaskName: "mission-task-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
).MissionTaskModel(
missionTaskName: "mission-task-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->MissionGroupModel(
"mission-group-0001" // missionGroupName
)->MissionTaskModel(
"mission-task-0001" // missionTaskName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.mission.namespace_(
"namespace-0001"
).mission_group_model(
"mission-group-0001"
).mission_task_model(
"mission-task-0001"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
).MissionTaskModel(
missionTaskName: "mission-task-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
).MissionTaskModel(
missionTaskName: "mission-task-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->MissionGroupModel(
"mission-group-0001" // missionGroupName
)->MissionTaskModel(
"mission-task-0001" // missionTaskName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Mission::Model::FMissionTaskModel> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.mission.namespace_(
"namespace-0001"
).mission_group_model(
"mission-group-0001"
).mission_task_model(
"mission-task-0001"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listMissionTaskModels
그룹 내 미션 태스크 목록을 취득합니다
지정된 미션 그룹 내의 모든 개별 미션 태스크를 취득합니다.
각 미션 태스크는 하나의 미션 목표를 나타냅니다. 예를 들어 “전투에서 5회 승리”, “골드 1,000 수집”, “스테이지 3 클리어"와 같은 것입니다.
각 태스크에서는 다음이 정의됩니다:
- 대상 카운터와 임계값(예: 카운터 “battle_wins” 가 5 이상)
- 플레이어가 달성 보상을 수령했을 때 지급되는 보상(예: 젬 100개)
- 전제 태스크(선택 사항)(예: “전투에서 10회 승리"는 “전투에서 5회 승리” 달성 후에만 표시됨)
미션 시스템은 다음과 같이 자동으로 동작합니다:
- 플레이어가 게임 내에서 어떤 행동을 하면(전투 승리, 골드 수집 등) 대응하는 카운터가 가산됩니다
- 시스템이 카운터 값이 태스크의 임계값을 충족하는지 확인합니다
- 충족하면 태스크가 “달성"으로 표시됩니다
- 플레이어는 ReceiveRewards 를 사용하여 보상을 수령할 수 있습니다
그룹 내 각 태스크의 목표와 보상을 포함한 미션 목록을 표시할 때 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| missionGroupName | string | ✓ | ~ 128자 | 미션 그룹 모델 이름 미션 그룹 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzMissionTaskModel> | 미션 태스크 모델 리스트 |
구현 예제
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
var items = await domain.MissionTaskModelsAsync(
).ToListAsync(); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
var it = domain.MissionTaskModels(
);
List<EzMissionTaskModel> items = new List<EzMissionTaskModel>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->MissionGroupModel(
"mission-group-0001" // missionGroupName
);
const auto It = Domain->MissionTaskModels(
);
TArray<Gs2::UE5::Mission::Model::FEzMissionTaskModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeMissionTaskModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeMissionTaskModels(callbackId); var domain = gs2.Mission.Namespace(
namespaceName: "namespace-0001"
).MissionGroupModel(
missionGroupName: "mission-group-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeMissionTaskModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeMissionTaskModels(callbackId); const auto Domain = Gs2->Mission->Namespace(
"namespace-0001" // namespaceName
)->MissionGroupModel(
"mission-group-0001" // missionGroupName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeMissionTaskModels(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeMissionTaskModels(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
이벤트 핸들러
OnCompleteNotification
미션 태스크를 달성했을 때 사용하는 푸시 알림
| 이름 | 타입 | 설명 |
|---|---|---|
| namespaceName | string | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| groupName | string | 미션 그룹명 이 달성 상황 레코드가 속한 미션 그룹의 이름입니다. 사용자별·미션 그룹별로 하나의 달성 상황 레코드가 존재합니다. |
| userId | string | 사용자ID |
| taskName | string | 미션 태스크 이름 |
구현 예제
gs2.Mission.OnCompleteNotification += notification =>
{
var namespaceName = notification.NamespaceName;
var groupName = notification.GroupName;
var userId = notification.UserId;
var taskName = notification.TaskName;
}; gs2.Mission.OnCompleteNotification += notification =>
{
var namespaceName = notification.NamespaceName;
var groupName = notification.GroupName;
var userId = notification.UserId;
var taskName = notification.TaskName;
}; Gs2->Mission->OnCompleteNotification().AddLambda([](const auto Notification)
{
const auto NamespaceName = Notification->NamespaceNameValue;
const auto GroupName = Notification->GroupNameValue;
const auto UserId = Notification->UserIdValue;
const auto TaskName = Notification->TaskNameValue;
}); ez.mission.complete_notification.connect(func(notification):
var namespace_name = notification.namespace_name
var group_name = notification.group_name
var user_id = notification.user_id
var task_name = notification.task_name
)