> 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/scenes-sdk7/arquitectura/systems.md).

# Sistemas

Aprende cómo se usan los Systems para actualizar el estado de la escena

Las scenes de Decentraland dependen de *systems* para actualizar cualquier dato a lo largo del tiempo, incluida la información almacenada en cada entity [components](/creator/content-creator-es/scenes-sdk7/arquitectura/entities-components.md).

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-de62a18d51b28bebd55c86e8ef5a8a783467ae62%2Fecs-big-picture.png?alt=media\&token=0d7a02a2-955a-44ed-ae77-5df99c49e530)

*systems* son lo que hacen que las scenes sean dinámicas, son functions que se ejecutan periódicamente en cada tick del game loop de la scene, cambiando lo que se renderizará.

El siguiente ejemplo muestra una declaración básica de system:

```ts
// Definir el system
function mySystem() {
  console.log("Se ejecuta en cada tick. Mi system está corriendo")
}
// Añadir el system al engine
engine.addSystem(mySystem)
```

La function en un system puede hacer lo que quieras. Normalmente, actuará sobre todas las entities que cumplan cierto [query](/creator/content-creator-es/scenes-sdk7/arquitectura/querying-components.md), siguiendo cierta lógica para cambiar los valores almacenados en los components de la entity.

```ts
function moveSystem(dt: number) {
  // iterar sobre todas las entities con un Transform
  for (const [entity] of engine.getEntitiesWith(Transform)) {

  // obtener un component Transform mutable
  const transform = Transform.getMutable(entity)

  // actualizar el valor de la position
    transform.position.z += 0.01
  }
}

engine.addSystem(moveSystem)
```

En el ejemplo anterior, el system `MoveSystem` es una function que se ejecuta en cada tick del game loop, cambiando la position de cada entity en la scene que tiene un Transform.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-826c0dcfcfc5a6d5719de5a0939214a534078567%2Fecs-system-new.png?alt=media\&token=59a83c9e-0d01-454b-bd5e-4ca61779a3f3)

Puedes tener varios systems en tu scene para desacoplar distintos comportamientos, haciendo que tu código sea más limpio y más fácil de escalar y reutilizar. Por ejemplo, un system podría encargarse de la physics, otro podría hacer que una entity obstáculo se mueva continuamente de un lado a otro, otro podría encargarse de la AI de los personajes.

Varios systems pueden actuar sobre una sola entity. Por ejemplo, un personaje no jugador podría moverse por sí mismo basándose en una AI, pero también verse afectado por la gravedad cuando accidentalmente camina por un acantilado. En ese escenario, los systems de physics y AI ni siquiera necesitan conocerse entre sí. Reevalúan de forma independiente su estado actual en cada tick del game loop e implementan su propia lógica separada.

## La function del system

La function de un system se ejecuta periódicamente, una vez por cada tick del game loop. Esto ocurre automáticamente; no necesitas llamar explícitamente a esta function desde ningún lugar de tu código.

En una scene de Decentraland, puedes pensar en el game loop como la agregación de todas las functions de system de tu scene.

{% hint style="warning" %}
**📔 Nota**: No puedes añadir la misma function de system al engine más de una vez. Si intentas añadir un system que ya fue añadido, el engine lanza un error: `System "<name>" already added to the engine`.
{% endhint %}

## Gestionar entities por referencia

Algunos components y systems están pensados para usarse solo en una entity de la scene. Por ejemplo, en una entity que almacena la puntuación de un juego o quizá una puerta principal que sea única en la scene. Para acceder a una de esas entities dentro de un system, puedes simplemente referirte a la entity o a sus components por nombre en las functions del system.

```ts
// declarar la referencia de la entity en el scope del módulo para que los systems puedan acceder a ella
let game: Entity

export function main(){
	// crear una nueva entity
	game = engine.addEntity()

	// añadir un component a esa entity
	ScoreComponent.create(game)
}

// Definir el system
export function UpdateScore() {

  // llamar a la referencia de la entity individual
  const points = ScoreComponent.get(game).points
  console.log(points)
}

// Añadir el system al engine
engine.addSystem(UpdateScore)
```

