# SDK Quick Start

El Decentraland SDK es una potente herramienta que te permite crear o mejorar tus Scenes escribiendo código en Typescript (Javascript + Types).

{% hint style="info" %}
**💡 Consejo**: Si prefieres crear tus Scenes solo con herramientas no-code, consulta [Scene Editor en Creator Hub](https://github.com/decentraland/docs/blob/main/creator/sdk7/get-started/about-editor.md).
{% endhint %}

{% hint style="info" %}
**💡 Consejo**: También puedes crear Scenes describiendo lo que quieres a un asistente de IA, sin escribir código a mano. Consulta [Vibe Coding con IA](/creator/content-creator-es/scenes-sdk7/primeros-pasos/vibe-coding.md).
{% endhint %}

Este tutorial te guía por la configuración inicial y te muestra los conceptos básicos para escribir código en una scene de Decentraland.

## Instala Creator Hub

Creator Hub te permite crear, previsualizar y desplegar scenes de Decentraland. Descarga Creator Hub [aquí](https://decentraland.org/download/creator-hub).

Para editar el código de tu scene, también debes instalar [Visual Studio Code](https://code.visualstudio.com/), si aún no lo tienes.

Lee [Guía de instalación](https://github.com/decentraland/docs/blob/main/creator/sdk7/get-started/editor-installation.md) para más detalles sobre cómo instalar Creator Hub.

## Crea tu primera scene

Para crear tu primera scene, sigue estos pasos.

1. Abre Creator Hub.
2. Selecciona la **Scenes** pestaña y haz clic en **Create Scene**.

   ![](/files/3b7f53546b510b9535c14d88abce0e59633bd13d)
3. Luego puedes elegir entre diferentes templates iniciales. Para este ejercicio, elige **Empty Scene**.

Este paso puede tardar un par de minutos. Rellena tu folder con el conjunto predeterminado de files para una scene básica.

Una vez que termine, verás la cuadrícula vacía de tu scene.

## Añade items de los asset packs

Explora **Asset packs** en la sección inferior del Scene Editor en Creator Hub, arrastra un par de items y ajusta sus posiciones. Para fines de este tutorial, cualquier item servirá por ahora.

![](/files/b1d095e2e84abbb3351804ebbf09a0a52c752ecb)

Para colocar un elemento, haz clic y arrástralo desde el menú del asset pack hasta una ubicación en tu escena en el canvas.

![](/files/d79bd37a9838e6830f270ccd0c87483f6d041534)

Los items ya colocados se pueden hacer click y arrastrar para reposicionarlos libremente. Consulta [lo esencial del Scene Editor](https://github.com/decentraland/docs/blob/main/creator/sdk7/get-started/scene-editor-essentials.md#position-items) para más detalles.

{% hint style="info" %}
**💡 Consejo**: Cubre toda la scene con un item de ground. Los items de tipo **Ground** tienen un icono de cubo de pintura. Si arrastras uno de estos a tu scene, cubrirá todo el Ground de tu scene con copias de este item.

<img src="https://github.com/decentraland/docs-creator/blob/main/images/editor/ground.png" alt="Ground" data-size="original">
{% endhint %}

## Ejecuta una preview

Haz click en el **Preview** botón en el menú superior para cargar tu scene dentro de Decentraland. Ahora puedes explorar la scene como un avatar de Decentraland.

![](/files/b828d6d79325003aa2961bc9689bcc586fa83f87)

Lee más sobre la preview de la scene en [previsualizar una scene](/creator/content-creator-es/scenes-sdk7/primeros-pasos/preview-scene.md).

{% hint style="info" %}
**💡 Consejo**: Puedes mantener abierta la ventana de preview mientras sigues trabajando en tu scene, y se actualizará cada vez que hagas un cambio en el Scene Editor.
{% endhint %}

## Activos 3D personalizados

Descarga este modelo 3D de un aguacate en formato *glb* desde el siguiente [enlace](https://github.com/decentraland-scenes/avocado/raw/main/avocado-glb.zip) y descomprímelo.

![](/files/5e4fc13139baedc869ecf073aefd55282fb4e2df)

1. Haz clic en el signo más en la esquina superior derecha de la sección Asset Packs de la UI de Scene Editor.
2. Arrastra el **avocado.glb** file al área de la UI de Scene Editor y haz clic en **Import**.

   ![](/files/cca2ad4874161fc1b0a6428c3cb470f27575643b)

Ahora puedes encontrar el **avocado.glb** modelo en la **Local Assets** pestaña, dentro del **Scene** folder. Arrástralo a tu scene, como harías con cualquier item de Asset Packs.

![](/files/463b73bdc6b450fa9710bfd9afc39f832d094cea)

## Edita el código de la scene

Las siguientes secciones describen cómo puedes editar el código de tu scene, dándote mucha más libertad como creador.

Haz click en el **<> Code** botón en el menú superior para abrir el proyecto de tu scene en Visual Studio Code.

![](/files/c98aeaf7cb690147dbbe58baf141fb7c301a18ca)

{% hint style="warning" %}
**📔 Nota**: Instala [Visual Studio Code](https://code.visualstudio.com/), si aún no lo tienes.
{% endhint %}

Esto abre una ventana separada con Visual Studio Code. En el margen izquierdo puedes navegar por los files y la estructura de folders de tu proyecto.

![](/files/a1d5c8e192945316439c93a40a723b063a53b09e)

Abre la pestaña `index.ts` file desde dentro del `src` folder de tu scene. Su contenido debería verse así:

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

export function main() {}
```

Las dos primeras líneas tratan con declaraciones de `import` . Estas obtienen referencias a cosas que están definidas en otros files, para que puedan usarse en este file. No necesitarás tratar directamente con estas líneas en este tutorial, pero ten en cuenta que la lista de cosas que se obtienen crecerá a medida que escribas tu código.

Observa que este file define una function llamada `main()`. Esta function es el punto de entrada de la scene; cualquier código que pongas allí se ejecutará cuando la scene se cargue por primera vez. Si escribes líneas de código fuera de esta function, nunca se ejecutarán.

En la sección anterior mostramos cómo puedes arrastrar fácilmente el modelo 3D personalizado de aguacate a tu scene de una forma no-code. Ahora añadiremos un segundo aguacate, para ver cómo lograr lo mismo escribiendo código.

Reemplaza el contenido completo de tu `index.ts` file con lo siguiente. Estas líneas amplían la `main()` function y añaden un par de imports:

```ts
import { Vector3 } from '@dcl/sdk/math'
import { engine, Transform, GltfContainer } from '@dcl/sdk/ecs'

export function main() {
	// crear un Entity nuevo desde cero
	let avocado2 = engine.addEntity()

	// darle un Transform
	Transform.create(avocado2, {
		position: Vector3.create(8, 0, 8),
	})

	// darle un GLTF
	GltfContainer.create(avocado2, {
		src: 'assets/scene/avocado.glb',
	})
}
```

Si abres de nuevo la preview de la scene, ahora deberías ver dos aguacates: el que añadiste en el Scene Editor y el que añadiste mediante código.

![](/files/2813263f879bdc504440d48e5c2a091d4e6066d3)

Las líneas que acabas de añadir crean un nuevo [entity](/creator/content-creator-es/scenes-sdk7/arquitectura/entities-components.md)Entity [shape](/creator/content-creator-es/scenes-sdk7/esenciales-de-contenido-3d/shape-components.md) basado en el modelo 3D que descargaste, y [establecen su posición y escala](/creator/content-creator-es/scenes-sdk7/esenciales-de-contenido-3d/entity-positioning.md) a través del **Transform**.

Ahora vuelve al Scene Editor y selecciona el primer aguacate que añadiste. En el panel de properties de este item verás que la UI para los components Transform y GLTF muestra la misma información que en el código que acabas de escribir.

![](/files/50ecd79fd9ada4b8e94906f4a58015d6a08797bd)

## Añade interactividad

Para que tu scene sea más atractiva, hagamos que las entities de la scene respondan a las interacciones del player.

Al final de la `main()` function (antes de que la cierre el último **}**), añade un manejador de pointer events a la entity del aguacate. Esto ejecuta una function personalizada cada vez que el player hace click en el aguacate.

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: avocado2,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Collect' },
	},
	function () {
		console.log('CLICKED AVOCADO')
	}
)
```

{% hint style="info" %}
**💡 Consejo**: Visual Studio Code te ayuda marcando errores de sintaxis, autocompletando mientras escribes e incluso mostrando sugerencias inteligentes que dependen del contexto. También puedes hacer clic en un object para ver la definición completa de su class.

Si alguna de las words que pegaste está subrayada en rojo, pasa el cursor sobre ellas para ver si VS Studio ofrece una solución fácil. Probablemente tendrás que hacer esto para **pointerEventsSystem**, y **InputAction**.

Al hacer clic en la bombilla se sugerirá `Update import from @dcl/sdk/ecs`. Selecciona esta opción para añadir imports al inicio de tu `index.ts` archivo.
{% endhint %}

El `pointerEventsSystem.onPointerDown()` statement define tres cosas:

* Qué `entity` funciona sobre qué entity los pointer events.
* Un `opts` object con parámetros adicionales opcionales. En este caso incluimos qué botón usar y qué texto de hint mostrar.
* Una function que se ejecutará cada vez que se haga click en la entity.

En este caso, la function que estamos ejecutando es muy simple. Solo tiene una línea y simplemente imprime un texto en la consola.

```ts
console.log('CLICKED AVOCADO')
```

En el `opts` section, estamos configurando el `button` field para que escuche el pointer button (el botón izquierdo del mouse en un PC). También estamos configurando el `hoverText` parameter para mostrar texto personalizado. De ese modo, los players leerán el texto "collect" cuando pasen el cursor sobre el aguacate, y sabrán qué ocurrirá si hacen click en él. El aguacate aún no hace mucho, pero llegaremos a eso en los siguientes pasos.

Para ver ese mensaje que registra el event de click, tendrás que abrir la consola. Para hacerlo, abre de nuevo la preview de la scene si aún no la tienes en ejecución, y presiona la **\`** key para alternar la visualización de la consola. Ahora, cada vez que hagas click en el aguacate que añadiste mediante código, verás:

![](/files/c25f939bd2b0d28ba90feb9f248f49b1a4850b13)

{% hint style="warning" %}
\*\*📔 Note\*\*: Para que una entity sea clickable, debe tener una geometría collider. El modelo usado aquí ya incluye una. Consulta la sección \[Colliders]\(../3d-modeling/colliders.md) para ver alternativas para modelos que no incluyen una geometría collider.
{% endhint %}

Ahora hagamos que esa function de click haga algo más interesante: hagamos que el aguacate desaparezca. Usa \`

engine.removeEntity()\` para eliminar el aguacate una vez que se haga click sobre él. Añadamos una línea extra a nuestro snippet:

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: avocado2,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Collect' },
	},
	function () {
		console.log('CLICKED AVOCADO')
		engine.removeEntity(avocado2)
	}
)
```

Ahora, al hacer click, el aguacate desaparece de tu scene.

## Tweens

Los Tweens describen una transición gradual de una posición/rotación/escala a otra, durante un período de tiempo.

Empecemos añadiendo un tween de escala a nuestro aguacate, solo para probar la feature. Añade las siguientes líneas dentro de la `main()` function, al final, sin cambiar nada de lo que ya añadiste:

```ts
export function main() {
	// Código de snippets anteriores (no cambiar)
	// (...)

	// Código nuevo:
	Tween.setMove(avocado2, 
		Vector3.create(3, 0, 3), 
		Vector3.create(8, 0, 8), 
		5000
	)

}
```

{% hint style="info" %}
**💡 Consejo**: Al pegar esto, puede que encuentres más words subrayadas en rojo por imports que faltan.

Pasa el cursor sobre cada una y haz clic en la bombilla; te sugerirá `Update import from @dcl/sdk/ecs`. Selecciona esta opción para añadir imports al inicio de tu `index.ts` archivo.
{% endhint %}

El `Tween` component que creamos tiene argumentos que hacen que cambie de posición, desde una posición en las coordinates *3,0,3* de la scene, hasta las coordinates *8,0,8*, durante un período de 5000 milisegundos (5 segundos). Este movimiento comenzará en cuanto empiece la scene.

A `Tween` La function setMove requiere la siguiente información:

* `entity`: Qué entity usar
* `start`: Posición inicial.
* `end`: Posición final.
* `duration`: Duración (en milisegundos) de la escala de inicio a fin.

También está disponible este otro parámetro opcional:

* `easingFunction`: Qué tipo de curva usar para controlar la tasa de cambio a lo largo del tiempo. En este caso usamos linear, que da como resultado un cambio suave y constante.

Podemos experimentar con el parámetro `easingFunction` : para obtener efectos interesantes. Por ejemplo, en su lugar podemos usar `EF_EASEINBOUNCE` para realizar la transición usando una interpolación ease-in bounce, que comienza con un efecto rebotante y luego pasa de lento a rápido.

{% hint style="info" %}
**💡 Consejo**: También puedes usar el **Tween** component para escalar o rotar una entity durante un período de tiempo, ¡es una herramienta realmente útil! Aprende más [aquí](/creator/content-creator-es/scenes-sdk7/esenciales-de-contenido-3d/move-entities.md)
{% endhint %}

## Usa tus propias functions

En esta sección añadiremos otro tween a la escala del Aguacate para que el efecto de desaparición se vea más atractivo. Pero tomaremos un enfoque un poco menos directo para introducir algunos otros conceptos.

La forma más simple de hacer que nuestro aguacate se encoja cuando hacemos click en él es añadir un tween dentro de la function de pointer events, en lugar de la línea `engine.removeEntity(avocado2)`. Pero, en su lugar, vamos a crear este tween en una function separada que luego podamos reutilizar para otros items. ¡Así no tendremos que escribir el mismo código dos veces! Nuestra nueva function será independiente de `main()`, así que no hará nada por sí sola, pero pronto la llamaremos.

```ts
function collect(myEntity: Entity) {

	Tween.setScale(myEntity, 
		Vector3.One(), 
		Vector3.Zero(), 
		500,
		EasingFunction.EF_EASEINBOUNCE
	)
}
```

Observa que el tween se añade a una entity llamada `myEntity`, en lugar de `avocado2`. `myEntity` es realmente un placeholder; no existe ninguna entity con ese nombre en la scene. Proviene de un parámetro definido en la function. Cuando llamas a la `collect()` function, puedes pasar cualquier entity de la scene, y se le aplicará un `Tween` . Más sobre eso más adelante.

{% hint style="info" %}
**💡 Consejo**: Siempre que haya código que puedas usar varias veces en tu scene, es buena práctica ponerlo dentro de una function. Así solo tienes que escribirlo una vez y es más fácil de mantener.
{% endhint %}

Aquí creamos un Tween que afecta al *Escala*, así que ahora `start` y `end` se refiere al tamaño del aguacate, no a la posición. Pasa de un tamaño de uno a cero, durante una duración de 500 milisegundos (medio segundo), y usa una function de easing `EASEINBOUNCE` , que le da un divertido efecto rebotante.

Ahora modifiquemos la function que escribimos para cuando hacemos click en el aguacate. Cambiemos la línea que dice `engine.removeEntity(avocado)`, y en su lugar llamemos a la `collect()` function que acabamos de definir, pasando una referencia a nuestra entity del aguacate:

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: avocado2,
		opts: { button: InputAction.IA_POINTER, hoverText: 'Collect' },
	},
	function () {
		console.log('CLICKED AVOCADO')

		collect(avocado2)
	}
)
```

Si ahora abres la preview de la scene y haces click en el aguacate, deberías verlo desaparecer con estilo, realizando un divertido movimiento saltarín.

{% hint style="warning" %}
**📔 Nota**: Puede que ya hayas deducido que ahora el aguacate se encoge hasta un tamaño de 0, pero sigue existiendo. No cubriremos esto en este primer tutorial, pero en un escenario ideal deberías asegurarte de eliminar la entity después de que el tween termine, para optimizar el rendimiento de tu scene. Consulta [Al finalizar el tween](/creator/content-creator-es/scenes-sdk7/esenciales-de-contenido-3d/move-entities.md#on-tween-finished).
{% endhint %}

## Referencia un item del Scene Editor

Tu código también puede hacer cosas con los items que añadiste visualmente en el Scene Editor en Creator Hub. Puedes obtener estos items por nombre en tu código, usando la function `engine.getEntityOrNullByName()`. Usa el nombre del item que ves escrito en el [entity tree](https://github.com/decentraland/docs/blob/main/creator/sdk7/get-started/scene-editor-essentials.md#the-entity-tree).

En este ejemplo, tenemos una entity llamada **Yellow Crate**. Puedes usar cualquier item que quieras, solo asegúrate de escribir su nombre exactamente como aparece en el entity tree.

{% hint style="info" %}
**💡 Consejo**: Puedes renombrar entities haciendo clic derecho y seleccionando **Rename** sobre la entity en el entity tree.
{% endhint %}

![](/files/b1d095e2e84abbb3351804ebbf09a0a52c752ecb)

```ts
export function main() {
	// Aguacate stuff

	const crate = engine.getEntityOrNullByName('Yellow Crate')

	if (crate) {
		console.log('The crate exists')
	}
}
```

En el snippet anterior, usamos `engine.getEntityOrNullByName()` para obtener una referencia a una entity llamada *Yellow Crate*. En la siguiente línea, hacemos `if (crate)` para asegurarnos de que realmente exista una entity con este nombre en la scene. Si no la hay, entonces el valor de `crate` será `null`. Ver [Reference Items](https://github.com/decentraland/docs/blob/main/creator/sdk7/code/reference-items.md) para más información.

{% hint style="info" %}
**💡 Consejo**: Todas las entities añadidas mediante el Scene Editor ya se habrán cargado en tu scene cuando se llame al código en la function `main()` . Debería ser seguro referenciarlas en esta function, o en otras functions llamadas indirectamente por ella.
{% endhint %}

Ahora añadamos un comportamiento de pointer a nuestra entity Yellow Crate, igual que hicimos con el aguacate.

```ts
export function main() {
	// Aguacate stuff

	const crate = engine.getEntityOrNullByName('Yellow Crate')

	if (crate) {
		console.log('The crate exists')

		pointerEventsSystem.onPointerDown(
			{
				entity: crate,
				opts: { button: InputAction.IA_POINTER, hoverText: 'Collect' },
			},
			function () {
				console.log('CLICKED CRATE')
				collect(crate)
			}
		)
	}
}
```

Observa cómo estamos llamando a la `collect()` function que definimos antes. Como la function se define por separado, ¡solo necesitamos escribir esa única línea para llamarla!

{% hint style="info" %}
**💡 Consejo**: También puedes obtener [Smart Items](https://github.com/decentraland/docs/blob/main/creator/sdk7/interactivity-1/smart-items.md) de tu scene del mismo modo, y hacer lo que quieras con ellas mediante código. Consulta [Reference Items](https://github.com/decentraland/docs/blob/main/creator/sdk7/code/reference-items.md) para más información.
{% endhint %}

## Más tutoriales

Lee [coding-scenes](https://github.com/decentraland/docs-creator/blob/main/sdk7/getting-started/coding-scenes.md) para una comprensión general de cómo funcionan las scenes de Decentraland.

Para ejemplos creados con SDK7, consulta la [Página de ejemplos](https://studios.decentraland.org/resources?sdk_version=SDK7) que contiene varias scenes pequeñas, todas escritas con SDK7.

Consulta la **Guía de desarrollo** sección para obtener más instrucciones sobre cómo añadir contenido a tu scene.

## Interactúa con otros developers

Visita [El Discord de Decentraland](https://dcl.gg/discord) como la [Discord de la DAO de Decentraland](https://discord.gg/bxHtcMxUs4), para unirte a una animada discusión sobre lo que es posible y cómo hacerlo.

Para depurar cualquier issue, te recomendamos que consultes las [Solución de problemas](/creator/content-creator-es/scenes-sdk7/depuracion/troubleshooting.md) y [debug](/creator/content-creator-es/scenes-sdk7/depuracion/debug-in-preview.md) secciones en la documentación. Si no encuentras una solución allí, puedes publicar issues en la [categoría SDK Support](https://forum.decentraland.org/c/support-sdk/11) Foro de Decentraland.

También puedes publicar en [Stack Overflow](https://stackoverflow.com/questions/ask?tags=+\[decentraland-ecs]), usando las tags `decentraland` o `decentraland-ecs`.

También puedes pedir ayuda en el [Discord de Decentralnad](https://dcl.gg/discord). En la **Support** section, el **#sdk** channel es para preguntas sobre código, el **#builder-and-3d** channel es para preguntas sobre modelos 3D y arte. **#code-contribution** es para discutir PRs sobre el codebase del SDK.

En el [Discord de la DAO de Decentraland](https://discord.gg/bxHtcMxUs4) también puedes obtener ayuda en el **sdk-support** channel.

## Activos de arte 3D

Una buena experiencia tendrá un gran arte 3D que la acompañe. Si te interesa crear esos modelos 3D tú mismo, te animamos a hacerlo; consulta la [sección de Modelado 3D](/creator/content-creator-es/modelado-3d-y-animaciones/3d-models.md) para más información. Pero si prefieres centrarte en la parte de código o diseño de juego, ¡no necesitas crear tus propios assets!

Aquí tienes algunas fuentes para conseguir excelentes modelos 3D que puedes usar en una scene de Decentraland:

* [IWB Catalog](https://dcl-iwb.co/)
* [Asset Ovi](https://assetovi.com/)
* [SketchFab](https://sketchfab.com/)
* [Clara.io](https://clara.io/)
* [Archive3D](https://archive3d.net/)
* [SketchUp 3D Warehouse](https://3dwarehouse.sketchup.com/)
* [Thingiverse](https://www.thingiverse.com/)
* [ShareCG](https://www.sharecg.com/)
* [CGTrader](https://cgtrader.com)

También puedes usar herramientas de Generative AI para generar tus propios modelos 3D. Echa un vistazo a:

* [Meshy](https://www.meshy.ai/)
* [Luma AI](https://lumalabs.ai/genie)
* [TRipo3D](https://www.tripo3d.ai/app)
* [Rodin](https://hyper3d.ai/rodin)

{% hint style="warning" %}
**📔 Nota**: Los models deben estar en los formatos compatibles `.gltf` o `.glb` y deben tener un número de triangles, textures y materials que se ajuste a las [limitaciones de la scene](/creator/content-creator-es/scenes-sdk7/optimizacion/scene-limitations.md). Si obtienes models de un sitio de terceros, presta atención a las restricciones de licencia que tenga el contenido que descargas.
{% endhint %}

## Publica tu scene

Si eres propietario de LAND, de un Decentraland NAME o de un nombre ENS de ETH, o tienes permisos otorgados por alguien que lo sea, puedes subir tu scene a Decentraland. Consulta [publishing](/creator/content-creator-es/scenes-sdk7/publicacion/publishing.md).

## Otra información útil

* [Libraries](https://studios.decentraland.org/resources?sdk_version=SDK7\&resource_type=Library)
* [Restricciones de diseño para games](/creator/content-creator-es/scenes-sdk7/disenar-la-experiencia/design-games.md)
* [3D modeling](/creator/content-creator-es/modelado-3d-y-animaciones/3d-models.md)
* [Scene limitations](/creator/content-creator-es/scenes-sdk7/optimizacion/scene-limitations.md)


---

# Agent Instructions: 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:

```
GET https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/primeros-pasos/sdk-101.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
