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

# GS2-Enhance SDK for Game Engine API 레퍼런스

게임 엔진용 GS2-Enhance SDK의 모델 사양과 API 레퍼런스



## 모델

### EzProgress

강화 진행 상황<br>

강화 시작 시 생성되며, 종료 시 삭제됩니다.<br>

강화 도중에 앱을 종료한 경우에는 이 데이터가 남은 상태가 되며<br>
엔티티가 보유한 진행 중인 강화 정보로부터 게임을 재개할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ | UUID |  ~ 36자 | 강화 진행 상황 ID<br>강화 진행 상황의 고유 ID를 보유합니다.<br>ID는 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 강화 진행 상황을 식별하는 데 사용됩니다. |
| rateName | string |  | ✓ |  |  ~ 128자 | 강화 레이트 모델 이름<br>이 강화 조작의 파라미터를 정의하는 강화 레이트 모델의 이름입니다. 대상 인벤토리, 소재 인벤토리, 경험치 계층, 보너스 레이트를 지정하는 모델을 참조합니다. |
| propertyId | string |  | ✓ |  |  ~ 1024자 | 강화 대상의 프로퍼티 ID<br>강화되는 GS2-Inventory 아이템의 프로퍼티 ID입니다. 강화 완료 시 경험치를 받는 특정 아이템 인스턴스를 식별합니다. |
| experienceValue | long |  | ✓ |  | 0 ~ 9223372036854775805 | 획득할 수 있는 경험치<br>소비한 소재로부터 산출된 기본 경험치입니다. 이 값은 각 소재의 메타데이터에 정의된 경험치에 소재 수량을 곱한 값의 합계로 결정됩니다. |
| rate | float |  | ✓ |  | 0 ~ 100.0 | 경험치 배율<br>기본 경험치에 적용되는 보너스 배율입니다. 강화 레이트 모델의 보너스 레이트에서 가중치 추첨으로 결정됩니다. 1.0은 보너스 없음을, 1.0보다 큰 값은 "대성공" 보너스를 나타냅니다(예: 1.5로 경험치 150%). |

**관련 메서드:**
deleteProgress - 진행 중인 강화를 취소한다
end - 강화를 완료한다 (2단계 흐름)
getProgress - 현재 강화의 진행 정보를 취득한다


---

### EzRateModel

강화 레이트 모델<br>

강화 레이트는 강화에 사용하는 소재와 강화 대상을 정의한 데이터입니다.<br>

소재 데이터와 강화 대상 데이터는 모두 GS2-Inventory에서 관리되고 있어야 합니다.<br>
강화로 얻는 경험치는 GS2-Inventory의 메타데이터에 JSON 형식으로 기록됩니다.<br>
여기서는 메타데이터의 어느 계층에 경험치 값이 저장되어 있는지를 기재해야 합니다.<br>

