[task] | code [pass] | ⏳ 미판정 [title] | 타이머 만들기 [question] | `CardPairGameLogic` 스크립트에서 `OnUpdate(delta)`를 통해 `RemainingTime`을 감소시키고 0 이하가 되면 `EndGame()`을 호출하여 `CardPairGameUI`를 비활성화하는 타이머 로직을 작성해줘. [answer] | 카드 짝 맞추기 게임의 남은 시간을 매 프레임마다 감소시키고, 0 이하가 되면 게임을 종료하는 로직은 `OnUpdate` 생명주기 메서드를 통해 구현할 수 있습니다. 다음과 같이 `Property` 블록에 남은 시간을 추적할 `RemainingTime`과 총 플레이 시간 `PlayTime`을 선언하고, `Method` 블록에서 게임 시작 시 `RemainingTime`을 초기화하며, 매 프레임 `delta` 값을 차감하여 0 이하로 떨어지면 `EndGame()`을 호출하도록 작성합니다. ```lua Property: [None] [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | #### CardPairGameLogic 로직 ```lua Property: [None] Entity CardPairGameUI = /ui/CardPairGameUI [None] number PlayTime = 60 [None] number RemainingTime = 0 Method: [client only] void OnBeginPlay() { self:StartGame() } [client only] void StartGame() { self.CardPairGameUI.Enable = true
[task] | two_turn [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | PlayerStats 컴포넌트를 통해 카드 짝 맞추기 게임의 점수를 어떻게 관리하는지? [answer] | PlayerStats 컴포넌트를 사용하여 카드 짝 맞추기 게임의 점수를 관리하는 방법은 다음과 같습니다. **1. PlayerStats 컴포넌트 구성** `DefaultPlayer`에 `PlayerStats` 컴포넌트를 추가하고, 점수를 저장하기 위한 `Score` 프로퍼티와 점수를 증가시키는 `AddScore` 메서드를 정의합니다. ```lua Property: [None] number Score = 0 Method: void AddScore (number add) { self.Score = self.Score + a [followup] | AddScore 함수의 매개변수 add 값을 동적으로 변경하거나, 특정 조건(예: 연속 성공)에서 점수 배율을 적용하려면 코드를 어떻게 수정해야 하는가? [followup_answer] | 제공된 참고 문서에는 `AddScore` 함수의 매개변수 값을 동적으로 변경하거나, 연속 성공과 같은 특정 조건에서 점수 배율을 적용하는 방법에 대한 설명이나 코드 예제가 포함되어 있지 않습니다. 문서에 명시된 내용만으로는 `AddScore` 함수 내부 로직을 수정하여 배율이나 조건부 점수 증가를 구현하는 방법을 알 수 없습니다. 따라서 해당 요구사항에 따른 코드 수정 방법은 제공된 문서에서 확인할 수 없습니다. [scores] | [judge_reason] | [source_doc] | # 점수 만들기 카드 짝 맞출 때마다 일정한 점수가 증가하게 만들어봅시다. 1. **PlayerStats** 컴포넌트를 **DefalutPlayer**에 추가합니다. **PlayerStats** 컴포넌트는 점수 증가를 담당합니다. 2. **PlayerStats** 컴포넌트에 number 타입 프로퍼티를 아래와 같이 추가합니다. ```lua Property: [None] number Score = 0 ``` 3. 초깃값이 0인 **Score** 프로퍼티에 점수가 더해질 수 있도록 `A
[task] | single_turn [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | type() 함수로 변수의 유형을 확인하는 것이 중요한 이유는 무엇이며, 메이플스토리 월드에서 제공하는 별도의 데이터 타입은 어떤 상황에서 일반 루아 타입과 다른 방식으로 사용되나요? [answer] | `type()` 함수로 변수의 유형을 확인하는 것은 루아가 동적 타입 언어이기 때문에 매우 중요합니다. 루아에서 변수를 생성할 때 유형을 명시하지 않으며, 변수에 할당된 값에 따라 유형이 자동으로 결정됩니다. 따라서 `type()`을 사용하면 특정 변수가 `number`, `string`, `table`, `boolean`, `nil` 등 어떤 유형인지를 런타임에 정확히 파악할 수 있습니다. 이는 값의 타입에 따라 다른 로직을 수행하거나, 잘못된 타입의 값이 전달되었을 때 오류를 방지하는 데 필수적입니다. 메이플스토리 월드는 일반 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 루아의 변수는 내부적으로 유형이 존재하기는 하지만 변수를 생성할 때 그 유형을 명시하지는 않습니다. 변수에 들어가는 값에 따라 그 유형이 정해집니다. | 변수 유형 | 설명 | | --- | --- | | nil | 값이 없음을 뜻합니다. 논리 연산에서 nil은 거짓(false)이고 전역 변수 및 테이블 키에서의 nil은 버려집니다. | | boolean | true와 false 값만 갖습니다. 0, 1의 수치로 변환되지 않습니다. | | number | 64비트 실수입니다. | | integer | 64비트 정수입니다. |
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | `OnBeginPlay()` 함수 내부에서 지역 변수 `a`를 문자열 "A"로 초기화한 후, `if` 문 안에서 `a`의 값을 1로 변경하고 `b`를 "B"로 선언하여 각각 `log()`로 출력하는 스크립트를 작성해줘. [answer] | 메이플스토리 월드 스크립트 컴포넌트 형식에 맞춰 요청하신 로직을 구현한 스크립트는 다음과 같습니다. ```lua Property: [None] Method: [server only] void OnBeginPlay() { local a = "A" log(a) if true then a = 1 local b = "B" log(a) log(b) end } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드에서는 **루아**라는 언어를 사용하여 스크립트를 작성합니다. 이번 시간에는 **루아**의 기본 사용법과 메이플스토리 월드에서 사용하는 예제를 함께 살펴보겠습니다. # 변수 변수란 데이터를 저장하는 메모리 공간, 값을 담아두는 그릇입니다. ## 변수의 범위 루아에서 사용하는 변수는 아래의 두 가지로 나뉩니다. | 변수 | 설명 | | --- | --- | | 전역(global) 변수 | 어느 곳이든 접근 가능한 변수로 아무 선언 없이 사용하면 전역 변수입니다. **단, 메이플스토리
[task] | single_turn [pass] | ⏳ 미판정 [title] | 타이머 만들기 [question] | SelectCardCard 메서드에서 self.SelectedCard 를 저장하고 card:CardOn() 을 호출하는데, 두 번째 카드를 선택할 때 첫 번째 카드와 비교하는 로직이 이 코드에는 빠져있어, 전체적인 짝 맞추기 판정 로직은 어디서 구현해야 하는지 궁금합니다. [answer] | 제시된 참고 문서에는 `SelectCardCard` 메서드에서 첫 번째 카드와 두 번째 카드를 비교하여 짝을 판정하는 로직이 포함되어 있지 않습니다. 문서에 따르면, 카드 클릭 시 이벤트 핸들러를 통해 `_CardPairGameLogic:OnCardClicked(self)` 를 호출하는 구조만 확인됩니다. 따라서 전체적인 짝 맞추기 판정 로직(첫 번째 카드 저장, 두 번째 카드 선택 시 비교, 일치 여부 처리 등)은 **`_CardPairGameLogic` 컴포넌트(또는 해당 로직을 담고 있는 다른 스크립트)의 `OnCardCli [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua Property: [None] Entity CardSpawnRoot = /ui/CardPairGameUI/UI_Board/UI_Blocks/UI_Block_Group [None] Card SelectedCard = nil [None] Entity TimeText = /ui/CardPairGameUI/UI_Board/Background/Title/Timer_Background/UI_Time/UI_Time_Text Method: [client only] void OnUpdate (number delta) { sel
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | OnBeginPlay()에서 사전 변수에 여러 key-value를 추가한 후, 특정 key의 값을 nil로 설정하여 삭제하고, 다시 pairs()로 순회하며 남아있는 모든 key-value를 로그로 출력하는 스크립트를 작성해줘 [answer] | 요청하신 동작을 수행하는 mLua 스크립트는 다음과 같습니다. ```lua Property: [None] table myDictionary = {} Method: [server only] void OnBeginPlay() { -- 사전 변수에 여러 key-value 추가 self.myDictionary.name = "Tom" self.myDictionary.age = 30 self.myDictionary.favoriteGame = "MapleStory Worlds" self.myDictiona [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 배열에서 값을 제거할 때는 `table.remove()` 함수를 사용합니다. ```lua local array = {11, 22, 33, 44, 55} -- 1번 인덱스를 제거 table.remove(array, 1) log(array[1]) -- 22 ``` > **더 알아보기** > 스크립트 에디터에서 테이블에서 활용할 수 있는 다양한 함수들을 확인할 수 있습니다. > ## 사전(Dictionary) 사전은 **key - value** 형태의 테이블입니다. 자료 구조에서 데이터를 빠르게 검색하기 위해 주로 사용합니다.
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | OnUpdate()에서 table.remove() 함수를 사용해 로컬 배열에서 첫 번째 요소를 제거한 후, 남은 배열의 첫 번째 인덱스 값을 로그로 출력하는 스크립트를 작성해줘 [answer] | mLua 스크립트 컴포넌트 형식에 맞춰 요청하신 코드를 작성했습니다. `OnUpdate`가 매 프레임 호출되므로, 배열이 비어있을 때 `table.remove`를 호출하면 오류가 발생할 수 있습니다. 이를 방지하기 위해 배열의 길이를 확인하는 조건문을 추가했습니다. ```lua Property: [None] number[] TestArray = {} Method: [server only] void OnBeginPlay() { self.TestArray = {11, 22, 33, 44, 55} } [server only] [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 배열에서 값을 제거할 때는 `table.remove()` 함수를 사용합니다. ```lua local array = {11, 22, 33, 44, 55} -- 1번 인덱스를 제거 table.remove(array, 1) log(array[1]) -- 22 ``` > **더 알아보기** > 스크립트 에디터에서 테이블에서 활용할 수 있는 다양한 함수들을 확인할 수 있습니다. > ## 사전(Dictionary) 사전은 **key - value** 형태의 테이블입니다. 자료 구조에서 데이터를 빠르게 검색하기 위해 주로 사용합니다.
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | 기타 연산자 중 배열 길이(#)와 문자열 합치기(..)를 사용해 문자열 배열의 길이를 구하고 각 요소를 " - "으로 연결한 문자열을 log로 출력하는 스크립트를 작성해줘 [answer] | ```lua local a = {"HELLO", "MapleStory Worlds", "mLua"} log(#a) -- 3 local result = a[1] .. " - " .. a[2] .. " - " .. a[3] log(result) -- HELLO - MapleStory Worlds - mLua ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 산술 연산을 할 때 사용하는 연산자입니다. | 연산자 | 설명 | | --- | --- | | `+` | 더하기 | | `-` | 빼기 | | `*` | 곱하기 | | `/` | 나누기 | | `//` | 나눈 후 몫만 취함 | | `%` | 나눈 후 나머지만 취함 | | `^` | 지수 | 예를 들어 아래와 같이 입력하고 **log**를 출력하면 주석의 값이 출력됩니다. ```lua log(1 + 1) -- 2 log(1 - 1) -- 0 log(5 * 5) -- 25 log(13 / 5) -- 2.6 log(13 // 5)
[task] | single_turn [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | table.insert() 함수를 사용해 배열 중간에 값을 삽입할 때 두 번째 인수로 인덱스를 지정해야 하는 구체적인 문법과, 이 방식이 마지막에 추가하는 경우와 어떻게 다른가요? [answer] | `table.insert()` 함수를 사용하여 배열 중간에 값을 삽입할 때는 함수의 두 번째 인수로 값을 삽입할 위치(인덱스)를 지정해야 합니다. 마지막에 추가할 때는 두 번째 인수를 생략하면 됩니다. 구체적인 문법과 차이점은 다음과 같습니다. ### 1. 배열 중간에 값 삽입하기 `table.insert(array, index, value)` 형식을 사용합니다. * **첫 번째 인수**: 대상 배열 * **두 번째 인수**: 삽입할 위치의 인덱스 (1부터 시작) * **세 번째 인수**: 삽입할 값 기존에 해당 인 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 루아의 변수는 내부적으로 유형이 존재하기는 하지만 변수를 생성할 때 그 유형을 명시하지는 않습니다. 변수에 들어가는 값에 따라 그 유형이 정해집니다. | 변수 유형 | 설명 | | --- | --- | | nil | 값이 없음을 뜻합니다. 논리 연산에서 nil은 거짓(false)이고 전역 변수 및 테이블 키에서의 nil은 버려집니다. | | boolean | true와 false 값만 갖습니다. 0, 1의 수치로 변환되지 않습니다. | | number | 64비트 실수입니다. | | integer | 64비트 정수입니다. |
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | OnUpdate 함수에서 로컬 테이블에 10, 20, 30을 저장하고, 2번 인덱스의 값을 99로 변경한 후 4번 인덱스에 40을 추가하여 배열의 최종 상태를 log()로 확인하는 스크립트를 작성해줘 [answer] | ```lua Method: [client only] void OnUpdate (number delta) { local testArray = {10, 20, 30} testArray[2] = 99 testArray[4] = 40 log(testArray[1]) -- 10 log(testArray[2]) -- 99 log(testArray[3]) -- 30 log(testArray[4]) -- 40 } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 루아의 변수는 내부적으로 유형이 존재하기는 하지만 변수를 생성할 때 그 유형을 명시하지는 않습니다. 변수에 들어가는 값에 따라 그 유형이 정해집니다. | 변수 유형 | 설명 | | --- | --- | | nil | 값이 없음을 뜻합니다. 논리 연산에서 nil은 거짓(false)이고 전역 변수 및 테이블 키에서의 nil은 버려집니다. | | boolean | true와 false 값만 갖습니다. 0, 1의 수치로 변환되지 않습니다. | | number | 64비트 실수입니다. | | integer | 64비트 정수입니다. |
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | Type Annotation의 문법 구조와 적용 대상 위치를 설명하되, `---@type`를 사용하는 3줄 이내의 코드 예시를 포함해서 작성하세요. [answer] | `---@type` 어노테이션은 변수를 선언하거나 값을 할당하는 줄의 바로 위에 작성하며, 해당 줄에 할당되는 변수의 타입을 명시하는 역할을 합니다. 이를 통해 스크립트 에디터에서 퀵 인포, 시그니처 헬퍼, 코드 컴플리션 등의 도움을 받을 수 있습니다. ```lua ---@type string local testValue = "test" ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 **어노테이션**(Annotation)은 코드에 추가하여 사용하는 일종의 메타데이터입니다. 스크립트에 `--` 기호를 사용한 주석(Comment)은 스크립트 작성에 참고 역할만 하는 반면, `---@` 형태로 **어노테이션**을 작성하면 **퀵 인포**나 **시그니처 헬퍼**, **코드 컴플리션** 등 스크립트 어시스트의 도움을 받을 수 있습니다. 본 과정을 통해 메이플스토리 월드에서 제공하는 **어노테이션**의 종류와 활용 방법을 알아봅시다. > **더 알아보기** > 퀵 인포, 시그니처 헬퍼, 코드 컴플리
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | SetCards 메서드에서 카드 묶음(deckTable)을 생성하는 과정과 중복 카드를 추가하는 로직을 단계별 번호 목록으로 정리하세요. [answer] | `SetCards` 메서드에서 카드 묶음(`deckTable`)을 생성하고 중복 카드를 추가하는 로직은 다음과 같은 단계로 진행됩니다. 1. `deckTable`과 `cardTable`을 각각 빈 테이블로 초기화합니다. 2. `_DataService:GetRowCount("CardSet")`을 호출하여 `CardSet` 데이터의 행 수를 `deckCount` 변수에 저장합니다. 3. 1부터 `deckCount`까지 반복하며, `_DataService:GetCell("CardSet", i, 1)`을 통해 각 행의 1열에 있는 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua Property: [None] Entity CardSpawnRoot = /ui/CardPairGameUI/UI_Board/UI_Blocks/UI_Block_Group [None] Card SelectedCard = nil [None] Entity TimeText = /ui/CardPairGameUI/UI_Board/Background/Title/Timer_Background/UI_Time/UI_Time_Text [None] Entity ScoreText = /ui/CardPairGameUI/UI_Board/Backgro
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | 산술 연산자와 관계 연산자를 활용해 주어진 두 숫자 중 큰 값을 log로 출력하는 스크립트를 작성해줘 [answer] | mLua 스크립트 형식을 준수하여 두 숫자를 비교하고 큰 값을 출력하는 스크립트는 다음과 같습니다. ```lua Property: [None] number NumA = 10 number NumB = 25 Method: [server only] void OnBeginPlay() { -- 관계 연산자(>)를 사용해 두 숫자 비교 if self.NumA > self.NumB then log(self.NumA) else log(self.NumB) end } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 산술 연산을 할 때 사용하는 연산자입니다. | 연산자 | 설명 | | --- | --- | | `+` | 더하기 | | `-` | 빼기 | | `*` | 곱하기 | | `/` | 나누기 | | `//` | 나눈 후 몫만 취함 | | `%` | 나눈 후 나머지만 취함 | | `^` | 지수 | 예를 들어 아래와 같이 입력하고 **log**를 출력하면 주석의 값이 출력됩니다. ```lua log(1 + 1) -- 2 log(1 - 1) -- 0 log(5 * 5) -- 25 log(13 / 5) -- 2.6 log(13 // 5)
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | OnUpdate 함수에서 로컬 테이블에 1부터 5까지의 정수를 순차적으로 추가하여 저장하고, 마지막 인덱스에 접근하여 값이 5인지 확인하는 스크립트를 작성해줘 [answer] | 메이플스토리 월드 mLua 스크립트 형식에 맞춰 요청하신 내용을 구현했습니다. `OnUpdate` 함수 내에서 로컬 테이블을 선언하고, 1부터 5까지의 정수를 순차적으로 추가한 후 마지막 인덱스에 접근하여 값이 5인지 확인하는 로직을 포함합니다. ```lua Method: [server only] void OnUpdate(number delta) { local numbers = {} for i = 1, 5 do numbers[#numbers + 1] = i end loc [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 루아의 변수는 내부적으로 유형이 존재하기는 하지만 변수를 생성할 때 그 유형을 명시하지는 않습니다. 변수에 들어가는 값에 따라 그 유형이 정해집니다. | 변수 유형 | 설명 | | --- | --- | | nil | 값이 없음을 뜻합니다. 논리 연산에서 nil은 거짓(false)이고 전역 변수 및 테이블 키에서의 nil은 버려집니다. | | boolean | true와 false 값만 갖습니다. 0, 1의 수치로 변환되지 않습니다. | | number | 64비트 실수입니다. | | integer | 64비트 정수입니다. |
[task] | single_turn [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | 사전(Dictionary)에서 특정 키에 해당하는 값을 삭제할 때 nil을 설정하는 것과 테이블에서 요소를 제거하는 방식의 차이점이 뭔가요? [answer] | 메이플스토리 월드의 mLua(Lua 5.3) 환경에서 사전(Dictionary)의 키-값 삭제와 테이블(배열) 요소 제거는 대상 구조와 사용하는 함수, 그리고 데이터 정합성 측면에서 명확한 차이가 있습니다. ### 1. 사전(Dictionary)에서 값 삭제 사전은 `key - value` 형태의 테이블입니다. 사전에서 특정 데이터를 삭제할 때는 해당 **Key의 값을 `nil`로 설정**하는 방식을 사용합니다. * **방식**: `myDictionary.key = nil` * **특징**: * `table.r [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 배열에서 값을 제거할 때는 `table.remove()` 함수를 사용합니다. ```lua local array = {11, 22, 33, 44, 55} -- 1번 인덱스를 제거 table.remove(array, 1) log(array[1]) -- 22 ``` > **더 알아보기** > 스크립트 에디터에서 테이블에서 활용할 수 있는 다양한 함수들을 확인할 수 있습니다. > ## 사전(Dictionary) 사전은 **key - value** 형태의 테이블입니다. 자료 구조에서 데이터를 빠르게 검색하기 위해 주로 사용합니다.
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | `LuaTest` 컴포넌트를 Hierarchy의 `common`에 추가하고, `OnBeginPlay()`에서 `log()` 함수를 사용하여 변수 범위와 프로퍼티 접근 방식을 검증하는 전체적인 테스트 스크립트를 작성해줘. [answer] | 요청하신 `LuaTest` 컴포넌트 스크립트입니다. `Property` 블록에 `[Sync]` 속성이 붙은 `testP` 프로퍼티를 선언하고, `Method` 블록의 `OnBeginPlay()`에서 프로퍼티 접근(`self.testP`)과 지역 변수(`local a`, `local b`)의 유효 범위 및 파괴 여부를 `log()` 함수를 통해 출력하도록 구성했습니다. ```lua Property: [Sync] integer testP = 0 Method: [server only] void OnBeginPlay() { lo [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드에서는 **루아**라는 언어를 사용하여 스크립트를 작성합니다. 이번 시간에는 **루아**의 기본 사용법과 메이플스토리 월드에서 사용하는 예제를 함께 살펴보겠습니다. # 변수 변수란 데이터를 저장하는 메모리 공간, 값을 담아두는 그릇입니다. ## 변수의 범위 루아에서 사용하는 변수는 아래의 두 가지로 나뉩니다. | 변수 | 설명 | | --- | --- | | 전역(global) 변수 | 어느 곳이든 접근 가능한 변수로 아무 선언 없이 사용하면 전역 변수입니다. **단, 메이플스토리
[task] | single_turn [pass] | ⏳ 미판정 [title] | 타이머 만들기 [question] | SetCards 메서드에서 deckCount / 2 로 반복문을 돌리는데, 만약 CardSet 데이터 행 수가 홀수라면 어떤 오류가 발생하거나 로직이 어떻게 깨지는지 설명해 주세요. [answer] | `SetCards` 메서드에서 `deckCount`가 홀수일 경우, **오류가 발생하지는 않지만 카드가 절반만 생성되어 게임 로직이 깨지는** 문제가 발생합니다. 구체적인 분석은 다음과 같습니다. ### 1. 반복문 로직 분석 `SetCards` 메서드 내의 카드 생성을 위한 반복문은 다음과 같이 작성되어 있습니다. ```lua for i = 1, (deckCount / 2) do table.insert(cardTable, deckTable[i]) table.insert(cardTable, deckTable[i] [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua Property: [None] Entity CardSpawnRoot = /ui/CardPairGameUI/UI_Board/UI_Blocks/UI_Block_Group [None] Card SelectedCard = nil [None] Entity TimeText = /ui/CardPairGameUI/UI_Board/Background/Title/Timer_Background/UI_Time/UI_Time_Text Method: [client only] void OnUpdate (number delta) { sel
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | 여러 값을 할당받을 때 Type Annotation을 일부 적용하는 규칙을 단계별 번호 목록으로 정리하고, 지정된 타입이 적용되는 순서를 명시하세요. [answer] | 여러 값을 할당받을 때 Type Annotation을 일부 적용하는 규칙과 적용 순서는 다음과 같습니다. 1. **일부 적용 가능 여부**: 여러 값을 한 번에 할당받을 때, 모든 값에 타입을 지정하지 않고 일부 값에만 Type Annotation을 적용할 수 있습니다. 2. **적용 순서**: 지정된 타입은 **앞의 값부터** 순서대로 적용됩니다. 3. **제약 사항**: 앞의 값을 건너뛰고 뒤의 값만 따로 타입을 지정하는 것은 불가능합니다. 즉, `local a, b, c = ...`와 같이 세 값을 받을 때 Type [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 **어노테이션**(Annotation)은 코드에 추가하여 사용하는 일종의 메타데이터입니다. 스크립트에 `--` 기호를 사용한 주석(Comment)은 스크립트 작성에 참고 역할만 하는 반면, `---@` 형태로 **어노테이션**을 작성하면 **퀵 인포**나 **시그니처 헬퍼**, **코드 컴플리션** 등 스크립트 어시스트의 도움을 받을 수 있습니다. 본 과정을 통해 메이플스토리 월드에서 제공하는 **어노테이션**의 종류와 활용 방법을 알아봅시다. > **더 알아보기** > 퀵 인포, 시그니처 헬퍼, 코드 컴플리
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | Table 타입 지정 시 가능한 문법 조합을 `table`, `table<Entity>`, `table<string, Entity>` 등 3가지 형태를 포함하여 표로 정리하세요. [answer] | Table 타입 지정 시 사용할 수 있는 문법 조합은 다음과 같습니다. | 문법 형태 | 예시 코드 | 설명 | | :--- | :--- | :--- | | `table` | `---@type table`<br>`local testTable = {}` | Key와 Value의 타입을 명시하지 않는 일반 Table 타입 지정 | | `table<VALUE_TYPE>` | `---@type table<Entity>`<br>`local testTable = {}` | Value 타입만 명시하는 경우 (Key 타입은 미지정) | | `t [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 **어노테이션**(Annotation)은 코드에 추가하여 사용하는 일종의 메타데이터입니다. 스크립트에 `--` 기호를 사용한 주석(Comment)은 스크립트 작성에 참고 역할만 하는 반면, `---@` 형태로 **어노테이션**을 작성하면 **퀵 인포**나 **시그니처 헬퍼**, **코드 컴플리션** 등 스크립트 어시스트의 도움을 받을 수 있습니다. 본 과정을 통해 메이플스토리 월드에서 제공하는 **어노테이션**의 종류와 활용 방법을 알아봅시다. > **더 알아보기** > 퀵 인포, 시그니처 헬퍼, 코드 컴플리
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | Param Annotation의 문법과 매개 변수 타입 지정 예시를 3문장 이내로 설명하세요. [answer] | `---@param param_name PARAM_TYPE` 문법을 함수 정의문 직전에 작성하여 매개 변수의 타입을 지정합니다. 예를 들어 `---@param testParamA Entity`라고 적으면 해당 매개 변수가 Entity 타입임을 알려 스크립트 어시스트의 도움을 받을 수 있습니다. 여러 매개 변수가 있는 경우 각 매개 변수별로 `---@param` 어노테이션을 반복하여 사용할 수 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **Param Annotation**을 사용해 대상이 되는 함수의 매개 변수 타입을 지정하여 스크립트 어시스트의 도움을 받을 수 있습니다. **Param Annotation**은 함수 정의문에 사용합니다. 아래와 같은 문법으로 **Param Annotation**을 사용합니다. ```lua ---@param param_name PARAM_TYPE ``` ##### 사용 예시 ```lua ---@param testParamA Entity local function TestFunction(testParamA) end ``` ```
[task] | single_turn [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | IsEmpty 함수가 카드의 Visible 속성을 기준으로 빈 상태를 판별하는 방식에서, Visible이 false인 카드가 존재하지 않으면 어떤 결과가 반환되나요? [answer] | `IsEmpty` 함수는 `self.CardSpawnRoot.Children` 배열에 포함된 모든 카드를 순회하며 각 카드의 `Visible` 속성을 확인합니다. 만약 순회 중 `Visible`이 `true`인 카드가 하나라도 발견되면 즉시 `false`를 반환합니다. 따라서 `Visible`이 `false`인 카드가 존재하지 않는다는 것은, 배열 내 모든 카드의 `Visible` 값이 `false`임을 의미합니다. 이 경우 for 루프가 정상적으로 종료되고, 함수는 최종적으로 **`true`** 를 반환합니다. 즉, 모든 카드가 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | [client Only] void ClearCardEntities () { local cardEntities = self.CardSpawnRoot.Children for i = 1, #cardEntities do cardEntities[i]:Destroy() end } [client only] void SelectCardCard (Card card) { self.SelectedCard = card card:CardOn() } [client only] void
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | Return Annotation이 지원하는 복수 반환 타입의 문법과 사용 예시 코드를 주석으로만 출력하세요. [answer] | Return Annotation은 `---@return TYPE1, TYPE2` 문법을 사용하여 복수 반환 타입을 지정할 수 있으며, 여러 타입은 쉼표(,)로 구분합니다. ```lua ---@return Entity, string local function TestFunction(testParamA, testParamB) return self.Entity, "strValue" end ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **Param Annotation**을 사용해 대상이 되는 함수의 매개 변수 타입을 지정하여 스크립트 어시스트의 도움을 받을 수 있습니다. **Param Annotation**은 함수 정의문에 사용합니다. 아래와 같은 문법으로 **Param Annotation**을 사용합니다. ```lua ---@param param_name PARAM_TYPE ``` ##### 사용 예시 ```lua ---@param testParamA Entity local function TestFunction(testParamA) end ``` ```
[task] | single_turn [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | 클라이언트 쪽에서 _UserService.LocalPlayer의 PlayerStats.Score를 읽어와 표시하는데, 서버와 클라이언트의 점수 동기화가 제대로 안 되어 값이 달라지는 현상이 발생하는 원인은 무엇일까요? [answer] | 제공된 참고 문서에는 `_UserService.LocalPlayer`를 통해 `PlayerStats.Score`를 읽어 텍스트에 표시하는 코드(`UpdateText` 메서드)는 포함되어 있습니다. ```lua [client only] void UpdateText() { local remainingTime = _CardPairGameLogic.RemainingTime self.TimeText.TextComponent.Text = tostring(math.floor(remainingTime)) local [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua Property: [None] Entity CardSpawnRoot = /ui/CardPairGameUI/UI_Board/UI_Blocks/UI_Block_Group [None] Card SelectedCard = nil [None] Entity TimeText = /ui/CardPairGameUI/UI_Board/Background/Title/Timer_Background/UI_Time/UI_Time_Text [None] Entity ScoreText = /ui/CardPairGameUI/UI_Board/Backgro
[task] | code [pass] | ⏳ 미판정 [title] | 메이플스토리 월드 루아 기초 [question] | `testFunction()` 메서드를 정의하여 `self.testP` 프로퍼티 값을 읽어 `log()`로 출력하고, 전역/지역 변수 범위에 따라 `nil`이 되는 변수를 확인하기 위해 `a` 변수를 참조하는 스크립트를 작성해줘. [answer] | 메이플스토리 월드의 mLua 스크립트 형식과 제공된 예제 코드를 기준으로 요청하신 내용을 구현한 스크립트입니다. 1. **Property**: `[Sync]` 속성을 가진 `integer testP` 프로퍼티를 정의합니다. 2. **Method**: - `OnBeginPlay()`: 서버에서 실행되며, `testP` 값을 초기화하고 지역 변수 `a`를 정의한 뒤 `testFunction()`을 호출합니다. - `testFunction()`: `self.testP` 값을 `log()`로 출력합니다. 또한 `OnBeginP [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드에서는 **루아**라는 언어를 사용하여 스크립트를 작성합니다. 이번 시간에는 **루아**의 기본 사용법과 메이플스토리 월드에서 사용하는 예제를 함께 살펴보겠습니다. # 변수 변수란 데이터를 저장하는 메모리 공간, 값을 담아두는 그릇입니다. ## 변수의 범위 루아에서 사용하는 변수는 아래의 두 가지로 나뉩니다. | 변수 | 설명 | | --- | --- | | 전역(global) 변수 | 어느 곳이든 접근 가능한 변수로 아무 선언 없이 사용하면 전역 변수입니다. **단, 메이플스토리
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | Param Annotation과 Return Annotation의 적용 전후 차이점을 표로 정리해서 보여주세요. [answer] | 참고 문서에는 Param Annotation과 Return Annotation의 적용 전후 차이점을 보여주는 표의 내용은 비어 있으며, 구체적인 시각적 차이점을 기술한 텍스트 정보가 없습니다. 따라서 문서에 명시된 정보만으로는 두 Annotation의 적용 전후 차이점을 표로 정리하여 보여줄 수 없습니다. 참고로 문서에서 제공한 문법만 정리하면 다음과 같습니다. **Param Annotation 문법** ```lua ---@param param_name PARAM_TYPE ``` **Return Annotation 문법** [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **Param Annotation**을 사용해 대상이 되는 함수의 매개 변수 타입을 지정하여 스크립트 어시스트의 도움을 받을 수 있습니다. **Param Annotation**은 함수 정의문에 사용합니다. 아래와 같은 문법으로 **Param Annotation**을 사용합니다. ```lua ---@param param_name PARAM_TYPE ``` ##### 사용 예시 ```lua ---@param testParamA Entity local function TestFunction(testParamA) end ``` ```
[task] | code [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | PlayerStats 컴포넌트에 number 타입의 Score 프로퍼티를 초깃값 0으로 설정하고, 매개변수 add를 받는 AddScore 메서드를 구현하여 self.Score에 점수를 누적하는 로직을 작성해줘 [answer] | 요청하신 **PlayerStats** 컴포넌트 스크립트는 다음과 같습니다. ```lua Property: [None] number Score = 0 Method: void AddScore (number add) { self.Score = self.Score + add } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 점수 만들기 카드 짝 맞출 때마다 일정한 점수가 증가하게 만들어봅시다. 1. **PlayerStats** 컴포넌트를 **DefalutPlayer**에 추가합니다. **PlayerStats** 컴포넌트는 점수 증가를 담당합니다. 2. **PlayerStats** 컴포넌트에 number 타입 프로퍼티를 아래와 같이 추가합니다. ```lua Property: [None] number Score = 0 ``` 3. 초깃값이 0인 **Score** 프로퍼티에 점수가 더해질 수 있도록 `A
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | 여러 값을 반환하는 함수와 함께 다른 값을 지정할 때 괄호를 통한 타입 구분 문법을 코드 블록 1개만 출력하세요. [answer] | ```lua ---@type (function(paramA:string, paramB:Entity):AttackComponent, string), Entity local testFunction, testEntity = function(testParamA, testParamB) return atkComponent, "strValue" end, self.Entity ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Function은 아래와 같은 문법으로 타입을 지정합니다. ```lua ---@type function(param_name: PARAM_TYPE):RETURN_TYPE ``` ##### 사용 예시 ```lua ---@type function() local testFunction = function() end ``` ```lua ---@type function(testParamA:string, testParamB:Entity) local testFunction = function(testParamA, testParamB) end
[task] | single_turn [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | CreateCardEntities에서 카드 엔티티를 생성할 때 CardSpawnRoot를 부모로 지정하는 것이 카드의 위치와 렌더링 순서에 어떤 영향을 미치나요? [answer] | 제공된 참고 문서에는 `CreateCardEntities` 메서드에서 `_SpawnService:SpawnByModelId` 호출 시 `self.CardSpawnRoot`를 마지막 인자로 전달하는 코드만 포함되어 있습니다. 문서에는 `CardSpawnRoot`를 부모로 지정할 때 카드의 **구체적인 위치 좌표 값**이나 **렌더링 순서(Depth, Z-index 등)에 대한 기술적 설명**이 없습니다. 따라서 제공된 문서 범위 내에서는 카드의 위치와 렌더링 순서에 미치는 정확한 영향을 설명할 수 없습니다. 단, 문서에 포함된 코 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua Property: [None] Entity CardSpawnRoot = /ui/CardPairGameUI/UI_Board/UI_Blocks/UI_Block_Group [None] Card SelectedCard = nil [None] Entity TimeText = /ui/CardPairGameUI/UI_Board/Background/Title/Timer_Background/UI_Time/UI_Time_Text [None] Entity ScoreText = /ui/CardPairGameUI/UI_Board/Backgro
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 어노테이션 활용하기 [question] | `TestFunction`에서 시그니처 헬퍼 도움을 받기 위해 필요한 Type Annotation 주석과 호출 예시를 2문장 이내로 설명하세요. [answer] | `TestFunction` 반환값에 `---@type function(paramA:string, paramB:AttackComponent):string, boolean` 주석을 붙여야 시그니처 헬퍼가 활성화됩니다. 이후 `local strValue, boolValue = test("param", self.Entity.AttackComponent)`처럼 호출하면 매개변수와 반환값의 타입을 확인할 수 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Function은 아래와 같은 문법으로 타입을 지정합니다. ```lua ---@type function(param_name: PARAM_TYPE):RETURN_TYPE ``` ##### 사용 예시 ```lua ---@type function() local testFunction = function() end ``` ```lua ---@type function(testParamA:string, testParamB:Entity) local testFunction = function(testParamA, testParamB) end
[task] | single_turn [pass] | ⏳ 미판정 [title] | 점수 만들기 [question] | 클라이언트 전용 메서드인 ClearCardEntities를 서버에서 호출하려고 하면 어떤 문제가 발생할 수 있나요? [answer] | `ClearCardEntities` 메서드는 `[client only]` 실행 공간으로 선언되어 있습니다. mLua에서는 클라이언트 전용 메서드를 서버에서 직접 호출할 수 없으므로, 서버 스크립트에서 이 메서드를 호출하면 런타임 오류(예: 함수를 찾을 수 없음 또는 접근 권한 오류)가 발생합니다. 이는 `ClearCardEntities` 내부에서 `self.CardSpawnRoot.Children`을 순회하며 `cardEntities[i]:Destroy()`를 호출하는 로직을 포함하고 있기 때문입니다. `CardSpawnRoot` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | [client Only] void ClearCardEntities () { local cardEntities = self.CardSpawnRoot.Children for i = 1, #cardEntities do cardEntities[i]:Destroy() end } [client only] void SelectCardCard (Card card) { self.SelectedCard = card card:CardOn() } [client only] void