> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md).

# 코딩 필수 요소

이 세트는 Decentraland의 클라이언트와 SDK에서 어떻게 작동하는지 이해하는 데 도움이 됩니다.

## 개발 도구

매우 높은 수준에서, Decentraland는 **소프트웨어 개발 키트** (SDK)를 사용하면 다음을 할 수 있습니다:

* 기본 *프로젝트* Decentraland 씬을 포함하며, 콘텐츠를 렌더링하고 실행하는 데 필요한 모든 에셋이 들어 있습니다.
* 씬의 콘텐츠를 웹 브라우저에서 로컬로 빌드, 테스트, 미리 보기할 수 있습니다. 완전히 오프라인으로, 이더리움 트랜잭션을 수행하거나 LAND를 소유할 필요 없이 가능합니다.
* Decentraland API를 사용해 TypeScript 코드를 작성하여 씬에 상호작용적이고 동적인 동작을 추가합니다.
* 씬의 콘텐츠를 콘텐츠 서버에 업로드합니다.
* 보유한 LAND 토큰을 업로드한 콘텐츠의 URL에 연결합니다.

우리 SDK에는 다음이 포함됩니다:

* **크리에이터 허브**: 그 밖에도 쉬운 드래그 앤 드롭 인터페이스로 씬을 만들 수 있게 해주는 독립 실행형 애플리케이션입니다. 미리 보기 실행, 디버그, 코드 편집, 게시를 할 수 있습니다. [더 읽기](/creator/content-creator-ko/scene-editor/get-started/about-editor.md)
* **Decentraland ECS**: 상호작용형 경험을 만들 수 있게 해주는 도우미 메서드 프레임워크가 들어 있는 TypeScript 패키지입니다. 이를 사용해 씬의 오브젝트를 만들고 조작하며, 플레이어 또는 다른 애플리케이션 간의 인월드 거래를 원활하게 할 수 있습니다. ( [최신 ECS 레퍼런스](https://github.com/decentraland/ecs-reference/blob/master/docs-latest/decentraland-ecs.md))
* **씬 예제**: 다음에서 영감과 코딩 모범 사례를 얻어보세요 [씬 예제](https://studios.decentraland.org/resources?sdk_version=SDK7).

기타 레거시 도구:

* **웹 편집기**: 간단한 씬을 만들고 게시하기 위한 웹 기반 도구입니다.

## 요구 사항

씬을 로컬에서 개발할 때 LAND 토큰을 소유할 필요는 없습니다. 씬의 개발과 테스트는 완전히 오프라인으로 가능하며, 이더리움 네트워크(Decentraland가 LAND 또는 Decentraland 이름의 소유권을 확립하는 데 사용하는 시스템)나 콘텐츠 서버에 씬을 배포할 필요도 없습니다.

다음이 필요합니다:

* **크리에이터 허브**: 그 밖에도 쉬운 드래그 앤 드롭 인터페이스로 씬을 만들 수 있게 해주는 독립 실행형 애플리케이션입니다. 미리 보기 실행, 디버그, 코드 편집, 게시를 할 수 있습니다. [더 읽기](/creator/content-creator-ko/scene-editor/get-started/about-editor.md).

씬의 코드를 편집할 계획이라면, 다음 중 하나를 설치해야 합니다:

* <img src="https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-72733d889cecbb74400d2c9292b43a212b253969%2Fvscode.png?alt=media" alt="VS Code" data-size="line"> **Visual Studio Code**: 다운로드 [여기](https://code.visualstudio.com/). 코드를 훨씬 더 빠르고 오류를 적게 내며 작성하는 데 도움이 됩니다. 소스 코드 편집기는 구문 오류를 표시하고, 작성하는 동안 자동 완성하며, 현재 상황에 따라 달라지는 스마트 제안도 보여줍니다. 코드에서 오브젝트를 클릭하면 해당 클래스의 전체 정의와 지원하는 속성을 볼 수도 있습니다.
* <img src="https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-2c1650edc9dbc881f65cd788d7c8ccfa2c27575c%2Fcursor-icon.png?alt=media" alt="Cursor" data-size="line"> **Cursor AI**: 다운로드 [여기](https://www.cursor.com/). AI가 통합된 강력한 코드 편집기입니다. 코드 작성을 도와줄 다양한 AI 모델을 선택할 수 있으며, 모두 무료입니다. AI 도우미는 작성 중 자동 완성만 하는 것이 아니라, 큰 코드베이스 리팩터링, 문서 작성 등도 요청할 수 있습니다.

{% hint style="info" %}
**💡 팁**: Cursor, OpenDCL, Claude Code 같은 AI 도우미를 사용해 평범한 언어 설명만으로 전체 씬을 만들 수 있습니다. TypeScript 경험은 필요하지 않습니다. 다음을 참조하세요 [AI와 함께하는 바이브 코딩](/creator/content-creator-ko/sdk7/getting-started/vibe-coding.md) 시작하려면.
{% endhint %}

## 지원되는 언어 및 구문

Decentraland는 [TypeScript(.ts)](https://www.typescriptlang.org/docs/handbook/jsx.html) 를 씬 작성의 기본 언어로 사용합니다.

TypeScript는 JavaScript의 상위집합이므로, JavaScript에 익숙하다면 거의 같다고 느끼겠지만 TypeScript에는 타입 선언이 포함됩니다. 타입 선언 덕분에 자동 완성, 더 나은 디버깅 힌트 같은 기능을 사용할 수 있어 개발 속도가 빨라지고 더 견고한 코드베이스를 만들 수 있습니다. 이러한 기능들은 모두 긍정적인 개발자 경험의 핵심 요소입니다.

씬이 빌드되면, 작성한 TypeScript 코드는 더 가벼워지도록 축소된 JavaScript로 컴파일됩니다. TypeScript의 원본 소스 코드는 서버에 업로드되지 않고, 컴파일된 JavaScript 버전만 업로드됩니다.

### 다른 언어

TypeScript 대신 다른 도구나 언어를 사용해 JavaScript로 컴파일할 수 있으며, 컴파일된 스크립트가 scene의 `main` 필드에 설정된 경로와 일치하는 단일 JavaScript 파일 안에 포함되어 있기만 하면 됩니다. `scene.json` 파일(기본값으로 *bin/index.js*). 제공되는 모든 타입 선언은 TypeScript로 작성되며, 다른 언어와 트랜스파일러는 공식적으로 지원되지 않습니다.

## 씬

LAND에 배포하는 콘텐츠를 **씬**. 씬은 3D 콘텐츠를 렌더링하는 상호작용형 프로그램입니다. 게임일 수도 있고, 상호작용형 경험일 수도 있고, 미술관일 수도 있으며, 원하는 무엇이든 될 수 있습니다!

씬은 Decentraland의 가상 LAND에 배포됩니다. LAND는 이더리움 스마트 계약에 의해 유지되는 희소한 비대체 자산입니다. 단일 **파슬**, 즉 16미터 x 16미터 크기의 LAND 구획이나 여러 인접한 파슬에 배포할 수 있습니다.

플레이어가 Decentraland를 방문하면, 맵을 따라 이동하면서 각 씬의 콘텐츠를 다운로드하고 렌더링합니다. 씬에서 멀어지면 해당 씬을 언로드합니다.

CLI에서 미리 보기를 실행하여 자신의 기기에서 씬을 로컬로 실행할 수도 있습니다.

## 엔터티 및 컴포넌트

Decentraland의 3차원 씬은 [엔티티-컴포넌트-시스템](https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system) 아키텍처를 기반으로 하며, 씬의 모든 것은 *entity*엔티티입니다 *컴포넌트*, 각 컴포넌트는 속한 엔티티에 특정 속성을 부여합니다. 문 엔티티에는 최소한 Transform 컴포넌트(위치, 회전, 크기를 설정하는)와 모양을 제공하는 또 다른 컴포넌트가 있을 가능성이 큽니다. 컴포넌트는 단지 데이터를 저장하는 곳일 뿐이며, 그 자체로는 어떤 동작도 수행하지 않습니다.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-ee29a02358e859a30079072e8da958b899aea659%2Fecs-components-new%20\(1\).png?alt=media)

```ts
export function main() {
	// 엔티티 생성
	const door = engine.addEntity()

	// transform 컴포넌트를 통해 엔티티에 위치 부여
	Transform.create(door, {
		position: Vector3.create(5, 1, 5),
	})

	// GltfContainer 컴포넌트를 통해 엔티티에 보이는 형태 부여
	GltfContainer.create(door, {
		src: 'assets/models/door.glb',
	})
}
```

엔티티는 다른 엔티티 안에 중첩되어 트리 구조를 이룰 수 있습니다. 웹 개발에 익숙하다면 엔티티를 DOM 트리의 요소처럼, 컴포넌트를 이러한 각 요소의 속성처럼 생각하면 이해하기 쉬울 것입니다.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-8b6c8cd679f648a41400eb6f29889cd09ede8947%2Fecs-nested-entities-new%20\(1\).png?alt=media)

엔티티는 추상적인 개념입니다. 엔티티는 단지 ID일 뿐이며, 서로 다른 컴포넌트를 그룹화하기 위한 참조로 사용됩니다.

참고 [엔티티와 컴포넌트](/creator/content-creator-ko/sdk7/architecture/entities-components.md) 이 두 개념과 Decentraland 씬에서 어떻게 사용되는지 자세히 살펴보려면

### 사용자 지정 컴포넌트

기본 컴포넌트 집합(예: `Transform`, `GltfContainer`, `재질`, 등)은 엔진에 의해 해석되며, 엔티티가 어떻게 보이는지, 위치가 어디인지, 소리를 내는지 등에 직접적인 영향을 미칩니다.

또한 다음을 정의할 수 있습니다 *사용자 정의 컴포넌트* 씬의 메커니즘에 유용할 수 있는 데이터를 저장하기 위해서입니다. 엔진은 이러한 컴포넌트의 값이 무엇을 의미하는지 해석하지 못하며, 씬이 렌더링되는 방식에 직접적인 결과를 주지 않습니다. 하지만 씬 코드에 이 값들을 감시하고 반응하는 로직을 작성할 수 있습니다. 예를 들어 문의 열림/닫힘 상태를 추적하는 커스텀 "doorState" 컴포넌트를 정의할 수 있습니다. 이 경우 해당 컴포넌트는 그 상태를 추적하는 값을 저장하는 장소일 뿐입니다. 씬에서 문이 열리고 닫히는 것을 보려면, 이 값들을 사용해 문의 회전에 영향을 주는 로직을 별도로 구현해야 하며, 이는 엔진이 해석할 수 있는 `Transform` 컴포넌트의 값입니다.

참고 [사용자 정의 컴포넌트](/creator/content-creator-ko/sdk7/architecture/custom-components.md) 자세한 정보는

### 이름으로 엔티티 가져오기

Creator Hub의 Scene Editor에서 드래그 앤 드롭으로 추가한 엔티티에도 코드로 접근하여 더 편집하고 동작을 추가할 수 있습니다.

사용: `engine.getEntityOrNullByName()` 엔티티를 가져오려면, Scene Editor UI에서 엔티티에 할당된 이름을 전달하는

```ts
function main() {
	const door = engine.getEntityOrNullByName('door3')
}
```

함수를 사용하세요. 각 엔티티에는 고유한 이름이 있어야 합니다.

참고 [이름으로 엔티티 가져오기](/creator/content-creator-ko/sdk7/architecture/entities-components.md#get-an-entity-by-name) 자세한 정보는

엔티티가 [스마트 아이템](/creator/content-creator-ko/scene-editor/interactivity/smart-items.md)라면, 또한 해당 엔티티의 **동작** 를 호출하거나 그 **트리거** 에 코드로 구독할 수도 있습니다. 다음을 참조하세요 [참조 항목](/creator/content-creator-ko/scene-editor/extend-with-code/reference-items.md).

## 시스템

엔티티와 컴포넌트는 씬의 오브젝트에 대한 정보를 저장하는 장소입니다. *시스템* 컴포넌트에 저장된 정보를 시간에 따라 변경하는 함수를 담고 있습니다.

시스템은 게임 로직을 구현하는 곳으로, 게임 루프의 각 틱마다 주기적으로 업데이트되거나 확인되어야 하는 작업을 수행합니다.

시스템은 게임 루프의 [*업데이트 패턴*](http://gameprogrammingpatterns.com/update-method.html).

```ts
// 기본 시스템
function mySystem() {
	console.log('내 시스템이 실행 중입니다')
}

engine.addSystem(mySystem)

// dt가 있는 시스템
function mySystemDT(dt: number) {
	console.log('이전 프레임 이후 경과 시간:  ', dt)
}

engine.addSystem(mySystemDT)
```

하나의 씬에는 동시에 0개 또는 많은 시스템이 실행될 수 있습니다. 시스템은 씬이 지속되는 동안 서로 다른 시점에 켜거나 끌 수 있습니다. 일반적으로 독립적인 동작은 서로 다른 시스템에 분리해 두는 것이 좋습니다.

참고 [시스템](/creator/content-creator-ko/sdk7/architecture/systems.md) 씬에서 시스템이 어떻게 사용되는지 더 자세한 내용은

### 게임 루프

그 [게임 루프](http://gameprogrammingpatterns.com/game-loop.html) 는 Decentraland 씬 코드의 핵심입니다. 일정한 간격으로 코드의 일부를 순환 실행하며 다음을 수행합니다:

* 플레이어 입력 감지
* 씬 업데이트
* 씬 다시 렌더링

대부분의 전통적인 소프트웨어 프로그램에서는 모든 이벤트가 플레이어의 행동에 의해 직접 트리거됩니다. 플레이어가 버튼을 클릭하거나 메뉴를 열기 전까지는 프로그램 상태의 어떤 것도 변하지 않습니다.

하지만 상호작용형 환경과 게임은 다릅니다. 씬의 모든 변화가 반드시 플레이어의 행동으로 인해 발생하는 것은 아닙니다. 씬에는 스스로 움직이는 애니메이션 오브젝트나 자신만의 AI를 가진 NPC가 있을 수도 있습니다. 일부 플레이어 행동은 완료되는 데 여러 틱이 걸릴 수도 있습니다. 예를 들어 문이 열리는 데 전체 1초가 필요하다면, 문이 움직이는 동안 문의 회전은 약 30번에 걸쳐 점진적으로 업데이트되어야 합니다.

루프의 각 반복을 *틱*. Decentraland 씬은 가능한 경우 초당 30틱으로 렌더링됩니다. 기기가 각 틱을 렌더링하는 데 어려움을 겪는다면 업데이트 빈도가 낮아질 수 있습니다.

각 틱마다 씬이 업데이트된 뒤, 업데이트된 값을 기반으로 다시 렌더링됩니다.

Decentraland 씬에는 명시적으로 선언된 게임 루프가 있는 것이 아니라, 오히려 [시스템](/creator/content-creator-ko/sdk7/architecture/systems.md) 씬의

컴파일과 렌더링은 백엔드에서 수행되므로, 씬을 개발하는 동안 직접 처리할 필요가 없습니다.

## 컴포넌트 조회

할 수 있습니다 [컴포넌트를 조회](/creator/content-creator-ko/sdk7/architecture/querying-components.md) 메서드를 사용하여 `engine.getEntitiesWith(...components)` 특정 컴포넌트를 가진 씬의 모든 엔티티를 추적할 수 있습니다.

컴포넌트는 다음 안에서 조회하는 것이 종종 합리적입니다: [시스템](/creator/content-creator-ko/sdk7/architecture/systems.md)그런 다음 반환된 각 엔티티를 순회하면서 각 엔티티에 같은 작업 집합을 수행합니다.

게임 루프의 매 틱마다 씬의 모든 엔티티를 반복하려고 하면 성능 비용이 상당할 수 있습니다. 조회로 반환된 엔티티만 참조하면, 관련 있는 엔티티만 다루고 있음을 보장할 수 있습니다.

```ts
// 시스템 정의
function boxHeightSystem(dt: number) {
	// MeshRenderer와 Transform 컴포넌트를 모두 포함하는 엔티티를 조회
	for (const [entity] of engine.getEntitiesWith(MeshRenderer, Transform)) {
		const transform = Transform.get(entity)
		console.log('상자의 높이:  ', transform.position.y)
	}
}

// 시스템을 엔진에 추가
engine.addSystem(boxHeightSystem)
```

## 씬 라이프사이클

느슨한 코드 줄을 바로 `index.ts`, 작성하기 시작하면 코드에 중요한 맥락이 부족할 수 있습니다. 예를 들어 플레이어 엔티티에 대한 정보나 Creator Hub에서 드래그 앤 드롭으로 추가된 엔티티에 대한 정보가 빠질 수 있습니다. 코드 줄이 읽히는 시점에는 그런 것들이 아직 로드되지 않았기 때문입니다.

그런 상황을 피하려면, 씬의 초기 로딩 코드는 항상 `함수 내부,` 함수를 사용해 작성하는 것이 권장됩니다( `index.ts` 파일에서) 엔트리포인트로 사용하세요. 이 함수는 씬의 초기 맥락이 모두 로드된 후에만 실행되며, 여기에는 Scene Editor UI를 통해 추가된 모든 항목이 포함됩니다.

다음 경우에는 코드를 `함수 내부,` 함수 밖에 작성할 수 있습니다:

* 코드가 간접적으로 `함수 내부,`
* 코드가 시스템을 정의하거나 엔진에 시스템을 추가하는 경우
* 코드가 다음 안에 있는 경우 [비동기 함수](/creator/content-creator-ko/sdk7/programming-patterns/async-functions.md)

{% hint style="warning" %}
**📔 참고**: async 함수나 시스템 내부의 코드가 처음 실행될 때쯤이면, 씬의 모든 것이 이미 올바르게 초기화되어 있습니다.

[커스텀 컴포넌트](/creator/content-creator-ko/sdk7/architecture/custom-components.md) 정의는 예외이며, 항상 `함수 내부,` 함수 밖의 별도 파일에 작성해야 합니다. 다른 모든 것보다 먼저 해석되어야 `함수 내부,` 실행됩니다.
{% endhint %}

## 가변성

컴포넌트의 가변 버전 또는 불변(읽기 전용) 버전을 선택해 다룰 수 있습니다.  `.get()` 컴포넌트의 함수는 컴포넌트의 불변 버전을 반환합니다. 값은 읽을 수 있지만, 그 속성은 변경할 수 없습니다.

그 `.getMutable()` 함수는 해당 컴포넌트의 값을 변경할 수 있는 표현을 반환합니다. 컴포넌트를 변경할 계획이 있을 때만 가변 버전을 사용하세요. 컴포넌트의 불변 버전을 다루면 성능이 크게 향상됩니다.

```ts
// 불변 버전 가져오기(읽기 전용)
const immutableTransform = Transform.get(myEntity)

// 다음은 작동하지 않습니다:
// 	immutableTransform.position.y = 2

const mutableTransform = Transform.getMutable(myEntity)

// 다음은 엔티티의 위치를 실제로 변경합니다
mutableTransform.position.y = 2
```

참고 [변경 가능한 데이터](/creator/content-creator-ko/sdk7/programming-patterns/mutable-data.md) 자세한 내용은 다음을 참조하세요.

## 모든 것을 종합하면

그 *엔진* 은 다음 사이에 위치하는 것입니다 *엔티티*, 그리고 *컴포넌트* 한편에는 *시스템* 다른 한편에는

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-de62a18d51b28bebd55c86e8ef5a8a783467ae62%2Fecs-big-picture%20\(1\).png?alt=media)

씬의 컴포넌트에 저장된 모든 값은 해당 시점의 씬 상태를 나타냅니다. 게임 루프의 매 틱마다 엔진은 각 시스템의 함수를 실행해 컴포넌트에 저장된 값을 업데이트합니다.

모든 시스템이 실행된 뒤에는 각 엔티티의 컴포넌트가 새로운 값을 갖게 됩니다. 엔진이 씬을 렌더링할 때 이러한 새로 업데이트된 값을 사용하며, 플레이어는 엔티티가 새로운 상태에 맞게 변하는 것을 보게 됩니다.

```ts
export function main() {
	// 엔티티 생성
	const cube = engine.addEntity()

	// transform 컴포넌트를 통해 엔티티에 위치 부여
	Transform.create(cube, {
		position: Vector3.create(5, 1, 5),
	})

	// MeshRenderer 컴포넌트를 통해 엔티티에 보이는 형태를 부여
	MeshRenderer.setBox(cube)
}

// 시스템 정의
function rotationSystem(dt: number) {
	// MeshRenderer와 Transform 컴포넌트를 모두 포함하는 엔티티를 조회
	for (const [entity] of engine.getEntitiesWith(MeshRenderer, Transform)) {
		const transform = Transform.getMutable(entity)
		transform.rotation = Quaternion.multiply(
			transform.rotation,
			Quaternion.fromAngleAxis(dt * 10, Vector3.Up())
		)
	}
}

// 시스템을 엔진에 추가
engine.addSystem(rotationSystem)
```

위 예제에서는 `큐브` 엔티티와 `rotationSystem` 시스템이 엔진에 추가됩니다.  `큐브` 엔티티에는 `Transform`, 그리고 `MeshRenderer` 컴포넌트가 있습니다. 게임 루프의 매 틱마다 `rotationSystem` 시스템이 호출되며 `Transform` 의 컴포넌트에서 회전 값을 변경합니다. `큐브` 엔티티를 사용해 플레이어 카메라 위치에서 앞으로 레이를 추적합니다.

위 코드 대부분은 씬을 로드할 때 한 번만 실행된다는 점에 유의하세요. 예외는 `rotationSystem` 시스템으로, 게임 루프의 매 틱마다 호출됩니다.

## 씬 분리

여러분의 씬은 엔진(즉, 메인 스레드)과 같은 컨텍스트에서 실행되지 않습니다. 우리는 SDK를 렌더링 엔진과 완전히 분리된 방식으로 만들었습니다. 안전성과 성능상의 이유 모두를 고려해 그렇게 설계했습니다.

이러한 분리 때문에 씬 코드에서는 DOM이나 `window` 객체에 접근할 수 없으므로, 플레이어의 브라우저나 지리적 위치 같은 데이터에 접근할 수 없습니다.

분리는 RPC 프로토콜을 사용하여 이루어집니다. 이 프로토콜은 클라이언트의 작은 부분을 씬 렌더링과 이벤트 제어에만 할당합니다.

우리는 통신 프로토콜도 추상화했습니다. 이를 통해 씬을 WebWorker에서 로컬로 실행할 수 있습니다.

우리는 개발자들이 엔진 내부에 개입하거나, 심지어 엔진 안에 무엇이 있는지 알 필요조차 없기를 바랍니다. Decentraland 맵 전반에서 플레이어에게 일관된 경험을 보장해야 하며, 그런 '낮은' 수준에서는 실수가 더 쉽게 발생합니다.

이 분리는 이웃 씬이 플레이어가 다른 사람의 씬에 있는 동안 플레이어의 경험을 방해하는 것을 막는 데도 중요합니다. 플레이어는 여러 개의 인접한 씬을 동시에 로드해 둘 수 있으며, 각 씬은 자체 코드를 실행합니다. 일부 동작(예: 외부 링크 열기 또는 플레이어 이동)은 플레이어가 해당 특정 씬 위에 서 있을 때만 허용되며, 씬이 로드되어 있더라도 플레이어가 바깥에 있다면 허용되지 않습니다.

## 트리 셰이킹

TypeScript 소스 코드를 축소된 JavaScript 컴파일 코드로 변환할 때, 이 과정은 [트리 셰이킹](https://en.wikipedia.org/wiki/Tree_shaking) 을 수행하여 실제로 사용되는 코드 부분만 변환되도록 합니다. 이는 씬의 최종 코드를 최대한 가볍게 유지하는 데 도움이 됩니다. 특히 외부 라이브러리를 사용할 때 유용한데, 이런 라이브러리에는 사용되지 않는 기능이 많이 포함되어 있어 그렇지 않으면 씬이 불필요하게 커질 수 있기 때문입니다.

트리 셰이킹의 결과로, 씬에서 실행되길 원하는 코드는 모두 코드의 엔트리 포인트들에 어떤 식으로든 참조되어야 합니다: 그 `함수 내부,` 함수 on `index.ts`. 시스템은 또한 다음의 `index.ts` 파일에, 참조하지 않고도 엔진에 추가할 수 있습니다 `함수 내부,`. 이러한 파일에서 명시적 또는 간접적으로 참조되지 않은 코드는 씬에 포함되지 않습니다.

예를 들어 `extraContent.ts` 라는 이름의 파일이 있고 다음과 같은 내용이 있다면, 엔티티는 렌더링되지 않고 시스템도 실행을 시작하지 않습니다:

```ts
// extraContent.ts

const myEntity = engine.addEntity()
Transform.create(myEntity, {
	position: { x: 8, y: 0, z: 8 },
})
MeshRenderer.setBox(myEntity)

function mySystem(dt: number) {
	console.log('시스템 실행 중')
}

engine.addSystem(mySystem)
```

씬의 일부로 실행되게 하려면, 다음에서 참조할 수 있습니다 `index.ts` 다음과 같은 방식으로:

```ts
// extraContent.ts에서

export function addEntities() {
	const myEntity = engine.addEntity()
	Transform.create(myEntity, {
		position: { x: 8, y: 0, z: 8 },
	})
	MeshRenderer.setBox(myEntity)
}

export function mySystem(dt: number) {
	console.log('시스템 실행 중')
}

/////////////////////////////

// index.ts에서

import { addEntities, mySystem } from './extraContent'

export function main() {
	addEntities()
}

engine.addSystem(mySystem)
```

이 규칙의 예외는 커스텀 컴포넌트 정의입니다. 이것들은 다음을 통해 접근해서는 안 됩니다 `함수 내부,` 함수 엔트리포인트는 다른 무엇보다 먼저 해석되어야 하기 때문입니다.

## 가져오기

씬에서 사용되는 모든 함수, 객체, 컴포넌트 및 기타 요소는 사용하려는 각 파일에 import되어야 합니다. 이는 [트리 셰이킹](#tree-shaking)의 결과로, 전체 SDK를 패키징하는 대신 씬에서 사용하는 부분만 포함하기 때문입니다.

문서 전반의 스니펫은 깔끔하게 보이도록 각 파일 시작 부분의 import 줄을 생략하지만, 작동시키려면 씬에 직접 추가해야 합니다.

씬을 작성할 때 VS Studio Code를 사용하면, 스마트 자동 완성 옵션이 작성 중 import 처리를 알아서 해주므로 이를 따로 신경 쓸 필요가 없습니다.

하지만 스니펫을 씬에 붙여넣으면, 그 파일로 import되지 않은 일부 요소가 빨간색으로 표시되는 것을 볼 수 있습니다. 이를 수정하려면:

* 밑줄이 그어진 각 단어를 클릭하세요
* 해당 줄 왼쪽의 전구 아이콘을 클릭하세요
* 선택 **Import From 추가**
* 파일 시작 부분에 import 줄이 나타납니다.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-7a9b5a49dd3ff062e5609e6205f2a41c55d9ea55%2Fimports.png?alt=media)

가져올 항목이 매우 많다면, 다음도 선택할 수 있습니다 **누락된 import 모두 추가** 를 같은 드롭다운에서

요소가 사용되는 모든 파일에 import를 추가해야 한다는 점에 유의하세요.

VS Studio Code는 자체적으로 import의 올바른 경로를 해결할 수 있어야 합니다. 어떤 이유로든 그 과정에 문제가 있다면, 다음 빈 import 문을 파일 시작 부분에 붙여넣는 것이 요령입니다. 그러면 VS Studio가 나머지를 처리할 수 있어야 합니다.

```ts
import {} from '@dcl/sdk/ecs'
import {} from '@dcl/sdk/math'
```

## SDK 버전

새 씬을 개발할 때는 기본적으로 `@latest` 안정 버전 SDK 릴리스를 사용합니다.

다음 `@next` SDK 릴리스를 설치하여 아직 최신 안정 릴리스에 포함되지 않은 예정 기능을 활용하거나 미리 볼 수 있습니다.

그러려면 씬의 `package.json` 파일을 열고 다음 줄을 변경하세요:

```json
  "devDependencies": {
    "@dcl/js-runtime": "next",
    "@dcl/sdk": "next"
  },
```

그다음 씬 프로젝트 폴더에서 다음 명령을 실행하세요:

```
npm i
```

참고 [의존성 관리](/creator/content-creator-ko/sdk7/libraries/manage-dependencies.md) 자세한 내용은 다음을 참조하세요.

{% hint style="warning" %}
**📔 참고**: @next 버전은 때때로 문제가 있을 수 있다는 점을 기억하세요. 새 기능의 구문과 이름은 안정 버전으로 출시되기 전에 변경될 수 있습니다.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