강화 시 일정 확률로 `대성공`과 같은 형태로 입수할 수 있는 경험치량에 보정값을 적용할 수 있습니다.<br>
그 추첨 확률도 이 엔티티에서 정의합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 강화 레이트 모델 이름<br>강화 레이트 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(밑줄) .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| targetInventoryModelId | string |  | ✓ |  |  ~ 1024자 | 강화 대상으로 사용할 수 있는 GS2-Inventory 인벤토리 모델의 GRN<br>강화 대상이 되는 아이템을 보유하는 GS2-Inventory의 인벤토리 모델을 지정합니다. 강화되는 아이템은 이 인벤토리 모델에 속해 있어야 합니다. |
| acquireExperienceSuffix | string |  | ✓ |  |  ~ 1024자 | GS2-Experience에서 획득한 경험치를 저장하는 프로퍼티 ID에 부여하는 서픽스<br>아이템의 프로퍼티 ID 끝에 추가되어, 경험치가 저장되는 GS2-Experience의 프로퍼티 ID를 구성하는 문자열입니다. 같은 아이템에 여러 경험치 종류를 부여할 수 있습니다(예: 캐릭터 레벨의 "level", 호감도의 "like"). |
| materialInventoryModelId | string |  | ✓ |  |  ~ 1024자 | 강화 소재로 사용할 수 있는 GS2-Inventory 인벤토리 모델 GRN<br>강화 소재로 사용할 수 있는 아이템을 보유하는 GS2-Inventory의 인벤토리 모델을 지정합니다. 각 소재가 제공하는 경험치는 acquireExperienceHierarchy로 지정된 JSON 계층을 사용하여 아이템 모델의 메타데이터에 정의됩니다. |
| acquireExperienceHierarchy | List&lt;string&gt; |  |  |  | 0 ~ 10 items | ItemModel의 메타데이터에 저장할, 획득 경험치를 정의하는 JSON 데이터의 계층 구조 정의<br>GS2-Enhance에는 GS2-Inventory와 연동하여 강화를 수행하는 기능이 있으며, ItemModel의 메타데이터에 JSON 형식으로 강화 소재로 사용했을 때의 경험치량을 설정합니다.<br>예를 들어, { "aaa": { "bbb": { "experienceValue": 100 } } }와 같은 구조의 데이터 정의로 메타데이터에 설정하고 싶은 경우에는 [ "aaa", "bbb", "experienceValue" ]와 같이 지정합니다.<br>자세한 내용은 [마이크로서비스 소개 / GS2-Enhance](/microservices/enhance/#강화-레이트) 항목에서 설명합니다. |
| experienceModelId | string |  | ✓ |  |  ~ 1024자 | 강화 결과로 얻는 GS2-Experience 경험치 모델 GRN<br>강화로 얻은 경험치가 기록되는 GS2-Experience의 경험치 모델을 지정합니다. 경험치는 대상 아이템의 프로퍼티 ID와 acquireExperienceSuffix를 조합하여 식별되는 프로퍼티에 가산됩니다. |

**관련 메서드:**
getRateModel - 이름을 지정하여 강화 레이트 모델을 취득한다
listRateModels - 강화 레이트 모델 목록을 취득한다
enhance - 아이템을 강화한다


---

### EzUnleashRateModel

한계돌파 레이트 모델<br>

아이템의 한계돌파(해방) 조건을 정의합니다. GS2-Inventory에서 관리되는 아이템과 GS2-Grade의 그레이드 모델을 연결하여 그레이드 진행을 가능하게 합니다. 각 그레이드 레벨에서 소비하는 동일 종류 아이템의 수를 개별적으로 설정할 수 있어, 각 한계돌파 단계의 비용을 세밀하게 제어할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 한계돌파 레이트 모델명<br>한계돌파 레이트 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| targetInventoryModelId | string |  | ✓ |  |  ~ 1024자 | 한계돌파 대상에 사용할 수 있는 GS2-Inventory 인벤토리 모델 GRN<br>한계돌파 대상이 되는 아이템을 보유하는 GS2-Inventory의 인벤토리 모델을 지정합니다. 한계돌파하는 아이템과 소재로 소비되는 동일 종류 아이템 모두 이 인벤토리 모델에 속해 있어야 합니다. |
| gradeModelId | string |  | ✓ |  |  ~ 1024자 | 그레이드 모델 GRN<br>대상 아이템의 한계돌파 레벨을 추적하는 GS2-Grade의 그레이드 모델을 지정합니다. 한계돌파가 성공하면, 이 그레이드 모델 내에서 아이템의 그레이드가 가산됩니다. |
| gradeEntries | [List&lt;EzUnleashRateEntryModel&gt;](#ezunleashrateentrymodel) |  | ✓ |  | 1 ~ 1000 items | 그레이드 엔트리 목록<br>한계돌파의 각 그레이드 레벨에 대한 소재 비용을 정의합니다. 각 엔트리는 그레이드 값과, 해당 그레이드에 도달하기 위해 소비해야 하는 동일 종류 아이템 수를 매핑합니다. 예를 들어, 그레이드 1은 복제품 1개, 그레이드 2는 복제품 3개와 같이 설정할 수 있습니다. |

**관련 메서드:**
getUnleashRateModel - 이름을 지정하여 한계돌파 레이트 모델을 취득한다
listUnleashRateModels - 한계돌파 레이트 모델 목록을 취득한다


---

### EzUnleashRateEntryModel

한계돌파 레이트 엔트리 모델<br>

한계돌파 진행에서 단일 그레이드 레벨의 소재 비용을 정의합니다. 각 엔트리는 대상이 되는 그레이드 값과, 해당 그레이드를 달성하기 위해 소비해야 하는 동일 종류 아이템의 수를 지정합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| gradeValue | long |  | ✓ |  | 1 ~ 1000 | 대상 그레이드<br>이 엔트리가 비용을 정의하는 그레이드 값입니다. 이 그레이드 레벨로의 한계돌파를 실행할 때, needCount로 지정된 수의 아이템이 소비됩니다. |
| needCount | int |  | ✓ |  | 1 ~ 1000 | 동일 종류의 아이템을 몇 개 소비할지<br>대상 그레이드로의 한계돌파를 실행하기 위해 소비해야 하는 동일 종류 아이템의 수입니다. 이 아이템들은 한계돌파되는 아이템과 동일한 아이템 모델의 것입니다. |


**관련 모델:**
EzUnleashRateModel - 한계돌파 레이트 모델



---

### EzConfig

컨피그 설정<br>

트랜잭션의 변수에 적용하는 설정 값

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| key | string |  | ✓ |  |  ~ 64자 | 이름 |
| value | string |  |  |  |  ~ 51200자 | 값 |

**관련 메서드:**
end - 강화를 완료한다 (2단계 흐름)
start - 강화를 시작한다 (2단계 흐름)
enhance - 아이템을 강화한다


---

### EzMaterial

강화 소재<br>

강화 조작 중에 소비되는 소재 아이템을 나타냅니다. 각 소재는 특정 GS2-Inventory 아이템 세트를 참조하며, 소비할 수량을 지정합니다. 소재가 제공하는 경험치는 아이템 모델의 메타데이터로부터 결정됩니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| materialItemSetId | string |  | ✓ |  |  ~ 1024자 | 강화 소재가 되는 아이템 세트의 GRN<br>강화 소재로 소비되는 특정 GS2-Inventory 아이템 세트를 참조합니다. 아이템은 강화 레이트 모델에서 지정된 소재 인벤토리 모델에 속해 있어야 합니다. |
| count | int |  |  | 1 | 0 ~ 2147483645 | 소비 수량<br>이 소재 아이템의 소비 수량입니다. 이 소재로부터 얻는 합계 경험치는, 아이템 1개당 경험치(아이템 모델의 메타데이터에서 취득)에 이 수량을 곱하여 계산됩니다. |

**관련 메서드:**
start - 강화를 시작한다 (2단계 흐름)
enhance - 아이템을 강화한다


---

### EzVerifyActionResult

검증 액션 실행 결과

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| action | 문자열 열거형<br>enum {<br>}<br> |  | ✓ |  |  | 검증 액션에서 실행할 액션의 종류 |
| verifyRequest | string |  | ✓ |  |  ~ 524288자 | 액션 실행 시 사용되는 요청의 JSON 문자열 |
| statusCode | int |  |  |  | 0 ~ 999 | 상태 코드 |
| verifyResult | string |  |  |  |  ~ 1048576자 | 결과 내용 |


**관련 모델:**
EzTransactionResult - 트랜잭션 실행 결과



---

### EzConsumeActionResult

소비 액션 실행 결과

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| action | 문자열 열거형<br>enum {<br>}<br> |  | ✓ |  |  | 소비 액션에서 실행할 액션의 종류 |
| consumeRequest | string |  | ✓ |  |  ~ 524288자 | 액션 실행 시 사용되는 요청의 JSON 문자열 |
| statusCode | int |  |  |  | 0 ~ 999 | 상태 코드 |
| consumeResult | string |  |  |  |  ~ 1048576자 | 결과 내용 |


**관련 모델:**
EzTransactionResult - 트랜잭션 실행 결과



---

### EzAcquireActionResult

획득 액션 실행 결과

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| action | 문자열 열거형<br>enum {<br>}<br> |  | ✓ |  |  | 입수 액션에서 실행할 액션의 종류 |
| acquireRequest | string |  | ✓ |  |  ~ 524288자 | 액션 실행 시 사용되는 요청의 JSON 문자열 |
| statusCode | int |  |  |  | 0 ~ 999 | 상태 코드 |
| acquireResult | string |  |  |  |  ~ 1048576자 | 결과 내용 |


**관련 모델:**
EzTransactionResult - 트랜잭션 실행 결과



---

### EzTransactionResult

트랜잭션 실행 결과<br>

서버 사이드에서 트랜잭션 자동 실행 기능을 이용하여 실행된 트랜잭션의 실행 결과

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| transactionId | string |  | ✓ |  | 36 ~ 36자 | 트랜잭션 ID |
| verifyResults | [List&lt;EzVerifyActionResult&gt;](#ezverifyactionresult) |  |  |  | 0 ~ 10 items | 검증 액션의 실행 결과 목록 |
| consumeResults | [List&lt;EzConsumeActionResult&gt;](#ezconsumeactionresult) |  |  | [] | 0 ~ 10 items | 소비 액션의 실행 결과 목록 |
| acquireResults | [List&lt;EzAcquireActionResult&gt;](#ezacquireactionresult) |  |  | [] | 0 ~ 100 items | 획득 액션 실행 결과 리스트 |

**관련 메서드:**
end - 강화를 완료한다 (2단계 흐름)
start - 강화를 시작한다 (2단계 흐름)
enhance - 아이템을 강화한다


---

## 메서드

### getRateModel

이름을 지정하여 강화 레이트 모델을 취득한다<br>

이름을 지정하여 강화 레이트 모델을 1건 취득합니다.<br>
취득할 수 있는 정보에는 강화 대상 아이템이 속한 인벤토리, 소재가 속한 인벤토리, 소재로부터의 경험치 계산 방법, 보너스 레이트 확률 테이블이 포함됩니다.<br>
특정 강화 레시피의 상세 정보를 표시할 때 사용합니다. 예를 들어 무기 강화 화면에서 필요한 소재나 보너스 레이트 확률을 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| rateName | string |  | ✓|  |  ~ 128자 | 강화 레이트 모델 이름<br>강화 레이트 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(밑줄) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzRateModel](#ezratemodel) | 강화 레이트 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).RateModel(
        rateName: "character-level"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).RateModel(
        rateName: "character-level"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->RateModel(
        "character-level" // rateName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).rate_model(
        "character-level"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).RateModel(
        rateName: "character-level"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).RateModel(
        rateName: "character-level"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->RateModel(
        "character-level" // rateName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Enhance::Model::FRateModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).rate_model(
        "character-level"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listRateModels

강화 레이트 모델 목록을 취득한다<br>

이 네임스페이스에 등록되어 있는 모든 강화 레이트 모델을 취득합니다.<br>
레이트 모델은 강화 레시피를 정의합니다. 어떤 아이템을 소재로 사용할 수 있는지, 각 소재가 얼마의 경험치를 주는지, 보너스 배율 추첨이 있는지 등을 설정합니다.<br>
강화 UI를 구축할 때 사용합니다. 예를 들어 어떤 무기를 강화할 수 있고 어떤 소재를 받는지 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzRateModel&gt;](#ezratemodel) | 강화 레이트 모델 목록|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.RateModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.RateModels(
    );
    List<EzRateModel> items = new List<EzRateModel>();
    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;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->RateModels(
    );
    TArray<Gs2::UE5::Enhance::Model::FEzRateModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeRateModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeRateModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeRateModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeRateModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeRateModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeRateModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getUnleashRateModel

이름을 지정하여 한계돌파 레이트 모델을 취득한다<br>

이름을 지정하여 한계돌파(해방) 레이트 모델을 1건 취득합니다.<br>
취득할 수 있는 정보에는 대상 인벤토리, 아이템의 그레이드를 관리하는 그레이드 모델, 각 그레이드 레벨의 소재 요건을 정의하는 그레이드 엔트리 목록이 포함됩니다.<br>
특정 한계돌파 레시피의 상세 정보를 표시할 때 사용합니다. 예를 들어 아이템 상세 화면에서 "그레이드 1→2: 동일 아이템 1개 필요", "그레이드 2→3: 동일 아이템 2개 필요"와 같이 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| rateName | string |  | ✓|  |  ~ 128자 | 한계돌파 레이트 모델명<br>한계돌파 레이트 모델 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzUnleashRateModel](#ezunleashratemodel) | 한계돌파 레이트 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).UnleashRateModel(
        rateName: "character-level"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).UnleashRateModel(
        rateName: "character-level"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->UnleashRateModel(
        "character-level" // rateName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).unleash_rate_model(
        "character-level"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).UnleashRateModel(
        rateName: "character-level"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).UnleashRateModel(
        rateName: "character-level"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->UnleashRateModel(
        "character-level" // rateName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Enhance::Model::FUnleashRateModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).unleash_rate_model(
        "character-level"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listUnleashRateModels

한계돌파 레이트 모델 목록을 취득한다<br>

이 네임스페이스에 등록되어 있는 모든 한계돌파(해방) 레이트 모델을 취득합니다.<br>
한계돌파 레이트 모델은 아이템의 그레이드(레벨 상한)를 올리는 방법을 정의합니다. 예를 들어 같은 무기의 복제품을 소비하여 레벨 상한을 올리는 방식입니다.<br>
각 모델은 그레이드별로 필요한 소재를 지정할 수 있어, 아이템이 강해질수록 비용을 높일 수도 있습니다.<br>
한계돌파 UI 구축에 사용합니다. 어떤 아이템을 한계돌파할 수 있고 어떤 소재가 필요한지 플레이어에게 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzUnleashRateModel&gt;](#ezunleashratemodel) | 한계돌파 레이트 모델 목록|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.UnleashRateModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.UnleashRateModels(
    );
    List<EzUnleashRateModel> items = new List<EzUnleashRateModel>();
    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;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->UnleashRateModels(
    );
    TArray<Gs2::UE5::Enhance::Model::FEzUnleashRateModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeUnleashRateModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeUnleashRateModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeUnleashRateModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeUnleashRateModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeUnleashRateModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeUnleashRateModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### deleteProgress

진행 중인 강화를 취소한다<br>

플레이어의 진행 중인 강화의 진행 정보를 삭제하여 강화를 취소합니다.<br>
Start에서 소비된 소재는 반환되지 않습니다. 보류 중인 경험치 부여만 취소됩니다.<br>
플레이어가 강화를 취소하고 싶은 경우나, 다른 강화를 시작하기 전에 정리하고 싶은 경우에 사용합니다.<br>
또는 Start 호출 시 `force`를 true로 설정하면 기존 진행 정보를 자동으로 폐기할 수도 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzProgress](#ezprogress) | 강화의 진행 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var result = await domain.DeleteProgressAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var future = domain.DeleteProgressFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Progress(
    );
    const auto Future = Domain->DeleteProgress(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).me(game_session).progress(
    )

var async_result = await domain.delete_progress(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### end

강화를 완료한다 (2단계 흐름)<br>

Start API로 시작한 강화 처리를 완료합니다.<br>
Start 시에 사전 계산된 경험치와 보너스 레이트를 대상 아이템에 반영합니다.<br>
완료 후 진행 정보는 자동으로 삭제됩니다.<br>
결과에는 획득 경험치와 보너스 레이트가 포함되므로, "강화 완료! +1200 EXP"와 같은 최종 결과 화면을 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| config | [List&lt;EzConfig&gt;](#ezconfig) |  | | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzProgress](#ezprogress) | 강화의 진행 정보|
| transactionId | string | 발행된 트랜잭션 ID|
| stampSheet | string | 보상 지급 처리 실행에 사용하는 스탬프 시트|
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN|
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부|
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부|
| transaction | string | 발행된 트랜잭션|
| transactionResult | [EzTransactionResult](#eztransactionresult) | 트랜잭션 실행 결과|
| acquireExperience | long | 획득 경험치량|
| bonusRate | float | 경험치 보너스 배율(1.0=보너스 없음)|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var result = await domain.EndAsync(
        config: null
    );
    // New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
    // 에러가 발생하면 TransactionException이 발생합니다.
    // TransactionException::Retry()로 재시도할 수 있습니다.

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var future = domain.EndFuture(
        config: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    // New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
    // 에러가 발생하면 TransactionException이 발생합니다.
    // TransactionException::Retry()로 재시도할 수 있습니다.

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Progress(
    );
    const auto Future = Domain->End(
        // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).me(game_session).progress(
    )

var async_result = await domain.end(
    null # config
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getProgress

현재 강화의 진행 정보를 취득한다<br>

플레이어의 진행 중인 강화 진행 정보를 취득합니다.<br>
진행 정보에는 레이트 모델 이름, 대상 아이템, 사용한 소재, 사전 계산된 경험치, 추첨된 보너스 레이트가 포함됩니다.<br>
플레이어가 이탈했다가 돌아왔을 때 강화 확인 화면을 복원하는 데 사용합니다. 예를 들어 "+1200 EXP 획득 예정(대성공 x1.5)"을 다시 표시할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzProgress](#ezprogress) | 실행 중인 강화의 진행 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Progress(
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).me(game_session).progress(
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Progress(
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Enhance::Model::FProgress> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).me(game_session).progress(
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### start

강화를 시작한다 (2단계 흐름)<br>

소재를 소비하여 경험치와 보너스 레이트를 계산하지만, 경험치는 아직 반영하지 않습니다.<br>
계산 결과는 진행 정보로 저장되므로, 플레이어에게 확인 화면을 표시할 수 있습니다. 예를 들어 "+1200 EXP 획득 예정(대성공 x1.5)"과 같은 미리보기를 보여줄 수 있습니다.<br>
플레이어가 확인하면 End를 호출하여 실제로 대상 아이템에 경험치를 반영합니다.<br>
이미 진행 중인 강화가 있는 경우, `force`를 true로 설정하면 이를 폐기하고 새로운 강화를 시작할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| rateName | string |  | ✓|  |  ~ 128자 | 강화 레이트 모델 이름<br>이 강화 조작의 파라미터를 정의하는 강화 레이트 모델의 이름입니다. 대상 인벤토리, 소재 인벤토리, 경험치 계층, 보너스 레이트를 지정하는 모델을 참조합니다. |
| targetItemSetId | string |  | ✓|  |  ~ 1024자 | 강화 대상 아이템 세트의 GRN |
| materials | [List&lt;EzMaterial&gt;](#ezmaterial) |  | |  | 0 ~ 10 items | 강화 소재 목록 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| force | bool |  | | false |  | 이미 시작된 강화가 있는 경우 이를 폐기하고 시작할지 |
| config | [List&lt;EzConfig&gt;](#ezconfig) |  | | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| transactionId | string | 발행된 트랜잭션 ID|
| stampSheet | string | 강화 시작 처리 실행에 사용하는 스탬프 시트|
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN|
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부|
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부|
| transaction | string | 발행된 트랜잭션|
| transactionResult | [EzTransactionResult](#eztransactionresult) | 트랜잭션 실행 결과|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var result = await domain.StartAsync(
        rateName: "character-level",
        targetItemSetId: "item-set-0001",
        materials: new List<Gs2.Unity.Gs2Enhance.Model.EzMaterial> {
            new Gs2.Unity.Gs2Enhance.Model.EzMaterial() {
                MaterialItemSetId = "material-0001",
                Count = 1,
            },
        },
        force: null,
        config: null
    );
    // New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
    // 에러가 발생하면 TransactionException이 발생합니다.
    // TransactionException::Retry()로 재시도할 수 있습니다.

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Progress(
    );
    var future = domain.StartFuture(
        rateName: "character-level",
        targetItemSetId: "item-set-0001",
        materials: new List<Gs2.Unity.Gs2Enhance.Model.EzMaterial> {
            new Gs2.Unity.Gs2Enhance.Model.EzMaterial() {
                MaterialItemSetId = "material-0001",
                Count = 1,
            },
        },
        force: null,
        config: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    // New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
    // 에러가 발생하면 TransactionException이 발생합니다.
    // TransactionException::Retry()로 재시도할 수 있습니다.

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Progress(
    );
    const auto Future = Domain->Start(
        "character-level", // rateName
        "item-set-0001", // targetItemSetId
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Enhance::Model::FEzMaterial>>>();
            v->Add(
                MakeShared<Gs2::UE5::Enhance::Model::FEzMaterial>()
                ->WithMaterialItemSetId(TOptional<FString>("material-0001"))
                ->WithCount(TOptional<int32>(1))
            );
            return v;
        }() // materials
        // force
        // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).me(game_session).progress(
    )

var async_result = await domain.start(
    "character-level", # rate_name
    "item-set-0001", # target_item_set_id
    [
        Gs2EnhanceEzMaterial.new()
            .with_material_item_set_id("material-0001")
            .with_count(1),
    ], # materials
    null, # force
    null # config
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### enhance

아이템을 강화한다<br>

지정한 소재를 소비하여 대상 아이템에 경험치를 부여합니다(1단계로 완료).<br>
획득 경험치는 강화 레이트 모델을 기반으로 계산되며, 보너스 레이트 확률 테이블에서 배율이 추첨되는 경우가 있습니다. 예를 들어 "대성공"으로 경험치가 1.5배가 되는 방식입니다.<br>
결과에는 획득한 경험치량과 적용된 보너스 레이트가 포함되므로, "무기가 레벨업! +1200 EXP(대성공 x1.5)"와 같은 결과 화면을 표시할 수 있습니다.<br>
이는 가장 간단한 강화 방법입니다. 플레이어에게 결과를 보여준 후 확정하고 싶은 경우에는 Start/End 흐름을 사용해 주세요.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| rateName | string |  | ✓|  |  ~ 128자 | 강화 레이트 모델 이름<br>강화 레이트 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(밑줄) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetItemSetId | string |  | ✓|  |  ~ 1024자 | 강화 대상 아이템 세트의 GRN |
| materials | [List&lt;EzMaterial&gt;](#ezmaterial) |  | ✓|  | 1 ~ 10 items | 강화 소재 목록 |
| config | [List&lt;EzConfig&gt;](#ezconfig) |  | | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzRateModel](#ezratemodel) | 강화 레이트 모델|
| transactionId | string | 발행된 트랜잭션 ID|
| stampSheet | string | 강화 처리 실행에 사용하는 스탬프 시트|
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN|
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부|
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부|
| transaction | string | 발행된 트랜잭션|
| transactionResult | [EzTransactionResult](#eztransactionresult) | 트랜잭션 실행 결과|
| acquireExperience | long | 획득 경험치량|
| bonusRate | float | 경험치 보너스 배율(1.0=보너스 없음)|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Enhance(
    );
    var result = await domain.EnhanceAsync(
        rateName: "rate-0001",
        targetItemSetId: "item-set-0001",
        materials: new List<Gs2.Unity.Gs2Enhance.Model.EzMaterial> {
            new Gs2.Unity.Gs2Enhance.Model.EzMaterial() {
                MaterialItemSetId = "material-0001",
                Count = 1,
            },
        },
        config: null
    );
    // New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
    // 에러가 발생하면 TransactionException이 발생합니다.
    // TransactionException::Retry()로 재시도할 수 있습니다.

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Enhance.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Enhance(
    );
    var future = domain.EnhanceFuture(
        rateName: "rate-0001",
        targetItemSetId: "item-set-0001",
        materials: new List<Gs2.Unity.Gs2Enhance.Model.EzMaterial> {
            new Gs2.Unity.Gs2Enhance.Model.EzMaterial() {
                MaterialItemSetId = "material-0001",
                Count = 1,
            },
        },
        config: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    // New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
    // 에러가 발생하면 TransactionException이 발생합니다.
    // TransactionException::Retry()로 재시도할 수 있습니다.

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Enhance->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Enhance(
    );
    const auto Future = Domain->Enhance(
        "rate-0001", // rateName
        "item-set-0001", // targetItemSetId
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Enhance::Model::FEzMaterial>>>();
            v->Add(
                MakeShared<Gs2::UE5::Enhance::Model::FEzMaterial>()
                ->WithMaterialItemSetId(TOptional<FString>("material-0001"))
                ->WithCount(TOptional<int32>(1))
            );
            return v;
        }() // materials
        // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.enhance.namespace_(
        "namespace-0001"
    ).me(game_session).enhance(
    )

var async_result = await domain.enhance(
    "rate-0001", # rate_name
    "item-set-0001", # target_item_set_id
    [
        Gs2EnhanceEzMaterial.new()
            .with_material_item_set_id("material-0001")
            .with_count(1),
    ], # materials
    null # config
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---



