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

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

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



## 모델

### EzMold

폼 저장 영역<br>

게임 플레이어가 편성한 정보를 보유하는 엔티티입니다.<br>
편성 정보(Form)는 폼 저장 영역(Mold)마다 여러 개 보유할 수 있으며, 몇 개까지 보유할 수 있는지에 대한 캐파시티를 게임 플레이어 × 폼 저장 영역마다 개별적으로 설정할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 폼 저장 영역 모델의 이름<br>폼 저장 영역 모델 고유의 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| capacity | int |  | ✓ |  | 0 ~ 2147483646 | 현재 캐파시티<br>이 저장 영역에서 이 플레이어가 현재 이용할 수 있는 폼 저장 슬롯 수입니다. 초기값은 저장 영역 모델의 initialMaxCapacity로 설정되며, 캐파시티 증가 조작을 통해 maxCapacity까지 확장할 수 있습니다. |

**관련 메서드:**
getMold - 이름을 지정하여 편성 프리셋 저장 영역 조회
listMolds - 플레이어의 편성 프리셋 저장 영역 목록 조회
deleteForm - 저장된 편성 프리셋 삭제
getForm - 특정 저장된 편성 프리셋 조회
getFormWithSignature - 위변조 방지 서명과 함께 편성 프리셋 조회
setForm - 편성 프리셋 변경 내용 저장


---

### EzForm

폼<br>

폼은 편성 상태를 나타내는 엔티티입니다.<br>
편성 가능한 영역으로 `슬롯`을 정의할 수 있습니다.<br>