Para proyectos más grandes, recomendamos mantener las definiciones de system en archivos separados de la instanciación de entities y components.

## Recorrer una query de component

Muchas veces, tu scene tendrá múltiples entities del mismo tipo que tendrán comportamientos similares. Por ejemplo, muchas puertas que pueden abrirse, o muchos enemigos que pueden atacar al jugador. Tiene sentido gestionar todas estas entities similares en un solo system, iterando sobre la lista y realizando las mismas comprobaciones en cada una.

No quieres que la function de un system itere sobre *todo el* conjunto de entities de la scene, ya que esto podría resultar muy costoso en términos de capacidad de procesamiento. Para evitar esto, puedes [consultar components](/creator/content-creator-es/scenes-sdk7/arquitectura/querying-components.md), para iterar solo sobre las entities relevantes.

Por ejemplo, tu scene puede tener un `PhysicsSystem` que calcule el efecto de la gravedad sobre las entities de tu scene. Algunas entities de tu scene, como los árboles, no están pensadas para moverse nunca; así que sería inteligente evitar calcular el efecto de la gravedad sobre ellas. Puedes definir un `HasPhysics` component para marcar las entities que podrían verse afectadas por la gravedad, y luego hacer que `PhysicsSystem` solo se encargue de las entities devueltas por esta query.

```ts
// Definir el system
export function PhysicsSystem() {
  // iterar sobre todas las entities con un HasPhysics
  for (const [entity] of engine.getEntitiesWith(HasPhysics)) {

  // obtener un component Transform mutable
  const transform = Transform.getMutable(entity)

  // Calcular el efecto de la física
  }
}

// Añadir el system al engine
engine.addSystem(PhysicsSystem)
```

## Delta time between frames

La function en un system puede incluir opcionalmente un argumento llamado `dt`, de tipo `number` (que representa *delta time*).

```ts
function MySystem(dt: number) {

  // actualizar la scene
  console.log("tiempo transcurrido desde el último tick: ", dt)
}

engine.addSystem(MySystem)
```

*delta time* representa el tiempo que ha pasado desde el último tick del game loop, en segundos.

El `dt` el argumento es el tiempo real transcurrido desde el último tick del game loop, medido en segundos. El SDK no impone una tasa de ticks fija: el host runtime pasa este valor, y varía con la frame rate de la scene.

Cuanto más fluida se ejecute una scene, más frecuentemente ocurren los ticks y menor es cada `dt` valor de `dt` aumenta en consecuencia.

Esta frame rate del lado de la scene está limitada a 30 ticks por segundo, en cuyo caso el valor de `dt` es *1/30* (0.0333...).

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-9ebcec63913c57ddf96107a817b14797211c1de2%2Fecs-framerate.png?alt=media\&token=3493a280-5778-492f-afc5-e98b45d6beb6)

Cuando el procesamiento de un frame tarda más, el dibujo de ese frame se retrasa, y el `dt` pasado en el siguiente tick refleja ese intervalo más largo. El engine no compensa el retraso retroactivamente; `dt` siempre informa del tiempo real transcurrido para que tus systems puedan ajustarse a él.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-951edc3e7611eb138145de377ec07dfc8ec4836b%2Fecs-framerate-heavy.png?alt=media\&token=e3656977-e7aa-4f14-854b-e9071ed18b02)

Idealmente, deberías evitar que tu scene pierda frames, ya que esto afecta a la calidad de la experiencia del jugador. Dado que esto depende de la capacidad de procesamiento de la máquina del jugador, siempre existe la posibilidad de que tu scene deba estar preparada para gestionarlo de forma adecuada.

El `dt` La variable es útil cuando el procesamiento del frame supera el tiempo predeterminado. Suponiendo que el frame actual tardará tanto como el anterior, esta información puede usarse para calcular cuánto ajustar un cambio gradual, de modo que la tasa de cambio parezca constante y en proporción al retraso entre frames.

Consulta [posicionamiento de entity](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/entity-positioning.md) para ver ejemplos de cómo usar `dt` para hacer que el movimiento sea más suave.

## Bucle en un intervalo de tiempo

