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

# Systems

Aprenda como systems são usados para atualizar o estado da scene

As scenes do Decentraland dependem de *systems* para atualizar quaisquer dados ao longo do tempo, incluindo informações armazenadas no [components](/creator/content-creator-pt/scenes-sdk7/arquitetura/entities-components.md).

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

*systems* são o que tornam as scenes dinâmicas; são funções executadas periodicamente a cada tick do game loop da scene, alterando o que será renderizado.

O exemplo a seguir mostra uma declaração básica de system:

```ts
// Defina o system
function mySystem() {
  console.log("Executado a cada tick. Meu system está em execução")
}
// Adicione o system ao engine
engine.addSystem(mySystem)
```

A função em um system pode fazer qualquer coisa que você quiser. Normalmente, ela atua sobre todas as entities que atendem a determinada [query](/creator/content-creator-pt/scenes-sdk7/arquitetura/querying-components.md), seguindo uma lógica específica para alterar os valores armazenados nos components da Entity.

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

  // obter um componente Transform mutável
  const transform = Transform.getMutable(entity)

  // atualizar o valor de position
    transform.position.z += 0.01
  }
}

engine.addSystem(moveSystem)
```

No exemplo acima, o system `MoveSystem` é uma função que é executada a cada tick do game loop, alterando a posição de cada Entity na scene que tenha um Transform.

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-826c0dcfcfc5a6d5719de5a0939214a534078567%2Fecs-system-new.png?alt=media)

Você pode ter múltiplos systems na sua scene para desacoplar comportamentos diferentes, tornando seu código mais limpo e mais fácil de escalar e reutilizar. Por exemplo, um system pode lidar com física, outro pode fazer uma Entity-obstáculo se mover para frente e para trás continuamente, outro pode lidar com a IA dos personagens.

Múltiplos systems podem atuar sobre uma única Entity. Por exemplo, um personagem não jogável pode se mover por conta própria com base em uma IA, mas também ser afetado pela gravidade ao caminhar acidentalmente para fora de um penhasco. Nesse cenário, os systems de física e de IA nem precisam saber um do outro. Eles reavaliam independentemente seu estado atual a cada tick do game loop e implementam sua própria lógica separada.

## A função do system

A função de um system é executada periodicamente, uma vez a cada tick do game loop. Isso acontece automaticamente; você não precisa chamar essa função explicitamente de lugar nenhum no seu código.

Em uma scene do Decentraland, você pode pensar no game loop como a agregação de todas as funções de system na sua scene.

{% hint style="warning" %}
**📔 Nota**: Você não pode adicionar a mesma função de system ao engine mais de uma vez. Se tentar adicionar um system que já foi adicionado, o engine lança um erro: `System "<name>" já foi adicionado ao engine`.
{% endhint %}

## Lidar com entities por referência

Alguns components e systems são feitos para serem usados apenas em uma Entity na scene. Por exemplo, em uma Entity que armazena a pontuação de um jogo ou talvez um portão principal único na scene. Para acessar uma dessas entities dentro de um system, você pode simplesmente se referir à Entity ou aos seus components pelo nome nas funções do system.

```ts
// declarar a referência da Entity no escopo do módulo para que os systems possam acessá-la
let game: Entity

export function main(){
	// criar uma nova Entity
	game = engine.addEntity()

	// adicionar component a essa Entity
	ScoreComponent.create(game)
}

// Defina o system
export function UpdateScore() {

  // chamar a referência para a Entity individual
  const points = ScoreComponent.get(game).points
  console.log(points)
}

// Adicione o system ao engine
engine.addSystem(UpdateScore)
```

Para projetos maiores, recomendamos que você mantenha as definições de system em arquivos separados da instanciação de entities e components.

## Iterar sobre uma query de component

Muitas vezes, sua scene terá múltiplas entities do mesmo tipo que terão comportamentos semelhantes. Por exemplo, muitas portas que podem ser abertas, ou muitos inimigos que podem atacar o jogador. Faz sentido lidar com todas essas entities semelhantes em um único system, iterando pela lista e realizando as mesmas verificações em cada uma.

Você não quer que a função de um system itere sobre *todo o* conjunto de entities na scene, pois isso pode ser muito custoso em termos de poder de processamento. Para evitar isso, você pode [consultar components](/creator/content-creator-pt/scenes-sdk7/arquitetura/querying-components.md), para iterar apenas sobre as entities relevantes.

Por exemplo, sua scene pode ter um `PhysicsSystem` que calcula o efeito da gravidade sobre as entities da sua scene. Algumas entities da sua scene, como árvores, não devem se mover nunca; então seria inteligente evitar calcular os efeitos da gravidade sobre elas. Você pode definir um `HasPhysics` component para marcar entities que podem ser afetadas pela gravidade, e então fazer com que `PhysicsSystem` lidem apenas com as entities retornadas por esta query.

```ts
// Defina o system
export function PhysicsSystem() {
  // iterar sobre todas as entities com um HasPhysics
  for (const [entity] of engine.getEntitiesWith(HasPhysics)) {

  // obter um componente Transform mutável
  const transform = Transform.getMutable(entity)

  // Calcular o efeito da física
  }
}

// Adicione o system ao engine
engine.addSystem(PhysicsSystem)
```

## Delta time entre frames

A função em um system pode opcionalmente incluir um argumento chamado `dt`, do tipo `number` (representando *delta time*).

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

  // Atualizar scene
  console.log("tempo desde o último tick: ", dt)
}

engine.addSystem(MySystem)
```