무기·방어구라면 「오른손」「왼손」「몸통」「팔」과 같은 부위를 슬롯으로 하고,<br>
파티라면 「전위」「중위」「후위」와 같은 포지션을 슬롯으로 표현할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 폼 이름<br>이 폼이 속한 저장 영역 모델의 이름입니다. 이 폼 인스턴스에 적용되는 폼 모델(슬롯 구성)을 식별합니다. |
| index | int |  | ✓ |  | 0 ~ 2147483646 | 폼의 인덱스<br>저장 영역 내에서 이 폼이 차지하는 저장 슬롯을 식별하는 0부터 시작하는 인덱스입니다. 최대 인덱스는 저장 영역의 현재 캐파시티에 의해 제한됩니다. 예를 들어 인덱스 0을 「파티 1」, 인덱스 1을 「파티 2」와 같은 식으로 사용할 수 있습니다. |
| slots | [List&lt;EzSlot&gt;](#ezslot) |  |  |  | 0 ~ 10 items | 슬롯 목록<br>이 폼의 현재 슬롯 할당입니다. 각 항목은 폼 모델에서 정의된 슬롯에 대응하며, 해당 포지션에 할당된 리소스의 프로퍼티 ID를 보유합니다. 슬롯 이름은 폼 모델에서 정의된 것과 일치해야 합니다. |

**관련 메서드:**
deleteForm - 저장된 편성 프리셋 삭제
getForm - 특정 저장된 편성 프리셋 조회
getFormWithSignature - 위변조 방지 서명과 함께 편성 프리셋 조회
listForms - 저장된 편성 프리셋 목록 조회
setForm - 편성 프리셋 변경 내용 저장


---

### EzPropertyForm

프로퍼티 폼<br>

프로퍼티 폼은 편성 상태를 나타내는 엔티티입니다.<br>
Mold / Form과의 차이점은, 슬롯 수를 정의하고 각 슬롯에 편성을 기록하는 것이 Mold / Form이며,<br>
보유하고 있는 장비에 스킬을 설정하는 것처럼 수를 사전에 정하기 어려운 편성을 표현할 때 사용하는 것이 프로퍼티 폼입니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 프로퍼티 폼 이름<br>이 프로퍼티 폼의 슬롯 구성을 정의하는 프로퍼티 폼 모델의 이름입니다. 할당 가능한 슬롯을 결정합니다. |
| propertyId | string |  | ✓ |  |  ~ 1024자 | 프로퍼티 ID<br>이 프로퍼티 폼 인스턴스를 고유하게 식별하는 개발자 정의 식별자입니다. 일반적으로 이 폼이 설정하는 소유 리소스(예: GS2-Inventory의 아이템 세트)의 GRN을 설정합니다. 특정 장비에 스킬을 설정하는 등의 용도로 사용됩니다. |
| slots | [List&lt;EzSlot&gt;](#ezslot) |  |  |  | 0 ~ 10 items | 슬롯 목록<br>이 프로퍼티 폼의 현재 슬롯 할당입니다. 각 항목은 프로퍼티 폼 모델에서 정의된 슬롯에 대응합니다. 예를 들어 프로퍼티 폼이 장비의 스킬 설정을 나타내는 경우, 각 슬롯은 서로 다른 스킬 할당을 보유합니다. |

**관련 메서드:**
deletePropertyForm - 캐릭터나 아이템의 장비 세트 삭제
getPropertyForm - 특정 캐릭터나 아이템의 장비 세트 조회
getPropertyFormWithSignature - 위변조 방지 서명과 함께 캐릭터의 장비 세트 조회
listPropertyForms - 아이템별 장비 세트 목록 조회
setPropertyForm - 캐릭터나 아이템의 장비 세트 변경 내용 저장


---

### EzFormModel

폼 모델<br>

폼 모델은 편성 상태를 나타내는 엔티티입니다.<br>
편성 가능한 영역으로 `슬롯`을 정의할 수 있습니다.<br>

무기·방어구라면 「오른손」「왼손」「몸통」「팔」과 같은 부위를 슬롯으로 하고,<br>
파티라면 「전위」「중위」「후위」와 같은 포지션을 슬롯으로 표현할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 폼 모델명<br>폼 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| slots | [List&lt;EzSlotModel&gt;](#ezslotmodel) |  | ✓ |  | 1 ~ 10 items | 슬롯 모델 리스트<br>이 폼을 구성하는 슬롯 정의의 순서가 있는 리스트입니다. 각 슬롯은 할당 가능한 포지션을 나타내며, 슬롯명은 폼 내에서 고유해야 합니다. 장비에서는 "weapon", "armor", "accessory"와 같은 슬롯, 파티에서는 "position_1", "position_2"와 같은 슬롯을 생각할 수 있습니다. |

**관련 메서드:**
getFormModel - 폼의 슬롯 구성 정의 조회
deleteForm - 저장된 편성 프리셋 삭제
getForm - 특정 저장된 편성 프리셋 조회
getFormWithSignature - 위변조 방지 서명과 함께 편성 프리셋 조회
setForm - 편성 프리셋 변경 내용 저장


**관련 모델:**
EzMoldModel - 폼 저장 영역 모델



---

### EzMoldModel

폼 저장 영역 모델<br>

폼 저장 영역 모델은 파티 편성이라면 「불 속성 파티」「물 속성 파티」와 같은 형태로 저장하는 것을 상정하고 있습니다.<br>
저장할 수 있는 영역의 수는 제한할 수 있으며, 개별적으로 확장할 수도 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 폼 저장 영역 모델의 이름<br>폼 저장 영역 모델 고유의 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| formModel | [EzFormModel](#ezformmodel) |  | ✓ |  |  | 폼 모델 |
| initialMaxCapacity | int |  | ✓ |  | 1 ~ 2147483646 | 폼을 저장할 수 있는 초기 캐파시티<br>이 저장 영역에서 각 플레이어가 이용할 수 있는 기본 폼 저장 슬롯 수입니다. 예를 들어 3으로 설정하면 플레이어는 초기 상태에서 최대 3개의 서로 다른 편성(예: 「불 속성 파티」「물 속성 파티」「바람 속성 파티」)을 저장할 수 있습니다. 플레이어별로 maxCapacity까지 확장할 수 있습니다. |
| maxCapacity | int |  | ✓ |  | 1 ~ 2147483646 | 폼을 저장할 수 있는 최대 캐파시티<br>이 저장 영역에서 플레이어별 폼 저장 슬롯 수의 절대적인 상한입니다. 캐파시티 확장 조작을 수행하더라도 캐파시티는 이 값을 초과할 수 없습니다. initialMaxCapacity 이상의 값이어야 합니다. |

**관련 메서드:**
getMoldModel - 이름을 지정하여 편성 프리셋 모델 조회
listMoldModels - 편성 프리셋 모델 목록 조회
getMold - 이름을 지정하여 편성 프리셋 저장 영역 조회
deleteForm - 저장된 편성 프리셋 삭제
getForm - 특정 저장된 편성 프리셋 조회
getFormWithSignature - 위변조 방지 서명과 함께 편성 프리셋 조회
setForm - 편성 프리셋 변경 내용 저장


---

### EzPropertyFormModel

프로퍼티 폼 모델<br>

프로퍼티 폼 모델은 편성 상태를 나타내는 엔티티입니다.<br>
Mold / Form과의 차이점은, 슬롯 수를 정의하고 각 슬롯에 편성을 기록하는 것이 Mold / Form이며,<br>
보유하고 있는 장비에 스킬을 설정하는 것처럼 수를 사전에 정하기 어려운 편성을 표현할 때 사용하는 것이 프로퍼티 폼 모델입니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 프로퍼티 폼 모델 이름<br>프로퍼티 폼 모델 고유의 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| slots | [List&lt;EzSlotModel&gt;](#ezslotmodel) |  | ✓ |  | 1 ~ 10 items | 슬롯 모델 목록<br>이 프로퍼티 폼의 슬롯 정의를 순서대로 나열한 목록입니다. 캐파시티에 의해 폼 수가 제한되는 Mold/Form과 달리, 프로퍼티 폼은 프로퍼티 ID로 식별되며 보유하는 리소스마다 존재할 수 있습니다. 슬롯 이름은 폼 내에서 고유해야 합니다. |

**관련 메서드:**
getPropertyFormModel - 이름을 지정하여 아이템별 폼 모델 조회
listPropertyFormModels - 아이템별 폼 모델 목록 조회
deletePropertyForm - 캐릭터나 아이템의 장비 세트 삭제
getPropertyForm - 특정 캐릭터나 아이템의 장비 세트 조회
getPropertyFormWithSignature - 위변조 방지 서명과 함께 캐릭터의 장비 세트 조회
setPropertyForm - 캐릭터나 아이템의 장비 세트 변경 내용 저장


---

### EzSlotModel

슬롯 모델<br>

폼 모델 내의 하나의 슬롯을 정의합니다. 슬롯은 게임 리소스(아이템, 캐릭터, 장비 등)를 배치할 수 있는 할당 가능한 포지션을 나타냅니다. 프로퍼티 정규 표현식에 의해 슬롯에 설정 가능한 값이 검증됩니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 슬롯 모델명<br>폼 모델 내에서 이 슬롯을 고유하게 식별하는 이름입니다. 장비 폼에서는 "right_hand", "body"와 같은 이름이, 파티 폼에서는 "vanguard", "rear_guard"와 같은 이름이 일반적으로 사용됩니다. |
| propertyRegex | string |  |  | ".*" |  ~ 512자 | 프로퍼티로 설정 가능한 값의 정규 표현식<br>이 슬롯에 할당 가능한 프로퍼티 ID 값을 검증하는 정규 표현식 패턴입니다. 예를 들어 특정 GS2-Inventory 아이템 GRN이나 GS2-Dictionary 엔트리 GRN으로 제한할 수 있습니다. 기본값은 ".*"이며 임의의 값을 허용합니다. |
| metadata | string |  |  |  |  ~ 512자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |


**관련 모델:**
EzFormModel - 폼 모델
EzPropertyFormModel - 프로퍼티 폼 모델



---

### EzSlot

슬롯<br>

폼 내의 하나의 슬롯의 실제 할당 상태를 나타냅니다. 각 슬롯은 플레이어가 해당 포지션에 배치한 게임 리소스(GS2-Inventory의 아이템 세트나 GS2-Dictionary의 엔트리 등)를 참조하는 프로퍼티 ID를 보유합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 슬롯 모델명<br>폼 모델 내에서 이 슬롯을 고유하게 식별하는 이름입니다. 장비 폼에서는 "right_hand", "body"와 같은 이름이, 파티 폼에서는 "vanguard", "rear_guard"와 같은 이름이 일반적으로 사용됩니다. |
| propertyId | string |  |  |  |  ~ 1024자 | 프로퍼티 ID<br>이 슬롯에 할당된 게임 리소스를 참조하는 개발자 정의 식별자입니다. 일반적으로 GS2-Inventory의 아이템 세트 GRN, GS2-Dictionary의 엔트리 GRN, 또는 기타 리소스 식별자입니다. 슬롯 모델의 propertyRegex 패턴과 일치해야 합니다. |
| metadata | string |  |  |  |  ~ 1024자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |


**관련 모델:**
EzForm - 폼
EzPropertyForm - 프로퍼티 폼



---

### EzSlotWithSignature

서명된 슬롯<br>

플레이어가 참조하는 리소스를 소유하고 있음을 증명하는 암호 서명을 포함한 슬롯 할당입니다. 폼 업데이트 시 플레이어가 슬롯에 배치하는 아이템, 엔트리, 또는 기타 리소스를 실제로 소유하고 있는지 검증하여 부정한 할당을 방지하는 데 사용됩니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 슬롯 모델 이름<br>슬롯 모델 고유의 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| propertyType | 문자열 열거형<br>enum {<br>"gs2_inventory",<br>"gs2_simple_inventory",<br>"gs2_dictionary"<br>}<br> |  | ✓ |  |  | 프로퍼티 종류<br>이 슬롯이 참조하는 GS2 리소스의 종류를 지정합니다. 서명 검증 방법을 결정합니다. GS2-Inventory의 아이템 세트, GS2-Inventory의 심플 아이템, GS2-Dictionary의 엔트리는 각각 서로 다른 서명 형식을 가집니다.gs2_inventory: GS2-Inventory::ItemSet / gs2_simple_inventory: GS2-Inventory::SimpleItem / gs2_dictionary: GS2-Dictionary::Entry /  |
| body | string |  |  |  |  ~ 1048576자 | 페이로드<br>리소스를 소유한 GS2 서비스로부터 취득한 직렬화된 리소스 데이터입니다. 서명을 검증하고 소유권을 확인하는 데 필요한 리소스 상태 정보를 포함합니다. |
| signature | string |  |  |  |  ~ 1024자 | 프로퍼티 ID가 가리키는 리소스를 소유하고 있음을 증명하는 서명<br>리소스를 소유한 GS2 서비스에 의해 생성된 암호 서명입니다. 폼 업데이트 시 플레이어가 참조하는 아이템 세트, 심플 아이템, 또는 딕셔너리 엔트리를 소유하고 있는지 확인하기 위해 검증됩니다. |
| metadata | string |  |  |  |  ~ 1024자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |

**관련 메서드:**
setForm - 편성 프리셋 변경 내용 저장
setPropertyForm - 캐릭터나 아이템의 장비 세트 변경 내용 저장


---

### EzConfig

컨피그 설정<br>

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

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


---

### EzAcquireAction

입수 액션

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


---

### 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 | 획득 액션 실행 결과 리스트 |


---

## 메서드

### getMoldModel

이름을 지정하여 편성 프리셋 모델 조회<br>

이름을 지정하여 저장 영역 모델을 1건 취득합니다.<br>
취득할 수 있는 정보에는 연결된 폼 모델(슬롯 구성), 플레이어가 처음 저장할 수 있는 프리셋 수, 확장 후 최대 저장 개수가 포함됩니다.<br>
특정 프리셋 카테고리의 상세 정보를 표시할 때 사용합니다. 예를 들어 편성 상세 화면에서 "장비 프리셋: 3/5 사용 중, 최대 10까지 확장 가능"처럼 표시하는 데 유용합니다.

#### Request

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

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzMoldModel](#ezmoldmodel) | 폼 저장 영역|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).MoldModel(
        moldModelName: "mold-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).MoldModel(
        moldModelName: "mold-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).mold_model(
        "mold-0001"
    )

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.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).MoldModel(
        moldModelName: "mold-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

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

```

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

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

```

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

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).mold_model(
        "mold-0001"
    )

# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.

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

---

### listMoldModels

편성 프리셋 모델 목록 조회<br>

이 네임스페이스에 등록된 모든 저장 영역 모델을 취득합니다.<br>
저장 영역 모델은 "장비 프리셋"이나 "파티 프리셋"처럼 플레이어가 저장할 수 있는 편성 프리셋의 종류를 정의합니다. 초기 저장 개수와 확장 후 최대 저장 개수도 포함됩니다.<br>
각 저장 영역 모델은 슬롯 구성을 정의하는 폼 모델과 연결되어 있습니다.<br>
편성 관리 화면에서 "장비 세트(3/5칸 사용 중)"처럼 이용 가능한 프리셋 카테고리를 표시하는 데 사용합니다.

#### Request

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

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzMoldModel&gt;](#ezmoldmodel) | 폼 저장 영역 목록|

#### 구현 예제




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

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.MoldModels(
    );
    List<EzMoldModel> items = new List<EzMoldModel>();
    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->Formation->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->MoldModels(
    );
    TArray<Gs2::UE5::Formation::Model::FEzMoldModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


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




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

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

```

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

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

```

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

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

```


**⚠️ Warning**

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

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

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

---

### getMold

이름을 지정하여 편성 프리셋 저장 영역 조회<br>

특정 저장 영역 모델에 대한 플레이어의 저장 영역 레코드를 취득합니다.<br>
취득할 수 있는 정보에는 현재 용량(이 카테고리에서 플레이어가 사용할 수 있는 프리셋 칸 수)이 포함됩니다.<br>
특정 프리셋 카테고리의 상태를 확인할 때 사용합니다. 예를 들어 새로운 프리셋을 만들기 전에 "장비 프리셋: 3/5칸"처럼 표시하는 데 유용합니다.

#### Request

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

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzMold](#ezmold) | 폼 저장 영역|
| moldModel | [EzMoldModel](#ezmoldmodel) | 폼 저장 영역|

#### 구현 예제




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

```

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

```

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

```

**Godot**
```gdscript

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

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.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

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

```

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

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

```

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

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

```

**Godot**
```gdscript

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

# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.

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

---

### listMolds

플레이어의 편성 프리셋 저장 영역 목록 조회<br>

플레이어가 보유한 모든 저장 영역(프리셋 스토리지) 레코드를 취득합니다.<br>
각 저장 영역에는 해당 카테고리에서 플레이어가 저장할 수 있는 폼 프리셋의 현재 용량이 기록되어 있습니다.<br>
예를 들어 "장비 프리셋"이 5칸 중 3칸 사용 중, "파티 프리셋"이 3칸 중 1칸 사용 중인 것을 확인할 수 있습니다.<br>
편성 관리 개요 화면에서 모든 프리셋 카테고리와 그 사용 현황을 표시하는 데 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzMold&gt;](#ezmold) | 폼 저장 영역 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.MoldsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.Molds(
    );
    List<EzMold> items = new List<EzMold>();
    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->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->Molds(
    );
    TArray<Gs2::UE5::Formation::Model::FEzMoldPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


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




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

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

```

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

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

```

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

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

```


**⚠️ Warning**

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

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

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

---

### getFormModel

폼의 슬롯 구성 정의 조회<br>

특정 저장 영역 모델에 연결된 폼 모델을 취득합니다.<br>
폼 모델은 "무기 슬롯", "방어구 슬롯", "액세서리 슬롯"처럼 장비 편성이나 파티 편성을 구성하는 슬롯의 정의입니다.<br>
각 슬롯에는 어떤 종류의 아이템(인벤토리, 심플 인벤토리, 딕셔너리)을 설정할 수 있는지가 지정되어 있습니다.<br>
장비 편성 화면이나 포메이션 편집 화면을 구성할 때, 어떤 슬롯이 있는지 파악하기 위해 사용합니다.

#### Request

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

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFormModel](#ezformmodel) | 폼|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).MoldModel(
        moldModelName: "mold-0001"
    ).FormModel(
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).MoldModel(
        moldModelName: "mold-0001"
    ).FormModel(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->MoldModel(
        "mold-0001" // moldModelName
    )->FormModel(
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).mold_model(
        "mold-0001"
    ).form_model(
    )

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.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).MoldModel(
        moldModelName: "mold-0001"
    ).FormModel(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

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

```

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

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

```

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

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).mold_model(
        "mold-0001"
    ).form_model(
    )

# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.

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

---

### deleteForm

저장된 편성 프리셋 삭제<br>

저장 영역 내 지정한 인덱스의 폼 프리셋을 삭제하고 모든 슬롯 내용을 초기화합니다.<br>
프리셋 칸은 비워지며, 이후 새로운 편성을 저장하는 데 다시 사용할 수 있습니다.<br>
플레이어가 저장된 프리셋을 삭제하고자 할 때 사용합니다. 예를 들어 편성 상세 화면의 "프리셋 삭제" 버튼에 사용할 수 있습니다. 이 작업은 취소할 수 없으므로 확인 대화상자를 표시하는 것을 권장합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| moldModelName | string |  | ✓|  |  ~ 128자 | 폼 저장 영역 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| index | int |  | ✓|  | 0 ~ 2147483646 | 폼의 인덱스<br>저장 영역 내에서 이 폼이 차지하는 저장 슬롯을 식별하는 0부터 시작하는 인덱스입니다. 최대 인덱스는 저장 영역의 현재 캐파시티에 의해 제한됩니다. 예를 들어 인덱스 0을 「파티 1」, 인덱스 1을 「파티 2」와 같은 식으로 사용할 수 있습니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzForm](#ezform) | 폼|
| mold | [EzMold](#ezmold) | 폼 저장 영역|
| moldModel | [EzMoldModel](#ezmoldmodel) | 폼 저장 영역 모델|
| formModel | [EzFormModel](#ezformmodel) | 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var result = await domain.DeleteFormAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var future = domain.DeleteFormFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mold(
        "mold-0001" // moldModelName
    )->Form(
        0 // index
    );
    const auto Future = Domain->DeleteForm(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).mold(
        "mold-0001"
    ).form(
        0
    )

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

var result = async_result.result

```


---

### getForm

특정 저장된 편성 프리셋 조회<br>

저장 영역 모델명과 프리셋 인덱스(0, 1, 2 등)를 지정하여 폼 프리셋을 1건 취득합니다.<br>
취득할 수 있는 정보에는 각 슬롯의 내용(각 포지션에 어떤 아이템이 장착되어 있는지)이 포함됩니다.<br>
편성 상세 화면을 표시할 때 사용합니다. 예를 들어 "프리셋 1: 무기=철검, 방어구=강철 갑옷, 액세서리=질풍의 반지"처럼 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| moldModelName | string |  | ✓|  |  ~ 128자 | 폼 저장 영역 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| index | int |  | ✓|  | 0 ~ 2147483646 | 폼의 인덱스<br>저장 영역 내에서 이 폼이 차지하는 저장 슬롯을 식별하는 0부터 시작하는 인덱스입니다. 최대 인덱스는 저장 영역의 현재 캐파시티에 의해 제한됩니다. 예를 들어 인덱스 0을 「파티 1」, 인덱스 1을 「파티 2」와 같은 식으로 사용할 수 있습니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzForm](#ezform) | 폼|
| mold | [EzMold](#ezmold) | 폼 저장 영역|
| moldModel | [EzMoldModel](#ezmoldmodel) | 폼 저장 영역 모델|
| formModel | [EzFormModel](#ezformmodel) | 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mold(
        "mold-0001" // moldModelName
    )->Form(
        0 // index
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).mold(
        "mold-0001"
    ).form(
        0
    )

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.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

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

```

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

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

```

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

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).mold(
        "mold-0001"
    ).form(
        0
    )

# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.

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

---

### getFormWithSignature

위변조 방지 서명과 함께 편성 프리셋 조회<br>

데이터가 위변조되지 않았음을 증명하는 암호 서명과 함께 폼 프리셋을 취득합니다.<br>
클라이언트 측에서 SetForm으로 폼을 갱신할 때 이 서명이 필요합니다. 먼저 이 API로 현재 폼과 서명을 취득한 후, 변경 내용과 함께 그 서명을 전송해야 합니다.<br>
"편성 편집" 흐름의 첫 단계로 사용합니다. 현재 프리셋을 서명과 함께 취득하고, 플레이어가 변경하도록 한 후, SetForm으로 저장하는 흐름입니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| moldModelName | string |  | ✓|  |  ~ 128자 | 폼 저장 영역 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| index | int |  | ✓|  | 0 ~ 2147483646 | 폼의 인덱스<br>저장 영역 내에서 이 폼이 차지하는 저장 슬롯을 식별하는 0부터 시작하는 인덱스입니다. 최대 인덱스는 저장 영역의 현재 캐파시티에 의해 제한됩니다. 예를 들어 인덱스 0을 「파티 1」, 인덱스 1을 「파티 2」와 같은 식으로 사용할 수 있습니다. |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzForm](#ezform) | 폼|
| body | string | 서명 대상 값|
| signature | string | 서명|
| mold | [EzMold](#ezmold) | 폼 저장 영역|
| moldModel | [EzMoldModel](#ezmoldmodel) | 폼 저장 영역 모델|
| formModel | [EzFormModel](#ezformmodel) | 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var result = await domain.GetFormWithSignatureAsync(
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();
    var body = result.Body;
    var signature = result.Signature;

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var future = domain.GetFormWithSignatureFuture(
        keyId: "key-0001"
    );
    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;
    var body = future.Result.Body;
    var signature = future.Result.Signature;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mold(
        "mold-0001" // moldModelName
    )->Form(
        0 // index
    );
    const auto Future = Domain->GetFormWithSignature(
        "key-0001" // keyId
    );
    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();
    const auto Body = Result->Body;
    const auto Signature = Result->Signature;

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).mold(
        "mold-0001"
    ).form(
        0
    )

var async_result = await domain.get_form_with_signature(
    "key-0001" # key_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### listForms

저장된 편성 프리셋 목록 조회<br>

특정 저장 영역(프리셋 카테고리) 내에 플레이어가 저장한 모든 폼 프리셋을 취득합니다.<br>
각 폼은 아이템 참조가 설정된 슬롯의 집합입니다. 예를 들어 프리셋 1에는 무기 슬롯에 "철검", 방어구 슬롯에 "강철 갑옷"이 설정되어 있는 식입니다.<br>
프리셋 선택 화면을 구성하는 데 사용합니다. "프리셋 1: 공격형 빌드", "프리셋 2: 방어형 빌드"처럼 저장된 편성을 목록으로 표시하고 전환할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| moldModelName | string |  | ✓|  |  ~ 128자 | 폼 저장 영역 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzForm&gt;](#ezform) | 폼 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    );
    var items = await domain.FormsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    );
    var it = domain.Forms(
    );
    List<EzForm> items = new List<EzForm>();
    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->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mold(
        "mold-0001" // moldModelName
    );
    const auto It = Domain->Forms(
    );
    TArray<Gs2::UE5::Formation::Model::FEzFormPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


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




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

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

```

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

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

```

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

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

```


**⚠️ Warning**

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

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

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

---

### setForm

편성 프리셋 변경 내용 저장<br>

폼 프리셋의 슬롯 내용을 갱신합니다. 예를 들어 무기 슬롯을 "철검"에서 "화염검"으로 변경하는 조작입니다.<br>
위변조 방지를 위해 GetFormWithSignature로 취득한 서명이 필요합니다. 일반적인 흐름은 (1) GetFormWithSignature로 현재 폼과 서명을 취득, (2) 플레이어가 편성을 편집, (3) 새로운 슬롯 값과 서명을 첨부하여 이 API를 호출하는 순서입니다.<br>
지정한 인덱스에 아직 폼이 없는 경우 새로운 프리셋이 생성됩니다(저장 영역에 여유 용량이 있는 경우).

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| moldModelName | string |  | ✓|  |  ~ 128자 | 폼 저장 영역 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| index | int |  | ✓|  | 0 ~ 2147483646 | 폼의 인덱스<br>저장 영역 내에서 이 폼이 차지하는 저장 슬롯을 식별하는 0부터 시작하는 인덱스입니다. 최대 인덱스는 저장 영역의 현재 캐파시티에 의해 제한됩니다. 예를 들어 인덱스 0을 「파티 1」, 인덱스 1을 「파티 2」와 같은 식으로 사용할 수 있습니다. |
| slots | [List&lt;EzSlotWithSignature&gt;](#ezslotwithsignature) |  | ✓|  | 1 ~ 10 items | 슬롯 목록 |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzForm](#ezform) | 폼|
| mold | [EzMold](#ezmold) | 폼 저장 영역|
| moldModel | [EzMoldModel](#ezmoldmodel) | 폼 저장 영역 모델|
| formModel | [EzFormModel](#ezformmodel) | 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var result = await domain.SetFormAsync(
        slots: new List<Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature> {
            new Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature() {
                Name = "slot-0001",
                PropertyType = "gs2_dictionary",
                Body = "body",
                Signature = "signature",
            },
        },
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mold(
        moldModelName: "mold-0001"
    ).Form(
        index: 0
    );
    var future = domain.SetFormFuture(
        slots: new List<Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature> {
            new Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature() {
                Name = "slot-0001",
                PropertyType = "gs2_dictionary",
                Body = "body",
                Signature = "signature",
            },
        },
        keyId: "key-0001"
    );
    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;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mold(
        "mold-0001" // moldModelName
    )->Form(
        0 // index
    );
    const auto Future = Domain->SetForm(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Formation::Model::FEzSlotWithSignature>>>();
            v->Add(
                MakeShared<Gs2::UE5::Formation::Model::FEzSlotWithSignature>()
                ->WithName(TOptional<FString>("slot-0001"))
                ->WithPropertyType(TOptional<FString>("gs2_dictionary"))
                ->WithBody(TOptional<FString>("body"))
                ->WithSignature(TOptional<FString>("signature"))
            );
            return v;
        }(), // slots
        "key-0001" // keyId
    );
    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();

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).mold(
        "mold-0001"
    ).form(
        0
    )

var async_result = await domain.set_form(
    [
        Gs2FormationEzSlotWithSignature.new()
            .with_name("slot-0001")
            .with_property_type("gs2_dictionary")
            .with_body("body")
            .with_signature("signature"),
    ], # slots
    "key-0001" # key_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getPropertyFormModel

이름을 지정하여 아이템별 폼 모델 조회<br>

이름을 지정하여 프로퍼티 폼 모델을 1건 조회합니다.<br>
조회되는 정보에는 슬롯 정의가 포함됩니다. 어떤 슬롯("무기", "방어구", "스킬" 등)이 있고, 각 슬롯에 어떤 종류의 아이템을 설정할 수 있는지 알 수 있습니다.<br>
특정 캐릭터나 아이템의 장비 편집 화면을 구축할 때 사용합니다. 예를 들어, 플레이어가 캐릭터를 탭하여 장비를 관리하는 화면에 사용할 수 있습니다.

#### Request

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

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPropertyFormModel](#ezpropertyformmodel) | 프로퍼티 폼|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).PropertyFormModel(
        propertyFormModelName: "form-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).PropertyFormModel(
        propertyFormModelName: "form-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).property_form_model(
        "form-0001"
    )

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.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).PropertyFormModel(
        propertyFormModelName: "form-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

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

```

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

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

```

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

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).property_form_model(
        "form-0001"
    )

# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.

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

---

### listPropertyFormModels

아이템별 폼 모델 목록 조회<br>

이 네임스페이스에 등록된 모든 프로퍼티 폼 모델을 조회합니다.<br>
프로퍼티 폼 모델은, 번호가 매겨진 프리셋이 아닌 커스텀 프로퍼티 ID(캐릭터 ID나 무기 ID 등)로 식별되는 폼의 슬롯 구성을 정의합니다.<br>
각 캐릭터나 아이템마다 개별 장비 세트를 갖게 하고 싶을 때 유용합니다. 예를 들어 "용사의 장비", "마법사의 장비"처럼, 프로퍼티 ID에 캐릭터의 고유 ID를 사용합니다.<br>
편성 관리 화면에서 이용 가능한 아이템별 폼 종류를 표시하는 데 사용합니다.

#### Request

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

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzPropertyFormModel&gt;](#ezpropertyformmodel) | 프로퍼티 폼 목록|

#### 구현 예제




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

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.PropertyFormModels(
    );
    List<EzPropertyFormModel> items = new List<EzPropertyFormModel>();
    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->Formation->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->PropertyFormModels(
    );
    TArray<Gs2::UE5::Formation::Model::FEzPropertyFormModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


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




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

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

```

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

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

```

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

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

```


**⚠️ Warning**

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

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

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

---

### deletePropertyForm

캐릭터나 아이템의 장비 세트 삭제<br>

특정 프로퍼티 ID의 프로퍼티 폼을 삭제하고 모든 슬롯 내용을 초기화합니다.<br>
삭제 후 해당 캐릭터나 아이템은 장비 세트를 가지지 않는 상태가 됩니다. 이후 SetPropertyForm으로 새로운 세트를 만들 수 있습니다.<br>
플레이어가 캐릭터의 장비를 초기화하고자 할 때 사용합니다. 예를 들어 캐릭터 상세 화면의 "모든 장비 해제" 버튼에 사용할 수 있습니다. 장착 중인 아이템이 모두 해제되므로 확인 대화상자를 표시하는 것을 권장합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| propertyId | string |  | ✓|  |  ~ 1024자 | 프로퍼티 ID<br>이 프로퍼티 폼 인스턴스를 고유하게 식별하는 개발자 정의 식별자입니다. 일반적으로 이 폼이 설정하는 소유 리소스(예: GS2-Inventory의 아이템 세트)의 GRN을 설정합니다. 특정 장비에 스킬을 설정하는 등의 용도로 사용됩니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPropertyForm](#ezpropertyform) | 프로퍼티 폼|
| propertyFormModel | [EzPropertyFormModel](#ezpropertyformmodel) | 프로퍼티 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var result = await domain.DeletePropertyFormAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var future = domain.DeletePropertyFormFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PropertyForm(
        "form-0001", // propertyFormModelName
        "property-0001" // propertyId
    );
    const auto Future = Domain->DeletePropertyForm(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).property_form(
        "form-0001",
        "property-0001"
    )

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

var result = async_result.result

```


---

### getPropertyForm

특정 캐릭터나 아이템의 장비 세트 조회<br>

프로퍼티 폼 모델명과 프로퍼티 ID(캐릭터 ID 등)를 지정하여 프로퍼티 폼을 1건 취득합니다.<br>
취득할 수 있는 정보에는 각 슬롯의 내용(해당 캐릭터나 아이템의 각 포지션에 어떤 아이템이 장착되어 있는지)이 포함됩니다.<br>
캐릭터의 장비 상세 화면을 표시할 때 사용합니다. 예를 들어 "용사: 무기=화염검, 갑옷=드래곤 메일, 방패=성스러운 방패"처럼 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| propertyFormModelName | string |  | ✓|  |  ~ 128자 | 프로퍼티 폼 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| propertyId | string |  | ✓|  |  ~ 1024자 | 프로퍼티 ID<br>이 프로퍼티 폼 인스턴스를 고유하게 식별하는 개발자 정의 식별자입니다. 일반적으로 이 폼이 설정하는 소유 리소스(예: GS2-Inventory의 아이템 세트)의 GRN을 설정합니다. 특정 장비에 스킬을 설정하는 등의 용도로 사용됩니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPropertyForm](#ezpropertyform) | 프로퍼티 폼|
| propertyFormModel | [EzPropertyFormModel](#ezpropertyformmodel) | 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PropertyForm(
        "form-0001", // propertyFormModelName
        "property-0001" // propertyId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).property_form(
        "form-0001",
        "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

```


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




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

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

```

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

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

```

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

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

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).property_form(
        "form-0001",
        "property-0001"
    )

# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.

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

---

### getPropertyFormWithSignature

위변조 방지 서명과 함께 캐릭터의 장비 세트 조회<br>

데이터가 위변조되지 않았음을 증명하는 암호 서명과 함께 프로퍼티 폼을 취득합니다.<br>
클라이언트 측에서 SetPropertyForm으로 갱신할 때 이 서명이 필요합니다. 먼저 이 API로 현재 폼과 서명을 취득한 후, 변경 내용과 함께 그 서명을 전송해야 합니다.<br>
"캐릭터 장비 편집" 흐름의 첫 단계로 사용합니다. 현재 장비를 서명과 함께 취득하고, 플레이어가 변경하도록 한 후, SetPropertyForm으로 저장하는 흐름입니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| propertyFormModelName | string |  | ✓|  |  ~ 128자 | 프로퍼티 폼 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| propertyId | string |  | ✓|  |  ~ 1024자 | 프로퍼티 ID<br>이 프로퍼티 폼 인스턴스를 고유하게 식별하는 개발자 정의 식별자입니다. 일반적으로 이 폼이 설정하는 소유 리소스(예: GS2-Inventory의 아이템 세트)의 GRN을 설정합니다. 특정 장비에 스킬을 설정하는 등의 용도로 사용됩니다. |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPropertyForm](#ezpropertyform) | 프로퍼티 폼|
| body | string | 서명 대상 값|
| signature | string | 서명|
| propertyFormModel | [EzPropertyFormModel](#ezpropertyformmodel) | 프로퍼티 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var result = await domain.GetPropertyFormWithSignatureAsync(
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();
    var body = result.Body;
    var signature = result.Signature;

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var future = domain.GetPropertyFormWithSignatureFuture(
        keyId: "key-0001"
    );
    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;
    var body = future.Result.Body;
    var signature = future.Result.Signature;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PropertyForm(
        "form-0001", // propertyFormModelName
        "property-0001" // propertyId
    );
    const auto Future = Domain->GetPropertyFormWithSignature(
        "key-0001" // keyId
    );
    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();
    const auto Body = Result->Body;
    const auto Signature = Result->Signature;

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).property_form(
        "form-0001",
        "property-0001"
    )

var async_result = await domain.get_property_form_with_signature(
    "key-0001" # key_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### listPropertyForms

아이템별 장비 세트 목록 조회<br>

특정 프로퍼티 폼 모델에 대한 플레이어의 모든 프로퍼티 폼 레코드를 취득합니다.<br>
일반 폼(번호가 매겨진 프리셋 칸에 저장)과 달리, 프로퍼티 폼은 커스텀 프로퍼티 ID(일반적으로 캐릭터 ID나 아이템 ID)로 식별됩니다.<br>
예를 들어 "용사의 장비", "마법사의 장비", "궁수의 장비"처럼 각 캐릭터가 개별 장비 구성을 가지고 있는 경우의 목록을 취득할 수 있습니다.<br>
모든 캐릭터와 그 장비 구성을 표시하는 개요 화면을 구성하는 데 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| propertyFormModelName | string |  | ✓|  |  ~ 128자 | 프로퍼티 폼 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzPropertyForm&gt;](#ezpropertyform) | 프로퍼티 폼 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.PropertyFormsAsync(
        propertyFormModelName: "form-0001"
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.PropertyForms(
        propertyFormModelName: "form-0001"
    );
    List<EzPropertyForm> items = new List<EzPropertyForm>();
    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->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->PropertyForms(
        "form-0001" // propertyFormModelName
    );
    TArray<Gs2::UE5::Formation::Model::FEzPropertyFormPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


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




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

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

```

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

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

```

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

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

```


**⚠️ Warning**

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

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

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

---

### setPropertyForm

캐릭터나 아이템의 장비 세트 변경 내용 저장<br>

프로퍼티 폼의 슬롯 내용을 갱신합니다. 예를 들어 용사의 무기를 "철검"에서 "화염검"으로 변경하는 조작입니다.<br>
위변조 방지를 위해 GetPropertyFormWithSignature로 취득한 서명이 필요합니다. 일반적인 흐름은 (1) GetPropertyFormWithSignature로 현재 폼과 서명을 취득, (2) 플레이어가 장비를 편집, (3) 새로운 슬롯 값과 서명을 첨부하여 이 API를 호출하는 순서입니다.<br>
지정한 프로퍼티 ID에 아직 프로퍼티 폼이 없는 경우 자동으로 새로 생성됩니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| propertyFormModelName | string |  | ✓|  |  ~ 128자 | 프로퍼티 폼 모델 이름 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| propertyId | string |  | ✓|  |  ~ 1024자 | 프로퍼티 ID<br>이 프로퍼티 폼 인스턴스를 고유하게 식별하는 개발자 정의 식별자입니다. 일반적으로 이 폼이 설정하는 소유 리소스(예: GS2-Inventory의 아이템 세트)의 GRN을 설정합니다. 특정 장비에 스킬을 설정하는 등의 용도로 사용됩니다. |
| slots | [List&lt;EzSlotWithSignature&gt;](#ezslotwithsignature) |  | ✓|  | 1 ~ 10 items | 슬롯 목록 |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPropertyForm](#ezpropertyform) | 프로퍼티 폼|
| proeprtyFormModel | [EzPropertyFormModel](#ezpropertyformmodel) | 프로퍼티 폼 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var result = await domain.SetPropertyFormAsync(
        slots: new List<Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature> {
            new Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature() {
                Name = "slot-0001",
                PropertyType = "gs2_dictionary",
                Body = "body",
                Signature = "signature",
            },
        },
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Formation.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PropertyForm(
        propertyFormModelName: "form-0001",
        propertyId: "property-0001"
    );
    var future = domain.SetPropertyFormFuture(
        slots: new List<Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature> {
            new Gs2.Unity.Gs2Formation.Model.EzSlotWithSignature() {
                Name = "slot-0001",
                PropertyType = "gs2_dictionary",
                Body = "body",
                Signature = "signature",
            },
        },
        keyId: "key-0001"
    );
    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;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Formation->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PropertyForm(
        "form-0001", // propertyFormModelName
        "property-0001" // propertyId
    );
    const auto Future = Domain->SetPropertyForm(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Formation::Model::FEzSlotWithSignature>>>();
            v->Add(
                MakeShared<Gs2::UE5::Formation::Model::FEzSlotWithSignature>()
                ->WithName(TOptional<FString>("slot-0001"))
                ->WithPropertyType(TOptional<FString>("gs2_dictionary"))
                ->WithBody(TOptional<FString>("body"))
                ->WithSignature(TOptional<FString>("signature"))
            );
            return v;
        }(), // slots
        "key-0001" // keyId
    );
    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();

```

**Godot**
```gdscript

var domain = ez.formation.namespace_(
        "namespace-0001"
    ).me(game_session).property_form(
        "form-0001",
        "property-0001"
    )

var async_result = await domain.set_property_form(
    [
        Gs2FormationEzSlotWithSignature.new()
            .with_name("slot-0001")
            .with_property_type("gs2_dictionary")
            .with_body("body")
            .with_signature("signature"),
    ], # slots
    "key-0001" # key_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---



