[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | SetByInfoAndWait에서 DataStorageKeyInfo를 사용하여 저장할 때 일반 SetAndWait와 무엇이 다른가 [answer] | `SetByInfoAndWait`는 `SetAndWait`와 달리 단순한 문자열 키(`string key`) 대신 `DataStorageKeyInfo` 객체를 사용하여 데이터를 저장합니다. 두 메서드의 주요 차이점은 다음과 같습니다: 1. **키 정보의 상세화**: * `SetAndWait(string key, integer value)`: 문자열 형태의 키만 전달합니다. * `SetByInfoAndWait(DataStorageKeyInfo keyInfo, integer value)`: `DataStora [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | rection으로 오름/내림차순 정렬을 설정할 수 있습니다. min, max로 설정한 범위 내의 데이터들을 조회할 수 있습니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 조회용 객체와 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32, DataStorageVersionPages GetVersionsAndWait(string key, SortDirection sortDirection, DateTime minDate, DateTime maxDate) [ServerOnly] [Yield
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | IncreaseAsync를 호출했을 때 callbackFunction에 전달되는 에러 코드와 갱신된 값의 순서 [answer] | `IncreaseAsync` 메서드를 호출할 때, 작업이 완료되면 `callbackFunction`에 전달되는 인자의 순서는 **에러 코드**가 먼저이고, 그 다음에 **갱신된 값**입니다. 참고로 문서의 서명 `void IncreaseAsync(string key, integer delta, func<int32, string, integer> callbackFunction)`에는 `string` 타입(키)도 포함되어 있으나, 설명문에서는 "에러 코드, 키, 갱신된 값과 함께"라고 명시하고 있습니다. 질문에서 물은 '에러 코드'와 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | rection으로 오름/내림차순 정렬을 설정할 수 있습니다. min, max로 설정한 범위 내의 데이터들을 조회할 수 있습니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 조회용 객체와 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32, DataStorageVersionPages GetVersionsAndWait(string key, SortDirection sortDirection, DateTime minDate, DateTime maxDate) [ServerOnly] [Yield
[task] | two_turn [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | DataStorage에서 기존 값과 일치할 때만 업데이트하는 GetAndWait와 UpdateAndWait의 동작 원리는 무엇인가요? [answer] | `GetAndWait`와 `UpdateAndWait`는 데이터 무결성을 보장하기 위해 **CAS(Compare-And-Swap)** 방식을 기반으로 동작합니다. 1. **`GetAndWait`**: 특정 키(Key)에 저장된 현재 값을 가져옵니다. 2. **`UpdateAndWait`**: 이 함수는 단순히 값을 덮어쓰는 것이 아니라, **기존 값이 기대하는 값과 일치하는지 비교**합니다. * **성공**: 저장된 값이 `GetAndWait`로 가져온 값과 정확히 일치하면, 새로운 값으로 업데이트됩니다. * [followup] | UpdateAndWait에서 oldValue가 서버에 저장된 값과 다르면 어떤 에러코드가 반환되며, 실패 시 재시도 로직을 어떻게 구성해야 하나요? [followup_answer] | 참고 문서에는 `UpdateAndWait` 실패 시 반환되는 **구체적인 에러코드 값**에 대한 정보가 없습니다. 문서에는 `errorCode`가 0이 아닌 경우 실패로 간주한다는 내용(`if errorCode ~= 0 then`)만 명시되어 있으므로, 특정 에러코드는 확인되지 않습니다. 실패 시 재시도 로직을 구성할 때는 `UpdateAndWait`가 실패하면(에러코드가 0이 아니면) 다시 `GetAndWait`를 호출하여 최신 값을 가져오고, 이를 기반으로 다시 `UpdateAndWait`를 시도하는 루프 구조를 사용하는 것이 [scores] | [judge_reason] | [source_doc] | 일정 기간 내의 버전 정보를 조회하는 예제입니다. ```lua local ds = _DataStorageService:GetGlobalDataStorage("StorageName") local minDate = DateTime(2023, 03, 09, 20, 20, 0, 0) local maxDate = DateTime(2023, 03, 09, 22, 20, 0, 0) -- 값을 저장할 때 버전 값을 함께 지정한 경우에만 조회할 수 있습니다. local errorCode, versionPages = ds:GetVersion
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | TransactDeleteAndWait에서 여러 키를 삭제할 때 일부만 실패하면 어떻게 처리되는지 [answer] | 제공된 참고 문서에는 `TransactDeleteAndWait` 메서드의 시그니처(`int32, List<string> TransactDeleteAndWait(List<string> keys) [ServerOnly] [Yield]`)와 "입력한 키들을 삭제합니다"라는 설명, 그리고 반환값이 에러 코드와 `List<string>`임을 알 수 있습니다. 그러나 **일부 키 삭제에 실패했을 때의 구체적인 처리 방식**(예: 성공한 키 목록을 반환하는지, 실패한 키 목록을 반환하는지, 트랜잭션이 전체적으로 롤백되는지, 부분적으로 커밋되는 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | rection으로 오름/내림차순 정렬을 설정할 수 있습니다. min, max로 설정한 범위 내의 데이터들을 조회할 수 있습니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 조회용 객체와 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32, DataStorageVersionPages GetVersionsAndWait(string key, SortDirection sortDirection, DateTime minDate, DateTime maxDate) [ServerOnly] [Yield
[task] | single_turn [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | DataStorage 사용량 제한을 확인하고 관리하기 위해 크리에이터가 직접 구현해야 하는 로직과 시스템이 제공하는 기능은 어디까지인가요? [answer] | DataStorage 사용량 제한에 대해 시스템이 제공하는 기능과 크리에이터가 직접 구현해야 하는 로직은 다음과 같이 구분됩니다. **시스템이 제공하는 기능** 1. **사용량 제한 존재**: DataStorage에는 사용량 제한이 존재하며, 이 제한을 초과할 경우 데이터 저장이 실패할 수 있습니다. 2. **저장 시 에러 코드 반환**: 데이터를 저장할 때(`SetByInfoAndWait` 등) 사용량 제한을 초과하거나 다른 오류가 발생하면 에러 코드(errorcode)가 반환됩니다. **크리에이터가 직접 구현해야 하는 로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | * table * DataStorageKeyInfo * DateTime * DataStorageService * [Data DB 저장 및 불러오기](/docs?postId=68) * [DataStorage 사용량 제한 알아보기](/docs?postId=1044) * [DataStorage 사용량 제한 활용하기](/docs?postId=1045) * [DataStorage 활용하기](/docs?postId=692)
[task] | two_turn [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | GlobalDataStorage에서 특정 기간의 버전 정보를 조회하는 과정과 페이지 처리 방법은 어떻게 되나요? [answer] | GlobalDataStorage에서 특정 기간의 버전 정보를 조회하고 페이지를 처리하는 과정은 다음과 같습니다. 1. **서비스 및 스토리지 접근**: `_DataStorageService:GetGlobalDataStorage("StorageName")`을 호출하여 전역 데이터 스토리지 객체를 가져옵니다. 2. **기간 지정**: `DateTime` 타입으로 조회할 시작 시간(`minDate`)과 종료 시간(`maxDate`)을 정의합니다. 3. **버전 목록 조회**: `GetVersionsAndWait` 메서드를 호출합니다. [followup] | GetVersionsAndWait 호출 시 SortDirection과 DateTime 인자를 어떻게 조합해야 하며, IsLastPage 확인 후 MoveToNextPageAndWait를 반복 호출할 때 주의할 점은 무엇인가요? [followup_answer] | `GetVersionsAndWait` 호출 시 `SortDirection`과 `DateTime` 인자는 다음과 같이 조합합니다. 1. **인자 조합**: * `GetVersionsAndWait` 메서드는 `(Key, SortDirection, minDate, maxDate)` 순서로 인자를 받습니다. * `SortDirection`에는 정렬 방향을 지정하며, 예제에서는 `SortDirection.Ascending`(오름차순)이 사용되었습니다. * `minDate`와 `maxDate`에는 `Date [scores] | [judge_reason] | [source_doc] | 일정 기간 내의 버전 정보를 조회하는 예제입니다. ```lua local ds = _DataStorageService:GetGlobalDataStorage("StorageName") local minDate = DateTime(2023, 03, 09, 20, 20, 0, 0) local maxDate = DateTime(2023, 03, 09, 22, 20, 0, 0) -- 값을 저장할 때 버전 값을 함께 지정한 경우에만 조회할 수 있습니다. local errorCode, versionPages = ds:GetVersion
[task] | code [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | GlobalDataStorage의 TransactSetByInfoAsync를 통해 최대 20개까지 가능한 데이터 저장 중 5개의 아이템 카운트를 한 번에 트랜잭션 처리하고, 콜백에서 실패한 Key 목록이 있다면 이를 추출하여 별도 로그로 남기는 서버 전용 스크립트를 작성해줘 [answer] | GlobalDataStorage의 `TransactSetByInfoAsync`는 문서에 명시된 대로 **모든 작업 중 하나라도 실패한다면 함수 호출 자체가 실패**합니다. 따라서 "일부 성공, 일부 실패"라는 상태가 존재하지 않으며, 콜백(`callbackFunction`)은 **모든 키가 성공했을 때만** 호출됩니다. 실패 시 콜백은 호출되지 않으므로, **콜백 안에서 실패한 Key 목록을 추출해 로그로 남기는 것은 불가능**합니다. 실패 처리를 원한다면 `TransactSetByInfoAsync` 대신 동기 방식인 `Tran [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ageKeyInfo, string> keyValues) [ServerOnly] [Yield]** 입력한 DataStorageKeyInfo들로 데이터를 저장합니다. 모든 데이터 저장에 성공하면 에러 코드와 성공한 DataStorageKeyInfo를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. 모든 작업 중 하나라도 실패한다면, 함수 호출이 실패합니다. 한 번에 최대 20개 Key까지 조작 할 수 있습니다. - **void TransactSetByInfoAsync(Dictionary<DataStorageKeyInfo, s
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | GetSortedAndWait 예제 코드에서 while 루프를 사용하는 이유를 표로 정리하세요. [answer] | `GetSortedAndWait` 예제 코드에서 `while` 루프를 사용하는 이유는 **페이지네이션(페이지 분할) 처리** 때문입니다. `GetSortedAndWait`는 한 번에 모든 데이터를 반환하지 않고, 요청한 페이지 크기(예: 1000개) 단위로 데이터를 나누어 제공합니다. 따라서 모든 데이터를 확인하려면 현재 페이지의 데이터를 처리한 후, 마지막 페이지가 아니면 다음 페이지로 이동하는 과정을 반복해야 합니다. 구체적인 역할은 아래 표와 같습니다. | 단계 | 코드/메서드 | 역할 | | :--- | :--- | : [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # Examples #### IncreaseAndWait 값을 증가시키는 예제입니다. ```lua local ds = _DataStorageService:GetSortableDataStorage("Storage") -- "Key"에 해당하는 값이 없을 경우 기본 값으로 생성 후 1을 증가시킵니다. local errorCode, value = ds:IncreaseAndWait("Key", 1) ``` #### IncreaseAsync 값을 비동기로 증가시키는 예제입니다. ```lua local ds = _DataStor
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | 모든 메서드에 [ServerOnly] 태그가 붙어 있는데, 클라이언트에서 이 데이터를 직접 조회하거나 수정할 수 있는 방법이 없나요? [answer] | 제공된 문서 정보에 따르면, `SortableDataStorage`의 모든 메서드는 `[ServerOnly]` 태그를 가지고 있어 서버에서만 실행될 수 있습니다. 따라서 클라이언트에서 이 데이터를 직접 조회하거나 수정하는 API는 제공되지 않습니다. 클라이언트는 서버 스크립트에서 데이터를 조회한 후, 그 결과를 클라이언트로 전송하는 별도의 통신 메커니즘(예: 멀티캐스트, 클라이언트-서버 메시지 등)을 통해 간접적으로 데이터를 받아올 수 있지만, `SortableDataStorage` 자체를 클라이언트에서 직접 다루는 방법은 없습니 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | lbackFunction) [ServerOnly]** 입력한 DataStorageKeyInfo들로 데이터들을 저장합니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 저장에 성공한 DataStorageKeyInfo들과 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32 DeleteAndWait(string key) [ServerOnly] [Yield]** 입력한 키로 데이터를 삭제하고 에러 코드를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. - **void Delete
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | BatchDeleteAsync의 콜백 함수에서 에러 코드가 0이 아닌 경우, 삭제에 실패한 키를 어떻게 알 수 있나요? [answer] | BatchDeleteAsync의 콜백 함수가 전달하는 값은 에러 코드와 **삭제에 성공한 키들**의 목록입니다. 따라서 에러 코드가 0이 아니더라도, 콜백 인자로부터 직접적으로 '삭제에 실패한 키' 목록을 가져올 수 있는 방법은 제공되지 않습니다. 콜백 함수의 시그니처가 `func<int32, List<string>>`인 것을 보면, 두 번째 인자는 성공적으로 삭제된 키들의 리스트일 뿐 실패한 키들의 리스트가 아닙니다. 실패한 키를 알기 위해서는 원래 요청했던 전체 키 목록과 성공한 키 목록을 비교(차집합)하는 로직을 작성해야 합 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 정수형 데이터를 관리하고, 정렬한 데이터를 가져오는 기능이 있는 저장소입니다. 메이커와 출시 환경은 저장소를 공유하지 않습니다. # Properties - **string Name [ReadOnly]** DataStorage의 이름입니다. # Methods - **int32, List<string> BatchDeleteAndWait(List<string> keys) [ServerOnly] [Yield]** 입력한 키들로 데이터들을 삭제합니다. 에러 코드와 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을
[task] | two_turn [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | SetByInfoAndWait를 사용하여 버전을 지정해 값을 저장할 때, 기존 버전 값이 덮어쓰이지 않고 유지되는 메커니즘은 어떻게 작동하나요? [answer] | `SetByInfoAndWait`를 사용할 때 기존 버전 값이 덮어쓰이지 않고 유지되는 메커니즘은 **버전(Version) 식별자에 따른 독립적 저장** 원리입니다. `DataStorageKeyInfo` 객체에 `Key`와 `Version`을 함께 지정하여 `SetByInfoAndWait`를 호출하면, 시스템은 해당 `Key` + `Version` 조합을 고유한 저장 위치로 취급합니다. 따라서 동일한 `Key`를 사용하더라도 `Version` 값이 다르면 서로 다른 데이터 슬롯에 저장되어, 이미 저장된 과거 버전의 값이 손상되지 [followup] | 과거 버전(Version1)의 값을 가져와 최신 버전(Version2)에 다시 저장하는 과정에서 GetAndWait로 조회되는 값이 어떻게 변경되는지 코드 예시로 설명해 주세요. [followup_answer] | 과거 버전(Version1)의 값을 가져와 최신 버전(Version2)에 다시 저장하면, 이후 `GetAndWait`로 조회되는 값은 변경됩니다. `GetAndWait`는 기본적으로 최신 상태의 값을 반환하기 때문에, Version2에 새로운 값이 저장되면 그 값이 반환됩니다. 참고 문서의 "버전 활용" 예제를 보면, 다음 과정을 거칩니다: 1. `Version1`에 `"Value"` 저장 2. `Version2`에 `"Value2"` 저장 (이 시점에서 `GetAndWait`는 `"Value2"` 반환) 3. `Version1` [scores] | [judge_reason] | [source_doc] | 일정 기간 내의 버전 정보를 조회하는 예제입니다. ```lua local ds = _DataStorageService:GetGlobalDataStorage("StorageName") local minDate = DateTime(2023, 03, 09, 20, 20, 0, 0) local maxDate = DateTime(2023, 03, 09, 22, 20, 0, 0) -- 값을 저장할 때 버전 값을 함께 지정한 경우에만 조회할 수 있습니다. local errorCode, versionPages = ds:GetVersion
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | Increase와 Set 메서드의 파라미터 명세만 코드 블록으로 출력하고 설명은 주석으로 [answer] | ```lua Method: [server only] void OnBeginPlay() { -- IncreaseAndWait: 동기화(블로킹) 방식으로 값을 증가시킵니다. -- 파라미터: -- key (string): 데이터 저장 시 사용할 키 -- delta (integer): 증가시킬 값 (음수 가능) -- 반환값: -- errorCode (int32): 실행 결과 에러 코드 -- newValue (integer): 증가 후 갱신된 값 local errorCo [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | rection으로 오름/내림차순 정렬을 설정할 수 있습니다. min, max로 설정한 범위 내의 데이터들을 조회할 수 있습니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 조회용 객체와 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32, DataStorageVersionPages GetVersionsAndWait(string key, SortDirection sortDirection, DateTime minDate, DateTime maxDate) [ServerOnly] [Yield
[task] | single_turn [pass] | ⏳ 미판정 [title] | GlobalDataStoragePages [question] | LoadNextPageAndWait와 MoveToNextPageAndWait를 왜 나눠서 사용해야 하는지, 한 번에 다음 페이지로 넘어가지 않는 이유는 무엇인가요? [answer] | `LoadNextPageAndWait`와 `MoveToNextPageAndWait`를 분리해서 사용하는 이유는 **데이터 로딩(불러오기)**과 **페이지 이동(포인터 변경)**이라는 두 가지 독립적인 단계를 명확히 구분하고, 로딩 실패 시 안전한 처리를 가능하게 하기 위해서입니다. 구체적인 이유는 다음과 같습니다. 1. **로딩 실패 시 안전장치 (Error Handling)** * `LoadNextPageAndWait()`는 다음 페이지의 데이터를 서버에서 가져오는 과정이며, 성공 시 `0`, 실패 시 에러 코드를 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 월드의 GlobalDataStorage들을 조회할 수 있는 기능을 제공합니다. # Properties - **boolean IsLastPage [ReadOnly]** 현재 페이지가 마지막 페이지인지 확인합니다. # Methods - **table<GlobalDataStorage> GetCurrentPageDatas() [ServerOnly]** 현재 페이지의 GlobalDataStorage 목록을 가져옵니다. - **int32 LoadNextPageAndWait() [ServerOnly] [Yield]** 다음 페
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | 문서 내 예제 코드만 출력하고 설명은 주석으로 작성하세요. [answer] | ```lua -- 값을 증가시키는 예제입니다. local ds = _DataStorageService:GetSortableDataStorage("Storage") -- "Key"에 해당하는 값이 없을 경우 기본 값으로 생성 후 1을 증가시킵니다. local errorCode, value = ds:IncreaseAndWait("Key", 1) ``` ```lua -- 값을 비동기로 증가시키는 예제입니다. local ds = _DataStorageService:GetSortableDataStorage("Storage") ds: [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # Examples #### IncreaseAndWait 값을 증가시키는 예제입니다. ```lua local ds = _DataStorageService:GetSortableDataStorage("Storage") -- "Key"에 해당하는 값이 없을 경우 기본 값으로 생성 후 1을 증가시킵니다. local errorCode, value = ds:IncreaseAndWait("Key", 1) ``` #### IncreaseAsync 값을 비동기로 증가시키는 예제입니다. ```lua local ds = _DataStor
[task] | code [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | DataStorageKeyInfo 조건을 설정하여 데이터를 비동기 조회하고 에러 코드가 성공일 경우에만 데이터를 처리하는 스크립트를 _DataStorageService 를 사용하여 작성해줘. [answer] | `DataStorageKeyInfo` 객체를 생성하여 `Key`와 `Version`을 설정하고, `_DataStorageService`의 `GetGlobalDataStorage`로 저장소를 가져온 후 `GetByInfoAsync` 메서드를 사용하여 비동기 조회를 수행합니다. 콜백 함수에서 에러 코드가 0(성공)인 경우에만 데이터를 처리하도록 작성했습니다. ```lua Property: [Sync] number RetrievedValue = 0 Method: [server only] void OnBeginPlay() { [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | lbackFunction) [ServerOnly]** 입력한 DataStorageKeyInfo들로 데이터들을 저장합니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 저장에 성공한 DataStorageKeyInfo들과 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32 DeleteAndWait(string key) [ServerOnly] [Yield]** 입력한 키로 데이터를 삭제하고 에러 코드를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. - **void Delete
[task] | code [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | 태그를 가진 데이터 목록을 비동기 조회하여 페이지 객체를 받는 스크립트를 _DataStorageService 를 사용하여 작성해줘. [answer] | 태그를 가진 데이터 목록을 비동기적으로 조회하려면 `GetPagesAsync` 메서드를 사용합니다. 이 메서드는 입력으로 태그 문자열과 콜백 함수를 받아, 작업이 완료되면 에러 코드, 태그, 그리고 `SortableDataStorageItemPages` 타입의 페이지 객체를 반환합니다. 아래는 `_DataStorageService`를 사용하여 글로벌 데이터 스토리지에서 특정 태그("MyTag")를 가진 데이터를 비동기 조회하는 예제 스크립트입니다. ```lua Property: [None] string TargetTag = " [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | lbackFunction) [ServerOnly]** 입력한 DataStorageKeyInfo들로 데이터들을 저장합니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 저장에 성공한 DataStorageKeyInfo들과 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32 DeleteAndWait(string key) [ServerOnly] [Yield]** 입력한 키로 데이터를 삭제하고 에러 코드를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. - **void Delete
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | SortableDataStorage의 동기(Wait) 방식과 비동기(Async) 방식 메서드의 차이를 설명하되, 차이점을 비교하는 표로 정리하세요. [answer] | SortableDataStorage에서 동기(Wait) 방식과 비동기(Async) 방식 메서드의 주요 차이는 실행 흐름의 중단 여부, 반환 값의 형태, 그리고 콜백 함수의 사용 여부입니다. ### 1. 실행 방식 및 흐름 * **동기(Wait) 방식**: 메서드 호출 시 작업이 완료될 때까지 스크립트 실행을 **중단**(Yield)합니다. 작업이 끝난 후 바로 결과 값을 반환받아 후속 코드를 수행합니다. * **비동기(Async) 방식**: 메서드 호출 시 즉시 반환되고, 작업은 백그라운드에서 비동기로 수행됩니다. 작업이 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 정수형 데이터를 관리하고, 정렬한 데이터를 가져오는 기능이 있는 저장소입니다. 메이커와 출시 환경은 저장소를 공유하지 않습니다. # Properties - **string Name [ReadOnly]** DataStorage의 이름입니다. # Methods - **int32, List<string> BatchDeleteAndWait(List<string> keys) [ServerOnly] [Yield]** 입력한 키들로 데이터들을 삭제합니다. 에러 코드와 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | GetSortedAndWait 메서드에서 min과 max 파라미터는 정렬 순서와 관계없이 단순히 데이터 범위를 제한하는 것일까요? [answer] | 네, `GetSortedAndWait` 메서드의 `min`과 `max` 파라미터는 정렬 순서(`sortDirection`)와 무관하게 단순히 조회할 데이터의 **범위**를 제한하는 값입니다. 문서에 따르면 이 메서드는 다음과 같이 동작합니다: 1. `sortDirection` 파라미터로 오름차순 또는 내림차순 정렬 방식을 설정합니다. 2. `min`, `max` 파라미터로 **설정된 범위 내의 데이터들**만 조회합니다. 즉, 정렬 방향이 오름차순이든 내림차순이든 `min`~`max` 구간 안에 있는 데이터들을 필터링하여 가져오는 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | lbackFunction) [ServerOnly]** 입력한 DataStorageKeyInfo들로 데이터들을 저장합니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 저장에 성공한 DataStorageKeyInfo들과 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32 DeleteAndWait(string key) [ServerOnly] [Yield]** 입력한 키로 데이터를 삭제하고 에러 코드를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. - **void Delete
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | 모든 트랜잭션 함수에서 허용되는 최대 Key 수와, 작업 중 하나라도 실패했을 때의 함수 동작 방식을 2문장 이내로 설명하세요. [answer] | 모든 트랜잭션 함수에서 한 번에 조작할 수 있는 최대 Key 수는 20개입니다. 작업 중 하나라도 실패하면 함수 호출 자체가 실패합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | eld]** 입력한 키들로 데이터를 삭제합니다. 호출에 포함된 모든 작업이 성공하면 에러 코드, 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. 모든 작업 중 하나라도 실패한다면, 함수 호출이 실패합니다. 한 번에 최대 20개 Key까지 조작할 수 있습니다. - **void TransactDeleteAsync(List<string> keys, func<int32, List<string>> callbackFunction) [ServerOnly]** 입력한 키들로 데이터를 삭제합니다. 이 함수 호출은
[task] | single_turn [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | GlobalDataStorage에서 페이지를 순회할 때 while true 루프 내부에서 MoveToNextPageAndWait() 호출 없이 IsLastPage만 체크하면 무한 루프에 빠지지 않는지, 그리고 페이지 이동 로직의 정확한 실행 순서를 설명해 주시겠습니까? [answer] | 제공된 참고 문서의 코드 예제를 분석하면, `while true` 루프 내부에서 `MoveToNextPageAndWait()`를 호출하지 않고 `IsLastPage`만 체크할 경우 **무한 루프에 빠집니다.** ### 1. 무한 루프 발생 이유 참고 문서의 모든 예제( `BatchGetByInfoAndWait`, `GetPagesAndWait`, `GetVersionsAndWait` 등)에서 페이지 순회 로직은 동일한 패턴을 따릅니다. 1. 현재 페이지의 데이터를 가져옵니다. (`GetCurrentPageDatas()`) 2. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 데이터를 DataStorageKeyInfo를 통해 일괄로 가져오는 예제입니다. ```lua local ds = _DataStorageService:GetGlobalDataStorage("StorageName") local keyInfos = {} local keyInfo1 = DataStorageKeyInfo("Key1", "Version1", "Tag1") local keyInfo2 = DataStorageKeyInfo("Key2", "Version2", "Tag2") table.insert(keyInfos, keyInfo1
[task] | two_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | BatchSetAndWait와 BatchSetAsync 메서드는 각각 어떤 상황에서 사용되며, Yield 속성이 스크립트 실행에 미치는 영향은 무엇인가요? [answer] | **BatchSetAndWait와 BatchSetAsync의 사용 상황** 두 메서드 모두 정수형 데이터를 키와 값의 쌍(`Dictionary<string, integer>`)으로 저장하는 역할을 합니다. * **BatchSetAndWait**: 저장 작업이 완료될 때까지 스크립트 실행을 중단한 채 기다리는 동기적(Synchronous) 처리를 원할 때 사용합니다. 작업이 끝난 후 바로 반환되는 에러 코드와 저장에 성공한 키 목록을 즉시 확인하고 후속 로직을 실행해야 하는 경우에 적합합니다. * **BatchSetAsyn [followup] | BatchSetAndWait 호출 시 에러 코드와 성공한 키를 반환받아서 실패 항목을 재시도하는 로직을 작성해 주세요. [followup_answer] | `BatchSetAndWait`는 `Dictionary<string, integer>` 형태의 데이터를 받아 저장하며, 반환값으로 `int32` 타입의 에러 코드와 `List<string>` 타입의 저장에 성공한 키 목록을 제공합니다. 전체 저장 요청이 실패한 경우(에러 코드가 0이 아닌 경우)는 모든 키가 실패한 것으로 간주할 수 있으며, 부분적으로 성공한 경우(에러 코드가 0이지만 일부 키가 실패한 경우)는 요청한 키 목록에서 성공한 키 목록을 제외한 나머지 키를 재시도 대상으로 삼으면 됩니다. 아래는 `BatchSetAnd [scores] | [judge_reason] | [source_doc] | 정수형 데이터를 관리하고, 정렬한 데이터를 가져오는 기능이 있는 저장소입니다. 메이커와 출시 환경은 저장소를 공유하지 않습니다. # Properties - **string Name [ReadOnly]** DataStorage의 이름입니다. # Methods - **int32, List<string> BatchDeleteAndWait(List<string> keys) [ServerOnly] [Yield]** 입력한 키들로 데이터들을 삭제합니다. 에러 코드와 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | TransactDeleteAsync와 TransactSetAndWait의 차이점을 실행 방식(동기/비동기)과 반환 값 기준으로 3줄 이내의 표로 정리하세요. [answer] | | 구분 | TransactDeleteAsync | TransactSetAndWait | | :--- | :--- | :--- | | **실행 방식** | 비동기 (Callback으로 결과 전달) | 동기 (Yield로 스크립트 실행 중단) | | **반환 값** | 없음 (void) | int32 (에러 코드), List<string> (성공한 키들) | [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | eld]** 입력한 키들로 데이터를 삭제합니다. 호출에 포함된 모든 작업이 성공하면 에러 코드, 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. 모든 작업 중 하나라도 실패한다면, 함수 호출이 실패합니다. 한 번에 최대 20개 Key까지 조작할 수 있습니다. - **void TransactDeleteAsync(List<string> keys, func<int32, List<string>> callbackFunction) [ServerOnly]** 입력한 키들로 데이터를 삭제합니다. 이 함수 호출은
[task] | code [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | _DataStorageService:GetGlobalDataStorage("StorageName") 과 BatchGetByInfoAndWait 메서드를 사용하여 DataStorageKeyInfo 리스트를 만들고, 반환된 itemPages에서 IsLastPage와 MoveToNextPageAndWait를 활용해 모든 페이지의 데이터를 순회하며 item.KeyInfo.Key와 item.Value를 로그로 출력하는 스크립트를 작성해줘 [answer] | 요청하신 `_DataStorageService:GetGlobalDataStorage`와 `BatchGetByInfoAndWait`를 사용하여 데이터 키 정보를 일괄 조회하고, 페이지를 순회하며 `Key`와 `Value`를 출력하는 mLua 스크립트는 다음과 같습니다. ```lua Method: void FetchAndLogStorageData() { -- 전역 데이터 스토리지 인스턴스 가져오기 local ds = _DataStorageService:GetGlobalDataStorage("StorageName") [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 데이터를 DataStorageKeyInfo를 통해 일괄로 가져오는 예제입니다. ```lua local ds = _DataStorageService:GetGlobalDataStorage("StorageName") local keyInfos = {} local keyInfo1 = DataStorageKeyInfo("Key1", "Version1", "Tag1") local keyInfo2 = DataStorageKeyInfo("Key2", "Version2", "Tag2") table.insert(keyInfos, keyInfo1
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | BatchSetByInfoAndWait의 파라미터로 받는 DataStorageKeyInfo 객체는 어떤 필드를 가지고 있으며, 기존 string 키와 어떤 차이가 있나요? [answer] | `DataStorageKeyInfo` 객체는 `BatchSetByInfoAndWait` 메서드를 사용할 때 데이터의 키를 정의하는 데 사용됩니다. 제공된 참고 문서에 따르면, `DataStorageKeyInfo` 객체를 생성할 때 **3개의 문자열 인자**를 전달합니다. 예제 코드에서 다음과 같이 생성하는 것을 확인할 수 있습니다: ```lua local keyInfo1 = DataStorageKeyInfo("Key1", "Version1", "Tag1") ``` 이 3개의 인자는 각각 **기본 키(Key)**, **버전(Ver [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 정수형 데이터를 관리하고, 정렬한 데이터를 가져오는 기능이 있는 저장소입니다. 메이커와 출시 환경은 저장소를 공유하지 않습니다. # Properties - **string Name [ReadOnly]** DataStorage의 이름입니다. # Methods - **int32, List<string> BatchDeleteAndWait(List<string> keys) [ServerOnly] [Yield]** 입력한 키들로 데이터들을 삭제합니다. 에러 코드와 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을
[task] | code [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | 정렬 방향과 범위(min, max)를 지정하여 데이터를 비동기 조회하는 스크립트를 _DataStorageService 를 사용하여 작성해줘. [answer] | `_DataStorageService`를 통해 `SortableDataStorage` 인스턴스를 가져온 후, `GetSortedAsync` 메서드를 사용하여 정렬 방향과 범위를 지정하여 데이터를 비동기 조회하는 스크립트입니다. 참고 문서에 따르면 `GetSortedAsync`는 `SortDirection` 타입의 정렬 방향, `integer` 타입의 `min`, `max` 값을 인자로 받으며, 완료 시 에러 코드와 `SortableDataStorageItemPages` 객체를 콜백 함수로 전달합니다. ```lua Property [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | lbackFunction) [ServerOnly]** 입력한 DataStorageKeyInfo들로 데이터들을 저장합니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 저장에 성공한 DataStorageKeyInfo들과 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32 DeleteAndWait(string key) [ServerOnly] [Yield]** 입력한 키로 데이터를 삭제하고 에러 코드를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. - **void Delete
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | minDate와 maxDate로 버전 조회 시 특정 시간대 내 데이터를 필터링하는 구체적인 방식 [answer] | `minDate`와 `maxDate`는 `DateTime` 타입을 사용하며, 이 두 날짜 사이에 생성된 버전 데이터만 필터링하여 조회합니다. 구체적인 사용 방식은 다음과 같습니다. 1. **DateTime 생성**: `DateTime(년, 월, 일, 시, 분, 초, 밀리초)` 형식으로 시작 시간(`minDate`)과 종료 시간(`maxDate`)을 지정합니다. 2. **조회 메서드 호출**: `GetVersionsAndWait` (동기) 또는 `GetVersionsAsync` (비동기) 메서드를 호출할 때, 두 번째 인자로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | rection으로 오름/내림차순 정렬을 설정할 수 있습니다. min, max로 설정한 범위 내의 데이터들을 조회할 수 있습니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 조회용 객체와 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32, DataStorageVersionPages GetVersionsAndWait(string key, SortDirection sortDirection, DateTime minDate, DateTime maxDate) [ServerOnly] [Yield
[task] | instruction_following [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | TransactSetByInfoAndWait 메서드의 시그니처와 매개변수 타입만 추출하여 코드 블록으로 출력하고, 설명은 주석으로만 작성하세요. [answer] | ```lua -- TransactSetByInfoAndWait 메서드 시그니처 -- 매개변수: keyValues (Dictionary<DataStorageKeyInfo, integer>) -- 반환값: int32 (에러 코드), List<DataStorageKeyInfo> (저장에 성공한 키 정보 목록) int32, List<DataStorageKeyInfo> TransactSetByInfoAndWait(Dictionary<DataStorageKeyInfo, integer> keyValues) ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | eld]** 입력한 키들로 데이터를 삭제합니다. 호출에 포함된 모든 작업이 성공하면 에러 코드, 삭제에 성공한 키들을 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. 모든 작업 중 하나라도 실패한다면, 함수 호출이 실패합니다. 한 번에 최대 20개 Key까지 조작할 수 있습니다. - **void TransactDeleteAsync(List<string> keys, func<int32, List<string>> callbackFunction) [ServerOnly]** 입력한 키들로 데이터를 삭제합니다. 이 함수 호출은
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | SortableDataStorage에서 WaitAnd 계열과 Async 계열 메서드의 가장 큰 차이는 무엇이며, 스크립트 실행 흐름에 어떤 영향을 미치나요? [answer] | SortableDataStorage에서 `WaitAnd` 계열과 `Async` 계열 메서드의 가장 큰 차이는 **스크립트 실행을 중단시키는가(블로킹) 여부**입니다. 1. **WaitAnd 계열 (예: `GetAndWait`, `DeleteAndWait`)** * **특징:** `[Yield]` 태그가 붙어 있습니다. * **실행 흐름 영향:** 데이터 조회/저장/삭제 작업이 완료될 때까지 **현재 스크립트의 실행을 중단(블로킹)**합니다. * **결과 반환:** 작업이 끝난 후 에러 코드와 결과 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | lbackFunction) [ServerOnly]** 입력한 DataStorageKeyInfo들로 데이터들을 저장합니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 저장에 성공한 DataStorageKeyInfo들과 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32 DeleteAndWait(string key) [ServerOnly] [Yield]** 입력한 키로 데이터를 삭제하고 에러 코드를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. - **void Delete
[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorage [question] | GetVersionsAndWait와 GetVersionsAsync의 주요 차이점과 스크립트 실행 중단 여부 [answer] | `GetVersionsAndWait`와 `GetVersionsAsync`의 주요 차이점은 **동기/비동기 처리 방식**과 **스크립트 실행 중단 여부**입니다. ### 1. 스크립트 실행 중단 여부 * **GetVersionsAndWait**: 이 메서드는 `[Yield]` 속성을 가지며, 데이터 버전 조회 작업이 완료될 때까지 **현재 스크립트의 실행을 중단(블록킹)**합니다. 즉, 해당 함수 호출 이후의 코드는 조회가 끝난 후에만 실행됩니다. * **GetVersionsAsync**: 이 메서드는 비동기로 수행되며, 호 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | rection으로 오름/내림차순 정렬을 설정할 수 있습니다. min, max로 설정한 범위 내의 데이터들을 조회할 수 있습니다. 이 작업은 비동기로 수행되며, 작업이 완료되면 에러 코드, 조회용 객체와 함께 callbackFunction으로 전달된 함수가 호출됩니다. - **int32, DataStorageVersionPages GetVersionsAndWait(string key, SortDirection sortDirection, DateTime minDate, DateTime maxDate) [ServerOnly] [Yield
[task] | code [pass] | ⏳ 미판정 [title] | GlobalDataStorage [question] | _DataStorageService:GetGlobalDataStorage("StorageName") 과 BatchGetByInfoAndWait 메서드를 호출한 후, 반환된 errorCode가 0인 경우에만 itemPages를 처리하고, itemPages:GetCurrentPageDatas()에서 가져온 각 item의 item.KeyInfo.Tag가 "TargetTag"인 항목의 item.Value만 필터링하여 출력하는 스크립트를 작성해줘 [answer] | `_DataStorageService:GetGlobalDataStorage`를 통해 스토리지 인스턴스를 가져오고, `BatchGetByInfoAndWait` 호출 시 반환되는 `errorCode`가 0(성공)인지 확인한 후 데이터를 처리하는 로직입니다. 페이지 반복 처리 중 `GetCurrentPageDatas()`로 가져온 데이터 목록에서 `item.KeyInfo.Tag`가 `"TargetTag"`와 일치하는 항목의 `item.Value`만 필터링하여 출력합니다. ```lua Method: [server only] void F [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 데이터를 DataStorageKeyInfo를 통해 일괄로 가져오는 예제입니다. ```lua local ds = _DataStorageService:GetGlobalDataStorage("StorageName") local keyInfos = {} local keyInfo1 = DataStorageKeyInfo("Key1", "Version1", "Tag1") local keyInfo2 = DataStorageKeyInfo("Key2", "Version2", "Tag2") table.insert(keyInfos, keyInfo1