← 목록

mLua · Nemotron SDG 질문-응답 (SFT)

총 21,567개 · 페이지 1/719
🔀 랜덤 처음으로
불러오는 중…

[task] | single_turn [pass] | ⏳ 미판정 [title] | SortableDataStorageItemPages [question] | 페이지 조회 도중 LoadNextPageAndWait가 0이 아닌 값을 반환하면 어떤 에러를 의미하며, 이때 스크립트를 어떻게 처리해야 하나요? [answer] | `LoadNextPageAndWait()` 함수가 `0`이 아닌 값을 반환하면, 다음 페이지의 데이터를 불러오는 과정에서 오류가 발생했음을 의미합니다. 구체적인 에러 코드의 종류나 각 코드가 나타내는 상세한 원인은 제공된 정보에 포함되어 있지 않습니다. 이 경우 스크립트에서는 더 이상 페이지를 순회할 수 없으므로, 현재 루프를 중단하고 함수를 종료하는 것이 표준적인 처리 방식입니다. 예제 코드에서는 에러 코드가 `0`이 아닐 때 `return` 또는 `break`를 사용하여 즉시 조회 작업을 멈추고 있습니다. ```lua loc [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | SortableDataStorage에 저장된 데이터를 조회하는 기능을 제공합니다. # Properties - **boolean IsLastPage [ReadOnly]** 현재 페이지가 마지막 페이지인지 확인합니다. # Methods - **table<SortableDataStorageItem> GetCurrentPageDatas() [ServerOnly]** 현재 페이지의 데이터 목록을 가져옵니다. - **int32 LoadNextPageAndWait() [ServerOnly] [Yield]** 다음 페이지를 불러

[task] | single_turn [pass] | ⏳ 미판정 [title] | 스크린샷과 동적 스프라이트 [question] | OnBeginPlay 함수 내부에서 self:IsServer() 조건이 참일 때만 실행되는 코드가 있는 이유는 무엇인가요? [answer] | `OnBeginPlay` 함수 내부에서 `self:IsServer()` 조건을 확인하는 이유는 **`_ResourceService:SetSpriteUploadValidationCallback`** 함수가 서버에서만 실행될 수 있는 API이기 때문입니다. 스크립트는 기본적으로 서버와 클라이언트 양쪽에서 모두 실행됩니다. 그러나 스크린샷 업로드 요청을 검증하고 허용하는 로직은 월드의 중앙 서버에서 처리되어야 합니다. 따라서 `self:IsServer()`가 참(true)인 경우, 즉 현재 코드가 서버에서 실행되고 있을 때만 업로드 검 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 특정 키를 눌러 스크린샷을 찍은 뒤 월드의 특정 위치에 보이도록 하는 예제를 살펴봅시다. 1. **Hierarchy - Create Entity - Create Empty**를 클릭해 **EmptyEntity**를 생성합니다. **EmptyEntity**의 이름을 **Frame**으로 지정합니다. 2. **Frame** 엔티티의 프로퍼티 에디터에서 **TransformComponent, SpriteRendererComponent**를 추가합니다. 3. **Frame** 엔티티의 프로퍼티

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 기본 UI 컴포넌트 [question] | SpriteGUIRendererComponent의 OverrideSorting 프로퍼티가 활성화되는 조건과 UIMode의 동작 방식을 코드 주석 형식으로 설명하세요. [answer] | 참고 문서에 명시된 내용을 바탕으로 `OverrideSorting`의 활성화 조건과 `UIMode`의 동작 방식을 코드 주석 형식으로 설명합니다. ```lua Property: [None] boolean UseOverrideSorting = false Method: [client only] void OnBeginPlay() { local uiTransform = self.Entity.UITransformComponent local spriteRenderer = self.Entity.SpriteGUIRendererC [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 컴포넌트를 조합해 다양한 형태의 UI 엔티티를 구성할 수 있습니다. 이번 과정에서는 UI에서 자주 사용하는 기본 컴포넌트에 대해 알아봅니다. ##### 참고 가이드 * [UI 에디터](/docs?postId=120) * [UI 제작하기](/docs?postId=64) * [UI 엔티티 제어하기](/docs?postId=1154) # UITransformComponent [UITransformComponent](/apiReference/Components/UITransformComponent)는 UI 엔티티에

[task] | single_turn [pass] | ❌ 탈락 [title] | HitComponent [question] | HitComponent의 BoxSize를 남은 체력 비율에 맞춰 줄이려면 Vector2 연산 시 Clone()을 사용해야 하는 이유가 무엇인가요? [answer] | mLua에서 `Vector2`와 같은 구조체 타입은 **값 타입(value type)**으로 동작합니다. 이 때문에 `self.InitialBoxSize = self.Entity.HitComponent.BoxSize`와 같이 참조를 그대로 대입하면, 원본 `BoxSize`가 나중에 변경될 때 `InitialBoxSize` 값도 함께 변해버리는 문제가 생길 수 있습니다. 예제 코드에서 `OnBeginPlay()` 함수 내에서 `self.InitialBoxSize = self.Entity.HitComponent.BoxSize:Clon [followup] | [followup_answer] | [scores] | helpfulness=3 correctness=2 coherence=4 complexity=3 verbosity=2 [judge_reason] | mLua는 Lua 5.3 기반이라 Vector2가 값 타입(value type)이라는 설명은 언어적 사실과 어긋나며, 문서에도 Clone() 사용의 원인이 명시되어 있지 않아 근거 없는 추측에 기반한 답변입니다. [source_doc] | 다음은 몬스터가 플레이어의 공격을 받을 때마다 `HitComponent`의 BoxSize를 남은 체력에 반비례하게 키우는 예제입니다. ```lua Property: [Sync] number Health = 1000 [None] number InitialHealth = 0 [None] Vector2 InitialBoxSize = Vector2(0,0) Method: [server only] void OnBeginPlay () { self.InitialHealth = self.Health self.InitialBoxSize

[task] | code [pass] | ⏳ 미판정 [title] | TimeSpan으로 시간 표현하기 [question] | TimeSpan 객체의 "%s" 형식으로 초 수만 문자열로 추출하여 로그에 출력하는 스크립트를 작성해줘 [answer] | TimeSpan 객체의 초 수만 "%s" 형식으로 문자열로 추출하여 로그에 출력하는 스크립트는 다음과 같습니다. ```lua local timeSpan = TimeSpan(16, 4, 3, 17, 250) local timeSpanString = timeSpan:ToFormattedString("%s") log(timeSpanString) ``` 이 코드에서 `TimeSpan(16, 4, 3, 17, 250)`은 일 16, 시간 4, 분 3, 초 17, 밀리초 250을 가지는 TimeSpan 객체를 생성합니다. `ToForma [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | "hh" 사용자 지정 서식 지정자는 시간 수를 나타내는 값을 출력합니다. 시간 값이 0-9라면 출력 문자열 앞에 0이 포함됩니다. 일반적으로 하나의 숫자만 포함하는 문자열은 일 수로 해석됩니다. "hh" 사용자 지정 서식 지정자를 대신 사용하여 숫자 문자열을 시간 수로 해석할 수 있습니다. ```lua local timeSpan = TimeSpan(365, 3, 14, 45) log(timeSpan:ToFormattedString("dd'.'hh':'mm':'ss")) -- 365.03:14:45 ``` #### "m" "

[task] | single_turn [pass] | ⏳ 미판정 [title] | 영상 재생시키기 [question] | PlaySpeed 값이 0.5 미만 또는 3 이상으로 설정했을 때 어떤 문제가 발생하나요? [answer] | 문서에 따르면 `PlaySpeed` 프로퍼티는 **0.5부터 3 사이의 값**만 사용할 수 있는 것으로 명시되어 있습니다. 따라서 0.5 미만 또는 3 이상의 값을 설정할 경우, 허용된 범위를 벗어났으므로 정상적으로 동작하지 않거나 오류가 발생할 수 있습니다. 다만, 문서에는 허용 범위를 벗어났을 때 구체적으로 어떤 에러 메시지가 뜨는지나 어떤 현상이 발생하는지에 대한 추가적인 기술은 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 내가 찍은 영상 혹은 함께 보고 싶은 영상을 가져와 재생할 수 있습니다. # Youtube 관련 컴포넌트 소개 영상은 UI로 사용하거나 World에 배치해 사용할 수 있습니다. UI로 사용할 경우 YoutubeGUIPlayerComponent를 사용하고, World에 배치할 경우 YoutubePlayerWorldComponent를 사용합니다. UI로 사용한다면 영상은 배치한 곳에 고정되므로, 맵을 돌아다니더라도 유저가 보고 있는 화면의 특정 위치에서 움직이지 않습니다. World에서 영상을 사용한다면 배치한

[task] | single_turn [pass] | ❌ 탈락 [title] | UIModeTypeChangedEvent [question] | UIModeTypeChangedEvent 는 어떤 API 호출 때문에 발생하나요? [answer] | `UIModeTypeChangedEvent`는 **UITransformComponent**의 `UIMode` 프로퍼티가 변경될 때 발생합니다. 즉, 클라이언트 공간에서 특정 UI 엔티티의 `UITransformComponent.UIMode` 값을 다른 `UIModeType`으로 수정하는 API 호출이 이루어지면 이 이벤트가 트리거됩니다. 예를 들어, UI 엔티티의 `UITransformComponent`에 접근하여 `UIMode` 값을 변경하는 코드가 실행되면 해당 이벤트가 발생합니다. ```lua Property: [None [followup] | [followup_answer] | [scores] | helpfulness=3 correctness=1 coherence=2 complexity=2 verbosity=2 [judge_reason] | 이벤트 발생 원인을 올바르게 설명했으나, 코드 예제에서 `InputService`, `KeyDownEvent`, `KeyboardKey`, `UIModeType.FullScreen` 등 문서와 규칙에 없는 API를 지어냈습니다. [source_doc] | UITransformComponent의 UIMode가 바뀌었을 때 발생하는 이벤트입니다. 이 Event는 아래 API에 의해 발생합니다. * UITransformComponent <img src="https://img.shields.io/static/v1?label=Space&message=Client&color=c4a484" alt="custom" title="Client에서 이벤트가 발생합니다." data-nodeid="4"> # Properties - **UIModeType UIModeType** UI 엔티티가 그려지

[task] | single_turn [pass] | ⏳ 미판정 [title] | MSW MCP [question] | Google Antigravity IDE의 mcp_config.json에서 HTTP 서버를 정의할 때 사용해야 하는 특정 키 이름은 무엇인가요? [answer] | Google Antigravity IDE의 `mcp_config.json`에서 HTTP 서버를 정의할 때 사용해야 하는 특정 키 이름은 `serverUrl`입니다. 참고로 `type` 필드는 지원하지 않으며, HTTP 서버의 주소를 지정할 때 `url` 대신 `serverUrl` 키를 사용해야 합니다. ```json { "mcpServers": { "msw-mcp": { "serverUrl": "https://msw-mcp.nexon.com/mcp", "headers": { "Authorization": [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. Terminal에서 운영체제에 맞는 명령어를 입력하고, 서버를 등록합니다. 이 등록은 **사용자 글로벌 경로 (`~/.codex/config.toml`) 에 저장**되어 모든 Codex 세션에 공통 적용됩니다. **Windows(stdio)**: ```lua codex mcp add msw-maker-mcp -- cmd.exe /c call "%LOCALAPPDATA%\Nexon\MapleStory Worlds\MakerMCP\msw-maker-mcp.bat" ``` **macOS

[task] | single_turn [pass] | ⏳ 미판정 [title] | RigidbodyAttachEvent [question] | 클라이언트에서 이벤트 핸들러를 등록했는데 서버 엔티티가 붙는 경우 이벤트가 안 들어오는 것 같은데, 이는 공간(Space) 제한 때문인가요? [answer] | 네, 공간(Space) 제한 때문입니다. `RigidbodyAttachEvent`는 엔티티의 종류에 따라 발생 공간이 달라집니다. 1. **플레이어**: 클라이언트(Client)에서 이벤트가 발생합니다. 2. **플레이어가 아닌 엔티티 (서버 엔티티)**: 서버(Server) 공간에서 이벤트가 발생합니다. 따라서 질문하신 대로 **서버 엔티티**가 `RigidbodyComponent:AttachTo`를 통해 붙는 경우, 해당 이벤트는 **서버 공간**에서 발생하므로 클라이언트에서 등록한 이벤트 핸들러로는 감지할 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 엔티티가 RigidbodyComponent:AttachTo(string, Vector3)를 통해 특정 엔티티에 붙었을 때 발생하는 이벤트입니다. 플레이어는 클라이언트에서 발생하고, 그 외의 엔티티는 서버 공간에서 발생합니다. 이 Event는 아래 API에 의해 발생합니다. * RigidbodyComponent <img src="https://img.shields.io/static/v1?label=Space&message=Server,Client&color=c4a484" alt="custom" title="Server, Client

[task] | single_turn [pass] | ⏳ 미판정 [title] | 프로파일러로 월드 성능 분석하기 [question] | 타이머를 반복 실행하도록 설정했는데 Total Timer가 계속 쌓여서 FPS가 떨어지는 원인은 무엇인가요? [answer] | Total Timer가 계속 쌓여 FPS가 떨어지는 주된 원인은 **타이머를 생성한 뒤 명시적으로 제거하지 않는 것**입니다. 특히 다음 두 가지 경우에서 문제가 발생합니다. 1. `isRepeat`을 `true`로 설정하여 반복 실행되는 타이머를 생성했지만, 필요 이상으로 오래 유지되거나 종료 시점에 정리하지 않은 경우. 2. 타이머를 일시 정지한 뒤 제거하지 않고 방치한 경우. 반복 실행하는 타이머는 사용이 끝난 시점에 반드시 명시적으로 제거해야 Total Timer 개수가 과도하게 증가하는 것을 막을 수 있습니다. To [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Sync Property의 동기화 횟수입니다. | 항목 | 설명 | | --- | --- | | Send Count | 컴포넌트 단위의 동기화 및 프로퍼티 별 동기화 송신 횟수입니다. | | Receive Count | 컴포넌트 단위의 동기화 및 프로퍼티 별 동기화 수신 횟수입니다. | ##### Sync Property Count 관련 성능 저하 개선 Sync Property Count가 많아지면 FPS나 Tick에 악영향을 끼칠 수 있습니다. Sync Property는 None-Sync Property와 달리 내부적으로 동기

[task] | single_turn [pass] | ⏳ 미판정 [title] | 002_Intro [question] | aSpawnSet과 bSpawnSet 엔티티 중 Sync 동기화 속성이 적용된 변수는 어느 쪽이며, 그 이유는 무엇일까요? [answer] | `bSpawnSet` 변수에 `Sync` 동기화 속성이 적용되어 있습니다. 참고 문서의 `IntroManager` 컴포넌트 프로퍼티 정의에 따르면, `aSpawnSet`은 `[None]` 동기화 설정인 반면, `bSpawnSet`은 `[Sync]` 동기화 설정으로 명시되어 있습니다. 이는 `bSpawnSet`의 값(엔티티 참조)이 클라이언트와 서버 간에 동기화되도록 설계되었음을 의미합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # IntroManager 인트로 맵의 시스템을 관리하는 컴포넌트입니다. #### Property | 동기화 | Type | 이름 | 설명 | | --- | --- | --- | --- | | None | Component | ingameInfo | common의 InGameInfo 컴포넌트를 가진 변수입니다. | | None | SyncTable<string, string> | playerIntroReadyState | 인트로 맵에서 플레이어의 준비 상태를 확인합니다. key는 플레이어Id, value는 플레이어의 상태를 R

[task] | code [pass] | ⏳ 미판정 [title] | 엔티티의 생성과 삭제, 유효성 체크 [question] | `OnBeginPlay` 이벤트 핸들러에서 *SpawnService*의 `SpawnByEntity`를 호출하여 엔티티를 생성한 뒤, 반환값이 `nil`인지 `isvalid`로 확인하여 실패 시 에러 로그를 출력하는 스크립트를 작성해줘. [answer] | `OnBeginPlay`에서 `SpawnByEntity`를 호출하여 엔티티를 생성하고, 반환값이 `nil`인지 `isvalid`로 확인하여 실패 시 로그를 출력하는 스크립트는 다음과 같습니다. ```lua Method: [server only] void OnBeginPlay() { -- 복제할 원본 엔티티 경로 지정 local entity = _EntityService:GetEntityByPath("/maps/map01/monster-8") -- 생성할 엔티티 이름 및 위치 설정 local n [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 엔티티의 생성과 삭제는 월드를 제작하면서 가장 많이 사용하는 기능입니다. 이번 과정에서는 엔티티 생성과 삭제 방법, 그리고 엔티티 존재 여부를 확인하는 유효성 체크 기능을 살펴봅니다. # 엔티티 생성 **SpawnService**는 엔티티 생성 함수를 제공합니다. 주요 엔티티 생성 함수인 `SpawnByEntity`와 `SpawnByModelId`를 알아보겠습니다. ## SpawnByEntity 엔티티를 바탕으로 새로운 엔티티를 생성합니다. #### 매개 변수 |Parameter |Type |D

[task] | code [pass] | ⏳ 미판정 [title] | 충돌 그룹 만들기 [question] | Coin 모델에 추가된 ItemComponent 에서 HandleTriggerEnterEvent 를 구현하여 event.TriggerBodyEntity 의 CollisionGroup 이 Item 이 아닌 경우에만 self.Entity:Destroy() 를 호출하지 않도록 방어적으로 작성하는 스크립트를 작성해줘 [answer] | CollisionGroup을 직접 확인하는 API는 제공되지 않습니다. 충돌 그룹 매트릭스(Matrix)를 통해 충돌 허용 여부를 설정하면, 허용되지 않은 충돌은 `HandleTriggerEnterEvent` 이벤트 자체가 발생하지 않습니다. 따라서 `event.TriggerBodyEntity`의 CollisionGroup을 직접 검사하는 코드를 작성할 수 없으며, 질문에서 요구한 "CollisionGroup이 Item이 아닌 경우에만"이라는 조건을 스크립트 내에서 구현하는 것은 불가능합니다. 대신, 충돌 그룹 설정 단계에서 * [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 충돌 그룹 매트릭스(Matrix)는 충돌 그룹끼리의 충돌을 허용할지 말지를 결정할 때 사용합니다. 충돌 그룹을 생성하면 매트릭스에 자동으로 새로운 충돌 그룹이 생성됩니다. 충돌 그룹끼리의 충돌 허용 여부는 체크 박스를 선택해서 간단하게 설정할 수 있습니다. 매트릭스에 적힌 충돌 그룹끼리의 관계를 확인하고 충돌을 허용하고 싶다면 체크 박스를 활성화합니다. 1. **Panels - Collision Groups - Matrix**를 선택합니다. 2. 가로 세로의 그룹명을 확인한 뒤 충돌을 허용하면 체크 박스를 활성화합니다.

[task] | two_turn [pass] | ✅ 통과 [title] | TextInputEndEditEvent [question] | `TextInputEndEditEvent`가 발생하는 시점과 주요 속성에 대해 알려주세요. [answer] | `TextInputEndEditEvent`는 InputField의 값 변경이 완료되었을 때 발생하는 이벤트입니다. 이 이벤트는 `TextGUIRendererInputComponent` 또는 `TextInputComponent`에 의해 발생하며, 항상 클라이언트 공간에서 발생합니다. 이 이벤트 객체에는 다음과 같은 주요 속성이 있습니다: * **text** (string): 변경 완료된 텍스트 값입니다. 이벤트 처리 예제는 다음과 같습니다. ```lua Event Handler: [self] HandleTextInputEndEd [followup] | 이 이벤트 핸들러에서 `text` 속성을 가져와서 서버로 전송하려면 어떤 코드 구조를 짜야 하나요? [followup_answer] | 참고 문서에 따르면 `TextInputEndEditEvent`는 클라이언트 공간에서 발생하는 이벤트입니다. 제공된 문서에는 클라이언트에서 서버로 데이터를 전송하기 위한 API나 메서드에 대한 정보가 포함되어 있지 않으므로, 문서 근거만으로는 서버 전송을 위한 구체적인 코드 구조를 제시할 수 없습니다. 문서에 명시된 내용으로 작성할 수 있는 것까지를 정리하면, 이벤트 핸들러에서 `text` 속성을 가져오는 부분만 다음과 같이 구현할 수 있습니다. ```lua Event Handler: [self] HandleTextInputEnd [scores] | helpfulness=4 correctness=4 coherence=4 complexity=2 verbosity=2 [judge_reason] | 참고 문서에 명시된 발생 시점, 발생 컴포넌트, 클라이언트 공간 제약, 속성 정보 및 생성자 정보가 정확히 반영되었으며, mLua 스크립트 규칙에 부합하는 예제 코드를 제공하여 질문에 충실히 답변했습니다. [source_doc] | InputField의 값 변경이 완료되었을 때 발생하는 이벤트입니다. 이 Event는 아래 API에 의해 발생합니다. * TextGUIRendererInputComponent <img src="https://img.shields.io/static/v1?label=Space&message=Client&color=c4a484" alt="custom" title="Client에서 이벤트가 발생합니다." data-nodeid="4"> * TextInputComponent <img src="https://img.shields.io/stat

[task] | single_turn [pass] | ⏳ 미판정 [title] | 월드 숍 서비스 활용하기 [question] | PurchaseBtn 엔티티에 ButtonClickEvent를 연결할 때 OnBeginPlay 함수 내에서 GetChildByName을 사용하여 참조하는 것이 권장되는 이유는 무엇인가요? [answer] | 제공된 참고 문서에는 `OnBeginPlay` 함수 내에서 `GetChildByName`을 사용하여 `PurchaseBtn` 엔티티를 참조하는 것이 권장되는 이유에 대한 설명이나 근거가 포함되어 있지 않습니다. 문서에서는 단순히 `ItemSlot` 컴포넌트의 `OnBeginPlay` 메서드 예제 코드 내에서 `self.Entity:GetChildByName("PurchaseBtn")`를 호출하여 `self.PurchaseBtn`에 할당하고, 이후 `ConnectEvent`를 통해 `ButtonClickEvent`를 연결하는 코드를 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 상품 구매에 성공했을 때 포션 개수와 이용권 보유 여부를 확인할 수 있는 ui를 만들어봅시다. 1. **UI 에디터 - DefaultGroup - MyPotionInfo** 이미지 엔티티를 배치합니다. 2. 하위에 이미지와 텍스트 엔티티를 배치하고, 아래의 그림처럼 이름을 변경합니다. #### 상품 정보를 구매창에 불러오기 1. 새로운 **ItemSlot** 스크립트 컴포넌트를 생성하고 **Item, Pass UI엔티티**에 추가합니다. 2. **ItemSlot** 컴포넌트 스크립트 에디터 창을 열고, 프로퍼티를 추가합니다.

[task] | code [pass] | ⏳ 미판정 [title] | PolygonShape [question] | `PolygonShape`의 `Angle` 프로퍼티 값을 0에서 360까지 1초 동안 360도 회전하도록 `OnUpdate` 메서드에서 `delta` 값을 이용해 갱신하는 스크립트를 작성해줘 [answer] | PolygonShape의 Angle 프로퍼티를 1초 동안 360도 회전시키기 위해서는, 1초에 360도 회전한다는 의미이므로 각도 변화량이 초당 360도임을 의미합니다. OnUpdate 메서드의 delta 매개변수는 지난 프레임의 시간을 초 단위로 나타내므로, self.Angle 프로퍼티에 delta * 360 값을 더해주면 됩니다. ```lua Property: [None] PolygonShape polyShape = nil Method: [server only] void OnBeginPlay() { -- Polygon [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 충돌 관련 기능에 활용하는 다각형 모양을 나타냅니다. # Properties - **float Angle** 회전된 각도입니다. - **List<Vector2> Points** 다각형을 이루는 점들의 월드 좌표상 위치입니다. ##### inherited from Shape: - **Vector2 Position** 모양의 월드 좌표상 위치입니다. # Constructors - **PolygonShape(Vector2 position, List<Vector2> points, float angle)** 지정한

[task] | single_turn [pass] | ⏳ 미판정 [title] | 4. 아이템을 인벤토리에 추가하기 [question] | RemoveItemAt 함수에서 self.ItemStacks[slotIndex]가 nil인 경우를 방지하기 위해 호출 전에 반드시 확인해야 할 조건은 무엇인가요? [answer] | `RemoveItemAt` 함수를 호출하기 전에 `self.ItemStacks[slotIndex]`가 `nil`인 경우를 방지하려면, 해당 슬롯에 아이템이 실제로 존재하는지 확인해야 합니다. 문서에서 제공하는 `RemoveItemAt` 함수의 구현을 보면, 함수 내부에서 이미 `slotIndex`의 유효성(1부터 `self.Capacity` 사이)을 먼저 확인한 뒤, `self.ItemStacks[slotIndex]`가 `nil`인지 검사하고 있습니다. ```lua if slotIndex < 1 or slotInd [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua [server only] boolean RemoveItemAt (integer slotIndex, integer itemCount) { if slotIndex < 1 or slotIndex > self.Capacity then log_error("[SimpleInventory] (RemoveItemAt) 슬롯 인덱스 오류: " .. slotIndex) return false end if itemCount <

[task] | single_turn [pass] | ❌ 탈락 [title] | TeleportService [question] | 유저를 다른 월드로 이동시킬 때 반드시 출시된 월드 중 공개된 월드로만 이동이 가능한 제한 사항이 있는 이유는 무엇인가요? [answer] | 유저를 다른 월드로 이동시킬 때 반드시 출시된 월드 중 공개된 월드로만 이동이 가능해야 하는 구체적인 이유는 제공된 문서에 명시되어 있지 않습니다. 문서에는 `WarpUserToWorldAndWait`, `WarpUserToWorldAsync`, `WarpUserToWorldInstanceAndWait`, `WarpUserToWorldInstanceAsync` 함수 모두에 대해 "출시된 월드 중 공개된 월드로만 이동이 가능합니다"라는 제한 사항이 기술되어 있을 뿐, 그 배경이나 이유에 대한 설명은 포함되어 있지 않습니다. [followup] | [followup_answer] | [scores] | helpfulness=2 correctness=4 coherence=4 complexity=2 verbosity=2 [judge_reason] | 문서에 이유 설명이 없음을 정확히 인지하고, 지어내지 않은 채 사실관계를 명확히 전달하여 정확도와 일관성이 높지만, 질문의 의도(이유)에 대한 직접적 답변은 불가하다는 한계가 있음. [source_doc] | 함께 callbackFunction으로 전달된 함수가 호출됩니다. userIds는 워프시킬 유저들의 Id, destinationWorldId는 목적지 월드의 Id입니다. warpData로 전달한 데이터는 GetWarpRecord 함수로 확인할 수 있습니다. - **boolean WarpUserToWorldAndWait(string userId, string destinationWorldId, string warpData) [ServerOnly] [Yield]** 유저를 다른 월드로 워프시키고 성공 여부를 반환합니다. 출시된 월드

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | UserService의 UserEnterEvent와 UserLeaveEvent 핸들러 코드만 출력하고, 각 핸들러의 동작 설명은 주석으로 작성하세요. [answer] | ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) { -- 유저가 월드에 입장했을 때 발생하는 이벤트입니다. -- event.UserId를 통해 현재 게임에 입장한 유저의 UserId를 받습니다. local UserId = event.UserId log("User Enter! : "..UserId) } Event Handler: [service: UserService] HandleUserLeav [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 `UserService`를 통해 상황별로 **UserEntity**를 받는 방법을 알아봅니다. 간단한 스크립트 예제를 통해 `UserService`가 제공하는 기능을 알아보겠습니다. # 들어가기에 앞서 다음 가이드를 먼저 학습하면 본 과정을 이해하는 데 많은 도움이 됩니다. [서버와 클라이언트](/docs?postId=207) [실행 제어](/docs?postId=210) [Event System](/docs?postId=73) [Entity Event System](/docs?postId=176) # 예

[task] | single_turn [pass] | ✅ 통과 [title] | TextInputValueChangeEditorEvent [question] | 이 이벤트는 TextGUIRendererInputComponent와 TextInputComponent 중 어느 쪽에 연결해야 하며 둘의 차이는 무엇인가요? [answer] | 제공된 참고 문서에 따르면, `TextInputValueChangeEditorEvent`는 **`TextGUIRendererInputComponent`**와 **`TextInputComponent`** 두 컴포넌트 모두에서 발생합니다. 문서에는 이 두 컴포넌트 중 어느 쪽에 "반드시" 연결해야 한다는 우선순위나 제한 조건에 대한 명시적인 정보가 없으며, 단순히 이 이벤트가 두 API에 의해 발생한다고만 기술되어 있습니다. 따라서 두 컴포넌트 모두에서 이 이벤트를 처리할 수 있습니다. 참고 문서에는 `TextGUIRendererI [followup] | [followup_answer] | [scores] | helpfulness=4 correctness=4 coherence=4 complexity=2 verbosity=2 [judge_reason] | 문서에 없는 차이점을 지어내지 않고 문서 기반 정보로 정확히 답변했으며, mLua 규칙에 맞는 예제를 제시했습니다. [source_doc] | InputField의 값이 변경되었을 때 발생하는 에디터 이벤트입니다. 이 Event는 아래 API에 의해 발생합니다. * TextGUIRendererInputComponent <img src="https://img.shields.io/static/v1?label=Space&message=Editor&color=c4a484" alt="custom" title="Editor에서 이벤트가 발생합니다." data-nodeid="4"> * TextInputComponent <img src="https://img.shields.io/sta

[task] | single_turn [pass] | ⏳ 미판정 [title] | 머티리얼 활용하기 [question] | Mask 셰이더에서 MaskTexture를 지정할 때 사용할 수 있는 값의 형식은 어떻게 되나요? [answer] | Mask 셰이더의 `MaskTexture` 프로퍼티에 지정하는 값은 **텍스처 ID(문자열)** 형식입니다. 참고 문서의 예시에서 `MaskTexture`에 `0005fdee112f4ab8a59764021ac1dda0`와 같은 16진수 문자열이 사용된 것을 볼 수 있습니다. 이는 메이플스토리 월드에서 텍스처 리소스를 식별하는 고유 ID를 문자열 형태로 나타낸 것입니다. 따라서 `MaskTexture`에는 해당 마스킹에 사용할 텍스처의 **고유 ID 문자열**을 지정하면 됩니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 스프라이트 좌표를 왜곡하는 효과입니다. | @cols=2:@rows=1:셰이더 | 설명 | | :---: | --- | --- | | Noise | | 지속적으로 엔티티가 흔들립니다.| | RoundWave| | 중심 기준으로 동심원 파동을 그립니다. | | UVScroll| | 스프라이트 렌더링할 때 UV 좌표를 이동시킵니다. | | Wave| | 특정 지점에서 원형 파동을 그립니다. | | Glitch| | 무작위로 스프라이트의 다른 구역을 샘플링합니다. | | GrassMovement| | 풀이 흔들리는

[task] | instruction_following [pass] | ✅ 통과 [title] | AIChaseComponent [question] | SetTarget 메서드 호출 시 발생하는 자동 변경 사항과 GetCurrentTarget의 반환 타입을 2문장 이내로 요약하세요. [answer] | `SetTarget` 메서드를 호출하면 `IsChaseNearPlayer` 프로퍼티가 자동으로 비활성화됩니다. `GetCurrentTarget`은 추적 대상 엔티티를 `Entity` 타입으로 반환합니다. [followup] | [followup_answer] | [scores] | helpfulness=4 correctness=4 coherence=4 complexity=1 verbosity=2 [judge_reason] | 참고 문서에 명시된 SetTarget의 자동 비활성화 동작과 GetCurrentTarget의 반환 타입을 2문장 이내로 정확하고 간결하게 요약했습니다. [source_doc] | - **Entity GetCurrentTarget()** 추적 대상 엔티티를 반환합니다. - **void SetTarget(Entity targetEntity)** targetEntity를 추적하도록 설정합니다. 함수 호출 시 IsChaseNearPlayer 프로퍼티는 자동으로 비활성화됩니다 ##### inherited from AIComponent: - **BTNode CreateLeafNode(string nodeName, func<float> -> BehaviourTreeStatus onBehaveFunction)*

[task] | two_turn [pass] | ⏳ 미판정 [title] | 게임 시작 위치 설정 [question] | 게임 제작 중 특정 구간을 효율적으로 반복 테스트하기 위해 '여기서 시작' 기능을 사용하는 방법과 주의할 점은 무엇인가요? [answer] | 게임 제작 중 특정 구간을 효율적으로 반복 테스트하기 위해 '여기서 시작' 기능을 사용하는 방법은 다음과 같습니다. 1. **Scene 탭의 '여기서 시작' 버튼 선택**: Scene 탭 아래에 위치한 '여기서 시작' 버튼을 클릭합니다. 2. **테스트 시작 위치 이동 및 배치**: 테스트를 시작하고 싶은 위치(타일 혹은 발판 위)로 캐릭터를 이동시킨 후 배치합니다. 3. **테스트 시작**: 시작 버튼을 눌러 테스트를 실행합니다. 4. **결과 확인**: 설정한 위치에서 플레이어 아바타가 등장하여 테스트가 시작됩니다. [followup] | 테스트 시작 위치를 지정할 때 캐릭터가 의도한 위치에 나타나지 않는 문제가 발생하는 원인과 해결 방법을 자세히 알려주세요. [followup_answer] | 테스트 시작 위치를 지정했을 때 캐릭터가 의도한 위치에 나타나지 않고 임의로 화면 중앙에 배치되는 원인과 해결 방법은 다음과 같습니다. ### 원인 맵에 **발판이나 타일을 배치하지 않은 상태**에서 시작 위치를 지정할 경우, 테스트가 시작될 때 캐릭터가 의도한 위치가 아닌 임의로 화면 중앙에 배치됩니다. ### 해결 방법 캐릭터가 의도한 위치에 나타나도록 하려면, **'여기서 시작' 위치를 반드시 캐릭터가 설 수 있는 발판 영역 위에 두어야 합니다.** 즉, 테스트 시작 위치를 설정하기 전에 해당 위치에 타일이나 발판이 제대 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 **플레이어 아바타**의 등장 위치 설정 방법을 소개합니다. 게임 시작 위치, 재등장(리스폰), 게임 제작 중 테스트 위치 설정에 대해 알아보겠습니다. # 플레이어 아바타의 기본 위치 플레이어 아바타의 기본 위치는 화면 중간입니다. X, Y 좌표상 X값 0, Y값 0인 위치입니다. 기본적으로 게임 시작과 리스폰 위치가 이 설정을 따릅니다. 플레이어 아바타의 기본 위치는 **DefaultPlayer의 TransformComponent**에서 확인할 수 있습니다. # SpawnLocation을 이용한 시작

[task] | single_turn [pass] | ✅ 통과 [title] | ScreenRecordMode [question] | 숫자 2로 저장된 ScreenRecordMode 값을 스크립트에서 읽어서 사용하려면 어떻게 변환해야 하나요? [answer] | `ScreenRecordMode`의 `CastFrom(number value)` 정적 메서드를 사용하여 숫자 값을 해당 열거형 타입으로 변환할 수 있습니다. 숫자 `2`는 `ScreenRecordMode.ScreenAndMic` (화면과 마이크 소리 녹화)에 해당합니다. ```lua Method: [server only] void OnBeginPlay() { local rawValue = 2 local recordMode = ScreenRecordMode.CastFrom(rawValue) -- 변환 [followup] | [followup_answer] | [scores] | helpfulness=4 correctness=4 coherence=4 complexity=3 verbosity=2 [judge_reason] | 참고 문서의 CastFrom 메서드와 ScreenAndMic(2) 정의를 정확히 인용하여 코드를 제시했고, mLua 구문 규칙에도 부합합니다. [source_doc] | 화면 녹화 방식을 의미합니다. # Members | 이름 | 값 | 설명 | |---|---|---| | ScreenOnly | 0 | 화면을 녹화합니다. | | ScreenAndGameAudio | 1 | 화면과 월드 소리를 녹화합니다. | | ScreenAndMic | 2 | 화면과 마이크 소리를 녹화합니다. | | ScreenAndGameAudioAndMic | 3 | 화면, 월드 소리, 마이크 소리를 녹화합니다. | # Methods - **ScreenRecordMode CastFrom(number value) [St

[task] | two_turn [pass] | ✅ 통과 [title] | HitEvent [question] | 엔티티가 피격될 때 발생하는 HitEvent의 주요 속성(대미지, 공격자, 크리티컬 여부 등)은 무엇인가요? [answer] | `HitEvent`는 엔티티가 피격되었을 때 발생하는 이벤트로, 다음과 같은 주요 속성을 포함합니다. * **TotalDamage**: `integer` 타입으로, 해당 공격으로 입은 총 대미지 값입니다. * **AttackerEntity**: `Entity` 타입으로, 공격을 가한 엔티티를 가리킵니다. 공격자가 없는 경우 `nil`일 수 있습니다. * **IsCritical**: `boolean` 타입으로, 해당 공격이 크리티컬 여부인지 확인합니다. * **Damages**: `List<integer>` 타입으로, [followup] | Damages 리스트와 TotalDamage의 관계, 그리고 AttackerEntity가 nil이 될 수 있는 구체적인 상황은 무엇인가요? [followup_answer] | 제공된 참고 문서에는 `Damages` 리스트와 `TotalDamage` 간의 수학적 관계(예: 합이 일치하는지 여부)나 `AttackerEntity`가 `nil`이 되는 구체적인 상황(예: 환경 장애물, 시스템 공격 등)에 대한 설명이 포함되어 있지 않습니다. 문서에서 확인할 수 있는 사실은 다음과 같습니다. 1. **Damages**: "분할 표시될 대미지 리스트"입니다. 2. **TotalDamage**: "총 대미지"입니다. 3. **AttackerEntity**: "공격자 엔티티"이며, "nil일 수도 있습니다"라 [scores] | helpfulness=4 correctness=4 coherence=4 complexity=2 verbosity=2 [judge_reason] | 참고 문서에 명시된 HitEvent의 모든 속성(타입, 설명, Deprecated 상태 포함)을 정확하고 간결하게 나열하여 질문에 완벽하게 부합합니다. [source_doc] | 엔티티가 피격되었을 때 발생하는 이벤트입니다. 이 Event는 아래 API에 의해 발생합니다. * HitComponent <img src="https://img.shields.io/static/v1?label=Space&message=Server,Client&color=c4a484" alt="custom" title="Server, Client에서 이벤트가 발생합니다." data-nodeid="4"> # Properties - **Vector2 AttackCenter** 공격이 이루어진 중점입니다. - **Entity At

[task] | code [pass] | ⏳ 미판정 [title] | DataStorage [question] | DataStorageService의 GetGlobalDataStorage(string)를 사용해 전역 카운터를 관리하고, SetAndWait(key, value)로 증가된 값을 저장한 후, GetAndWait(key)로 값을 가져와서 log() 함수로 출력하는 스크립트를 작성해줘. [answer] | 요청하신 전역 카운터 관리 스크립트입니다. `_DataStorageService:GetGlobalDataStorage()`를 통해 전역 데이터를 얻고, `GetAndWait()`로 현재 값을 조회한 후 증가시켜 `SetAndWait()`로 다시 저장하는 로직으로 구현했습니다. ```lua Property: [None] integer globalCounter = 0 Method: [server only] void OnBeginPlay() { -- 전역 데이터 스토리지 획득 local globalStorage = _D [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 더는 사용하지 않는 타입입니다. 용도에 맞게 DataStorageService의 GetGlobalDataStorage(string), GetUserDataStorage(string), GetCreatorDataStorage(), GetSortableDataStorage(string)를 사용하세요. # Methods - **string GetAndWait(string key) [Deprecated] [ServerOnly] [Yield]** 더는 사용하지 않는 함수입니다. 용도에 맞게 GlobalDataStorage, UserD

[task] | single_turn [pass] | ⏳ 미판정 [title] | 타입의 이해 [question] | StructType을 사용해 이름, 학번, 학과 같은 데이터를 묶어 관리할 때 일반적인 프로그래밍 언어의 Structure와 동일한 방식으로 사용할 수 있나요? [answer] | 네, **StructType**은 일반적인 프로그래밍 언어의 Structure와 비슷한 기능을 합니다. 다른 데이터를 담는 변수들을 묶어서 관리할 때 사용할 수 있으며, 질문하신 것처럼 "이름, 학번, 학과"와 같은 데이터들을 하나의 타입으로 정의하고 묶어 사용할 수 있습니다. 다만, 제공된 문서에는 **StructType**의 구체적인 정의 문법이나 코드 예제가 포함되어 있지 않습니다. 따라서 구체적인 스크립트 작성 방법은 확인이 어렵습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 몬스터나 NPC 같은 엔티티에 AI를 적용할 때는 [AIComponent](/apiReference/Components/AIComponent)를 활용합니다. **AIComponent**로 행동 트리(Behaviour Tree)를 만들 수 있습니다. 이 행동 트리를 구성하는 노드 중 하나인 **Action 노드**를 생성할 때 **BTNodeType** 스크립트를 사용합니다. **Action 노드**는 "엔티티의 행동" 또는 "행동에 대한 조건"을 정의합니다. 예를 들어, 몬스터가 "대기" 상태에 있을 때 어떤 행동을 할지를 정의하

[task] | code [pass] | ⏳ 미판정 [title] | 행동 트리를 활용한 AI 만들기 [question] | AIComponent 로 생성한 Action Node 객체에 BTNodeType 으로 정의한 2초 대기 노드를 연결하여 AI 가 특정 위치에서 2초간 대기하도록 설정하는 스크립트를 작성해줘 [answer] | 제시된 참고 문서에는 `AIComponent`를 사용하여 Action Node 객체를 생성하고, 생성된 노드를 행동 트리(Behaviour Tree)에 연결하는 구체적인 API(예: `AddChild`, `AddNode`, `RootNode` 프로퍼티 등)나 코드가 포함되어 있지 않습니다. 문서에는 `BTNodeType` 스크립트 내에서 `OnInit()`와 `OnBehave()`를 구현하여 2초 대기 로직을 작성하는 방법과, `self.ParentAI`를 통해 부모 AI 엔티티에 접근하는 방법은 설명되어 있지만, **메인 AI [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 자식 노드가 Success 또는 Failure를 반환하면 부모 노드는 다음 자식 노드를 실행합니다. 그러나 자식 노드가 Running을 반환하면 부모 노드는 Running을 반환했던 자식 노드를 다음 프레임에 다시 실행합니다. 이 특성을 활용해 여러 프레임 동안 동작하는 노드를 만들 수 있습니다. 아래 그림과 같이 자식 노드 A, B, C가 있을 때 Sequence Node와 Selector Node의 경우 B 노드가 Running을 반환하는 동안 C 노드를 실행하지 않습니다. RandomSelector Node는 선택된 노드를 계

[task] | single_turn [pass] | ⏳ 미판정 [title] | ScreenshotService [question] | 캡처 함수를 호출했는데 스크립트 실행이 멈추는 현상이 발생했는데, 이것이 [Yield] 태그와 어떤 관련이 있나요? [answer] | mLua에서 `[Yield]` 태그가 붙은 함수는 호출 시 스크립트 실행을 일시 중단(블로킹)합니다. 캡처 함수 중 `CaptureFullScreenAsFileAndWait`, `CaptureFullScreenAsPixelDataAndWait`, `CaptureFullScreenToPhotoLibraryAndWait`가 이 태그를 가지고 있어, 화면 캡처와 파일 저장(또는 픽셀 데이터 처리)이 완료될 때까지 해당 스크립트의 실행 흐름이 멈춥니다. 이로 인해 캡처 처리가 끝날 때까지 이후에 작성된 코드(예: 다음 로직, 이벤트 처리 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 화면의 전체 또는 일부를 캡처하는 기능을 제공합니다. # Methods - **ScreenshotError, string CaptureFullScreenAsFileAndWait(string fileName, boolean includeUI = true) [ClientOnly] [Yield]** 화면 전체를 캡처해 PNG 파일로 저장합니다. MobileShareService와 연동해 캡처 이미지를 공유할 때 사용합니다. 저장을 완료하면 에러 코드와 저장 경로를 반환합니다. 수행하는 동안 스크립트 실행을 중단합니다. Window

[task] | code [pass] | ⏳ 미판정 [title] | 행동 트리 노드 만들기 [question] | OnBeginPlay 에서 SequenceNode 를 생성하고 ActionA, ActionB, ActionC 를 AttachChild 로 연결한 후, ActionB 를 DetachChild 로 제거하여 최종적으로 ActionA 와 ActionC 만 포함된 트리를 SetRootNode 로 설정하는 스크립트를 작성해줘 [answer] | 요청하신 동작을 수행하는 mLua 스크립트입니다. `OnBeginPlay`에서 노드들을 생성하고 연결한 뒤, `DetachChild`로 ActionB를 제거하고 최종 트리를 루트 노드로 설정합니다. ```lua [server only] void OnBeginPlay() { --CREATE NODE local sequence = SequenceNode("sq") local actionA = self:CreateNode("ActionA") local actionB = self:CreateNode("ActionB") local [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 이미 등록된 자식 노드를 제거할 때는 `DetachChild()`, `DetachChildAt()`를 활용합니다. * `DetachChild()`는 매개 변수로 떼어낼 자식 노드 객체를 넘겨 자식 노드를 제거합니다. * `DetachChildAt()`은 떼어낼 자식 노드 객체의 위치를 넘겨 자식 노드를 제거합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17168956211348925ff93ffd347379cb977b79e710f7c.png "detach") `