GS2-SkillTree SDK for Game Engine API 레퍼런스
모델
EzStatus
스킬 트리 해방 상황
특정 플레이어와 프로퍼티에 대한 스킬 트리의 해방 상태를 추적하는 모델입니다.
해방(언락)된 노드명의 목록을 관리합니다. 노드는 해방(목록에 추가), 구속(목록에서 제거), 초기화(전체 삭제)할 수 있습니다.
이미 해방된 노드를 해방하려 하거나, 미해방 노드를 구속하려 하면 오류가 발생합니다.
사용자가 처음 접근했을 때 자동으로 생성됩니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| statusId | string | ※ | ~ 1024자 | 상태
GRN
※ 서버가 자동으로 설정 | ||
| userId | string | ✓ | ~ 128자 | 사용자ID | ||
| releasedNodeNames | List<string> | [] | 0 ~ 1000 items | 해제된 노드 모델명 리스트 이 스킬트리에서 플레이어가 잠금 해제한 노드 모델명 리스트입니다. 해제(추가), 구속(삭제), 리셋(전체 초기화) 작업으로 갱신됩니다. 최대 1000건. |
EzNodeModel
노드 모델
스킬 트리 내의 노드를 정의하는 모델로, 해방 비용·전제 조건·반환 동작을 포함합니다.
각 노드에는 검증 액션(해방 전 조건 확인), 소비 액션(지불할 비용), 먼저 해방되어야 하는 전제 노드를 설정할 수 있습니다.
노드를 구속(미해방 상태로 되돌림)하면, 소비한 리소스가 반환율에 따라 부분적으로 반환됩니다.
반환 입수 액션은 소비 액션에 반환율을 곱하여 자동으로 계산됩니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 노드 모델명 노드 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||
| releaseVerifyActions | List<EzVerifyAction> | [] | 0 ~ 10 items | 해방 검증 액션 목록 이 노드를 해방하기 전에 실행되어 조건이 충족되었는지 확인하는 검증 액션의 목록입니다. 예를 들어 플레이어가 특정 레벨에 도달했는지, 특정 아이템을 소지하고 있는지를 검증할 수 있습니다. 검증 액션 중 하나라도 실패하면 노드 해방이 거부됩니다. 최대 10개 액션. | ||
| releaseConsumeActions | List<EzConsumeAction> | [] | 1 ~ 10 items | 해방 소비 액션 목록 이 노드를 해방할 때 실행되는 소비 액션의 목록으로, 해방 비용을 나타냅니다. 이 액션들은 반환 입수 액션 계산에도 사용됩니다. 노드를 구속할 때 각 소비 액션이 반환율에 따라 역산됩니다. 최소 1개의 소비 액션이 필요합니다. 최대 10개 액션. | ||
| returnAcquireActions | List<EzAcquireAction> | 0 ~ 10 items | 반환 입수 액션 목록 이 노드를 구속(취소)할 때 실행되는 입수 액션의 목록으로, 플레이어에게 반환되는 리소스를 나타냅니다. 이 필드는 해방 소비 액션에 반환율을 곱하여 자동 생성됩니다. 예를 들어 해방 비용이 골드 100이고 반환율이 0.8인 경우, 구속 시 골드 80이 반환됩니다. 최대 10개 액션. | |||
| restrainReturnRate | float | 1.0 | 0.0 ~ 1.0 | 반환율 이 노드를 구속(미해방 상태로 되돌림)했을 때 소비된 리소스가 반환되는 비율입니다. 1.0은 전액 반환, 0.5는 절반 반환, 0.0은 반환 없음을 의미합니다. 기본값은 1.0(전액 반환)입니다. 유효 범위: 0.0~1.0. |
EzConfig
컨피그 설정
트랜잭션의 변수에 적용하는 설정 값
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| key | string | ✓ | ~ 64자 | 이름 | ||
| value | string | ~ 51200자 | 값 |
EzAcquireAction
입수 액션
EzConsumeAction
소비 액션
EzVerifyAction
검증 액션
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 | 획득 액션 실행 결과 리스트 |
메서드
getNodeModel
특정 스킬 트리 노드의 상세 정보 취득
노드 이름을 지정하여 전제 조건, 해방 비용, 반환 설정을 포함한 상세 정보를 취득합니다.
플레이어가 스킬 트리에서 노드를 탭했을 때 상세 정보를 표시하는 데 사용합니다. 예를 들어:
- “파워 스트라이크” — 필요: 기본 공격(해방됨). 비용: 스킬 포인트 3. 효과: 공격력 +50%
- 노드의 구속 반환율이 80%라면, 이 노드를 되돌릴 때 비용의 80%가 반환됩니다
응답에는 다음이 포함됩니다:
- 전제 노드명: 먼저 해방되어야 하는 노드 목록
- 해방 시 소비 액션: 해방을 위해 필요한 비용(예: 스킬 포인트 3 소비)
- 해방 시 검증 액션: 해방을 허용하기 전에 확인되는 조건(예: 플레이어 레벨 >= 10)
- 구속 반환율: 노드를 되돌릴 때 반환되는 리소스의 비율(0.0~1.0)
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| nodeModelName | string | ✓ | ~ 128자 | 노드 모델명 노드 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzNodeModel | 노드 모델 |
구현 예제
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).NodeModel(
nodeModelName: "node-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).NodeModel(
nodeModelName: "node-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->NodeModel(
"node-0001" // nodeModelName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.skill_tree.namespace_(
"namespace-0001"
).node_model(
"node-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.SkillTree.Namespace(
namespaceName: "namespace-0001"
).NodeModel(
nodeModelName: "node-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).NodeModel(
nodeModelName: "node-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->NodeModel(
"node-0001" // nodeModelName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::SkillTree::Model::FNodeModel> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.skill_tree.namespace_(
"namespace-0001"
).node_model(
"node-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의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listNodeModels
스킬 트리의 전체 노드 목록 조회
스킬 트리의 모든 노드 정의를 조회합니다.
각 노드는 플레이어가 리소스를 소비하여 해방(잠금 해제)할 수 있는 스킬, 능력, 또는 강화를 나타냅니다.
스킬 트리는 분기 구조이며, 노드에는 전제 조건이 있습니다. 이후 노드를 해방하려면 이전 노드를 먼저 해방해 두어야 합니다.
예를 들어 “일반 공격” → “파워 스트라이크” → “크리티컬 슬래시"처럼, 각 노드의 해방에는 이전 노드가 필요합니다.
각 노드 정의에는 다음이 포함됩니다:
- 전제 노드: 이 노드를 해방하기 전에 해방되어 있어야 하는 다른 노드
- 해방 비용: 노드를 해방하기 위해 플레이어가 소비해야 하는 리소스(예: 스킬 포인트, 골드, 재료)
- 해방 조건: 추가로 충족해야 하는 요건(예: 최소 레벨)
- 구속 반환율: 플레이어가 나중에 이 노드를 되돌릴(잠글) 때 반환되는 리소스의 비율
스킬 트리 UI를 구축할 때 사용합니다. 모든 노드를 그리고, 전제 조건에 따라 연결하며, 어떤 노드가 해방 가능한지 표시할 수 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzNodeModel> | 노드 모델 리스트 |
구현 예제
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.NodeModelsAsync(
).ToListAsync(); var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.NodeModels(
);
List<EzNodeModel> items = new List<EzNodeModel>();
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->SkillTree->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->NodeModels(
);
TArray<Gs2::UE5::SkillTree::Model::FEzNodeModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeNodeModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeNodeModels(callbackId); var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeNodeModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeNodeModels(callbackId); const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeNodeModels(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeNodeModels(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getStatus
플레이어의 스킬 트리 진행 상황 취득
지정된 프로퍼티 ID의 스킬 트리에서 플레이어가 어떤 노드를 해방(언락)했는지를 취득합니다.
propertyId는 어떤 스킬 트리 인스턴스를 참조할지를 특정합니다. 게임이 캐릭터별로 하나의 스킬 트리를 가지는 경우, propertyId로 캐릭터 ID를 사용할 수 있습니다.
예를 들어 전사 캐릭터와 마법사 캐릭터는 각각 다른 propertyId로 별도의 스킬 트리 진행 상황이 관리됩니다.
스킬 트리 화면을 렌더링할 때 사용합니다. ListNodeModels로 트리 전체 구조를 취득한 후, 플레이어의 해방 상태를 겹쳐서 다음과 같이 표시합니다:
- 해방된 노드(언락됨, 하이라이트 표시)
- 해방 가능한 노드(전제 조건을 충족함, 다음에 해방 가능)
- 잠긴 노드(전제 조건을 아직 충족하지 못함, 회색 처리)
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 사용자마다 여러 개의 독립된 스킬트리 인스턴스를 가지기 위한 식별자입니다. 동일한 네임스페이스 내에서 플레이어가 서로 다른 캐릭터나 컨텍스트에 대해 별도의 스킬트리를 가지는 시나리오를 구현합니다. 최대 1024자. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzStatus | 상태 |
구현 예제
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"property-0001" // propertyId
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.skill_tree.namespace_(
"namespace-0001"
).me(game_session).status(
"property-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.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"property-0001" // propertyId
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::SkillTree::Model::FStatus> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.skill_tree.namespace_(
"namespace-0001"
).me(game_session).status(
"property-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의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
release
스킬 트리 노드 해방
스킬 트리의 하나 이상의 노드를 해방(언락)합니다. 플레이어는 필요한 리소스를 소비하고 노드가 활성화됩니다.
스킬 트리 UI의 “스킬 습득” 또는 “언락” 버튼에 해당합니다. 플레이어가 해방하려는 노드를 탭하면:
- 모든 전제 노드가 이미 해방되었는지 확인합니다
- 해방 조건(검증 액션)을 확인합니다 — 예: 최소 플레이어 레벨
- 해방 비용(소비 액션)을 차감합니다 — 예: 스킬 포인트 3 소비
- 노드가 해방됨으로 표시됩니다
여러 노드 이름을 전달하여 한 번에 여러 노드를 해방할 수 있습니다. 각 노드에 대해 모든 전제 조건과 비용이 검증됩니다.
전제 조건이 충족되지 않았거나 플레이어의 리소스가 부족한 경우, 해방이 실패하며 리소스는 소비되지 않습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| nodeModelNames | List<string> | ✓ | 1 ~ 1000 items | 노드 모델 이름 목록 | ||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 사용자마다 여러 개의 독립된 스킬트리 인스턴스를 가지기 위한 식별자입니다. 동일한 네임스페이스 내에서 플레이어가 서로 다른 캐릭터나 컨텍스트에 대해 별도의 스킬트리를 가지는 시나리오를 구현합니다. 최대 1024자. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzStatus | 상태 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 해방 처리 실행에 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var result = await domain.ReleaseAsync(
nodeModelNames: new List<string> {
"node-0001",
}
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var future = domain.ReleaseFuture(
nodeModelNames: new List<string> {
"node-0001",
}
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"property-0001" // propertyId
);
const auto Future = Domain->Release(
[]
{
auto v = TOptional<TArray<FString>>();
v->Add("node-0001");
return v;
}() // nodeModelNames
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.skill_tree.namespace_(
"namespace-0001"
).me(game_session).status(
"property-0001"
)
var async_result = await domain.release(
[
"node-0001",
] # node_model_names
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultreset
스킬 트리 전체 초기화(전체 리스펙)
스킬 트리의 모든 해방된 노드를 한 번에 미해방 상태로 되돌립니다. 각 노드의 구속 반환율에 따라 리소스가 반환됩니다.
“전체 스킬 초기화” 또는 “전체 리스펙” 버튼에 해당합니다. 플레이어는 스킬 트리를 처음부터 다시 시작합니다.
예를 들어 플레이어가 다양한 비용으로 10개의 노드를 해방한 경우, 10개 모두가 되돌려지고 설정된 반환율에 따라 각각 부분 환불이 이루어집니다.
주요 사용 사례:
- 플레이어가 다른 전략으로 스킬 트리를 다시 구성할 수 있는 “리스펙” 기능
- 모든 플레이어가 처음부터 다시 시작하는 시즌 리셋
- 게임 밸런스 변경으로 현재 빌드가 최적이 아니게 되었을 때 플레이어가 재조정할 수 있도록 하는 경우
Restrain(특정 노드를 선택적으로 되돌림)과 달리, Reset은 의존 관계와 관계없이 트리 전체에 영향을 줍니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 사용자마다 여러 개의 독립된 스킬트리 인스턴스를 가지기 위한 식별자입니다. 동일한 네임스페이스 내에서 플레이어가 서로 다른 캐릭터나 컨텍스트에 대해 별도의 스킬트리를 가지는 시나리오를 구현합니다. 최대 1024자. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzStatus | 상태 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 초기화 처리 실행에 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var result = await domain.ResetAsync(
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var future = domain.ResetFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"property-0001" // propertyId
);
const auto Future = Domain->Reset(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.skill_tree.namespace_(
"namespace-0001"
).me(game_session).status(
"property-0001"
)
var async_result = await domain.reset(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultrestrain
특정 노드를 잠금 상태로 되돌리기
해방된 하나 이상의 노드를 미해방 상태로 되돌립니다. 각 노드의 구속 반환율에 따라 해방 시 소비한 리소스의 일부가 반환됩니다.
“부분적인 리스펙” 기능입니다. 스킬 트리 전체를 초기화하는 대신, 특정 노드만 선택하여 취소할 수 있습니다.
예를 들어 노드 해방에 골드 100이 필요하고 구속 반환율이 0.8(80%)인 경우, 구속 시 골드 80이 반환됩니다.
중요한 규칙:
- 다른 해방된 노드가 의존하고 있는 노드(전제 조건으로 참조되는 노드)는 구속할 수 없습니다
- 다른 해방된 노드의 전제가 되는 노드를 구속하려면, 먼저 의존하는 노드를 구속해야 합니다
- 이를 통해 스킬 트리가 항상 유효한 상태로 유지됩니다(고립된 노드가 발생하지 않습니다)
스킬 트리 UI의 “스킬 취소” 또는 “되돌리기” 기능으로 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| nodeModelNames | List<string> | ✓ | 1 ~ 1000 items | 노드 모델 이름 목록 | ||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 사용자마다 여러 개의 독립된 스킬트리 인스턴스를 가지기 위한 식별자입니다. 동일한 네임스페이스 내에서 플레이어가 서로 다른 캐릭터나 컨텍스트에 대해 별도의 스킬트리를 가지는 시나리오를 구현합니다. 최대 1024자. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzStatus | 상태 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 미해방 상태로 되돌리는 처리 실행에 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var result = await domain.RestrainAsync(
nodeModelNames: new List<string> {
"node-0001",
}
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.SkillTree.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
propertyId: "property-0001"
);
var future = domain.RestrainFuture(
nodeModelNames: new List<string> {
"node-0001",
}
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->SkillTree->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"property-0001" // propertyId
);
const auto Future = Domain->Restrain(
[]
{
auto v = TOptional<TArray<FString>>();
v->Add("node-0001");
return v;
}() // nodeModelNames
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.skill_tree.namespace_(
"namespace-0001"
).me(game_session).status(
"property-0001"
)
var async_result = await domain.restrain(
[
"node-0001",
] # node_model_names
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result