*delta time* representa o tempo que passou desde o último tick do game loop, em segundos.

O `dt` O argumento é o tempo real decorrido desde o último tick do game loop, medido em segundos. O SDK não impõe uma taxa fixa de ticks: o runtime anfitrião passa esse valor, e ele varia com o framerate da scene.

Quanto mais suave uma scene roda, com mais frequência os ticks ocorrem e menor é cada `dt` valor. Quando um tick leva mais tempo para ser processado, passa mais tempo antes do próximo e `dt` aumenta de acordo.

Essa taxa de frames do lado da scene é limitada a 30 ticks por segundo, nesse caso, o valor de `dt` é *1/30* (0.0333...).

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-9ebcec63913c57ddf96107a817b14797211c1de2%2Fecs-framerate.png?alt=media)

Quando o processamento de um frame demora mais, a renderização desse frame é atrasada, e o `dt` transmitido no próximo tick reflete esse intervalo maior. O engine não compensa o atraso retroativamente; `dt` sempre informa o tempo efetivamente decorrido para que seus Systems possam se ajustar a ele.

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-951edc3e7611eb138145de377ec07dfc8ec4836b%2Fecs-framerate-heavy.png?alt=media)

Idealmente, você deve evitar que sua scene perca frames, pois isso afeta a qualidade da experiência do jogador. Como isso depende do poder de processamento da máquina do jogador, é sempre possível que sua scene precise estar pronta para lidar com isso com elegância.

O `dt` A variável é útil quando o processamento do frame excede o tempo padrão. Assumindo que o frame atual levará tanto tempo quanto o anterior, essa informação pode ser usada para calcular quanto ajustar uma mudança gradual, de modo que a taxa de mudança pareça estável e proporcional ao atraso entre frames.

Vê [posicionamento de entities](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/entity-positioning.md) para ver exemplos de como usar `dt` para tornar o movimento mais suave.

## Loop em um intervalo de tempo

Se você quiser que um system execute algo em um intervalo regular de tempo, você pode fazer isso combinando o `dt` argumento com um timer.

```ts
let timer: number = 10

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

engine.addSystem(LoopSystem)
```

Há também uma função de atalho `setInterval` e `clearInterval` que usa Systems em segundo plano. Isso permite uma versão mais fácil e curta quando a intenção é executar uma determinada função a cada X unidades de tempo.

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

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

Onde o primeiro argumento, `callback`, é a função a ser executada (neste caso, a `console.log()`), e o segundo argumento, `ms`(10000 neste caso), é a quantidade de milissegundos a aguardar entre cada execução da função.

Para parar o `setInterval` função, `clearInterval` é usado.

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

Onde `intervalId` é a referência ao `setInterval` retorno definido anteriormente.

Para casos de uso mais complexos, nos quais podem ser criados dinamicamente múltiplos atrasos e loops, pode valer a pena definir um componente personalizado para armazenar um valor de timer individual para cada Entity. Veja [componentes personalizados](/creator/content-creator-pt/scenes-sdk7/arquitetura/custom-components.md).

## Ordem de execução do System

Em alguns casos, quando você tem múltiplos Systems em execução, talvez se importe com qual system é executado primeiro pela sua scene.

Por exemplo, você pode ter um *física* system que atualiza a posição de entities na scene, e outro *de limites* system que garante que nenhuma das entities esteja posicionada fora dos limites da scene. Nesse caso, você quer garantir que o *de limites* system seja executado por último. Caso contrário, o *física* system poderia mover entities para fora dos limites da scene, mas o *de limites* system só descobrirá isso quando for executado novamente no próximo frame.

Ao adicionar um system ao engine, defina um campo opcional `priority` para determinar quando o system é executado em relação a outros Systems.

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

Systems com um número de priority maior são executados primeiro, então um system com priority de *5* é executado antes de um com priority *1*.

Systems aos quais não é atribuída uma priority explícita têm uma priority padrão de *100000*. Como números maiores são executados primeiro, esses Systems são executados antes daqueles com uma priority explícita menor.

Se dois Systems tiverem o mesmo número de priority, não há como saber com certeza qual deles será executado primeiro.

## Remover um system

Uma instância de um system pode ser adicionada ou removida do engine para ativá-lo ou desativá-lo.

Se um system for definido, mas não for adicionado ao engine, sua função não será chamada pelo engine.

Para remover um system, você deve primeiro dar a ele um nome ao adicioná-lo ao engine, para que possa se referir ao system mais tarde.

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

// adicionar system (dando a ele uma priority e um nome)
engine.addSystem(mySystem, 1, "DelaySystem")

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

A string que você passa para `engine.removeSystem()` deve corresponder ao nome que você atribuiu ao system quando o adicionou.

Outra forma de remover um system é passar a própria função do system para o `engine.removeSystem()` método. Dessa forma, você não precisa dar um nome ao system ao adicioná-lo.

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

// adicionar system
engine.addSystem(mySystem)

// remover system passando sua função
engine.removeSystem(mySystem)
```

`engine.removeSystem()` aceita tanto a string de nome que você atribuiu ao adicionar o system quanto uma referência à própria função do system.

Você pode usar o método abaixo para fazer um system encerrar-se automaticamente quando seu propósito estiver concluído.

```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 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-pt/scenes-sdk7/arquitetura/systems.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.