Si quieres que un system ejecute algo a intervalos regulares de tiempo, puedes hacerlo combinando el argumento `dt` con un timer.

```ts
let timer: number = 10

function LoopSystem(dt: number) {
  timer -= dt
  if (timer <= 0) {
      timer = 10
      // HAZ ALGO
    }
}

engine.addSystem(LoopSystem)
```

También existe una function abreviada `setInterval` y `clearInterval` que usa Systems en segundo plano. Esto permite una versión más sencilla y corta cuando la intención es ejecutar cierta function cada X cantidad de tiempo.

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

const intervalId = timers.setInterval(() => {
    console.log('Imprimiendo esto cada 10 segundos')
}, 10000)
```

Donde el primer argumento, `callback`, es la function que se ejecutará (en este caso, la `console.log()`), y el segundo argumento, `ms`(10000 en este caso), son los milisegundos a esperar entre cada ejecución de la function.

Para detener el `setInterval` function, `clearInterval` se usa.

```
timers.clearInterval(intervalId)
```

Donde `intervalId` es la referencia al `setInterval` return definido antes.

Para casos de uso más complejos, donde podrían crearse múltiples retrasos y bucles dinámicamente, puede valer la pena definir un component personalizado para almacenar un valor de timer individual para cada entity. Ver [Custom components](/creator/content-creator-es/scenes-sdk7/arquitectura/custom-components.md).

## Orden de ejecución de system

En algunos casos, cuando tienes varios systems en ejecución, puede importarte qué system se ejecuta primero en tu scene.

Por ejemplo, podrías tener un system de *physics* que actualice la position de las entities en la scene, y otro system de *boundaries* que se asegure de que ninguna de las entities esté posicionada fuera de los límites de la scene. En este caso, querrás asegurarte de que el *boundaries* system se ejecute el último. De lo contrario, el *physics* system podría mover entities fuera de los límites de la scene, pero el *boundaries* system no se enterará hasta que se ejecute de nuevo en el siguiente frame.

Al añadir un system al engine, establece un `priority` campo opcional

```ts
engine.addSystem(PhysicsSystem, 5)
engine.addSystem(BoundariesSystem, 1)
```

Los systems con un número de prioridad más alto se ejecutan primero, así que un system con una prioridad de *5* se ejecuta antes que uno con prioridad *1*.

Los systems a los que no se les da una prioridad explícita tienen una prioridad predeterminada de *100000*. Dado que los números más altos se ejecutan primero, estos systems se ejecutan antes que los que tienen una prioridad explícita más baja.

Si dos systems tienen el mismo número de prioridad, no hay forma de saber con certeza cuál de ellos se ejecutará primero.

## Eliminar un system

Se puede añadir o eliminar una instancia de un system del engine para activarlo o desactivarlo.

Si un system está definido pero no se añade al engine, su function no es llamada por el engine.

Para eliminar un system, primero debes darle un nombre al añadirlo al engine, para poder referirte al system más tarde.

```ts
// declarar system
function mySystem(dt: number){
  console.log("retraso desde el último tick: ", dt)
}

// añadir system (dándole una prioridad y un nombre)
engine.addSystem(mySystem, 1, "DelaySystem")

// eliminar system
engine.removeSystem("DelaySystem")
```

La cadena que pases a `engine.removeSystem()` debe coincidir con el nombre que asignaste al system cuando lo añadiste.

Otra forma de eliminar un system es pasar la propia function del system al método `engine.removeSystem()` . De esta manera no necesitas darle un nombre al system al añadirlo.

```ts
// declarar system
function mySystem(dt: number){
  console.log("retraso desde el último tick: ", dt)
}

// añadir system
engine.addSystem(mySystem)

// eliminar system pasando su function
engine.removeSystem(mySystem)
```

`engine.removeSystem()` acepta bien la cadena de nombre que asignaste al añadir el system, o una referencia a la propia function del system.

Puedes usar el método siguiente para hacer que un system se autodestruya cuando su propósito se haya completado.

```ts
   const mySystem = function(dt: number){
        time += dt
        if(time > 3){
		engine.removeSystem(mySystem)
        }
    }
    engine.addSystem(mySystem)
```


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/arquitectura/systems.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
