> 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-es/escenas-sdk7/primeros-pasos/sdk-101.md).

# Inicio rápido de SDK

El SDK de Decentraland es una poderosa herramienta que te permite crear o mejorar tus escenas escribiendo código en TypeScript (JavaScript + tipos).

Este tutorial te guía para crear tu primera escena, combinando las diferentes herramientas que tienes disponibles: el Scene Editor visual de Creator Hub, código escrito a mano y asistencia de IA **vibe coding**. Usarás las tres juntas y aprenderás cuándo destaca cada una.

## Instala Creator Hub

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

Para editar el código de tu escena, también necesitas un editor de código. [Visual Studio Code](https://code.visualstudio.com/) y [Cursor](https://www.cursor.com/) son ambas buenas opciones, pero cualquier editor de código funciona.

Lee la [guía de instalación](/creator/content-creator-es/scene-editor/empezar/editor-installation.md) para más detalles.

## Crea tu primera escena

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

   ![](/files/9a85f6137d4865c54567046800bb2f6e0462755e)
3. Elige una plantilla inicial. Para este ejercicio, elige la **Empty Scene**.

Este paso puede tardar un par de minutos. Poblará tu carpeta con el conjunto predeterminado de archivos para una escena básica. Una vez que termine, verás la cuadrícula vacía de tu escena.

## Añade elementos de los asset packs

Explora los **Asset packs** en la sección inferior del Scene Editor, y arrastra un par de elementos a tu escena. Cualquier elemento sirve por ahora.

![](/files/b1d095e2e84abbb3351804ebbf09a0a52c752ecb)

Los elementos ya colocados se pueden hacer clic y arrastrar para recolocarlos. Consulta [Conceptos básicos del Scene Editor](/creator/content-creator-es/scene-editor/empezar/scene-editor-essentials.md#position-items) para más detalles.

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

<img src="/files/8685592cce6058e8fb79a543a8dadbd547203c43" alt="Ground" data-size="original">
{% endhint %}

## Ejecuta una vista previa

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

![](/files/b828d6d79325003aa2961bc9689bcc586fa83f87)

Puedes mantener abierta la ventana de vista previa mientras trabajas: se actualiza cada vez que haces un cambio. Lee más en [previsualizar una escena](/creator/content-creator-es/escenas-sdk7/primeros-pasos/preview-scene.md).

## Recursos 3D personalizados

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

![](/files/5e4fc13139baedc869ecf073aefd55282fb4e2df)

Arrastra el **avocado.glb** archivo desde tu explorador de archivos al panel inferior del Scene Editor (el mismo panel que contiene las **Asset Packs** y **Local Assets** pestañas) y haz clic en **Import**.

![](/files/cca2ad4874161fc1b0a6428c3cb470f27575643b)

Ahora puedes encontrar el **avocado.glb** modelo en la **Local Assets** pestaña, dentro de la **Scene** carpeta. Arrastra el archivo a tu escena, como cualquier elemento de los Asset Packs.

![](/files/463b73bdc6b450fa9710bfd9afc39f832d094cea)

## Edita el código de la escena

Haz clic en el **<> Code** botón del menú superior para abrir el proyecto de tu escena en tu editor de código.

![](/files/c98aeaf7cb690147dbbe58baf141fb7c301a18ca)

{% hint style="warning" %}
**📔 Nota**: Si no se abre nada, asegúrate de tener un editor de código como [Visual Studio Code](https://code.visualstudio.com/) o [Cursor](https://www.cursor.com/) instalado.
{% endhint %}

En el margen izquierdo de tu editor de código puedes navegar por los archivos y la estructura de carpetas de tu proyecto. Abre el `index.ts` archivo dentro de la `src` carpeta. Su contenido debería verse así:

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

export function main() {}
```

Este archivo define una función llamada `main()`. Esta función es el punto de entrada de la escena: cualquier código que pongas allí se ejecuta cuando la escena se carga por primera vez. Como regla general, escribe tu código dentro de `main()`. Consulta [Ciclo de vida de la escena](/creator/content-creator-es/escenas-sdk7/primeros-pasos/coding-scenes.md#scene-lifecycle) para más detalles.

Ya arrastraste un aguacate a la escena de forma visual. Ahora vamos a añadir un segundo, esta vez escribiendo código. Sustituye todo el contenido de tu `index.ts` archivo por lo siguiente:

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

export function main() {
	// crear una nueva Entity 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',
	})
}
```

Estas líneas crean una nueva [Entity](/creator/content-creator-es/escenas-sdk7/arquitectura/entities-components.md), le dan una [forma](/creator/content-creator-es/escenas-sdk7/conceptos-basicos-de-contenido-3d/shape-components.md) basada en el modelo 3D que descargaste y [establecen su posición](/creator/content-creator-es/escenas-sdk7/conceptos-basicos-de-contenido-3d/entity-positioning.md) mediante el **Transform** componente.

Ejecuta la vista previa de la escena: ahora deberías ver dos aguacates, el que añadiste en el Scene Editor y el que añadiste mediante código.

![](/files/2813263f879bdc504440d48e5c2a091d4e6066d3)

{% hint style="warning" %}
**📔 Nota**: El segundo aguacate existe **solo en tu código**. Aparece cuando ejecutas la escena, pero el canvas del Scene Editor y el entity tree no pueden mostrar entities creadas en `index.ts`código
{% endhint %}

. No te alarmes si no lo ves en el editor. Esto es algo clave que debes tener en cuenta cuando combines edición visual con código. **primer** aguacate en el Scene Editor: el Properties panel muestra un **Transform** y un **GltfContainer** componente con el mismo tipo de campos que acabas de escribir en código. Son dos vistas de la misma cosa.

![](/files/50ecd79fd9ada4b8e94906f4a58015d6a08797bd)

## Añade interactividad con un Script

Hagamos que un aguacate responda al jugador. En lugar de escribir esto en `index.ts`, **Script component**: una forma de adjuntar código directamente a un elemento en el Scene Editor. Mantiene el comportamiento de cada elemento encapsulado, e incluso puedes reutilizar el mismo script en varios elementos.

1. En el Scene Editor, selecciona el primer aguacate (el que arrastraste; recuerda, el aguacate que solo existe en código no es visible aquí).
2. Haz clic en el **+** botón en la parte superior del Properties panel y añade el **Script** componente.
3. Haz clic en **+ Create New Script** y nómbralo `AvocadoScript`.

![](/files/b4336a71a27c23e0d4459bd5fdd71d61dd7f7bc0)

4. Haz clic en el **<> Code** botón del componente Script para abrir el nuevo archivo en tu editor de código.

El script es una clase con tres partes principales (se han recortado los comentarios por brevedad):

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

export class AvocadoScript {
	constructor(
		public src: string, // NO ELIMINAR
		public entity: Entity, // NO ELIMINAR
		// Añade tus entradas personalizadas abajo
	) {}

	start() {
		// Se llama una vez, cuando se carga la escena
	}

	update(dt: number) {
		// Se llama en cada frame
	}
}
```

* El **constructor** define parámetros que aparecen como campos editables en el componente Script de Creator Hub. No elimines `src` o `Entity`.
* **`start()`** se ejecuta **una vez**, cuando se carga la escena. Úsalo para la configuración: crear componentes, registrar controladores de clic, etc.
* **`update(dt)`** se ejecuta en **cada frame** del juego, aproximadamente 30 veces por segundo. Úsalo para comportamientos continuos, como el movimiento. `dt` te indica cuántos segundos pasaron desde el último frame.

Dentro de la clase, `this.entity` siempre se refiere a la entity que contiene el componente Script: en este caso, tu aguacate. Esto es lo que hace que los scripts sean reutilizables: adjunta el mismo script a diez elementos y cada uno actuará sobre sí mismo.

### Programa tu primera interacción con vibe coding

Puedes escribir el siguiente código a mano, pero este es un gran momento para probar **vibe coding**: describirle a un asistente de IA lo que quieres y dejar que él escriba el código. La mayoría de los editores de código tienen uno integrado, como el chat de Cursor, GitHub Copilot en VS Code o [Claude Code](https://claude.com/product/claude-code). Antes de tu primer prompt, instala las SDK skills de Decentraland, para que la IA conozca los patrones del SDK y cometa muchos menos errores:

```bash
npx skills add decentraland/sdk-skills
```

Consulta [Vibe Coding with AI](/creator/content-creator-es/escenas-sdk7/primeros-pasos/vibe-coding.md) para ver opciones de configuración y consejos para prompts.

Ahora prueba con un prompt como este:

> En @AvocadoScript.ts, haz que el aguacate registre un mensaje en la Console cuando el jugador haga clic en él.

Deberías acabar con algo como esto (o pégalo tú mismo):

```ts
import { engine, Entity, pointerEventsSystem, InputAction } from '@dcl/sdk/ecs'
import {} from '@dcl/sdk/math'

export class AvocadoScript {
	constructor(
		public src: string,
		public entity: Entity,
	) {}

	start() {
		pointerEventsSystem.onPointerDown(
			{
				entity: this.entity,
				opts: { button: InputAction.IA_POINTER },
			},
			() => {
				console.log('AGUACATE PULSADO')
			}
		)
	}

	update(dt: number) {}
}
```

El `pointerEventsSystem.onPointerDown()` La instrucción define tres cosas:

* Sobre qué `Entity` funcionan los pointer events: aquí `this.entity`, el aguacate que contiene el script.
* Un `opts` objeto: qué botón usar y otros argumentos opcionales que no estamos usando ahora.
* Una función que se ejecuta cada vez que se hace clic en la entity.

Para ver el mensaje registrado, ejecuta la vista previa y abre la Console haciendo clic en el ![](/files/5181ddfcf5ca0469e5b3bde5819cd0c448cebc2f) icono de la esquina superior derecha. También puedes activarla o desactivarla pulsando la **\`** tecla. Cada vez que hagas clic en el aguacate, verás:

![](/files/c25f939bd2b0d28ba90feb9f248f49b1a4850b13)

{% hint style="warning" %}
**📔 Nota**: Para que una entity sea clicable, debe tener una geometría collider. El modelo usado aquí ya incluye una. Consulta [Colliders](https://github.com/decentraland/docs/tree/main/creator/sdk7/3d-modeling/colliders.md) para ver soluciones alternativas para modelos que no la tienen.
{% endhint %}

### Haz desaparecer el aguacate

Registrar texto está bien, pero hagamos que el clic haga algo visible. Pregúntale a tu asistente de IA:

> Cuando se haga clic en el aguacate, haz que se reduzca hasta desaparecer con un tween con rebote, en lugar de limitarse a registrar. Además, establece el texto al pasar el cursor a "Recoger".

Deberías acabar con algo como:

```ts
import { engine, Entity, pointerEventsSystem, InputAction, Tween, EasingFunction } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'

export class AvocadoScript {
	constructor(
		public src: string,
		public entity: Entity,
	) {}

	start() {
		pointerEventsSystem.onPointerDown(
			{
				entity: this.entity,
				opts: { button: InputAction.IA_POINTER, hoverText: 'Recoger' },
			},
			() => {
				this.collect()
			}
		)
	}

	collect() {
		Tween.setScale(
			this.entity,
			Vector3.One(),
			Vector3.Zero(),
			500,
			EasingFunction.EF_EASEINBOUNCE
		)
	}

	update(dt: number) {}
}
```

Un **Tween** describe una transición gradual de la posición, rotación o escala de una entity a lo largo del tiempo. Aquí `Tween.setScale()` reduce el tamaño del aguacate desde su tamaño completo (`Vector3.One()`) a nada (`Vector3.Zero()`) durante 500 milisegundos, usando una curva de easing con rebote. Aprende más sobre tweens en [mover entities](/creator/content-creator-es/escenas-sdk7/conceptos-basicos-de-contenido-3d/move-entities.md).

Fíjate en que hemos puesto el tween en un `collect()` método separado en lugar de escribirlo dentro de la función de clic. Si tu IA escribió el tween directamente dentro de la función de clic, también está bien. Los métodos te permiten organizar tu código y reutilizar la misma lógica desde distintos lugares.

Ejecuta la vista previa y haz clic en el aguacate: debería desaparecer con estilo.

{% hint style="warning" %}
**📔 Nota**: El aguacate se reduce a un tamaño de 0, pero la entity sigue existiendo. En una escena real deberías eliminar la entity después de que termine el tween, para mantener el rendimiento de tu escena. Consulta [Al finalizar el tween](/creator/content-creator-es/escenas-sdk7/conceptos-basicos-de-contenido-3d/move-entities.md#on-tween-finished).
{% endhint %}

### Ejecuta código en cada frame

Hasta ahora, todo nuestro código se ejecutaba en `start()`. Usemos `update()` para hacer que el aguacate gire continuamente. Sustituye el constructor y `update()` por:

```ts
	constructor(
		public src: string,
		public entity: Entity,
		public speed: number = 45,
	) {}

	update(dt: number) {
		const transform = Transform.getMutable(this.entity)
		transform.rotation = Quaternion.multiply(
			transform.rotation,
			Quaternion.fromAngleAxis(this.speed * dt, Vector3.Up())
		)
	}
```

Tendrás que añadir `Transform` a los imports de `@dcl/sdk/ecs`, y `Quaternion` a los imports de `@dcl/sdk/math`.

En cada frame, esto hace girar un poco más el aguacate. Multiplicar por `dt` hace que el movimiento sea suave e independiente de la tasa de frames: el aguacate gira a 45 grados por segundo, sin importar lo rápido que funcione la máquina del jugador.

Como `speed` es un parámetro del constructor, también aparece como un campo en el componente Script de Creator Hub. Haz clic en el icono de actualización en la parte superior derecha del componente Script para verlo, y luego ajusta el valor sin tocar ningún código. Si adjuntas este script a varios elementos, cada uno puede tener su propia speed.

<img src="/files/0139fec85ce41cea17ee4d09537305eff9a2686c" alt="Botón de actualización" width="360">

Los scripts pueden hacer mucho más, como exponer acciones que otros smart items pueden activar. Consulta [Script component](/creator/content-creator-es/scene-editor/extender-con-codigo/script-component.md) para ver la imagen completa.

## Haz referencia a un elemento desde el Scene Editor

El componente Script es la forma más sencilla de dar comportamiento a un solo elemento, pero existe una alternativa: tu código en `index.ts` puede obtener cualquier elemento que hayas añadido visualmente, por nombre, usando `engine.getEntityOrNullByName()`. Esto es útil cuando una pieza de lógica involucra varios elementos, o cuando quieres tener todo en un solo lugar. Usa el nombre que aparece en el [entity tree](/creator/content-creator-es/scene-editor/empezar/scene-editor-essentials.md#the-entity-tree).

En este ejemplo, usamos una entity llamada **Yellow Crate**. Puedes usar cualquier elemento, solo escribe su nombre exactamente como aparece en el entity tree.

{% hint style="info" %}
**💡 Consejo**: Puedes cambiar el nombre de las entities haciendo clic con el botón derecho y seleccionando **Rename** en el entity tree.
{% endhint %}

```ts
export function main() {
	// código de avocado2 anterior
	// (...)

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

	if (crate) {
		pointerEventsSystem.onPointerDown(
			{
				entity: crate,
				opts: { button: InputAction.IA_POINTER, hoverText: 'Abrir' },
			},
			function () {
				console.log('CAJA PULSADA')
			}
		)
	}
}
```

Aquí `engine.getEntityOrNullByName()` obtiene una referencia a la entity llamada *Yellow Crate*. La `if (crate)` comprobación garantiza que la entity realmente exista en la escena; si no hay ninguna entity con ese nombre, `crate` es `null`. Consulta [Items de referencia](https://github.com/decentraland/docs/tree/main/creator/sdk7/code/reference-items.md) para más información.

{% hint style="info" %}
**💡 Consejo**: Todas las entities añadidas a través del Scene Editor ya están cargadas cuando `main()` se ejecuta, así que es seguro hacer referencia a ellas allí o en funciones llamadas indirectamente por `main()`.
{% endhint %}

## Más tutoriales

Lee [Programar escenas](/creator/content-creator-es/escenas-sdk7/primeros-pasos/coding-scenes.md) para obtener una visión general de cómo funcionan las escenas de Decentraland.

Para ver ejemplos creados con SDK7, echa un vistazo a la [página de ejemplos](https://studios.decentraland.org/resources?sdk_version=SDK7), que contiene varias escenas pequeñas.

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

## Interactúa con otros desarrolladores

Visita el [Decentraland Discord](https://dcl.gg/discord) y el [Decentraland DAO Discord](https://discord.gg/bxHtcMxUs4) para unirte a una animada conversación sobre qué es posible y cómo hacerlo en la **Creators** sección.

Para depurar cualquier problema, consulta las [Solución de problemas](/creator/content-creator-es/escenas-sdk7/depuracion/troubleshooting.md) y [depuración](/creator/content-creator-es/escenas-sdk7/depuracion/debug-in-preview.md) secciones. Un asistente de IA con las [SDK skills](/creator/content-creator-es/escenas-sdk7/primeros-pasos/vibe-coding.md) instaladas también es un gran compañero de depuración: pega el mensaje de error de la Console, o describe qué no está funcionando como se espera, y normalmente puede encontrar el problema en tu código. Si no encuentras una solución, puedes publicar en la [categoría SDK Support](https://forum.decentraland.org/c/support-sdk/11) en el Decentraland Forum.

## Recursos artísticos 3D

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

Aquí tienes algunas fuentes de modelos 3D que puedes usar en una escena 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 IA generativa para crear tus propios modelos 3D. Echa un vistazo a:

* [Blender MCP](https://github.com/ahujasid/blender-mcp) + [Claude Desktop](https://claude.ai/download): conecta un asistente de IA directamente a [Blender](https://www.blender.org/), para que puedas crear y editar modelos 3D describiendo lo que quieres. Todas son herramientas gratuitas.
* [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 modelos deben estar en los formatos compatibles `.gltf` o `.glb` formatos, y deben tener una cantidad de triángulos, texturas y materiales que se ajusten a las [limitaciones de la escena](/creator/content-creator-es/escenas-sdk7/optimizacion/scene-limitations.md). Si obtienes modelos de un sitio de terceros, presta atención a las restricciones de licencia del contenido que descargues.
{% endhint %}

## Publica tu escena

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

## Otra información útil

* [Vibe Coding with AI](/creator/content-creator-es/escenas-sdk7/primeros-pasos/vibe-coding.md)
* [Flujo de trabajo de desarrollo](/creator/content-creator-es/escenas-sdk7/primeros-pasos/dev-workflow.md)
* [Edición de escenas](/creator/content-creator-es/scene-editor/empezar/about-editor.md)
* [Conceptos básicos del Scene Editor](/creator/content-creator-es/scene-editor/empezar/scene-editor-essentials.md)
* [Restricciones de diseño para juegos](/creator/content-creator-es/escenas-sdk7/disenar-la-experiencia/design-games.md)
* [Modelado 3D](/creator/content-creator-es/modelado-3d-y-animaciones/3d-models.md)
* [Limitaciones de la escena](/creator/content-creator-es/escenas-sdk7/optimizacion/scene-limitations.md)


---

# 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-es/escenas-sdk7/primeros-pasos/sdk-101.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.
