

Aviso de fim do suporte: em 20 de maio de 2026, AWS encerrará o suporte para AWS SimSpace Weaver. Depois de 20 de maio de 2026, você não poderá mais acessar o SimSpace Weaver console ou os SimSpace Weaver recursos. Para obter mais informações, consulte [AWS SimSpace Weaver Fim do suporte](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html). 

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Trabalhando com SimSpace Weaver
<a name="working-with"></a>

Este capítulo fornece informações e orientações para ajudá-lo a criar seus próprios aplicativos no SimSpace Weaver.

**Topics**
+ [Configurar a simulação](working-with_configuring-simulation.md)
+ [Duração máxima de uma simulação](working-with_max-duration.md)
+ [Desenvolver aplicativos](working-with_developing-apps.md)
+ [Desenvolver aplicativos cliente](working-with_developing-client-applications.md)
+ [Obtenha o endereço IP e o número da porta de um aplicativo personalizado](working-with_get-ip.md)
+ [Lançamento do cliente de visualização Unreal Engine](working-with_unreal-client.md)
+ [Desenvolvimento local em SimSpace Weaver](working-with_local-development.md)
+ [AWS SimSpace Weaver SDK do aplicativo](working-with_app-sdk.md)
+ [AWS SimSpace Weaver estrutura de demonstração](working-with_demo-framework.md)
+ [Trabalhar com Service Quotas](working-with_quotas.md)
+ [Depurar simulações](working-with_debugging.md)
+ [Contêineres personalizados](working-with_custom-containers.md)
+ [Como trabalhar com Python](working-with_python.md)
+ [Suporte para outros mecanismos](working-with_engines.md)
+ [Uso de software licenciado com AWS SimSpace Weaver](working-with_byol.md)
+ [Gerenciando seus recursos com AWS CloudFormation](working-with_cloudformation.md)
+ [Snapshots](working-with_snapshots.md)
+ [Sistema de mensagens](working-with_messaging.md)

# Configurar a simulação
<a name="working-with_configuring-simulation"></a>

Um **esquema de simulação** (ou **esquema**) é um YAML-arquivo de texto formatado que especifica a configuração de uma simulação. É possível usar o mesmo esquema para iniciar várias simulações. O arquivo do esquema está localizado na pasta do projeto para a simulação. Você pode usar qualquer editor de texto para editar o arquivo. SimSpace Weaver só lê seu esquema quando inicia a simulação. Todas as edições feitas em um arquivo de esquema afetam somente as novas simulações, iniciadas após as edições. 

Para configurar sua simulação, edite seu arquivo de esquema de simulação (use o separador de caminho apropriado para seu sistema operacional):

```
project-folder\tools\project-name-schema.yaml
```

Carregue o esquema de simulação ao criar uma nova simulação. O script de ajuda de início rápido do projeto fará o carregamento do esquema como parte do processo para criar a simulação: 

```
project-folder\tools\windows\quick-start.py
```

Para obter mais informações sobre como executar o script de início rápido, consulte o [Tutorial detalhado](getting-started_detailed.md) [Conceitos básicos](getting-started.md) capítulo deste guia.

## Parâmetros de configuração da simulação
<a name="working-with_configuring-simulation_config-parameters"></a>

O esquema de simulação contém informações de inicialização, incluindo:
+ **Propriedades da simulação**: versão do SDK e configuração computacional (tipo e número de [operadores](w2aac51.md#glossary_worker))
+ **Relógios**: taxa de atualização e tolerâncias
+ **Estratégias de particionamento espacial**: topologia espacial (como a grade), limites e grupos de posicionamento (agrupamento de partição espacial em operadores)
+ **Domínios e seus aplicativos**: bucket do aplicativo, caminho e comandos de inicialização

SimSpace Weaver usa sua configuração de esquema para configurar e organizar partições espaciais, iniciar aplicativos e avançar na simulação na taxa de ticks especificada. 

**nota**  
O script create-project no SDK do SimSpace Weaver aplicativo gerará automaticamente um esquema de simulação para você, com base no aplicativo de amostra.

Os tópicos a seguir descrevem os parâmetros no esquema de simulação. Para obter uma descrição completa do esquema de simulação, consulte [SimSpace Weaver referência do esquema de simulação](schema-reference.md). 

**Topics**
+ [Parâmetros de configuração da simulação](#working-with_configuring-simulation_config-parameters)
+ [Versão do SDK](working-with_configuring-simulation_sdk-version.md)
+ [Propriedades da simulação](working-with_configuring-simulation_simulation-properties.md)
+ [Operadores](working-with_configuring-simulation_workers.md)
+ [Relógio](working-with_configuring-simulation_clock.md)
+ [Estratégias de particionamento](working-with_configuring-simulation_partitioning-strategies.md)
+ [Domínios](working-with_configuring-simulation_domains.md)

# Versão do SDK
<a name="working-with_configuring-simulation_sdk-version"></a>

O `sdk_version` campo especifica a versão para a SimSpace Weaver qual o esquema está formatado. Valores válidos: `1.17`, `1.16`, `1.15`, `1.14`, `1.13`, `1.12`

**Importante**  
O valor de `sdk_version` inclui somente o número da versão principal e o número da primeira versão secundária. Por exemplo, o valor `1.12` especifica todas as versões `1.12.x`, como `1.12.0`, `1.12.1`, e `1.12.2`.

# Propriedades da simulação
<a name="working-with_configuring-simulation_simulation-properties"></a>

A seção `simulation_properties` do esquema especifica a configuração de registro e um tipo de dados para o campo de índice (geralmente a localização espacial) das entidades.

```
simulation_properties:
  log_destination_service: "logs"
  log_destination_resource_name: "MySimulationLogs"
  default_entity_index_key_type: "Vector3<f32>"
```

O valor de `log_destination_service` determina a interpretação do valor de `log_destination_resource_name`. Atualmente, o único valor compatível é `logs`. Isso significa que o valor de `log_destination_resource_name` é o nome de um grupo de CloudWatch logs no Amazon Logs.

**nota**  
O registro é opcional. Se você não configurar as propriedades de destino do log, sua simulação não produzirá registros.

A propriedade `default_entity_index_key_type` é obrigatória. O único valor válido é `Vector3<f32>`.

# Operadores
<a name="working-with_configuring-simulation_workers"></a>

A `workers` seção especifica o tipo e o número de trabalhadores que você deseja para sua simulação. SimSpace Weaver usa seus próprios tipos de trabalhadores que são mapeados para os tipos de EC2 instância da Amazon. 

```
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 1
```

## Ativar simulações com vários operadores
<a name="working-with_configuring-simulation_workers_multi-worker"></a>

É possível criar uma simulação que use mais de um operador. Por padrão, as simulações usam um operador. Você deve modificar o esquema de simulação antes de iniciar a simulação. 

**nota**  
Não é possível alterar uma simulação que já foi iniciada. Se quiser habilitar vários operadores para uma simulação em execução, primeiro interrompa e exclua a simulação.

Para usar mais de um operador, defina o número `desired` de instâncias de computação para um valor maior que 1. Há um número máximo de aplicativos para cada operador. Para obter mais informações, consulte[SimSpace Terminais e cotas do Weaver](service-quotas.md). SimSpace Weaver usará apenas mais de 1 trabalhador quando o número de aplicativos em um trabalhador exceder esse limite. SimSpace Weaver pode colocar um aplicativo em qualquer um dos trabalhadores disponíveis. O posicionamento do aplicativo em um funcionário específico não é garantido. 

O trecho de esquema a seguir demonstra uma configuração para uma simulação que solicita dois operadores. O SimSpace Weaver tentará alocar o segundo operador se o número de aplicativos exceder o máximo de aplicativos para um operador.

```
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 2
```

# Relógio
<a name="working-with_configuring-simulation_clock"></a>

A seção `clock` especifica as propriedades do relógio da simulação. Atualmente, você só pode configurar a **taxa de atualização** (o número de marcações por segundo que o relógio envia aos aplicativos). A taxa de atualização é a taxa máxima. A taxa efetiva de marcações pode ser menor porque todas as operações (como atualizações de entidades) de uma marcação devem terminar antes que a próxima marcação possa começar. A taxa de atualização também é chamada de **taxa de relógio**.

Os valores válidos para a `tick_rate` dependem da `sdk_version` especificada em seu esquema.

**Valores válidos para a taxa de atualização**
+ Versões anteriores a `"1.14"`:
  + `10`
  + `15`
  + `30`
+ Versão `"1.14"` ou posterior:
  + `"10"`
  + `"15"`
  + `"30"`
  + `"unlimited"`

    Para obter mais informações, consulte [Taxa de atualização ilimitada](#working-with_configuring-simulation_clock_unlimited).

**Importante**  
Para esquemas com uma `sdk_version` anterior a `"1.14"` o valor da `tick_rate` é um **número inteiro**, como `30`.
Para esquemas com uma `sdk_version` de `"1.14"` ou posterior, o valor da `tick_rate` é uma **string**, como `"30"`. O valor **deve incluir aspas duplas**.  
Se você converter um esquema com versão `"1.12"` ou `"1.13"` em versão `"1.14"` ou posterior, deverá colocar o valor da `tick_rate` entre aspas duplas.

## Taxa de atualização ilimitada
<a name="working-with_configuring-simulation_clock_unlimited"></a>

É possível definir a `tick_rate` para `"unlimited"` para permitir que a simulação seja executada tão rapidamente quanto seu código puder ser executado. Com uma taxa de tick ilimitada, SimSpace Weaver envia o próximo tick imediatamente após todos os aplicativos concluírem os commits do tick atual.

**Importante**  
A taxa de ticks ilimitada não é suportada nas SimSpace Weaver versões anteriores à 1.14.0. O valor mínimo da `sdk_version` no esquema é `"1.14"`.

**Taxa de atualização ilimitada no SimSpace Weaver Local**  
O SimSpace Weaver Local implementa `"unlimited"` como se o esquema especificasse uma taxa de atualização de 10 kHz (10.000). O efeito é o mesmo de uma taxa de atualização ilimitada na Nuvem AWS. Ainda é preciso especificar `tick_rate: "unlimited"` no esquema. Para saber mais sobre o SimSpace Weaver Local, consulte [Desenvolvimento local em SimSpace Weaver](working-with_local-development.md).

## Perguntas frequentes sobre o relógio
<a name="working-with_configuring-simulation_clock_faq"></a>

### P1. Posso alterar uma simulação STARTED para usar uma taxa de atualização diferente?
<a name="working-with_configuring-simulation_clock_faq_q1"></a>

Não é possível alterar a taxa de atualização de uma simulação que já existe no Nuvem AWS em nenhum estágio de seu ciclo de vida. Também não é possível alterar a taxa de atualização de uma simulação em execução no SimSpace Weaver Local. É possível definir a `tick_rate` no esquema e iniciar uma nova simulação a partir desse esquema.

### P2. Posso executar minha simulação com uma taxa de atualização ilimitada em uma versão anterior a 1.14?
<a name="working-with_configuring-simulation_clock_faq_q2"></a>

Não, a taxa de atualização ilimitada não é compatível nas versões anteriores a 1.14.0.

## Solução de problemas do relógio
<a name="working-with_configuring-simulation_clock_troubleshooting"></a>

Se sua simulação falhar no início, você pode verificar o valor de `"StartError"` na saída da **DescribeSimulation**API. Um valor inválido de `tick_rate` no esquema produzirá os seguintes erros.

**nota**  
A saída de erro mostrada aqui é exibida em várias linhas para melhorar a legibilidade. A saída real do erro consiste em uma única linha.
+ A `sdk_version` é anterior a `"1.14"` e o valor da `tick_rate` é um número inteiro inválido. Valores válidos: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"}]"
  ```
+ A `sdk_version` é anterior a `"1.14"` e o valor da `tick_rate` é uma string. Valores válidos: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"},
      {\"errorType\":\"SchemaFormatInvalid\",
      \"errorMessage\":\"$.clock.tick_rate: string found, integer expected\"}]"
  ```
+ A `sdk_version` é `"1.14"` ou posterior e o valor da `tick_rate` é uma string inválida. Valores válidos: `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"}]"
  ```
+ A `sdk_version` é `"1.14"` ou posterior e o valor da `tick_rate` é um número inteiro. Valores válidos: `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"},
      {\"errorType\":\"SchemaFormatInvalid\",
      \"errorMessage\":\"$.clock.tick_rate: integer found, string expected\"}]"
  ```

# Estratégias de particionamento
<a name="working-with_configuring-simulation_partitioning-strategies"></a>

A seção `partitioning_strategies` especifica as propriedades de configuração para as partições de aplicativos espaciais. Você fornece seu próprio nome para uma estratégia de particionamento (um conjunto de propriedades nesta seção) e o usa na configuração do aplicativo espacial.

```
partitioning_strategies:
  MyGridPartitioning:
    topology: "Grid"
    aabb_bounds:
      x: [0, 1000]
      y: [0, 1000]
    grid_placement_groups:
      x: 1
      y: 1
```

A propriedade `topology` especifica o tipo de sistema de coordenadas que sua simulação usará. O valor `Grid` especifica uma grade bidimensional (2D).

Para uma `Grid` topologia, o espaço de simulação é modelado como uma caixa delimitadora alinhada ao eixo (AABB). Você especifica os limites das coordenadas para cada eixo do seu AABB na propriedade. `aabb_bounds` Todas as entidades que existem espacialmente em sua simulação devem ter uma posição dentro da AABB.

## Grupos de posicionamento de grade
<a name="working-with_configuring-simulation_partitioning-strategies_placement-groups"></a>

Um **grupo de posicionamento** é uma coleção de partições espaciais de aplicativos que você SimSpace Weaver deseja colocar no mesmo trabalhador. Você especifica o número e a organização dos grupos de posicionamento (em uma grade) na `grid_placement_groups` propriedade. SimSpace Weaver tentará distribuir uniformemente as partições entre os grupos de posicionamento. As áreas de propriedade de aplicativos espaciais com partições no mesmo grupo de posicionamento serão espacialmente adjacentes.

Recomendamos que x \$1 y seja igual ao número desejado de operadores. Se não for igual, SimSpace Weaver tentará equilibrar seus grupos de colocação entre os trabalhadores disponíveis.

Se você não especificar uma configuração de grupo de posicionamento, SimSpace Weaver calculará uma para você.

# Domínios
<a name="working-with_configuring-simulation_domains"></a>

Dê um nome para um conjunto de propriedades de configuração de um domínio. A configuração de lançamento de aplicativos em um domínio determina o tipo de domínio:
+ **`launch_apps_via_start_app_call`**: domínio personalizado
+ **`launch_apps_by_partitioning_strategy`**: domínio espacial
+ **`launch_apps_per_worker`**: domínio de serviço (não incluído no aplicativo de exemplo)

**Importante**  
SimSpace Weaver suporta até 5 domínios para cada simulação. Isso inclui todos os domínios espaciais, personalizados e de serviço.

```
domains:
  MyViewDomain:
    launch_apps_via_start_app_call: {}
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip"
      launch_command: ["MyViewApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 7000
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
```

**nota**  
SimSpace Weaver Os projetos do SDK do aplicativo versão 1.12.x usam buckets separados para os arquivos.zip do aplicativo e o esquema:  
weaver- *lowercase-project-name* - *account-number* -app-zips- *region*
weaver- *lowercase-project-name* - *account-number* -esquemas- *region*

**Topics**
+ [Configuração do aplicativo](working-with_configuring-simulation_domains_app-config.md)
+ [Configurar domínios espaciais](working-with_configuring-simulation_domains_spatial.md)
+ [Endpoints de rede](working-with_configuring-simulation_domains_endpoints.md)
+ [Configurar domínios de serviço](working-with_configuring-simulation_domains_service-domains.md)

# Configuração do aplicativo
<a name="working-with_configuring-simulation_domains_app-config"></a>

Especifique a configuração de um aplicativo (`app_config`) como parte da configuração de seu domínio. Todos os tipos de domínios usam essas mesmas propriedades de configuração do aplicativo.

```
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip"
      launch_command: ["MyViewApp"]
      required_resource_units:
        compute: 1
```

**nota**  
SimSpace Weaver Os projetos do SDK do aplicativo versão 1.12.x usam buckets separados para os arquivos.zip do aplicativo e o esquema:  
weaver- *lowercase-project-name* - *account-number* -app-zips- *region*
weaver- *lowercase-project-name* - *account-number* -esquemas- *region*

A propriedade `package` especifica o URI do S3 de um arquivo .zip em um bucket do S3. O arquivo .zip contém o executável do aplicativo (também chamado de *binário*) e quaisquer outros recursos necessários (como bibliotecas). Cada instância do executável do aplicativo é executada em um contêiner do Docker em um operador. 

A propriedade `launch_command` especifica o nome do executável e todas as opções de linha de comando para executar o aplicativo. O valor de `launch_command` é uma matriz. Cada token de toda a cadeia de comando de inicialização é um elemento na matriz.

**Exemplo**
+ Para o comando de lançamento: `MyTestApp --option1 value1`
+ Especifique: `launch_command: ["MyTestApp", "-option1", "value1"]`

A `required_resource_units` propriedade especifica o número de unidades de recursos computacionais que SimSpace Weaver devem ser alocadas para esse aplicativo. Uma unidade de recursos computacionais é uma quantidade fixa de capacidade de processamento (vCPU) e memória (RAM) em um operador. É possível aumentar esse valor para incrementar a quantidade de poder de computação disponível para o aplicativo quando ele é executado em um operador. Há um número limitado de unidades de recursos computacionais em cada operador. Para obter mais informações, consulte [SimSpace Terminais e cotas do Weaver](service-quotas.md).

# Configurar domínios espaciais
<a name="working-with_configuring-simulation_domains_spatial"></a>

Para domínios espaciais, você deve especificar uma `partitioning_strategy`. O valor dessa propriedade é o nome que você deu a uma estratégia de particionamento definida em outra parte do esquema. 

```
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
```

**nota**  
SimSpace Weaver Os projetos do SDK do aplicativo versão 1.12.x usam buckets separados para os arquivos.zip do aplicativo e o esquema:  
weaver- *lowercase-project-name* - *account-number* -app-zips- *region*
weaver- *lowercase-project-name* - *account-number* -esquemas- *region*

Uma estratégia de particionamento com uma `Grid` topologia (a única topologia suportada nesta versão) SimSpace Weaver direciona a organização das partições espaciais de aplicativos desse domínio em uma grade. A propriedade `grid_partition` especifica o número de linhas e colunas da grade de partição. 

SimSpace Weaver iniciará 1 instância do aplicativo espacial para cada célula na grade de partição. Por exemplo, se um domínio espacial tiver `grid_partition` valores `x: 2` e `y: 2` houver 2 \$1 2 = 4 partições no domínio espacial. SimSpace Weaver iniciará 4 instâncias do aplicativo configurado no domínio espacial e atribuirá 1 partição a cada instância do aplicativo.

**Tópicos**
+ [Requisitos de recursos para domínios espaciais](#working-with_configuring-simulation_domains_spatial_resources)
+ [Vários domínios espaciais](#working-with_configuring-simulation_domains_spatial_multiple)
+ [Perguntas frequentes sobre domínios espaciais](#working-with_configuring-simulation_domains_spatial_faq)
+ [Solucionar problemas de domínios espaciais](#working-with_configuring-simulation_domains_spatial_troubleshooting)

## Requisitos de recursos para domínios espaciais
<a name="working-with_configuring-simulation_domains_spatial_resources"></a>

É possível atribuir até 17 unidades de recursos de computação a cada operador. Especifique o número de unidades de recursos computacionais que cada aplicativo espacial usa na seção `app_config` do seu domínio espacial.

**Example Trecho de esquema mostrando as unidades de recursos computacionais para um aplicativo espacial**  

```
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-artifacts-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
```

Para calcular o número de unidades de recursos computacionais que um domínio exige, multiplique o número de células em sua grade (em sua `grid_partition`, `x`\$1`y`) pelo número de unidades de recursos computacionais atribuídas aos aplicativos espaciais.

No exemplo anterior, o domínio `MySpatialDomain` especifica:
+ `x`: `2`
+ `y`: `2`
+ `compute`: `1`

A grade para `MySpatialDomain` tem 2 x 2 = 4 células. O domínio espacial requer 4 x 1 = 4 unidades de recursos computacionais.

O número total de unidades de recursos computacionais para todos os domínios especificados em seu esquema deve ser menor ou igual ao número `desired` de operadores multiplicado pelo número máximo de unidades de recursos computacionais para cada operador (17).

## Vários domínios espaciais
<a name="working-with_configuring-simulation_domains_spatial_multiple"></a>

É possível configurar sua simulação para usar mais de um domínio espacial. Por exemplo, você pode usar um domínio espacial para controlar os principais atores em uma simulação (como pessoas e carros) e um domínio espacial diferente para controlar o ambiente.

Você também pode usar vários domínios espaciais para atribuir recursos distintos a diferentes partes da simulação. Por exemplo, se a simulação tem um tipo de entidade que tem dez vezes mais instâncias de entidade do que outro tipo, é possível criar domínios diferentes para lidar com cada tipo de entidade e alocar mais recursos para o domínio com mais entidades.

**Importante**  
SimSpace Weaver versões anteriores à 1.14.0 não oferecem suporte a vários domínios espaciais.

**Importante**  
AWS SimSpace Weaver Localatualmente não oferece suporte a vários domínios espaciais. Para saber mais sobre o SimSpace Weaver Local, consulte [Desenvolvimento local em SimSpace Weaver](working-with_local-development.md).

**Importante**  
SimSpace Weaver suporta até 5 domínios para cada simulação. Isso inclui todos os domínios espaciais, personalizados e de serviço.

### Configurar vários domínios espaciais
<a name="working-with_configuring-simulation_domains_spatial_multiple_configure"></a>

Para configurar mais de um domínio espacial, adicione as outras definições de domínio espacial como seções nomeadas distintas em seu esquema. Cada domínio deve especificar a chave `launch_apps_by_partitioning_strategy`. Veja o esquema de exemplo a seguir.

```
sdk_version: "1.14"
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 1
clock:
  tick_rate: "30"
partitioning_strategies:
  MyGridPartitioning:
    topology: Grid
    aabb_bounds:
      x: [0, 1000]
      y: [0, 1000]
domains:
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-artifacts-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
  MySecondSpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-artifacts-us-west-2/MySpatialApp2.zip"
      launch_command: ["MySpatialApp2"]
      required_resource_units:
        compute: 1
```

### Posicionar domínios espaciais juntos
<a name="working-with_configuring-simulation_domains_spatial_multiple_placement"></a>

Em alguns cenários, você pode desejar posicionar partições para um domínio espacial em operadores ao lado de partições de outro domínio. Isso pode melhorar as características de desempenho se essas partições criarem assinaturas entre domínios.

Adicione a chave de nível superior `placement_constraints` ao seu esquema para especificar quais domínios SimSpace Weaver devem ser colocados juntos. A chave `on_workers` necessária deve se referir a uma configuração de `workers` nomeada no esquema.

**Example Trecho de esquema mostrando domínios espaciais posicionados juntos**  

```
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 2
placement_constraints:
  - placed_together: ["MySpatialDomain", "MySecondSpatialDomain"]
    on_workers: ["MyComputeWorkers"]
```

**Importante**  
Se você usa grupos de posicionamento:  
Certifique-se de que X x Y seja um múltiplo do número de operadores.
Certifique-se de que os valores do grupo de posicionamento sejam divisores comuns para as dimensões da grade dos domínios que você posicionar juntos.
Se você **não usa** grupos de posicionamento:  
Certifique-se de que um eixo de suas grades de domínio espacial tenha um divisor comum igual ao número de operadores.
Para mais informações sobre grupos de posicionamento, consulte [Estratégias de particionamento](working-with_configuring-simulation_partitioning-strategies.md#working-with_configuring-simulation_partitioning-strategies_placement-groups).

## Perguntas frequentes sobre domínios espaciais
<a name="working-with_configuring-simulation_domains_spatial_faq"></a>

### P1. Como adicionar outro domínio espacial a uma simulação existente?
<a name="working-with_configuring-simulation_domains_spatial_faq_q1"></a>
+ **Para uma simulação em execução**: não é possível alterar a configuração de uma simulação em execução. Altere a configuração do domínio no esquema, faça o carregamento do esquema e dos .zips do aplicativo e inicie uma nova simulação.
+ **Para uma nova simulação**: adicione a configuração do domínio ao esquema, carregue o esquema e os .zips do aplicativo e inicie a nova simulação.

## Solucionar problemas de domínios espaciais
<a name="working-with_configuring-simulation_domains_spatial_troubleshooting"></a>

O erro a seguir ocorre ao iniciar a simulação com uma configuração de domínio inválida.

```
"StartError": "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
    \"We were unable to determine an arrangement of your domains that would fit 
    within the provided set of workers. This can generally be resolved by 
    increasing the number of workers if able, decreasing your domains\u0027 
    [\u0027\u0027grid_partition\u0027\u0027] values, or adjusting the 
    dimensions of your [\u0027\u0027grid_placement_groups\u0027\u0027].\"}]"
```

**Possíveis causas**
+ O esquema aloca mais unidades de recursos computacionais para aplicativos do que as disponíveis para os operadores.
+ SimSpace Weaver não consigo determinar um acordo para colocar domínios juntos em trabalhadores. Isso acontece quando vários domínios espaciais são especificados, mas não há um divisor comum ou um múltiplo entre as grades de domínio, como entre uma grade 2 x 4 e uma grade 3 x 5).

# Endpoints de rede
<a name="working-with_configuring-simulation_domains_endpoints"></a>

Aplicativos personalizados e de serviço podem ter endpoints de rede aos quais clientes externos podem se conectar. Especifique uma lista de números de porta como valor para `ingress_ports` no `endpoint_config`. Esses números de porta são TCP e UDP. O aplicativo personalizado ou de serviço deve ser vinculado aos números de porta que você especifica em`ingress_ports`. SimSpace Weaver aloca dinamicamente os números das portas em tempo de execução e mapeia essas portas para as portas dinâmicas. É possível chamar a API **describe-app** depois que seus aplicativos começarem a encontrar os números de porta dinâmicos (reais). Para obter mais informações, consulte [Obtenha o endereço IP e o número da porta de um aplicativo personalizadoObtenha o endereço IP e o número da porta](working-with_get-ip.md) no tutorial de início rápido.

```
domains:
  MyViewDomain:
    launch_apps_via_start_app_call: {}
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip"
      launch_command: ["MyViewApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 7000
```

**nota**  
SimSpace Weaver Os projetos do SDK do aplicativo versão 1.12.x usam buckets separados para os arquivos.zip do aplicativo e o esquema:  
weaver- *lowercase-project-name* - *account-number* -app-zips- *region*
weaver- *lowercase-project-name* - *account-number* -esquemas- *region*

**nota**  
`endpoint_config` é uma propriedade opcional para aplicativos personalizados e de serviço. Se você não especificar um `endpoint_config`, o aplicativo não terá um endpoint de rede.

# Configurar domínios de serviço
<a name="working-with_configuring-simulation_domains_service-domains"></a>

A presença de `launch_apps_per_worker:` em uma configuração de domínio indica que é um domínio de serviço que tem aplicativos de serviço. SimSpace Weaver inicia e interrompe aplicativos de serviço para você. Quando SimSpace Weaver inicia e interrompe um aplicativo, considera-se que o aplicativo tem um *ciclo de vida gerenciado*. SimSpace Weaver atualmente suporta a inicialização de 1 ou 2 aplicativos de serviço em cada trabalhador. 

**Example Exemplo de um domínio configurado para iniciar um aplicativo de serviço em cada operador**  

```
domains:
  MyServiceDomain:
    launch_apps_per_worker:
      count: 1
    app_config:
      package: "s3://weaver-myproject-111122223333-app-zips-us-west-2/PlayerConnectionServiceApp.zip"
      launch_command: ["PlayerConnectionServiceApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 9000
          - 9001
```

**Example Exemplo de um domínio configurado para iniciar dois aplicativos de serviço em cada operador**  

```
domains:
  MyServiceDomain:
    launch_apps_per_worker:
      count: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-app-zips-us-west-2/PlayerConnectionServiceApp.zip"
      launch_command: ["PlayerConnectionServiceApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 9000
          - 9001
```

# Duração máxima de uma simulação
<a name="working-with_max-duration"></a>

Cada simulação AWS SimSpace Weaver tem uma configuração de *duração máxima* que especifica o tempo máximo em que a simulação pode ser executada. Você fornece a duração máxima como parâmetro ao iniciar uma simulação. A [interface de programação de aplicações (API) `StartSimulation`](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html) tem um parâmetro de `MaximumDuration` opcional. O valor do parâmetro é um número de minutos (m ou M), horas (h ou H) ou dias (d ou D). Por exemplo, `1h` ou `1H` significa uma hora. O SimSpace Weaver interrompe a simulação ao atingir esse limite.

## Valor máximo
<a name="working-with_max-duration_max-value"></a>

O maior valor válido para `MaximumDuration` é `14D`, ou seu equivalente em horas (`336H`) ou minutos (`20160M`).

## Valor padrão
<a name="working-with_max-duration_default-value"></a>

O parâmetro `MaximumDuration` é opcional. Se você não fornecer um valor, SimSpace Weaver use um valor de`14D`.

## Valor mínimo
<a name="working-wtih_max-duration_min-value"></a>

O menor valor válido para `MaximumDuration` é numericamente equivalente a `0`. Por exemplo, os valores `0M`, `0H` e `0D` são numericamente equivalentes a `0`.

Se você fornecer o valor mínimo para a duração máxima, sua simulação transitará imediatamente para o `STOPPING` estado assim que atingir o `STARTED` estado.

## Iniciar uma simulação usando o console
<a name="working-with_max-duration_console"></a>

É possível fornecer um valor para a **Duração máxima** ao iniciar uma simulação no [console do SimSpace Weaver](https://console.aws.amazon.com/simspaceweaver). Insira o valor no campo **Duração máxima** do formulário de **Configurações da simulação** ao escolher **Iniciar simulação**.

**Importante**  
Se você não fornecer um valor para a **Duração máxima**, o SimSpace Weaver usará o [valor padrão](#working-with_max-duration_default-value) (`14D`).

## Status de uma simulação que atinge a duração máxima
<a name="working-with_max-duration_sim-state"></a>

Quando interrompe SimSpace Weaver automaticamente uma simulação que atinge sua duração máxima, o **status** da simulação é `STOPPING` (se estiver em andamento) ou`STOPPED`. No [console do SimSpace Weaver](https://console.aws.amazon.com/simspaceweaver), o **status de destino** da simulação ainda é`STARTED`, porque esse foi o último estado solicitado por um usuário.

# Desenvolver aplicativos
<a name="working-with_developing-apps"></a>

SimSpace Weaver o desenvolvimento requer um Amazon Linux 2 (AL2) ambiente para criar aplicativos porque suas simulações são executadas em Amazon Linux no AWS Cloud. Se você estiver usando Windows, você pode usar scripts no SDK do SimSpace Weaver aplicativo para criar e iniciar um Docker contêiner que funciona AL2 com as dependências de que você precisa para criar SimSpace Weaver aplicativos. Você também pode lançar um AL2 meio ambiente usando Windows Subsystem for Linux (WSL), ou use um nativo AL2 sistema. Para obter mais informações, consulte [Configure seu ambiente local para SimSpace Weaver](setting-up_local.md).

**nota**  
Independentemente de como você configura seu ambiente de desenvolvimento local, seus aplicativos são executados em Docker contêineres quando você os carrega para serem executados no Nuvem AWS. **Seus aplicativos não têm acesso direto ao sistema operacional do host**.

**Fluxo geral de um SimSpace Weaver aplicativo**

1. Crie uma aplicação.

1. Loop:

   1. Começar a atualização criando uma `Transaction`.

      1. Sair do loop se a simulação estiver sendo encerrada.

   1. Processar eventos da entidade de assinatura e propriedade.

   1. Atualizar a simulação.

   1. Confirmar a `Transaction` para finalizar a atualização.

1. Destruir o aplicativo.

## Aplicativos espaciais
<a name="working-with_developing-apps_spatial-apps"></a>

Cada aplicativo espacial tem uma área de propriedade que é uma região espacial do mundo da simulação. As entidades localizadas na área de propriedade de um aplicativo espacial são armazenadas na partição atribuída ao aplicativo. O aplicativo espacial único tem propriedade total (permissões de leitura e gravação) sobre todas as entidades dentro da partição atribuída. Nenhum outro aplicativo pode gravar nessas entidades. O aplicativo espacial avança o estado de suas entidades. Cada aplicativo espacial possui apenas uma partição. O SimSpace Weaver usa a localização espacial de uma entidade para indexá-la e atribuí-la a uma partição espacial do aplicativo.

O SDK do SimSpace Weaver aplicativo fornece um aplicativo de amostra. Você pode encontrar o código-fonte do aplicativo espacial do aplicativo de amostra na seguinte pasta (use o separador de caminho correto para seu sistema operacional): 

```
sdk-folder\Samples\PathfindingSample\src\SpatialApp
```

## Aplicativos personalizados
<a name="working-with_developing-apps_custom-apps"></a>

Você cria e usa aplicativos personalizados para interagir com a simulação. 

**Aplicativos personalizados podem**
+ Criar entidades
+ Assinar outras partições
+ Confirme as alterações

**Fluxo geral de um aplicativo personalizado**

1. Crie uma aplicação.

1. Inscreva-se em uma região específica na simulação:

   1. Crie uma `Transaction` para começar a primeira atualização.

   1. Crie uma assinatura para a região específica.

   1. Confirme a `Transaction` para finalizar a primeira atualização.

1. Loop:

   1. Criar uma `Transaction` para começar a atualização.

      1. Sair do loop se a simulação estiver sendo encerrada.

   1. Processar as alterações no processo.

   1. Confirmar a `Transaction` para finalizar a atualização.

1. Destruir o aplicativo.

Depois que um aplicativo personalizado cria uma entidade, ele deve transferir a entidade para um domínio espacial para que a entidade exista espacialmente na simulação. SimSpace Weaver usa a localização espacial da entidade para colocar a entidade na partição espacial apropriada do aplicativo. O aplicativo personalizado que criou a entidade não pode atualizar nem excluir a entidade depois de transferi-la para um domínio espacial. 

O SDK do SimSpace Weaver aplicativo fornece um aplicativo de amostra. É possível usar os aplicativos personalizados incluídos no aplicativo de exemplo como modelos para seus próprios aplicativos personalizados. Você pode encontrar o código-fonte do aplicativo de visualização (um aplicativo personalizado) do aplicativo de amostra na seguinte pasta (use o separador de caminho correto para seu sistema operacional):

```
sdk-folder\Samples\PathfindingSample\src\ViewApp
```

# Desenvolver aplicativos cliente
<a name="working-with_developing-client-applications"></a>

Alguns motivos para conectar um cliente a uma simulação incluem:
+ Injetar informações de trânsito em tempo real em uma simulação em escala urbana.
+ Crie *human-in-the-loop*simulações, nas quais um operador humano controla alguns aspectos da simulação.
+ Permitir que os usuários interajam com a simulação, como em uma simulação de treinamento.

Os aplicativos personalizados nesses exemplos funcionam como a interface entre o estado da simulação e o mundo externo. Os clientes se conectam aos aplicativos personalizados para interagir com a simulação. 

SimSpace Weaver não lida com os aplicativos clientes e sua comunicação com seus aplicativos personalizados. Você é responsável pelo design, criação, operação e segurança dos aplicativos cliente e pela comunicação deles com os aplicativos personalizados. O SimSpace Weaver expõe apenas um endereço IP e um número de porta para cada um dos aplicativos personalizados para que os clientes possam se conectar a eles. 

O SDK do SimSpace Weaver aplicativo fornece clientes para seu aplicativo de amostra. É possível usar esses clientes como modelos para seus próprios aplicativos cliente. É possível encontrar o código-fonte dos exemplos de aplicativos cliente na seguinte pasta: 

------
#### [ Docker ]

```
sdk-folder\packaging-tools\clients\PathfindingSampleClients
```

------
#### [ WSL ]

**Importante**  
Fornecemos essas instruções para a sua conveniência. Eles são para uso com Windows Subsystem for Linux (WSL)e não são compatíveis. Para obter mais informações, consulte [Configure seu ambiente local para SimSpace Weaver](setting-up_local.md).

```
sdk-folder/packaging-tools/clients/PathfindingSampleClients
```

------

Para obter mais informações sobre como criar e usar os clientes de aplicativos de amostra, consulte os tutoriais em. [Começando com SimSpace Weaver](getting-started.md) 

# Obtenha o endereço IP e o número da porta de um aplicativo personalizado
<a name="working-with_get-ip"></a>

Para visualizar sua simulação, você cria um aplicativo personalizado e se conecta a ele com um cliente. Para obter mais informações, consulte os tutoriais em. [Começando com SimSpace Weaver](getting-started.md) Você pode usar o procedimento a seguir para obter o endereço IP e o número da porta do seu aplicativo personalizado. Use o separador de caminho apropriado para seu sistema operacional (por exemplo, `\` no Windows e `/` no Linux).

**Como obter o endereço IP e o número da porta**

1. Use a ** ListSimulations**API para obter o nome da sua simulação.

   ```
   aws simspaceweaver list-simulations
   ```

   Resultado do exemplo:

   ```
   {
       "Simulations": [
           {
               "Status": "STARTED",
               "CreationTime": 1664921418.09,
               "Name": "MyProjectSimulation_22-10-04_22_10_15",
               "Arn": "arn:aws:simspaceweaver:us-west-2: 111122223333:simulation/MyProjectSimulation_22-10-04_22_10_15",
               "TargetStatus": "STARTED"
           }
       ]
   
   }
   ```

1. Use a ** DescribeSimulation**API para obter uma lista de domínios em sua simulação.

   ```
   aws simspaceweaver describe-simulation --simulation simulation-name
   ```

   Procure a seção `Domains` na seção `LiveSimulationState` da saída.

   Resultado do exemplo:

   ```
       "LiveSimulationState": {
           "Domains": [
               {
                   "Type": "",
                   "Name": "MySpatialSimulation",
                   "Lifecycle": "Unknown"
               },
               {
                   "Type": "",
                   "Name": "MyViewDomain",
                   "Lifecycle": "ByRequest"
               }
           ],
   ```

1. Use a ** ListApps**API para obter uma lista de aplicativos personalizados em um domínio. Por exemplo, o nome de domínio do aplicativo de visualização (personalizado) no projeto de amostra é`MyViewDomain`. Procure o nome do aplicativo na saída.

   ```
   aws simspaceweaver list-apps --simulation simulation-name --domain domain-name
   ```

   Resultado do exemplo:

   ```
    
   {
       "Apps": [
           {
               "Status": "STARTED",
               "Domain": "MyViewDomain",
               "TargetStatus": "STARTED",
               "Name": "ViewApp",
               "Simulation": "MyProjectSimulation_22-10-04_22_10_15"
           }
       ]
   }
   ```

1. Use a ** DescribeApp**API para obter o endereço IP e o número da porta. Para o projeto de exemplo, o nome do domínio é `MyViewDomain` e o nome do aplicativo é `ViewApp`. 

   ```
   aws simspaceweaver describe-app --simulation simulation-name --domain domain-name --app app-name
   ```

   O endereço IP e o número da porta estão no bloco do `EndpointInfo` na saída. O endereço IP é o valor de `Address` e o número da porta é o valor de `Actual`.

   Resultado do exemplo:

   ```
   {
       "Status": "STARTED",
       "Domain": "MyViewDomain",
       "TargetStatus": "STARTED",
       "Simulation": "MyProjectSimulation_22-10-04_22_10_15",
       "LaunchOverrides": {
           "LaunchCommands": []
       },
       "EndpointInfo": {
           "IngressPortMappings": [
               {
                   "Declared": 7000,
                   "Actual": 4321
               }
           ],
           "Address": "198.51.100.135"
       },
       "Name": "ViewApp"
   }
   ```
**nota**  
O valor de `Declared` é o número da porta à qual o código do seu aplicativo deve ser vinculado. O valor de `Actual` é o número da porta que é SimSpace Weaver exposta aos clientes para se conectarem ao seu aplicativo. SimSpace Weaver mapeia a `Declared` porta até a `Actual` porta.

# Lançamento do cliente de visualização Unreal Engine
<a name="working-with_unreal-client"></a>

 Navegue até: 

```
sdk-folder/Samples/PathfindingSample/tools/cloud
```

1. Execute um dos seguintes comandos:
   + Docker: `python quick-start.py`
   + WSL: `python quick-start.py --al2`

1. Obtenha o endereço IP e o número da porta “real”. Eles estarão na saída do console da execução do quick-start.py ou obtenha-os seguindo os procedimentos em[Obtenha o endereço IP e o número da porta de um aplicativo personalizadoObtenha o endereço IP e o número da porta](working-with_get-ip.md).

1.  Navegue até: 

   ```
   sdk-folder/Clients/TCP/UnrealClient/lib
   ```

1.  Execute os seguintes comandos para criar a biblioteca NNG: 

   ```
   cmake -S . -B build 
   cmake --build build --config RelWithDebInfo 
   cmake --install build
   ```

1.  Em um **editor de texto**, abra `view_app_url.txt`. 

1.  Atualize a URL com o endereço IP e o número da porta do seu aplicativo de visualização: `tcp://ip-address:actual-port-number` (deve ser semelhante a `tcp://198.51.100.135:1234`). 

1.  No **editor Unreal**, escolha **jogar**. 

## Solução de problemas
<a name="working-with_unreal-client_troubleshooting"></a>
+  **A etapa de CMake instalação do NNG falha com “Talvez precise de privilégios administrativos “:** 

  ```
  CMake Error at build/_deps/nng-build/src/cmake_install.cmake:39 (file):
    file cannot create directory: C:/Program Files
    (x86)/ThirdPartyNngBuild/lib.  Maybe need administrative privileges.
  Call Stack (most recent call first):
    build/_deps/nng-build/cmake_install.cmake:37 (include)
    build/cmake_install.cmake:73 (include)
  ```
  +  **Resolução:** Se `nng.lib` ou `nng.so` existir no diretório UnrealClient /lib, esse erro pode ser ignorado com segurança. Caso contrário, tente executar os comandos cmake build em um terminal com privilégios de administrador. 
+  **“CMake para encontrar um arquivo de configuração de pacote fornecido pelo nng”:** 

  ```
  CMake Error at CMakeLists.txt:23 (find_package):
  By not providing "Findnng.cmake" in CMAKE_MODULE_PATH this project has
   asked CMake to find a package configuration file provided by "nng", but
   CMake did not find one.
  ```
  +  **Resolução:** CMake está tendo problemas para encontrar o `Findnng.cmake` arquivo. Ao criar com CMake, adicione o argumento`-DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty`. Certifique-se de que o `Findnng.cmake` arquivo ainda esteja no `ThirdParty` diretório antes de executar novamente a compilação. CMake 

    ```
    cmake -S . -B build -DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty
    cmake --build build --config RelWithDebInfo 
    cmake --install build
    ```

# Desenvolvimento local em SimSpace Weaver
<a name="working-with_local-development"></a>

Você pode implantar seus SimSpace Weaver aplicativos localmente para testes e depuração rápidos.

**Requisitos**
+ Siga as etapas em [Configurando para SimSpace Weaver](setting-up.md).

**Topics**
+ [Etapa 1: Inicie sua simulação local](working-with_local_launch.md)
+ [Etapa 2: Visualize sua simulação local](working-with_local-development_view.md)
+ [Etapa 3: interrompa sua simulação local (opcional no Windows)](working-with_local-development_stop-sim.md)
+ [Solução de problemas de desenvolvimento local em SimSpace Weaver](working-with_local-development_troubleshooting.md)

# Etapa 1: Inicie sua simulação local
<a name="working-with_local_launch"></a>

1. Navegue até

   ```
   cd sdk-folder/Samples/sample-name/tools/local
   ```

1. Execute o comando a seguir para criar e iniciar sua simulação localmente.

   ```
   python quick-start.py
   ```

   Esse script fará o seguinte:

   1. Crie o projeto.
      +  `quick-start.py`chama a `build_project` função definida em build.py. Essa etapa variará de acordo com o projeto. Para o PathfindingSample, CMake é usado. O comando CMake e Docker pode ser encontrado em build.py. 

   1. Inicie sua simulação local
      + O script iniciará um processo local para cada partição espacial definida no esquema.
      + O script iniciará um processo para cada aplicativo personalizado definido no esquema.
      + Os aplicativos espaciais serão lançados primeiro, seguidos pelos aplicativos personalizados — cada um na ordem em que aparecem no esquema.

**Importante**  
Ao iniciar em um ambiente que não suporta GUI, como uma sessão SSH do console, use a `--noappwindow` opção para redirecionar toda a saída para o terminal atual.

**Importante**  
Para usuários de Linux, o script pressupõe que seu sistema tenha o `xterm` comando. Se sua distribuição Linux não tiver o `xterm` comando, use a `--noappwindow` opção para redirecionar toda a saída para o terminal atual.
+  -h, --help 
  +  Liste esses parâmetros. 
+  --limpar 
  +  Exclua o conteúdo do diretório de compilação antes de compilar. 
+  --sem construção 
  +  Pule a reconstrução do projeto. 
+  --nenhuma janela de aplicativo 
  +  Não abra uma nova janela para cada aplicativo. Em vez disso, redirecione o stdout para o terminal atual. 
+  --arquivo de log 
  +  Grave a saída do console em um arquivo de registros. 
+  --cliente do console 
  +  Conecte automaticamente o cliente do console listado na configuração. 
+  --esquema esquema
  + Qual esquema essa invocação usará. O padrão é 'SCHEMA' em config.py. 

# Etapa 2: Visualize sua simulação local
<a name="working-with_local-development_view"></a>

Para visualizar sua simulação local, você pode usar qualquer um dos clientes incluídos no SimSpaceWeaverAppSdkDistributable. Para obter mais informações sobre como criar e usar os clientes de amostra, consulte os tutoriais em. [Começando com SimSpace Weaver](getting-started.md)

Você deve atualizar o endereço IP e o número da porta no cliente para se conectar ao aplicativo de visualização para a simulação local. Sempre use os seguintes valores com SimSpace Weaver Local:

```
tcp://127.0.0.1:7000
```

Dependendo do cliente selecionado, você pode atualizar o endereço IP e o número da porta da seguinte forma:
+ **Unreal**: altera a URL na linha 1 do `view_app_url.txt`
+ **Console**: inicia o cliente com o endereço IP e a URL do número da porta como parâmetro

# Etapa 3: interrompa sua simulação local (opcional no Windows)
<a name="working-with_local-development_stop-sim"></a>

**nota**  
Essa etapa é obrigatória no Linux, mas opcional no Windows.

1.  Navegue até: 

   ```
   sdk-folder/Samples/sample-name/tools/local
   ```

1.  Execute o comando a seguir para interromper sua simulação local e excluir quaisquer recursos de memória compartilhada. 

   ```
   python stop-and-delete.py
   ```

    Esse script fará o seguinte: 
   +  Pare os processos locais. 
   +  Exclua o objeto de memória compartilhada (necessário somente no Linux). 

**stop-and-deleteparâmetros.py**
+  -h, --help 
  +  Liste esses parâmetros. 
+  --parar 
  +  Apenas tente interromper os processos. 
+  --excluir 
  +  Apenas tente excluir os recursos de memória compartilhada. 
+  --processo 
  +  O nome do processo a interromper. Use isso se o nome do seu processo não corresponder ao nome do pacote no esquema. 
+  --esquema esquema 
  +  Qual esquema essa invocação usará. O padrão é o valor de 'SCHEMA' em config.py. 

# Solução de problemas de desenvolvimento local em SimSpace Weaver
<a name="working-with_local-development_troubleshooting"></a>
+  **Linux: comando xterm não encontrado/não pode ser aberto** 
  + Os scripts locais presumem que o comando xterm existe quando executado no Linux. Se você não tiver o comando xterm ou estiver executando em um ambiente que não oferece suporte à GUI, use a `--noappwindow` opção ao executar o script de início rápido.
+  **Nenhuma janela de aplicativo está abrindo\$1** 
  +  Isso acontece quando a simulação local falha imediatamente. Para ver a saída do console após a falha, use as `--logfile` opções `--noappwindow` ou ao executar o script de início rápido. 
+  **A simulação não funciona depois que o aplicativo de visualização é iniciado ou o cliente de visualização se conecta\$1** 
  +  A execução com a `—noappwindow` opção normalmente resolve esses tipos de problemas. Caso contrário, reiniciar algumas vezes também terá sucesso (embora em uma taxa muito menor). 

# AWS SimSpace Weaver SDK do aplicativo
<a name="working-with_app-sdk"></a>

O SDK do SimSpace Weaver aplicativo fornece APIs que você pode usar para controlar as entidades em sua simulação e responder aos SimSpace Weaver eventos. Isso inclui o seguinte namespace: 
+ **API**: principais definições da API e seu uso

Link com a seguinte biblioteca:
+ `libweaver_app_sdk_cxx_v1_full.so`

**Importante**  
A biblioteca está disponível para vinculação dinâmica quando você executa os aplicativos no Nuvem AWS. Não é necessário carregá-la com os aplicativos.

**nota**  
O SDK do SimSpace Weaver aplicativo APIs controla os dados em sua simulação. Eles APIs são separados do SimSpace Weaver serviço APIs, que controla seus recursos SimSpace Weaver de serviço (como simulações, aplicativos e relógios) em. AWS Para obter mais informações, consulte [SimSpace Weaver Referências de API](api-reference.md).

**Topics**
+ [Os métodos da API retornam um Result](working-with_app-sdk_return-result.md)
+ [Interagir com o SDK do aplicativo no nível superior](working-with_app-sdk_top-level.md)
+ [Gerenciamento de simulações](working-with_app-sdk_sim.md)
+ [Assinaturas](working-with_app-sdk_sub.md)
+ [Entidades](working-with_app-sdk_ent.md)
+ [Eventos da entidade](working-with_app-sdk_events.md)
+ [Result e tratamento de erros](working-with_app-sdk_result.md)
+ [Genéricos e tipos de domínio](working-with_app-sdk_generics.md)
+ [Operações diversas do SDK do aplicativo](working-with_app-sdk_misc.md)

# Os métodos da API retornam um Result
<a name="working-with_app-sdk_return-result"></a>

A maioria das funções da SimSpace Weaver API tem um tipo de retorno`Aws::WeaverRuntime::Result<T>`. Se a função for executada com sucesso, o `Result` conterá `T`. Caso contrário, o `Result` contém um `Aws::WeaverRuntime::ErrorCode` que representa um código de erro do Rust App SDK.

**Example Exemplo**  

```
Result<Transaction> BeginUpdate(Application& app)
```

Esse método:
+ Retorna `Transaction` se `BeginUpdate()` for executado com sucesso.
+ Retorna `Aws::WeaverRuntime::ErrorCode` caso o `BeginUpdate()` falhe.

# Interagir com o SDK do aplicativo no nível superior
<a name="working-with_app-sdk_top-level"></a>

**Ciclo de vida**
+ O SDK do SimSpace Weaver aplicativo gerencia o ciclo de vida do aplicativo. Não é preciso ler ou gravar o estado do ciclo de vida de um aplicativo.

**Partições**
+ Use `Result <PartitionSet> AssignedPartitions(Transaction& txn);` para obter partições próprias.
+ Use `Result <PartitionSet> AllPartitions(Transaction& txn);` para obter todas as partições na simulação.

# Gerenciamento de simulações
<a name="working-with_app-sdk_sim"></a>

Esta seção descreve soluções para tarefas comuns de gerenciamento de simulações.

**Topics**
+ [Iniciar uma simulação](working-with_app-sdk_sim_start.md)
+ [Atualizar uma simulação](working-with_app-sdk_sim_update.md)
+ [Encerrar uma simulação](working-with_app-sdk_sim_terminate.md)

# Iniciar uma simulação
<a name="working-with_app-sdk_sim_start"></a>

Usar `CreateApplication()` para criar um app.

**Example Exemplo**  

```
Result<Application> applicationResult = Api::CreateApplication();

if (!applicationResult)
{
    ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(applicationResult);

    std::cout << "Failed to create application. Error code " <<
        static_cast<std::underlying_type_t<ErrorCode>>(errorCode) <<
        " Last error message "<< Api::LastErrorMessage() << ".";

    return 1;
}

/**
* Run simulation
*/
RunSimulation(std::move(applicationResult.assume_value()));
```

# Atualizar uma simulação
<a name="working-with_app-sdk_sim_update"></a>

Use as seguintes funções de `BeginUpdate` para atualizar o aplicativo:
+ `Result<Transaction> BeginUpdate(Application& app)`
+ `Result<bool> BeginUpdateWillBlock(Application& app)`: informa se o `BeginUpdate()` bloqueará ou não.

Execute `Result<void> Commit(Transaction& txn)` para confirmar as alterações.

**Example Exemplo**  

```
Result<void> AppDriver::RunSimulation(Api::Application app) noexcept
{
    while (true)
    {
        {
            bool willBlock;

            do
            {
                WEAVERRUNTIME_TRY(willBlock, Api::BeginUpdateWillBlock(m_app));
            } while (willBlock);
        }

        WEAVERRUNTIME_TRY(Transaction transaction, Api::BeginUpdate(app));

        /**
         * Simulate app.
         */
        WEAVERRUNTIME_TRY(Simulate(transaction));
        WEAVERRUNTIME_TRY(Api::Commit(std::move(transaction)));
    }

    return Success();
}
```

# Encerrar uma simulação
<a name="working-with_app-sdk_sim_terminate"></a>

Use `Result<void> DestroyApplication(Application&& app)` para encerrar o aplicativo e a simulação.

Outros aplicativos descobrem que a simulação é encerrada quando recebem `ErrorCode::ShuttingDown` de chamadas para `BeginUpdateWillBlock()` ou `BeginUpdate()`. Quando um aplicativo recebe `ErrorCode::ShuttingDown`, ele pode chamar `Result<void> DestroyApplication(Application&& app)` para se encerrar.

**Example Exemplo**  

```
Result<void> AppDriver::EncounteredAppError(Application&& application) noexcept
{
    const ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(runAppResult);

    switch (errorCode)
    {
    case ErrorCode::ShuttingDown:
        {
            // insert custom shutdown process here.

            WEAVERRUNTIME_TRY(Api::DestroyApplication(std::move(application)));
            return Success();
        }
    default:
        {
            OnAppError(errorCode);
            return errorCode;
        }
    }
}
```

**Importante**  
Apenas chame `Result<void> DestroyApplication(Application&& app)` após `Api::Commit()`. Destruir um aplicativo durante uma atualização pode causar um comportamento indefinido.

**Importante**  
Você deve chamar `DestroyApplication()` antes do encerramento do programa para garantir que o aplicativo seja relatado como encerrado com êxito.  
Deixar de chamar `DestroyApplication()` quando o programa for encerrado fará com que o status seja considerado como `FATAL`.

# Assinaturas
<a name="working-with_app-sdk_sub"></a>

Crie uma assinatura com uma área de assinatura e um ID de domínio. O ID do domínio representa o domínio que possui essa área de assinatura. Uma `BoundingBox2F32` descreve a área de assinatura. Use a seguinte função para criar uma assinatura:

```
Result<SubscriptionHandle> CreateSubscriptionBoundingBox2F32(Transaction& txn, DomainId id, const BoundingBox2F32& boundingBox)
```

**Example Exemplo**  

```
Result<void> CreateSubscriptionInSpatialDomain(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(Api::PartitionSet partitionSet, Api::AllPartitions(transaction)); 
    
    Api::DomainId spatialDomainId;

    for (const Api::Partition& partition : partitionSet.partitions)
    {
        if (partition.domain_type == Api::DomainType::Spatial)
        {
            /**
            * Get the spatial domain ID.
            */
            spatialDomainId = partition.domain_id;
            break;
        }
    }
    
    constexpr Api::BoundingBox2F32 subscriptionBounds { 
        /* min */ { /* x */ 0, /* y */ 0 }, 
        /* max */ { /* x */ 1000, /* y */ 1000 } }

    WEAVERRUNTIME_TRY(
        Api::SubscriptionHandle subscriptionHandle,
        Api::CreateSubscriptionBoundingBox2F32(
        transaction,
        spatialDomainId,
        subscriptionBounds));
        
    return Success();
}
```

Você pode usar o `Api::SubscriptionHandle` retornado por `CreateSubscriptionBoundingBox2F32()` para modificar a assinatura. Transfira-o como argumento para as seguintes funções:

```
Result<void> ModifySubscriptionBoundingBox2F32(Transaction& txn, SubscriptionHandle handle, const BoundingBox2F32& boundingBox)
```

```
Result<void> DeleteSubscription(Transaction& txn, SubscriptionHandle handle)
```

# Entidades
<a name="working-with_app-sdk_ent"></a>

Você liga para o `Store` e `Load` APIs usando o `Api:Entity` do `Result<Api::Entity>` retornado de `CreateEntity()` ou de um evento de mudança de propriedade quando uma entidade entra na área de assinatura do aplicativo (para obter mais informações, consulte[Eventos da entidade](working-with_app-sdk_events.md)). Recomendamos que você rastreie seus `Api::Entity` objetos para poder usá-los com eles APIs.

**Topics**
+ [Criar entidades](working-with_app-sdk_ent_create.md)
+ [Transferir uma entidade para um domínio espacial](working-with_app-sdk_ent_transfer.md)
+ [Gravar e ler dados do campo da entidade](working-with_app-sdk_ent_readwrite.md)
+ [Armazenar a posição de uma entidade](working-with_app-sdk_ent_store-position.md)
+ [Carregar a posição de uma entidade](working-with_app-sdk_ent_load-position.md)

# Criar entidades
<a name="working-with_app-sdk_ent_create"></a>

Use `CreateEntity()` para criar uma entidade. Defina o significado de `Api::TypeId` que você transferirá para essa função.

```
Namespace
{
    constexpr Api::TypeId k_entityTypeId { /* value */ 512 };
}

Result<void> CreateEntity(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(
        Api::Entity entity,
        Api::CreateEntity(
            transaction, Api::BuiltinTypeIdToTypeId(k_entityTypeId )));
}
```

**nota**  
Os valores de 0-511 para `Api::BuiltinTypeId` são reservados. Sua entidade TypeID (`k_entityTypeId`neste exemplo) deve ter um valor de 512 ou superior.

# Transferir uma entidade para um domínio espacial
<a name="working-with_app-sdk_ent_transfer"></a>

Depois que um aplicativo personalizado ou de serviço cria uma entidade, deve transferir a entidade para um domínio espacial para que a entidade exista espacialmente na simulação. As entidades em um domínio espacial podem ser lidas por outros aplicativos e atualizadas por um aplicativo espacial. Use a API `ModifyEntityDomain()` para transferir uma entidade para um domínio espacial.

```
AWS_WEAVERRUNTIME_API Result<void> ModifyEntityDomain(Transaction& txn, const Entity& entity, DomainId domainId) noexcept;
```

Se `DomainId` não corresponder à `Partition` atribuída pelo aplicativo de chamada, então `DomainId` deve ser para um `Domain` de `DomainType::Spatial`. A transferência de propriedade para o novo `Domain` ocorre durante `Commit(Transaction&&)`.Parâmetros

`txn`  
A `Transaction` atual.

`entity`  
A `Entity` de destino para a mudança de `Domain`.

`domainId`  
O `DomainId` do `Domain` de destino para a `Entity`.

Essa API retornará `Success` se o domínio da entidade tiver sido alterado com sucesso.

# Gravar e ler dados do campo da entidade
<a name="working-with_app-sdk_ent_readwrite"></a>

Todos os campos de dados da entidade são do tipo blob. É possível gravar até 1.024 bytes de dados em uma entidade. Recomendamos manter os blobs tão pequenos quanto possível, pois tamanhos maiores reduzirão o desempenho. Ao gravar em um blob, você passa SimSpace Weaver um ponteiro para os dados e seu comprimento. Quando você lê um blob, o SimSpace Weaver fornece um ponteiro e um comprimento para a leitura. Todas as leituras devem ser concluídas antes da chamada `Commit()` no aplicativo. Os ponteiros retornados de uma chamada de leitura são invalidados quando o aplicativo chama `Commit()`.

**Importante**  
A leitura de um ponteiro de blob em cache após `Commit()` não é suportada e pode fazer com que a simulação falhe.
A gravação em um ponteiro blob retornado de uma chamada de leitura não é suportada e pode fazer com que a simulação falhe.

**Topics**
+ [Armazenar dados de campo de uma entidade](working-with_app-sdk_ent_readwrite_store.md)
+ [Carregar os dados de campo de uma entidade](working-with_app-sdk_ent_readwrite_load.md)
+ [Carregar dados de campo de entidades removidas](working-with_app-sdk_ent_readwrite_load-removed.md)

# Armazenar dados de campo de uma entidade
<a name="working-with_app-sdk_ent_readwrite_store"></a>

Os exemplos a seguir demonstram como armazenar (gravar no State Fabric) os dados de campo de uma entidade de propriedade do aplicativo. Esses exemplos usam a função a seguir:

```
AWS_WEAVERRUNTIME_API Result<void> StoreEntityField(
    Transaction& txn,
    const Entity& entity,
    TypeId keyTypeId,
    FieldIndex index,
    std::int8_t* src,
    std::size_t length) noexcept;
```

O parâmetro `Api::TypeId keyTypeId` representa o tipo de dados transmitidos.

O parâmetro `Api::TypeId keyTypeId` deve receber o correspondente `Api::TypeId` de `Api::BuiltinTypeId`. Se não houver uma conversão apropriada, use `Api::BuiltinTypeId::Dynamic`.

Para tipos de dados complexos, use `Api::BuiltInTypeId::Dynamic`.

**nota**  
O valor de `FieldIndex index` deve ser maior que 0. O valor 0 é reservado para a chave de índice (consulte `StoreEntityIndexKey()`).

**Example Exemplo de uso de tipos de dados primitivos**  

```
namespace
{
    constexpr Api::FieldIndex k_isTrueFieldId { /* value */ 1 };
}

Result<void> SetEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    bool value = true;
    
    auto* src = reinterpret_cast<std::int8_t*>(value);
    size_t length = sizeof(*value);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Bool),
        k_isTrueFieldId,
        src,
        length));
}
```

**Example Exemplo usando um struct para armazenar os dados**  

```
namespace
{
    constexpr Api::FieldIndex k_dataFieldId { /* value */ 1 };
}

struct Data
{
    bool boolData;
    float floatData;
};

Result<void> SetEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    Data data = { /* boolData */ false, /* floatData */ -25.93 };
    
    auto* src = reinterpret_cast<std::int8_t*>(data);
    size_t length = sizeof(*data);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Dynamic),
        k_dataFieldId,
        src,
        length));
}
```

# Carregar os dados de campo de uma entidade
<a name="working-with_app-sdk_ent_readwrite_load"></a>

Os exemplos a seguir demonstram como carregar (ler no State Fabric) os dados de campo de uma entidade. Esses exemplos usam a seguinte função:

```
Result<std::size_t> LoadEntityField(
    Transaction& txn,
    const Entity& entity,
    TypeId keyTypeId,
    FieldIndex index,
    std::int8_t** dest) noexcept;
```

O parâmetro `Api::TypeId keyTypeId` deve receber o correspondente `Api::TypeId` de `Api::BuiltinTypeId`. Se não houver uma conversão apropriada, use `Api::BuiltinTypeId::Dynamic`.

**nota**  
O valor do índice `FieldIndex` deve ser maior que 0. O valor 0 é reservado para a chave de índice (consulte `StoreEntityIndexKey()`).

**Example Exemplo de uso de tipos de dados primitivos**  

```
namespace
{
    constexpr Api::FieldIndex k_isTrueFieldId { /* value */ 1 };
}

Result<void> LoadEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Api::LoadEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Bool),
        k_isTrueFieldId,
        &dest));
    
    bool isTrueValue = *reinterpret_cast<bool*>(dest);
}
```

**Example Exemplo usando um struct para armazenar os dados**  

```
namespace
{
    constexpr Api::FieldIndex k_dataFieldId { /* value */ 1 };
}

struct Data
{
    bool boolData;
    float floatData;
};

Result<void> LoadEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Api::LoadEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Dynamic),
        k_dataFieldId,
        &dest));
    
    Data dataValue = *reinterpret_cast<Data*>(dest);
}
```

# Carregar dados de campo de entidades removidas
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

Não é possível carregar (ler no State Fabric) dados de campos de entidades que foram removidas das áreas de propriedade e assinatura do aplicativo. O exemplo a seguir resulta em um erro porque chama `Api::LoadIndexKey()` em uma entidade como resultado de uma `Api::ChangeListAction::Remove`. O segundo exemplo mostra uma forma correta de armazenar e carregar dados da entidade diretamente no aplicativo.

**Example Exemplo de código incorreto**  

```
Result<void> ProcessSubscriptionChanges(Transaction& transaction)
{
    /* ... */
    
    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, 
        Api::AllSubscriptionEvents(transaction));
    
    for (const Api::SubscriptionEvent& event : 
        subscriptionChangeList.changes)
    {
        switch (event.action)
        {
        case Api::ChangeListAction::Remove:
            {
                std::int8_t* dest = nullptr;
    
                /**
                 * Error!
                 * This calls LoadEntityIndexKey on an entity that
                 * has been removed from the subscription area.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));
    
                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                break;
            }
        }
 
    }

    /* ... */
}
```

**Example Exemplo de uma forma correta de armazenar e carregar dados da entidade no aplicativo**  

```
Result<void> ReadAndSaveSubscribedEntityPositions(Transaction& transaction)
{
    static std::unordered_map<Api::EntityId, AZ::Vector3> 
        positionsBySubscribedEntity;

    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, 
        Api::AllSubscriptionEvents(transaction));

    for (const Api::SubscriptionEvent& event : 
        subscriptionChangeList.changes)
    {
        switch (event.action)
        {
        case Api::ChangeListAction::Add:
            {
                std::int8_t* dest = nullptr;

                /**
                 * Add the position when the entity is added.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));

                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                positionsBySubscribedEntity.emplace(
                    event.entity.descriptor->id, position);

                break;
            }
        case Api::ChangeListAction::Update:
            {
                std::int8_t* dest = nullptr;

                /**
                 * Update the position when the entity is updated.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));

                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                positionsBySubscribedEntity[event.entity.descriptor->id] = 
                    position;

                break;
            }
        case Api::ChangeListAction::Remove:
            {
                /**
                 * Load the position when the entity is removed.
                 */
                AZ::Vector3 position = positionsBySubscribedEntity[
                    event.entity.descriptor->id];

                /**
                 * Do something with position...
                 */
                break;
            }
        }
    }
    
    /* ... */
}
```

# Armazenar a posição de uma entidade
<a name="working-with_app-sdk_ent_store-position"></a>

Você pode armazenar (gravar no State Fabric) a posição de uma entidade usando uma estrutura de dados inteira. Esses exemplos usam a seguinte função:

```
Result<void> StoreEntityIndexKey(
    Transaction& txn, 
    const Entity& entity, 
    TypeId keyTypeId, 
    std::int8_t* src, 
    std::size_t length)
```

**nota**  
Forneça `Api::BuiltinTypeId::Vector3F32` para `Api::StoreEntityIndexKey()`, conforme mostrado nos exemplos a seguir.

**Example Exemplo de uso de uma matriz para representar a posição**  

```
Result<void> SetEntityPositionByFloatArray(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::array<float, 3> position = { /* x */ 25, /* y */ 21, /* z */ 0 };
    
    auto* src = reinterpret_cast<std::int8_t*>(position.data());
    std::size_t length = sizeof(position);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(Api::BuiltinTypeId::Vector3F32),
        src,
        length));
}
```

**Example Exemplo usando um struct para representar a posição**  

```
struct Position 
{
   float x;
   float y;
   float z;
};

Result<void> SetEntityPositionByStruct(
    Api::Entity& entity, 
    Transaction& transaction)
{
    Position position = { /* x */ 25, /* y */ 21, /* z */ 0 };
    
    auto* src = reinterpret_cast<std::int8_t*>(&position);
    std::size_t length = sizeof(position);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(Api::BuiltinTypeId::Vector3F32),
        src,
        length));
}
```

# Carregar a posição de uma entidade
<a name="working-with_app-sdk_ent_load-position"></a>

Você pode carregar (ler no State Fabric) a posição de uma entidade usando uma estrutura de dados inteira. Esses exemplos usam a seguinte função:

**nota**  
Forneça `Api::BuiltinTypeId::Vector3F32` para `Api::LoadEntityIndexKey()`, conforme mostrado nos exemplos a seguir.

**Example Exemplo de uso de uma matriz para representar a posição**  

```
Result<void> GetEntityPosition(Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Aws::WeaverRuntime::Api::LoadEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Vector3F32),
        &dest));
        
    std::array<float, 3> position = 
        *reinterpret_cast<std::array<float, 3>*>(dest);
}
```

**Example Exemplo usando um struct para representar a posição**  

```
struct Position 
{struct
   float x;
   float y;
   float z;
};

Result<void> GetEntityPosition(Api::Entity& entity, Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Aws::WeaverRuntime::Api::LoadEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Vector3F32),
        &dest));
        
    Position position = *reinterpret_cast<Position*>(dest);
}
```

# Eventos da entidade
<a name="working-with_app-sdk_events"></a>

Você pode usar as seguintes funções no SDK do SimSpace Weaver aplicativo para obter todos os eventos de propriedade e assinatura:
+ `Result<OwnershipChangeList> OwnershipChanges(Transaction& txn) `
+ `Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn) `

Você pode usar a estrutura de SimSpace Weaver demonstração se precisar de processamento de eventos de entidade orientado por retorno de chamada. Para obter mais informações, consulte o seguinte arquivo de cabeçalho:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/DemoFramework/EntityEventProcessor.h`

Também é possível criar seu próprio processamento de eventos de entidade.

**Topics**
+ [Iterar eventos para entidades próprias](working-with_app-sdk_events_own.md)
+ [Iterar eventos para entidades assinadas](working-with_app-sdk_events_sub.md)
+ [Iterar eventos de mudança de propriedade para entidades](working-with_app-sdk_events_change.md)

# Iterar eventos para entidades próprias
<a name="working-with_app-sdk_events_own"></a>

Use `OwnershipChanges()` para obter uma lista de eventos para entidades próprias (entidades na área de propriedade do aplicativo). A função tem a assinatura a seguir:

```
Result<OwnershipChangeList> OwnershipChanges(Transaction& txn)
```

Faça a iteração das entidades com um loop, conforme demonstrado no exemplo a seguir.

**Example Exemplo**  

```
WEAVERRUNTIME_TRY(Result<Api::OwnershipChangeList> ownershipChangesResult, Api::OwnershipChanges(transaction));

for (const Api::OwnershipChange& event : ownershipChangeList.changes)
{
    Api::Entity entity = event.entity;
    Api::ChangeListAction action = event.action;

    switch (action)
    {
    case Api::ChangeListAction::None:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Remove:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Add:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Update:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Reject:
        // insert code to handle the event
        break;
    }
}
```

**Tipos de eventos**
+ `None`: a entidade está na área e os dados de posição e campo não foram modificados.
+ `Remove`: a entidade foi removida da área.
+ `Add`: a entidade foi adicionada à área.
+ `Update`: a entidade está na área e foi modificada.
+ `Reject`: o aplicativo falhou ao remover a entidade da área.

**nota**  
No caso de um evento `Reject`, o aplicativo tentará a transferência novamente na próxima marcação.

# Iterar eventos para entidades assinadas
<a name="working-with_app-sdk_events_sub"></a>

Use `AllSubscriptionEvents()` para obter uma lista de eventos para entidades assinadas (entidades na área de assinatura do aplicativo). A função tem a assinatura a seguir:

```
Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn)
```

Faça a iteração das entidades com um loop, conforme demonstrado no exemplo a seguir.

**Example Exemplo**  

```
WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, Api::AllSubscriptionEvents(transaction));

for (const Api::SubscriptionEvent& event : subscriptionChangeList.changes)
{
    Api::Entity entity = event.entity;
    Api::ChangeListAction action = event.action;

    switch (action)
    {
    case Api::ChangeListAction::None:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Remove:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Add:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Update:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Reject:
        // insert code to handle the event
        break;
    }
}
```

**Tipos de eventos**
+ `None`: a entidade está na área e os dados de posição e campo não foram modificados.
+ `Remove`: a entidade foi removida da área.
+ `Add`: a entidade foi adicionada à área.
+ `Update`: a entidade está na área e foi modificada.
+ `Reject`: o aplicativo falhou ao remover a entidade da área.

**nota**  
No caso de um evento `Reject`, o aplicativo tentará a transferência novamente na próxima marcação.

# Iterar eventos de mudança de propriedade para entidades
<a name="working-with_app-sdk_events_change"></a>

Para obter eventos em que uma entidade se move entre uma área de propriedade e uma área de assinatura, compare as mudanças entre os eventos atuais e anteriores de propriedade e assinatura da entidade.

Lide com esses eventos lendo:
+ `Api::SubscriptionChangeList`
+ `Api::OwnershipEvents`

Compare as alterações com os dados armazenados anteriormente.

O exemplo a seguir mostra como lidar com eventos de mudança de propriedade da entidade. Este exemplo pressupõe que, para entidades em transição entre entidades subscritas e entidades de propriedade (em qualquer direção), o remove/add event occurs first followed by the subscription remove/add evento de propriedade na próxima marca. 

**Example Exemplo**  

```
Result<void> ProcessOwnershipEvents(Transaction& transaction)
{
    using EntityIdsByAction =
        std::unordered_map<Api::ChangeListAction, 
        std::vector<Api::EntityId>>;
    using EntityIdSetByAction =
        std::unordered_map<Api::ChangeListAction, 
        std::unordered_set<Api::EntityId>>;
   
    static EntityIdsByAction m_entityIdsByPreviousOwnershipAction;
    
    EntityIdSetByAction entityIdSetByAction;
   
    /**
     * Enumerate Api::SubscriptionChangeList items 
     * and store Add and Remove events.
     */ 
    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionEvents, 
        Api::AllSubscriptionEvents(transaction));
   
    for (const Api::SubscriptionEvent& event : subscriptionEvents.changes)
    {
        const Api::ChangeListAction action = event.action;
    
        switch (action)
        {
        case Api::ChangeListAction::Add:
        case Api::ChangeListAction::Remove:
    
            {
                entityIdSetByAction[action].insert(
                    event.entity.descriptor->id);
                break;
            }
        case Api::ChangeListAction::None:
        case Api::ChangeListAction::Update:
        case Api::ChangeListAction::Reject:
            {
                break;
            }
        }
    }
    
    EntityIdsByAction entityIdsByAction;
    
    /**
     * Enumerate Api::OwnershipChangeList items 
     * and store Add and Remove events.
     */
    
    WEAVERRUNTIME_TRY(Api::OwnershipChangeList ownershipChangeList, 
        Api::OwnershipChanges(transaction));
   
    for (const Api::OwnershipChange& event : ownershipChangeList.changes)
    {
        const Api::ChangeListAction action = event.action;
    
        switch (action)
        {
        case Api::ChangeListAction::Add:
        case Api::ChangeListAction::Remove:
            {
                entityIdsByAction[action].push_back(
                    event.entity.descriptor->id);
                break;
            }
        case Api::ChangeListAction::None:
        case Api::ChangeListAction::Update:
        case Api::ChangeListAction::Reject:
            {
                break;
            }
        }
    
    }
      
    std::vector<Api::EntityId> fromSubscribedToOwnedEntities;
    std::vector<Api::EntityId> fromOwnedToSubscribedEntities;
   
    /**
     * Enumerate the *previous* Api::OwnershipChangeList Remove items
     * and check if they are now in 
     * the *current* Api::SubscriptionChangeList Add items.
     *
     * If true, then that means 
     * OnEntityOwnershipChanged(bool isOwned = false)
     */ 
    for (const Api::EntityId& id : m_entityIdsByPreviousOwnershipAction[
        Api::ChangeListAction::Remove])
    {
        if (entityIdSetBySubscriptionAction[
            Api::ChangeListAction::Add].find(id) !=
                entityIdSetBySubscriptionAction[
                Api::ChangeListAction::Add].end())
        {
            fromOwnedToSubscribedEntities.push_back(id);
        }
    }
    
   
    /**
     * Enumerate the *previous* Api::OwnershipChangeList Add items
     * and check if they are now in 
     * the *current* Api::SubscriptionChangeList Remove items.
     *
     * If true, then that means 
     * OnEntityOwnershipChanged(bool isOwned = true)
     */ 
    for (const Api::EntityId& id : m_entityIdsByPreviousOwnershipAction[
        Api::ChangeListAction::Add])
    {
        if (entityIdSetBySubscriptionAction[
            Api::ChangeListAction::Remove].find(id) !=
            
                entityIdSetBySubscriptionAction[
                Api::ChangeListAction::Remove].end())
        {
            fromSubscribedToOwnedEntities.push_back(id);
        }
    }
    
    m_entityIdsByPreviousOwnershipAction = entityIdsByOwnershipAction;
    
    return Success();
}
```

# Result e tratamento de erros
<a name="working-with_app-sdk_result"></a>

A classe `Aws::WeaverRuntime::Result<T>` usa uma biblioteca `Outcome` de terceiros. Use o padrão a seguir para verificar `Result` e capturar os erros retornados pelas chamadas de API.

```
void DoBeginUpdate(Application& app)
{
    Result<Transaction> transactionResult = Api::BeginUpdate(app);
    
    if (transactionResult)
    {
        Transaction transaction = 
            std::move(transactionResult).assume_value();
        
        /**
         * Do things with transaction ...
         */
    }
    else
    {     
        ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(transactionResult);
        /**
         * Macro compiles to:
         * ErrorCode errorCode = transactionResult.assume_error();
         */
    }
}
```

## Result macro de declaração de controle
<a name="working-with_app-sdk_result_macro"></a>

Dentro de uma função com um tipo de retorno `Aws::WeaverRuntime::Result<T>`, é possível usar a macro `WEAVERRUNTIME_TRY` em vez do padrão de código anterior. A macro executará a função passada para ela. Se a função passada falhar, a macro fará com que a função envolvente retorne um erro. Se a função passada for bem-sucedida, a execução avançará para a próxima linha. O exemplo a seguir mostra a nova gravação da função `DoBeginUpdate()` anterior. Esta versão usa a `WEAVERRUNTIME_TRY` macro em vez da if-else estrutura de controle. O tipo de retorno da função é `Aws::WeaverRuntime::Result<void>`.

```
Aws::WeaverRuntime::Result<void> DoBeginUpdate(Application& app)
{
    /**
     * Execute Api::BeginUpdate() 
     * and return from DoBeginUpdate() if BeginUpdate() fails.
     * The error is available as part of the Result.
     */
    WEAVERRUNTIME_TRY(Transaction transaction, Api::BeginUpdate(m_app));
    
    /**
     * Api::BeginUpdate executed successfully.
     *
     * Do things here.
     */
    
    return Aws::Success();
}
```

Se `BeginUpdate()` falhar, a macro `DoBeginUpdate()` retorna mais cedo com uma falha. Você pode usar a macro `WEAVERRUNTIME_EXPECT_ERROR` para obter o `Aws::WeaverRuntime::ErrorCode` de `BeginUpdate()`. O exemplo a seguir mostra como a função `Update()` chama `DoBeginUpdate()` e obtém o código de erro em caso de falha.

```
void Update(Application& app)
{
    Result<void> doBeginUpdateResult = DoBeginUpdate(app);
    
    if (doBeginUpdateResult)
    {
        /**
         * Successful.
         */
    }
    else
    {    
        /**
         * Get the error from Api::BeginUpdate().
         */ 
        ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(doBeginUpdateResult);

    }
}
```

Você pode tornar o código de erro `BeginUpdate()` disponível para uma função que chamará `Update()` alterando o tipo de retorno de `Update()` para `Aws::WeaverRuntime::Result<void>`. Repita o processo para continuar enviando o código de erro mais abaixo na pilha de chamadas.

# Genéricos e tipos de domínio
<a name="working-with_app-sdk_generics"></a>

O SDK do SimSpace Weaver aplicativo fornece os tipos de dados de precisão única `Api::Vector2F32` e`Api::BoundingBox2F32`, e a precisão dupla e. `Api::Vector2F64` `Api::BoundingBox2F64` Esses tipos de dados são estruturas de dados passivas sem métodos convenientes. Observe que a API usa apenas `Api::Vector2F32` e `Api::BoundingBox2F32`. Use esses tipos de dados para criar e modificar assinaturas.

A estrutura de SimSpace Weaver demonstração fornece uma versão mínima do AzCore biblioteca matemática, que contém `Vector3` `Aabb` e. Para obter mais informações, consulte os arquivos de cabeçalho em:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/AzCore/Math`

# Operações diversas do SDK do aplicativo
<a name="working-with_app-sdk_misc"></a>

**Topics**
+ [AllSubscriptionEvents and OwnershipChanges conter eventos da última chamada](working-with_app-sdk_misc_events-from-last-call.md)
+ [Libere os bloqueios de leitura após o processamento SubscriptionChangeList](working-with_app-sdk_misc_release-locks.md)
+ [Criar uma instância de aplicativo independente para testes](working-with_app-sdk_misc_testing-app.md)

# AllSubscriptionEvents and OwnershipChanges conter eventos da última chamada
<a name="working-with_app-sdk_misc_events-from-last-call"></a>

Os valores de retorno das chamadas para `Api::AllSubscriptionEvents()` e `Api::OwnershipChanges()` contêm eventos da última chamada, **não da última marcação**. No exemplo a seguir, `secondSubscriptionEvents` e `secondOwnershipChangeList` estão vazios porque suas funções são chamadas imediatamente após as primeiras chamadas.

Se você esperar dez marcações e depois chamar `Api::AllSubscriptionEvents()` e `Api::OwnershipChanges()`, os resultados conterão eventos e alterações das últimas dez marcações (e não da última).

**Example Exemplo**  

```
Result<void> ProcessOwnershipChanges(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(
        Api::SubscriptionChangeList firstSubscriptionEvents,
        Api::AllSubscriptionEvents(transaction));
    WEAVERRUNTIME_TRY(
        Api::OwnershipChangeList firstOwnershipChangeList,
        Api::OwnershipChanges(transaction));
    
    WEAVERRUNTIME_TRY(
        Api::SubscriptionChangeList secondSubscriptionEvents,
        Api::AllSubscriptionEvents(transaction));
    WEAVERRUNTIME_TRY(
        Api::OwnershipChangeList secondOwnershipChangeList,
        Api::OwnershipChanges(transaction));
    
    /**
     * secondSubscriptionEvents and secondOwnershipChangeList are 
     * both empty because there are no changes since the last call.
     */
}
```

**nota**  
A função `AllSubscriptionEvents()` é implementada, mas a função `SubscriptionEvents()` **não está implementada**.

# Libere os bloqueios de leitura após o processamento SubscriptionChangeList
<a name="working-with_app-sdk_misc_release-locks"></a>

Ao iniciar uma atualização, há segmentos de memória compartilhada para os dados confirmados em outras partições da marca anterior. Esses segmentos de memória compartilhada podem ser bloqueados pelos leitores. Um aplicativo não pode ser confirmado totalmente até que todos os leitores tenham liberado os bloqueios. Como otimização, um aplicativo deve chamar `Api::ReleaseReadLeases()` para liberar os bloqueios após o processamento dos itens de `Api::SubscriptionChangelist`. Isso reduz a contenção no momento da confirmação. A `Api::Commit()` libera as concessões de leitura por padrão, mas é uma prática recomendada liberá-las manualmente após o processamento das atualizações da assinatura.

**Example Exemplo**  

```
Result<void> ProcessSubscriptionChanges(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(ProcessSubscriptionChanges(transaction));
    
    /**
     * Done processing Api::SubscriptionChangeList items.
     * Release read locks. 
     */
        
    WEAVERRUNTIME_EXPECT(Api::ReleaseReadLeases(transaction));
    
    ...
}
```

# Criar uma instância de aplicativo independente para testes
<a name="working-with_app-sdk_misc_testing-app"></a>

Use `Api::CreateStandaloneApplication()` para criar um aplicativo independente e testar a lógica dele antes de executar o código em uma simulação real.

**Example Exemplo**  

```
int main(int argc, char* argv[])
{
    Api::StandaloneRuntimeConfig config = { 
        /* run_for_seconds (the lifetime of the app) */ 3,
        /* tick_hertz (the app clock rate) */ 10 };
    
    Result<Application> applicationResult =
        Api::CreateStandaloneApplication(config);

    ...
}
```

# AWS SimSpace Weaver estrutura de demonstração
<a name="working-with_demo-framework"></a>

A estrutura de AWS SimSpace Weaver demonstração (estrutura de demonstração) é uma biblioteca de utilitários que você pode usar para desenvolver SimSpace Weaver aplicativos.

**A estrutura de demonstração fornece**
+ Amostras de código e padrões de programação para você usar e examinar
+ Abstrações e funções utilitárias que simplificam o desenvolvimento de aplicativos simples
+ Uma maneira mais simples de testar recursos experimentais do SDK do SimSpace Weaver aplicativo

Projetamos o SDK do SimSpace Weaver aplicativo com acesso de baixo nível para SimSpace Weaver APIs oferecer maior desempenho. Por outro lado, projetamos a estrutura de demonstração para fornecer abstrações de alto nível e acesso APIs que SimSpace Weaver facilitem o uso. O custo da facilidade de uso é um nível de desempenho mais baixo em comparação com o uso direto do SDK do SimSpace Weaver aplicativo. Simulações que podem tolerar menor desempenho (como aquelas sem requisitos de desempenho em tempo real) podem ser boas candidatas para usar a estrutura de demonstração. Recomendamos que você use a funcionalidade nativa no SDK do aplicativo SimSpace Weaver para aplicativos complexos porque a estrutura de demonstração não é um kit de ferramentas completo.

**A estrutura de demonstração inclui**
+ Exemplos de código de trabalho que oferecem compatibilidade e demonstram:
  + Gerenciamento do fluxo de aplicativos
  + Processamento de eventos de entidades orientado por retorno de chamada
+ Um conjunto de bibliotecas utilitárias de terceiros:
  + spdlog (uma biblioteca de registros)
  + Uma versão mínima do AZCore (uma biblioteca matemática) que contém somente:
    + Vector3
    + Aabb
  + cxxopts (uma biblioteca de análise de opções de linha de comando)
+ Funções utilitárias específicas para SimSpace Weaver

A estrutura de demonstração consiste em uma biblioteca, arquivos de origem e CMakeLists. Os arquivos estão incluídos no pacote distribuível do SDK do SimSpace Weaver aplicativo.

# Trabalhar com Service Quotas
<a name="working-with_quotas"></a>

Esta seção descreve como trabalhar com as cotas de serviço para SimSpace Weaver. As **cotas** também são chamadas de **limites**. Para uma lista de Service Quotas, consulte [SimSpace Terminais e cotas do Weaver](service-quotas.md). APIsNesta seção, são do conjunto de **aplicativos APIs**. O aplicativo APIs é diferente do serviço APIs. O aplicativo APIs faz parte do SDK do SimSpace Weaver aplicativo. Você pode encontrar a documentação do aplicativo APIs na pasta SDK do aplicativo em seu sistema local:

```
sdk-folder\SimSpaceWeaverAppSdk-sdk-version\documentation\index.html
```

**Topics**
+ [Obter os limites de um aplicativo](#working-with_quotas_get-app-limits)
+ [Obter a quantidade de recursos usados por um aplicativo](#working-with_quotas_get-app-resources)
+ [Redefinir métricas](#working-with_quotas_reset-metrics)
+ [Exceder um limite](#working-with_quotas_exceed-limit)
+ [Ficar sem memória](#working-with_quotas_out-of-memory)
+ [Práticas recomendadas](#working-with_quotas_best-practices)

## Obter os limites de um aplicativo
<a name="working-with_quotas_get-app-limits"></a>

É possível usar a API de aplicativo **RuntimeLimits** para consultar os limites de um aplicativo.

```
Result<Limit> RuntimeLimit(Application& app, LimitType type)
```Parâmetros

**Application& app**  
Uma referência ao aplicativo.

**Tipo de LimitType**  
Uma enumeração com os seguintes tipos de limite:  

```
enum LimitType {
    Unset = 0,
    EntitiesPerPartition = 1,
    RemoteEntityTransfers = 2,
    LocalEntityTransfers = 3
};
```

O exemplo a seguir consulta o limite de contagem de entidades.

```
WEAVERRUNTIME_TRY(auto entity_limit,
    Api::RuntimeLimit(m_app, Api::LimitType::EntitiesPerPartition))
Log::Info("Entity count limit", entity_limit.value);
```

## Obter a quantidade de recursos usados por um aplicativo
<a name="working-with_quotas_get-app-resources"></a>

É possível chamar a API de aplicativo **RuntimeMetrics** para obter a quantidade de recursos usados por um aplicativo:

```
Result<std::reference_wrapper<const AppRuntimeMetrics>> RuntimeMetrics(Application& app) noexcept
```Parâmetros

**Application& app**  
Uma referência ao aplicativo.

A API retorna uma referência a uma struct que contém as métricas. Um contador de métricas contém um valor total contínuo crescente. Um medidor de métricas contém um valor que pode aumentar ou diminuir. O runtime do aplicativo atualiza um contador sempre que um evento aumenta em valor. O runtime só atualiza os medidores quando você chama a API. O SimSpace Weaver garante que a referência seja válida durante toda a vida útil do aplicativo. Chamadas repetidas para a API não alterarão a referência.

```
struct AppRuntimeMetrics {
    uint64_t total_committed_ticks_gauge,

    uint32_t active_entity_gauge,
    uint32_t ticks_since_reset_counter,

    uint32_t load_field_counter,
    uint32_t store_field_counter,

    uint32_t created_entity_counter,
    uint32_t deleted_entity_counter,

    uint32_t entered_entity_counter,
    uint32_t exited_entity_counter,

    uint32_t rejected_incoming_transfer_counter,
    uint32_t rejected_outgoing_transfer_counter
}
```

## Redefinir métricas
<a name="working-with_quotas_reset-metrics"></a>

A API de aplicativo **ResetRuntimeMetrics** redefine os valores na struct `AppRuntimeMetrics`.

```
Result<void> ResetRuntimeMetrics(Application& app) noexcept
```

O exemplo a seguir demonstra como fazer chamadas **ResetRuntimeMetrics** pelo app.

```
if (ticks_since_last_report > 100)
{
    auto metrics = WEAVERRUNTIME_EXPECT(Api::RuntimeMetrics(m_app));
    Log::Info(metrics);

    ticks_since_last_report = 0;

    WEAVERRUNTIME_EXPECT(Api::ResetRuntimeMetrics(m_app));
}
```

## Exceder um limite
<a name="working-with_quotas_exceed-limit"></a>

Uma chamada de API do aplicativo que excede um limite retornará um `ErrorCode::CapacityExceeded`, exceto para transferências de entidades. O SimSpace Weaver trata as transferências de entidades de forma assíncrona como parte das operações da API de aplicativo **Confirmar** e **BeginUpdate**. Portanto, não há uma operação específica que retorne um erro se uma transferência falhar devido ao limite de transferência da entidade. Para detectar falhas de transferência, compare os valores atuais de `rejected_incoming_transfer_counter` e `rejected_outgoing_transfer_counter` (na struct `AppRuntimeMetrics`) com os valores anteriores. As entidades rejeitadas não estarão na partição, mas o aplicativo ainda poderá simulá-las.

## Ficar sem memória
<a name="working-with_quotas_out-of-memory"></a>

SimSpace Weaver usa um processo de coleta de lixo para limpar e liberar a memória liberada. É possível gravar dados mais rápido do que o coletor de lixo pode liberar memória. Se isso acontecer, as operações de gravação poderão exceder o limite de memória reservada do aplicativo. O SimSpace Weaver retornará um erro interno com uma mensagem que contém `OutOfMemory` e detalhes adicionais. Para obter mais informações, consulte [Distribua gravações ao longo do tempo](#working-with_quotas_best-practices_spread-writes).

## Práticas recomendadas
<a name="working-with_quotas_best-practices"></a>

As práticas recomendadas a seguir são diretrizes gerais para criar aplicativos e evitar ultrapassar limites. Elas podem não se aplicar ao design específico do seu aplicativo.

### Monitorar com frequência e diminuir a velocidade
<a name="working-with_quotas_best-practices_monitor"></a>

Você deve monitorar suas métricas com frequência e desacelerar as operações que estão perto de atingir um limite.

### Evite exceder os limites de assinatura e de transferência
<a name="working-with_quotas_best-practices_subscription-and-xfer"></a>

Se possível, projete sua simulação para reduzir o número de assinaturas remotas e transferências de entidades. É possível usar grupos de posicionamento para colocar várias partições no mesmo operador e reduzir a necessidade de transferências remotas de entidades entre operadores. 

### Distribua gravações ao longo do tempo
<a name="working-with_quotas_best-practices_spread-writes"></a>

O número e o tamanho das atualizações em uma marcação podem ter um impacto significativo no tempo e na memória necessários para confirmar uma transação. Grandes requisitos de memória podem fazer com que o runtime do aplicativo fique sem memória. É possível distribuir as gravações ao longo do tempo para reduzir o tamanho total médio das atualizações por marcação. Isso pode ajudar a melhorar o desempenho e evitar ultrapassar os limites. Recomendamos que você não escreva mais do que uma média de 12 MB em cada marcação ou 1,5 KB para cada entidade. 

# Depurar simulações
<a name="working-with_debugging"></a>

Use os seguintes métodos para obter informações sobre as simulações.

**Tópicos**
+ [Use SimSpace Weaver Local e veja a saída do console](#working-with_debugging_use-local)
+ [Veja seus registros no Amazon CloudWatch Logs](#working-with_debugging_logs)
+ [Use **describe** Chamadas de API](#working-with_debugging_api)
+ [Conectar um cliente](#working-with_debugging_client)

## Use SimSpace Weaver Local e veja a saída do console
<a name="working-with_debugging_use-local"></a>

Recomendamos que você desenvolva suas simulações localmente primeiro e depois as execute na Nuvem AWS. Você pode visualizar a saída do console diretamente ao executar com SimSpace Weaver Local. Para obter mais informações, consulte[Desenvolvimento local em SimSpace Weaver](working-with_local-development.md).

## Veja seus registros no Amazon CloudWatch Logs
<a name="working-with_debugging_logs"></a>

Quando você executa sua simulação no console, Nuvem AWS a saída dos seus aplicativos é enviada para fluxos de log no Amazon CloudWatch Logs. Sua simulação também grava outros dados de log. Você deve habilitar o registro em seu esquema de simulação se quiser que ela grave dados de log. Para obter mais informações, consulte [SimSpace Weaver loga no Amazon CloudWatch Logs](cloudwatch-logs.md).

**Atenção**  
A simulação pode produzir grandes quantidades de dados de log. Os dados de registro podem crescer muito rapidamente. Você deve observar seus registros de perto e interromper as simulações quando não precisar mais que sejam executadas. Os registros podem gerar grandes custos.

## Use **describe** Chamadas de API
<a name="working-with_debugging_api"></a>

Você pode usar o serviço APIs a seguir para obter informações sobre suas simulações no Nuvem AWS.
+ **ListSimulations**— obtenha uma lista de todas as suas simulações no Nuvem AWS.  
**Example Exemplo**  

  ```
  aws simspaceweaver list-simulations
  ```
+ **DescribeSimulation**: obtenha detalhes sobre uma simulação.  
**Example Exemplo**  

  ```
  aws simspaceweaver describe-simulation --simulation MySimulation
  ```
+ **DescribeApp**: obtenha detalhes sobre um aplicativo.  
**Example Exemplo**  

  ```
  aws simspaceweaver describe-app --simulation MySimulation --domain MyCustomDomain --app MyCustomApp
  ```

Para obter mais informações sobre o SimSpace Weaver APIs, consulte[SimSpace Weaver Referências de API](api-reference.md).

## Conectar um cliente
<a name="working-with_debugging_client"></a>

É possível conectar um cliente a um aplicativo personalizado ou de serviço em execução definido com um `endpoint_config` no esquema de simulação. O SDK do SimSpace Weaver aplicativo inclui clientes de amostra que você pode usar para visualizar o aplicativo de amostra. É possível examinar o código-fonte desses clientes de exemplo e o aplicativo de exemplo para ver como criar seus próprios clientes. Para obter mais informações sobre como criar e executar os clientes de amostra, consulte os tutoriais em. [Começando com SimSpace Weaver](getting-started.md)

É possível encontrar o código-fonte dos clientes de exemplo na seguinte pasta:
+ `sdk-folder\packaging-tools\clients\PathfindingSampleClients\`

# Depuração de simulações locais
<a name="working-with_debugging_local"></a>

É possível depurar aplicativos do SimSpace Weaver Local com o Microsoft Visual Studio. Para obter mais informações sobre como depurar com o Visual Studio, consulte [https://learn.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour](https://learn.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour). 

**Como depurar uma simulação local**

1. Verifique se o `schema.yaml` está no diretório de trabalho.

1. No **Visual Studio**, abra o menu de contexto de cada aplicativo que deseja depurar (como `PathfindingSampleLocalSpatial` ou `PathfindingSampleLocalView`) e defina o diretório de trabalho na seção de depuração.

1. Abra o menu de contexto do aplicativo que deseja depurar e selecione **Definir como projeto de inicialização**.

1. Escolha F5 para começar a depurar o aplicativo.

Os requisitos para depurar uma simulação são os mesmos que os requisitos para executar normalmente uma simulação. Você deve iniciar o número de aplicativos espaciais especificados no esquema. Por exemplo, se seu esquema especificar uma grade 2x2 e você iniciar um aplicativo espacial no modo de depuração, a simulação não será executada até que você inicie mais três aplicativos espaciais (no modo de depuração ou não).

Para depurar um aplicativo personalizado, você deve primeiro iniciar os aplicativos espaciais e depois o aplicativo personalizado no depurador.

Observe que a simulação é executada em sincronia. Assim que um aplicativo atingir um ponto de interrupção, todos os outros aplicativos serão pausados. Depois de continuar a partir desse ponto de interrupção, os outros aplicativos também continuarão.

# Contêineres personalizados
<a name="working-with_custom-containers"></a>

AWS SimSpace Weaver aplicativos são executados em ambientes em contêineres Amazon Linux 2 (AL2). No Nuvem AWS, SimSpace Weaver executa suas simulações em contêineres Docker criados a partir de uma `amazonlinux:2` imagem servida pelo Amazon Elastic Container Registry (Amazon ECR). É possível criar uma imagem do Docker personalizada, armazená-la no Amazon ECR e usar essa imagem para sua simulação em vez da imagem do Docker que fornecemos.

É possível usar um contêiner personalizado para gerenciar suas dependências de software e incluir componentes de software adicionais que não estão na imagem do Docker padrão. Por exemplo, você pode adicionar as bibliotecas de software disponíveis publicamente que seu aplicativo usa ao contêiner e colocar somente seu código personalizado no arquivo .zip do aplicativo.

**Importante**  
Só oferecemos suporte a imagens do AL2 Docker hospedadas nos repositórios do Amazon ECR, seja na Galeria Pública do Amazon ECR ou em seu registro privado do Amazon ECR. Não oferecemos compatibilidade a imagens do Docker hospedadas fora do Amazon ECR. Para obter mais informações sobre o Amazon ECR, consulte a *[documentação do Amazon Elastic Container Registry](https://docs.aws.amazon.com/ecr)*.

**Topics**
+ [Criar um contêiner personalizado](working-with_custom-containers_create.md)
+ [Modificar um projeto para usar um contêiner personalizado](working-with_custom-containers_modify-project.md)
+ [Perguntas frequentes sobre contêineres personalizados](working-with_custom-containers_faq.md)
+ [Solução de problemas com contêineres](working-with_custom-containers_troubleshooting.md)

# Criar um contêiner personalizado
<a name="working-with_custom-containers_create"></a>

Essas instruções pressupõem que você saiba como usar o Docker e o Amazon Elastic Container Registry (Amazon ECR). Para obter mais informações sobre o Amazon ECR, consulte o *[Guia do usuário da Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide)*.

**Pré-requisitos**
+ A identidade (uso ou função) do IAM que você usa para realizar essas ações tem as permissões corretas para usar o Amazon ECR
+ O Docker está instalado em seu sistema local

**Como criar um contêiner personalizado**

1. Crie o `Dockerfile`.

   A) `Dockerfile` executar AWS SimSpace Weaver aplicativos começa com a Amazon Linux 2 imagem no Amazon ECR.

   ```
   # parent image required to run AWS SimSpace Weaver apps
   FROM public.ecr.aws/amazonlinux/amazonlinux:2
   ```

1. Compile seu `Dockerfile`.

1. Carregue a imagem no registro do contêiner do Amazon ECR.
   + [Use o Console de gerenciamento da AWS](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html)
   + [Use a AWS Command Line Interface](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
**nota**  
Se você receber um erro `AccessDeniedException` ao tentar carregar sua imagem de contêiner para o Amazon ECR, sua identidade do IAM (usuário ou função) pode não ter as permissões necessárias para usar o Amazon ECR. Você pode anexar a política `AmazonEC2ContainerRegistryPowerUser` AWS gerenciada à sua identidade do IAM e tentar novamente. Para obter informações sobre como anexar políticas, consulte [Adicionar e remover permissões de identidade do IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) no *Guia do usuário do AWS Identity and Access Management *.

# Modificar um projeto para usar um contêiner personalizado
<a name="working-with_custom-containers_modify-project"></a>

Essas instruções pressupõem que você já saiba como usar AWS SimSpace Weaver e queira tornar seus fluxos de trabalho de desenvolvimento e armazenamento de aplicativos Nuvem AWS mais eficientes.

**Pré-requisitos**
+ Você tem um contêiner personalizado no Amazon Elastic Container Registry (Amazon ECR). Para obter mais informações sobre como criar um contêiner personalizado, consulte [Criar um contêiner personalizado](working-with_custom-containers_create.md).

**Como modificar seu projeto para usar um contêiner personalizado**

1. Adicione permissões à função do aplicativo de simulação do seu projeto para usar o Amazon ECR.

   1. Se você ainda não tem uma política do IAM com as seguintes permissões, crie a política. Sugerimos o nome `simspaceweaver-ecr` para a política. Para obter informações sobre como criar políticas, consulte [Criar políticas do IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) no *Guia do usuário do AWS Identity and Access Management *.

      ```
      {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "Statement",
                  "Effect": "Allow",
                  "Action": [
                      "ecr:BatchGetImage",
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:GetAuthorizationToken"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

   1. Encontre o nome da função do aplicativo de simulação do seu projeto:

      1. Em um editor de texto, abra o CloudFormation modelo:

         ```
         sdk-folder\PackagingTools\sample-stack-template.yaml
         ```

      1. Encontre a propriedade `RoleName` abaixo de `WeaverAppRole`. O valor é o nome da função do aplicativo de simulação do seu projeto.  
**Example**  

         ```
         AWSTemplateFormatVersion: "2010-09-09"
         Resources:
           WeaverAppRole:
             Type: 'AWS::IAM::Role'
             Properties:
               RoleName: 'weaver-MySimulation-app-role'
               AssumeRolePolicyDocument:
                 Version: "2012-10-17"		 	 	 
                 Statement:
                 - Effect: Allow
                   Principal:
                     Service:
                       - 'simspaceweaver.amazonaws.com'
         ```

   1. Anexe a política `simspaceweaver-ecr` à função do aplicativo de simulação do projeto. Para obter informações sobre como anexar políticas, consulte [Adicionar e remover permissões de identidade do IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) no * Guia do usuário do AWS Identity and Access Management *. 

   1. Navegue até o comando a seguir `sdk-folder` e execute-o para atualizar a SimSpace Weaver pilha de amostras:

      ```
      python setup.py --cloudformation
      ```

1. Especifique suas imagens de contêiner no esquema de simulação do projeto.
   + É possível adicionar a propriedade `default_image` opcional abaixo de `simulation_properties` para especificar uma imagem de contêiner personalizada padrão para todos os domínios.
   + Adicione a propriedade `image` em `app_config` para um domínio no qual você deseja usar uma imagem de contêiner personalizada. Especifique o URI do repositório do Amazon ECR como o valor. É possível especificar uma imagem diferente para cada domínio.
     + Se uma `image` não for especificada para um domínio e uma `default_image` for especificada, os aplicativos desse domínio usarão a imagem padrão.
     + Se `image` não for especificado para um domínio e `default_image` não for especificado, os aplicativos nesse domínio serão executados em um SimSpace Weaver contêiner padrão.  
**Example Trecho de esquema que inclui configurações personalizadas de contêiner**  

   ```
   sdk_version: "1.17.0"
   simulation_properties:
     log_destination_service: "logs"
     log_destination_resource_name: "MySimulationLogs"
     default_entity_index_key_type: "Vector3<f32>"
     default_image: "111122223333.dkr.ecr.us-west-2.amazonaws.com/my-ecr-repository:latest" # image to use if no image specified for a domain
   domains:
     MyCustomDomain:
       launch_apps_via_start_app_call: {}
       app_config:
         package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip" 
         launch_command: ["MyViewApp"]  
         required_resource_units:
           compute: 1
         endpoint_config:
           ingress_ports:
             - 7000
         image: "111122223333.dkr.ecr.us-west-2.amazonaws.com/my-ecr-repository:latest" # custom container image to use for this domain 
     MySpatialDomain:
       launch_apps_by_partitioning_strategy:
         partitioning_strategy: "MyGridPartitioning"
         grid_partition:
           x: 2
           y: 2
       app_config:
         package: "s3://weaver-myproject-111122223333-us-west-2/MySpatialApp.zip" 
         launch_command: ["MySpatialApp"] 
         required_resource_units:
           compute: 1
         image: "111122223333.dkr.ecr.us-west-2.amazonaws.com/my-ecr-repository:latest" # custom container image to use for this domain
   ```

1. Crie e carregue o seu projeto normalmente.

# Perguntas frequentes sobre contêineres personalizados
<a name="working-with_custom-containers_faq"></a>

## P1. O que eu faço se eu quiser alterar o conteúdo do meu contêiner?
<a name="working-with_custom-containers_faq_q1"></a>
+ **Para uma simulação em execução**: você não pode alterar o contêiner para uma simulação em execução. Você deve criar um novo contêiner e iniciar uma nova simulação que use esse contêiner.
+ **Para uma nova simulação**: crie um novo contêiner, faça o upload para o Amazon Elastic Container Registry (Amazon ECR) e inicie uma nova simulação que use esse contêiner.

## P2. Como posso alterar a imagem do contêiner para minha simulação?
<a name="working-with_custom-containers_faq_q2"></a>
+ **Para uma simulação em execução**: você não pode alterar o contêiner para uma simulação em execução. Você deve iniciar uma nova simulação que use o novo contêiner.
+ **Para uma nova simulação**: especifique a nova imagem do contêiner no esquema de simulação do seu projeto. Para obter mais informações, consulte [Modificar um projeto para usar um contêiner personalizado](working-with_custom-containers_modify-project.md).

# Solução de problemas com contêineres
<a name="working-with_custom-containers_troubleshooting"></a>

**Topics**
+ [AccessDeniedException ao enviar sua imagem para o Amazon Elastic Container Registry (Amazon ECR)](working-with_custom-containers_troubleshooting_access-denied.md)
+ [Uma simulação que usa um contêiner personalizado falha ao iniciar](working-with_custom-containers_troubleshooting_no-start.md)

# AccessDeniedException ao enviar sua imagem para o Amazon Elastic Container Registry (Amazon ECR)
<a name="working-with_custom-containers_troubleshooting_access-denied"></a>

Se você receber um erro `AccessDeniedException` ao tentar carregar sua imagem de contêiner para o Amazon ECR, sua identidade do IAM (usuário ou função) pode não ter as permissões necessárias para usar o Amazon ECR. Você pode anexar a política `AmazonEC2ContainerRegistryPowerUser` AWS gerenciada à sua identidade do IAM e tentar novamente. Para obter informações sobre como anexar políticas, consulte [Adicionar e remover permissões de identidade do IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) no * Guia do usuário do AWS Identity and Access Management *.

# Uma simulação que usa um contêiner personalizado falha ao iniciar
<a name="working-with_custom-containers_troubleshooting_no-start"></a>

**Dicas de solução de problemas**
+ Se o registro estiver ativado para sua simulação, verifique seus logs de erro.
+ Teste sua simulação sem um contêiner personalizado.
+ Teste sua simulação localmente. Para obter mais informações, consulte [Desenvolvimento local em SimSpace Weaver](working-with_local-development.md).

# Como trabalhar com Python
<a name="working-with_python"></a>

Você pode usar o Python para seus SimSpace Weaver aplicativos e clientes. O kit de desenvolvimento de software Python (Python SDK) está incluído como parte do pacote distribuível padrão SimSpace Weaver do SDK do aplicativo. O desenvolvimento com Python funciona de forma semelhante ao desenvolvimento em outras linguagens compatíveis.

**Importante**  
SimSpace Weaver suporta apenas a versão 3.9 do Python.

**Importante**  
SimSpace Weaver o suporte para Python requer a SimSpace Weaver versão 1.15.0 ou posterior.

**Topics**
+ [Criar um projeto do Python](working-with_python_create-project.md)
+ [Iniciar uma simulação em Python](working-with_python_start-sim.md)
+ [Cliente de exemplo Python](working-with_python_client.md)
+ [Perguntas frequentes sobre o uso do Python](working-with_python_faq.md)
+ [Solução de problemas relacionados ao Python](working-with_python_troubleshooting.md)

# Criar um projeto do Python
<a name="working-with_python_create-project"></a>

## Contêiner personalizado do Python
<a name="working-with_python_create-project_container"></a>

Para executar sua SimSpace Weaver simulação baseada em Python no Nuvem AWS, você pode criar um contêiner personalizado que inclua as dependências necessárias. Para obter mais informações, consulte [Contêineres personalizados](working-with_custom-containers.md). 

Um contêiner personalizado do Python deve incluir o seguinte:
+ gcc
+ openssl-devel
+ bzip2-devel
+ libffi-devel
+ wget
+ tar
+ gzip
+ make
+ Python (versão 3.9)

Se você usar o modelo `PythonBubblesSample` para criar seu projeto, poderá executar o script `quick-start.py` (localizado na pasta `tools` do projeto) para criar uma imagem do Docker com as dependências necessárias. O script carrega a imagem para o Amazon Elastic Container Registry (Amazon ECR).

O script `quick-start.py` usa o seguinte `Dockerfile`:

```
FROM public.ecr.aws/amazonlinux/amazonlinux:2
RUN yum -y install gcc openssl-devel bzip2-devel libffi-devel 
RUN yum -y install wget
RUN yum -y install tar
RUN yum -y install gzip
RUN yum -y install make
WORKDIR /opt
RUN wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz 
RUN tar xzf Python-3.9.0.tgz
WORKDIR /opt/Python-3.9.0
RUN ./configure --enable-optimizations
RUN make altinstall
COPY requirements.txt ./
RUN python3.9 -m pip install --upgrade pip
RUN pip3.9 install -r requirements.txt
```

É possível adicionar suas próprias dependências ao `Dockerfile`:

```
RUN yum -y install dependency-name
```

O arquivo `requirements.txt` contém uma lista dos pacotes Python necessários para a simulação da amostra `PythonBubblesSample`:

```
Flask==2.1.1
```

É possível adicionar suas próprias dependências do pacote Python ao `requirements.txt`:

```
package-name==version-number
```

O `Dockerfile` e o `requirements.txt` estão na pasta `tools` do projeto.

**Importante**  
Tecnicamente, você não precisa usar um contêiner personalizado com sua simulação do Python, mas é altamente recomendável que você use um contêiner personalizado. O contêiner padrão do Amazon Linux 2 (AL2) que fornecemos não tem Python. Portanto, se você não usar um contêiner personalizado que tenha Python, deverá incluir o Python e as dependências necessárias em cada arquivo zip do aplicativo para o qual você carrega. SimSpace Weaver

# Iniciar uma simulação em Python
<a name="working-with_python_start-sim"></a>

Você pode iniciar sua simulação baseada em Python da mesma forma que uma SimSpace Weaver simulação normal, tanto no SimSpace Weaver Local e SimSpace Weaver no Nuvem AWS. Para obter mais informações, consulte os tutoriais em. [Começando com SimSpace Weaver](getting-started.md)

O `PythonBubblesSample` inclui seu próprio cliente de exemplo em Python. Para obter mais informações, consulte [Cliente de exemplo Python](working-with_python_client.md). 

# Cliente de exemplo Python
<a name="working-with_python_client"></a>

Se você usar o modelo `PythonBubblesSample` para criar um projeto, ele conterá um cliente de exemplo em Python. É possível usar o cliente de exemplo para visualizar a simulação `PythonBubblesSample`. Você também pode usar o cliente de exemplo como ponto de partida para criar seu próprio cliente Python.

O procedimento a seguir pressupõe que você tenha criado um projeto `PythonBubblesSample` e iniciado sua simulação.

**Como iniciar o cliente Python**

1. Em uma **janela do prompt de comando**, acesse a pasta do projeto de `PyBubbleClient` amostra.

   ```
   cd sdk-folder\Clients\HTTP\PyBubbleClient
   ```

1. Execute o cliente Python.

   ```
   python tkinter_client.py --host ip-address --port port-number
   ```

**Parâmetros**  
**host**  
O endereço IP da simulação. Para uma simulação iniciada no Nuvem AWS, você pode encontrar o endereço IP da simulação no [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver) ou usar o procedimento [Obtenha o endereço IP e o número da porta de um aplicativo personalizadoObtenha o endereço IP e o número da porta](working-with_get-ip.md) do tutorial de início rápido. Para uma simulação local, use `127.0.0.1` como endereço IP.  
**port**  
O número da porta da simulação. Para uma simulação iniciada no Nuvem AWS, esse é o número da `Actual` porta. É possível encontrar o número da porta da simulação no [console do SimSpace Weaver](https://console.aws.amazon.com/simspaceweaver) ou usar o procedimento em [Obtenha o endereço IP e o número da porta de um aplicativo personalizadoObtenha o endereço IP e o número da porta](working-with_get-ip.md) do tutorial de início rápido. Para uma simulação local, use `7000` como número da porta.  
**simsize**  
O número máximo de entidades a serem exibidas no cliente.

# Perguntas frequentes sobre o uso do Python
<a name="working-with_python_faq"></a>

## P1. Quais versões do Python são compatíveis?
<a name="working-with_python_faq_q1"></a>

SimSpace Weaver suporta apenas a versão 3.9 do Python.

# Solução de problemas relacionados ao Python
<a name="working-with_python_troubleshooting"></a>

**Topics**
+ [Falha durante a criação do contêiner personalizado](working-with_python_troubleshooting_create-container-failure.md)
+ [A simulação do Python falha ao iniciar](working-with_python_troubleshooting_no-start.md)
+ [Um cliente de simulação ou visualização do Python gera um erro ModuleNotFound](working-with_python_troubleshooting_module-not-found.md)

# Falha durante a criação do contêiner personalizado
<a name="working-with_python_troubleshooting_create-container-failure"></a>

Se você receber um erro de `no basic auth credentials` após a execução de `quick-start.py`, pode haver um problema com suas credenciais temporárias para o Amazon ECR. Execute o seguinte comando com seu Região da AWS ID e número AWS da conta:

```
aws ecr get-login-password --region region | docker login --username AWS --password-stdin account_id.dkr.ecr.region.amazonaws.com
```

**Example**  

```
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.region.amazonaws.com
```

**Importante**  
Certifique-se de que o Região da AWS especificado seja o mesmo que você usa para sua simulação. Use um desses Regiões da AWS SimSpace Weaver suportes. Para obter mais informações, consulte [SimSpace Terminais e cotas do Weaver](service-quotas.md).

Depois de executar o comando `aws ecr`, execute o `quick-start.py` novamente.

**Outros recursos de solução de problemas a serem verificados**
+ [Solução de problemas com contêineres](working-with_custom-containers_troubleshooting.md)
+ [Solução de problemas do Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/troubleshooting.html) no *Guia do usuário do Amazon ECR*
+ [Confirmar com o Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html) no *Guia do usuário do Amazon ECR*

# A simulação do Python falha ao iniciar
<a name="working-with_python_troubleshooting_no-start"></a>

É possível ver o erro `Unable to start app` no log de gerenciamento da sua simulação. Isso pode acontecer se a criação do contêiner personalizado falhar. Para obter mais informações, consulte [Falha durante a criação do contêiner personalizado](working-with_python_troubleshooting_create-container-failure.md). Para obter mais informações sobre logs, consulte [SimSpace Weaver loga no Amazon CloudWatch Logs](cloudwatch-logs.md).

Se você tiver certeza de que não há nada de errado com seu contêiner, verifique o código-fonte Python do aplicativo. Você pode usar: SimSpace Weaver Local para testar seu aplicativo. Para obter mais informações, consulte [Desenvolvimento local em SimSpace Weaver](working-with_local-development.md).

# Um cliente de simulação ou visualização do Python gera um erro ModuleNotFound
<a name="working-with_python_troubleshooting_module-not-found"></a>

O Python gera um erro `ModuleNotFound` quando não consegue localizar um pacote Python necessário.

Se sua simulação estiver no Nuvem AWS, certifique-se de que seu contêiner personalizado tenha todas as dependências necessárias listadas em seu`requirements.txt`. Lembre-se de executar o `quick-start.py` novamente se você editar o `requirements.txt`.

Se você receber o erro para o cliente `PythonBubblesSample`, use `pip` para instalar o pacote indicado:

```
pip install package-name==version-number
```

# Suporte para outros mecanismos
<a name="working-with_engines"></a>

Você pode usar seu próprio costume C\$1\$1 motor com SimSpace Weaver. No momento, estamos desenvolvendo compatibilidade para os seguintes mecanismos. Há documentação separada para cada um desses mecanismos.

**Importante**  
As integrações com os mecanismos listados aqui são experimentais. Eles estão disponíveis para visualização.

**Mecanismos**
+ [Unity](#working-with_engines_unity)(versão mínima 2022.3.19.F1)
+ [Unreal Engine](#working-with_engines_unreal) (versão mínima 5.0)

## Unity
<a name="working-with_engines_unity"></a>

Você deve ter o Unity ambiente de desenvolvimento já instalado antes de você criar SimSpace Weaver simulações com o Unity. Para obter mais informações, consulte as instruções separadas:

```
sdk-folder\Unity-Guide.pdf
```

## Unreal Engine
<a name="working-with_engines_unreal"></a>

Você deve construir um Unreal Engine servidor dedicado a partir do código-fonte. SimSpaceWeaverAppSdkDistributable Inclui uma versão do PathfindingSample para Unreal Engine. Para obter mais informações, consulte as instruções separadas: 

```
sdk-folder\Unreal-Engine-Guide.pdf
```

# Uso de software licenciado com AWS SimSpace Weaver
<a name="working-with_byol"></a>

AWS SimSpace Weaver permite que você crie simulações com o mecanismo e o conteúdo de simulação de sua escolha. Em relação ao uso de SimSpace Weaver, você é responsável por obter, manter e aderir aos termos de licença de qualquer software ou conteúdo usado em suas simulações. Verifique se o contrato de licenciamento permite implantar o software e o conteúdo em um ambiente de host virtual.

# Gerenciando seus recursos com AWS CloudFormation
<a name="working-with_cloudformation"></a>

Você pode usar AWS CloudFormation para gerenciar seus AWS SimSpace Weaver recursos. CloudFormation é um AWS serviço separado que ajuda você a especificar, provisionar e gerenciar sua AWS infraestrutura como código. *[Com CloudFormation você, crie um arquivo JSON ou YAML, chamado de modelo.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-templates template)* O modelo especifica os detalhes da infraestrutura. O CloudFormation usa seu modelo para provisionar a infraestrutura como uma única unidade, chamada *[pilha](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#w2ab1b5c15b9)*. Ao excluir sua pilha, você pode CloudFormation excluir tudo na pilha ao mesmo tempo. É possível gerenciar o modelo usando processos de gerenciamento de código-fonte padrão (por exemplo, rastreando-o em um sistema de controle de versão como o [Git](https://git-scm.com/)). Para obter mais informações sobre CloudFormation, consulte o [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide).

**Seu recurso de simulação**  
Em AWS, um *recurso* é uma entidade com a qual você pode trabalhar. Os exemplos incluem uma EC2 instância da Amazon, um bucket do Amazon S3 ou uma função do IAM. Sua SimSpace Weaver simulação é um recurso. Nas configurações, você geralmente especifica um AWS recurso no formulário`AWS::service::resource`. Para SimSpace Weaver, você especifica seu recurso de simulação como`AWS::SimSpaceWeaver::Simulation`. Para obter mais informações sobre seu recurso de simulação em CloudFormation, consulte a [SimSpace Weaver](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-simspaceweaver-simulation.html)seção no *Guia AWS CloudFormation do usuário*.

**Como posso usar CloudFormation com SimSpace Weaver?**  
Você pode criar um CloudFormation modelo que especifique os AWS recursos que você deseja provisionar. Seu modelo pode especificar uma arquitetura inteira, parte de uma arquitetura ou uma pequena solução. Por exemplo, você pode especificar uma arquitetura para sua SimSpace Weaver solução que inclua buckets do Amazon S3, permissões do IAM, um banco de dados de suporte no Amazon Relational Database Service ou no Amazon DynamoDB e seu recurso. `Simulation` Em seguida, você pode usar CloudFormation para provisionar todos esses recursos como uma unidade e ao mesmo tempo.

**Example Modelo que cria recursos do IAM e inicia uma simulação**  
O modelo de exemplo a seguir cria permissões e um perfil do IAM que o SimSpace Weaver usará para realizar ações em sua conta. Os scripts do SDK do SimSpace Weaver aplicativo criam a função e as permissões em uma área específica Região da AWS quando você cria um projeto, mas você pode usar um CloudFormation modelo para implantar a simulação em outra pessoa Região da AWS sem executar os scripts novamente. Por exemplo, você pode fazer isso para configurar uma simulação de backup para fins de recuperação de desastres.  
Neste exemplo, o nome original da simulação é `MySimulation`. Já existe um bucket para o esquema no Região da AWS local onde CloudFormation construirá a pilha. O bucket contém uma versão do esquema configurada adequadamente para executar a simulação naquela Região da AWS. Lembre-se de que o esquema especifica a localização dos arquivos .zip do seu aplicativo, que é um bucket do Amazon S3 na mesma Região da AWS da simulação. O aplicativo compacta o bucket e os arquivos já devem existir no Região da AWS quando CloudFormation cria a pilha, caso contrário, sua simulação não será iniciada. Observe que o nome do bucket neste exemplo inclui o Região da AWS, mas isso não determina onde o bucket está realmente localizado. Você deve se certificar de que o bucket está realmente nele Região da AWS (você pode verificar as propriedades do bucket no console do Amazon S3, com o Amazon APIs S3 ou com os comandos do Amazon S3 no). AWS CLI  
Este exemplo usa algumas funções e parâmetros integrados CloudFormation para realizar a substituição de variáveis. Para mais informações, consulte [Referência da função intrínseca](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) e [Referência de pseudoparâmetros](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) no *Guia do usuário do AWS CloudFormation *.  

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  WeaverAppRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: SimSpaceWeaverAppRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
          Principal:
            Service:
              - simspaceweaver.amazonaws.com
          Action:
            - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: SimSpaceWeaverAppRolePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
            - Effect: Allow
              Action:
                - logs:PutLogEvents
                - logs:DescribeLogGroups
                - logs:DescribeLogStreams
                - logs:CreateLogGroup
                - logs:CreateLogStream
              Resource: *
            - Effect: Allow
              Action:
                - cloudwatch:PutMetricData
              Resource: *
            - Effect: Allow
              Action:
                - s3:ListBucket
                - s3:PutObject
                - s3:GetObject
              Resource: *
  MyBackupSimulation:
    Type: AWS::SimSpaceWeaver::Simulation
    Properties:
      Name: !Sub 'mySimulation-${AWS::Region}'
      RoleArn: !GetAtt WeaverAppRole.Arn
      SchemaS3Location:
        BucketName: !Sub 'weaver-mySimulation-${AWS::AccountId}-schemas-${AWS::Region}'
        ObjectKey: !Sub 'schema/mySimulation-${AWS::Region}-schema.yaml'
```

# Usando instantâneos com AWS CloudFormation
<a name="working-with_cloudformation_snapshots"></a>

Um [snapshot](working-with_snapshots.md) é um backup de uma simulação. O exemplo a seguir inicia uma nova simulação a partir de um instantâneo em vez de um esquema. O instantâneo neste exemplo foi criado a partir de uma simulação de projeto do SDK do SimSpace Weaver aplicativo. CloudFormation cria o novo recurso de simulação e o inicializa com dados do instantâneo. A nova simulação pode ter uma `MaximumDuration` diferente da simulação original.

Recomendamos que você faça e use uma cópia da função do aplicativo da simulação original. A função do aplicativo da simulação original pode ser excluída se você excluir a pilha do CloudFormation dessa simulação.

```
Description: "Example - Start a simulation from a snapshot"
Resources:
  MyTestSimulation:
    Type: "AWS::SimSpaceWeaver::Simulation"
    Properties:
      MaximumDuration: "2D"
      Name: "MyTestSimulation_from_snapshot"
      RoleArn: "arn:aws:iam::111122223333:role/weaver-MyTestSimulation-app-role-copy"   
      SnapshotS3Location:
        BucketName: "weaver-mytestsimulation-111122223333-artifacts-us-west-2"
        ObjectKey: "snapshot/MyTestSimulation_22-12-15_12_00_00-230428-1207-13.zip"
```

# Snapshots
<a name="working-with_snapshots"></a>

É possível criar um *snapshot* para fazer backup dos dados da entidade de simulação a qualquer momento. O SimSpace Weaver criará um arquivo .zip em um bucket do Amazon S3. Você pode criar uma nova simulação com o instantâneo. SimSpace Weaver inicializa o State Fabric de sua nova simulação com os dados da entidade armazenados no instantâneo, inicia os aplicativos espaciais e de serviços que estavam em execução quando o instantâneo foi criado e ajusta o relógio para a marca apropriada. SimSpace Weaver obtém a configuração da sua simulação a partir do instantâneo em vez de um arquivo de esquema. Os arquivos .zip do aplicativo devem estar no mesmo local no Amazon S3 em que estavam na simulação original. Você deve iniciar todos os aplicativos personalizados separadamente.

**Tópicos**
+ [Casos de uso para snapshots](#working-with_snapshots_use-cases)
+ [Use o SimSpace Weaver console para trabalhar com instantâneos](working-with_snapshots_console.md)
+ [Use o AWS CLI para trabalhar com instantâneos](working-with_snapshots_cli.md)
+ [Usando instantâneos com AWS CloudFormation](working-with_cloudformation_snapshots.md)
+ [Perguntas frequentes sobre snapshots](working-with_snapshots_faq.md)

## Casos de uso para snapshots
<a name="working-with_snapshots_use-cases"></a>

### Retornar a um estado anterior e explorar cenários de ramificação
<a name="working-with_snapshots_use-case_branching"></a>

É possível criar um snapshot da simulação para salvá-la em um estado específico. Em seguida, você pode criar várias novas simulações a partir desse snapshot e explorar diferentes cenários que podem se ramificar a partir desse estado.

### Práticas recomendadas de recuperação de desastres e segurança
<a name="working-with_snapshots_use-cases_best-practice"></a>

Recomendamos que você faça backup regular da simulação, especialmente para simulações que são executadas por mais de uma hora ou usam vários operadores. Os backups podem ajudar você a se recuperar de desastres e incidentes de segurança. Os snapshots fornecem uma maneira de você fazer backup da simulação. Os snapshots exigem que os arquivos .zip do aplicativo estejam no mesmo local no Amazon S3 de antes. Se você precisar mover os arquivos .zip do aplicativo para outro local, deverá usar uma solução de backup personalizada. 

Para obter mais informações sobre as melhores práticas, consulte [Melhores práticas ao trabalhar com SimSpace Weaver](best-practices.md) e [Melhores práticas de segurança para SimSpace Weaver](security_best-practices.md).

### Estender a duração da simulação
<a name="working-with_snapshots_use-cases_extend-duration"></a>

O *recurso de simulação* é a representação da simulação no SimSpace Weaver. Todos os recursos de simulação têm uma configuração de `MaximumDuration`. Um recurso de simulação é interrompido automaticamente quando atinge o `MaximumDuration`. O valor máximo de `MaximumDuration` é `14D` (14 dias). 

Se você precisar que sua simulação persista por mais tempo do que `MaximumDuration` do recurso de simulação, você pode criar um snapshot antes que o recurso de simulação alcance a `MaximumDuration`. É possível iniciar uma nova simulação (criar um novo recurso de simulação) com seu snapshot. O SimSpace Weaver inicializa os dados da entidade a partir do snapshot, inicia os mesmos aplicativos espaciais e de serviços executados antes e restaura o relógio. É possível iniciar aplicativos personalizados e realizar qualquer inicialização personalizada adicional. É possível definir a `MaximumDuration` do novo recurso de simulação com um valor diferente ao iniciá-lo.

# Use o SimSpace Weaver console para trabalhar com instantâneos
<a name="working-with_snapshots_console"></a>

Você pode usar o SimSpace Weaver console para criar um instantâneo da sua simulação.

**Topics**
+ [Criar um snapshot](#working-with_snapshots_console_create)
+ [Inicie uma simulação a partir de um snapshot](#working-with_snapshots_console_start)

## Usar o console para criar um snapshot
<a name="working-with_snapshots_console_create"></a>

**Para criar um snapshot**

1. Faça login no Console de gerenciamento da AWS e conecte-se ao [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver).

1. No painel de navegação, escolha **Simulações**.

1. Selecione o botão de opção ao lado do nome da simulação. O **status** da simulação deve ser **Iniciado**. 

1. Na parte superior da página, escolha **Criar política**.

1. Em **Configurações do snapshot**, em **Destino do snapshot**, insira o URI do Amazon S3 de um bucket ou bucket e pasta onde você SimSpace Weaver deseja criar seu snapshot. É possível escolher **Procurar no S3** se preferir navegar pelos buckets disponíveis e selecionar um local.
**Importante**  
O bucket do Amazon S3 deve estar na mesma Região da AWS que a simulação.
**nota**  
SimSpace Weaver cria uma `snapshot` pasta dentro do destino do snapshot selecionado. SimSpace Weaver cria o arquivo.zip de instantâneo nessa `snapshot` pasta.

1. Escolha **Criar snapshot**.

## Usar o console para iniciar uma simulação a partir de um snapshot
<a name="working-with_snapshots_console_start"></a>

Para iniciar uma simulação a partir de um snapshot, seu arquivo .zip do snapshot deve existir em um bucket do Amazon S3 que sua simulação possa acessar. Sua simulação usa permissões definidas na função do aplicativo que você selecionar ao iniciar a simulação. Todos os arquivos .zip do aplicativo da simulação original devem existir nos mesmos locais de quando o snapshot foi criado.

**Como iniciar uma simulação a partir de um snapshot**

1. Faça login no Console de gerenciamento da AWS e conecte-se ao [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver).

1. No painel de navegação, escolha **Simulações**.

1. Na parte superior da página, escolha **Iniciar simulação**.

1. Em **Configurações de simulação**, insira um nome e uma descrição opcional para sua simulação. O nome da simulação deve ser exclusivo na Conta da AWS.

1. Para o **Método de início da simulação**, escolha **Usar um snapshot no Amazon S3**.

1. Para o **URI do Amazon S3 para snapshot**, insira o URI do Amazon S3 do arquivo de snapshot ou escolha **Procurar no S3** para navegar e selecionar o arquivo.
**Importante**  
O bucket do Amazon S3 deve estar na mesma Região da AWS que a simulação.

1. Para o **Perfil do IAM**, selecione a função do aplicativo que sua simulação usará.

1. Em **Duração máxima**, insira o tempo máximo pelo qual seu recurso de simulação deve ser executado. O valor máximo é `14D`. Para mais informações sobre a duração máxima, consulte [.](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)

1. Em **Tags: *opcional***, escolha **Adicionar nova tag** se quiser adicionar uma tag.

1. Escolha **Iniciar simulação**.

# Use o AWS CLI para trabalhar com instantâneos
<a name="working-with_snapshots_cli"></a>

Você pode usar o AWS CLI para chamar o a SimSpace Weaver APIs partir de um prompt de comando. Você deve ter o AWS CLI instalado e configurado corretamente. Para obter mais informações, consulte [Instalando ou atualizando a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) no *Guia do AWS Command Line Interface usuário da versão 2*.

**Topics**
+ [Criar um snapshot](#working-with_snapshots_cli_create)
+ [Inicie uma simulação a partir de um snapshot](#working-with_snapshots_cli_start)

## Use o AWS CLI para criar um instantâneo
<a name="working-with_snapshots_cli_create"></a>

**Para criar um snapshot**
+ Em um **prompt de comando**, chame a API `CreateSnapshot`.

  ```
  aws simspaceweaver create-snapshot --simulation simulation-name —destination s3-destination
  ```

  **Parâmetros**  
simulation  
O nome de uma simulação iniciada. É possível usar `aws simspaceweaver list-simulations` para ver os nomes e status das simulações.  
destination  
Uma string que especifica o bucket de destino do Amazon S3 e o prefixo de chave de objeto opcional para seu arquivo de snapshot. Seu prefixo de chave de objeto geralmente é uma pasta no seu bucket. SimSpace Weaver cria seu instantâneo dentro de uma `snapshot` pasta nesse destino.   
O bucket do Amazon S3 deve estar na mesma Região da AWS que a simulação.

  **Exemplo**

  ```
  aws simspaceweaver create-snapshot —simulation MyProjectSimulation_23-04-29_12_00_00 —destination BucketName=weaver-myproject-111122223333-artifacts-us-west-2,ObjectKeyPrefix=myFolder
  ```

Para obter mais informações sobre a `CreateSnapshot` API, consulte [CreateSnapshot](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_CreateSnapshot.html)a *Referência AWS SimSpace Weaver da API*.

## Use o AWS CLI para iniciar uma simulação a partir de um instantâneo
<a name="working-with_snapshots_cli_start"></a>

**Como iniciar uma simulação a partir de um snapshot**
+ Em um **prompt de comando**, chame a API `StartSimulation`.

  ```
  aws simspaceweaver start-simulation --name simulation-name --role-arn role-arn --snapshot-s3-location s3-location
  ```

  **Parâmetros**  
name  
Nome da nova simulação. O nome da simulação deve ser exclusivo em seu Conta da AWS. É possível usar `aws simspaceweaver list-simulations` para ver os nomes das simulações existentes.  
role-arn  
Nome do Recurso da Amazon (ARN) da função de aplicativo que sua simulação usará.  
snapshot-s3-location  
Uma string que especifica o bucket do Amazon S3 e a chave do objeto do arquivo de snapshot.  
O bucket do Amazon S3 deve estar na mesma Região da AWS que a simulação.

  **Exemplo**

  ```
  aws simspaceweaver start-simulation —name MySimulation —role-arn arn:aws:iam::111122223333:role/weaver-MyProject-app-role —snapshot-s3-location BucketName=weaver-myproject-111122223333-artifacts-us-west-2,ObjectKey=myFolder/snapshot/MyProjectSimulation_23-04-29_12_00_00-230429-1530-27.zip
  ```

Para obter mais informações sobre a `StartSimulation` API, consulte [StartSimulation](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)a *Referência AWS SimSpace Weaver da API*.

# Perguntas frequentes sobre snapshots
<a name="working-with_snapshots_faq"></a>

**A simulação continua sendo executada durante um snapshot?**  
Os recursos de simulação continuam sendo executados durante um snapshot e você continua recebendo cobranças de faturamento por esse período. O tempo conta para a duração máxima da simulação. Seus aplicativos não recebem marcações enquanto o snapshot está em andamento. Se o status do relógio era `STARTED` quando a criação do snapshot começou, seu relógio ainda indicará o status `STARTED`. Os aplicativos recebem marcações novamente após o término do snapshot. Se o status do relógio era `STOPPED`, o status do relógio permanecerá `STOPPED`. Observe que uma simulação com um status `STARTED` está sendo executada mesmo que o status do relógio seja `STOPPED`.

**O que acontece se um snapshot estiver em andamento e a simulação atingir sua duração máxima?**  
A simulação finalizará o snapshot e será interrompida assim que o processo de captura do snapshot terminar (com ou sem sucesso). Recomendamos que você teste o processo de snapshot com antecedência para descobrir quanto tempo leva, o tamanho do arquivo de snapshot que você pode esperar e se ele será concluído com êxito.

**O que acontece se eu interromper uma simulação que tem um snapshot em andamento?**  
Um snapshot em andamento é interrompido imediatamente quando você interrompe a simulação. Ele não criará um arquivo de snapshot.

**Como posso interromper um snapshot em andamento?**  
A única maneira de interromper um snapshot em andamento é interromper a simulação. **Não é possível reiniciar a simulação depois que ela for interrompida.**

**Quanto tempo vai levar para concluir o snapshot?**  
O tempo necessário para criar um snapshot depende da simulação. Recomendamos que você teste o processo de captura instantânea com antecedência para descobrir quanto tempo levará para sua simulação.

**Qual será o tamanho do meu arquivo de snapshot?**  
O tamanho de um arquivo de snapshot depende da simulação. Recomendamos que você teste o processo de captura do snapshot com antecedência para descobrir o tamanho do arquivo para a simulação.

# Sistema de mensagens
<a name="working-with_messaging"></a>

A API de mensagens simplifica a comunicação entre aplicativos na simulação. APIs enviar e receber mensagens faz parte do SDK do SimSpace Weaver aplicativo. Atualmente, as mensagens usam a abordagem de melhor esforço para enviar e receber mensagens. SimSpace Weaver tenta send/receive enviar mensagens na próxima simulação, mas não há garantias de entrega, pedido ou horário de chegada.

**Tópicos**
+ [Casos de uso para mensagens](#working-with_messaging_use-cases)
+ [Usando a mensagem APIs](working-with_messaging_using.md)
+ [Quando usar mensagens](working-with_messaging_when-to-use.md)
+ [Dicas para trabalhar com mensagens](working-with_messaging_tips.md)
+ [Erros de mensagens e solução de problemas](working-with_messaging_troubleshooting.md)

## Casos de uso para mensagens
<a name="working-with_messaging_use-cases"></a>

**Comunique-se entre aplicativos de simulação**  
Use a API de mensagens para se comunicar entre os aplicativos em sua simulação. Use-o para alterar o estado das entidades à distância, alterar o comportamento da entidade ou transmitir informações para toda a simulação.

**Confirmar o recebimento de uma mensagem**  
As mensagens enviadas contêm informações sobre o remetente no cabeçalho da mensagem. Use essas informações para enviar de volta uma resposta de confirmação ao receber uma mensagem.

**Encaminhar dados recebidos por um aplicativo personalizado para outros aplicativos dentro da simulação**  
As mensagens não substituem a forma como os clientes se conectam aos aplicativos personalizados em execução SimSpace Weaver. No entanto, as mensagens permitem aos usuários um método de encaminhar dados de aplicativos personalizados que recebem dados do cliente para outros aplicativos que não têm uma conexão externa. O fluxo de mensagens também pode funcionar ao contrário, permitindo que aplicativos sem conexão externa encaminhem dados para um aplicativo personalizado e depois para um cliente. 

# Usando a mensagem APIs
<a name="working-with_messaging_using"></a>

As mensagens APIs estão contidas no SDK do SimSpace Weaver aplicativo (versão mínima 1.16.0). O sistema de mensagens é compatível com C\$1\$1, Python e nossas integrações com o Unreal Engine 5 e o Unity.

Há duas funções que lidam com transações de mensagens: `SendMessage` `ReceiveMessages` e. Todas as mensagens enviadas contêm um destino e uma carga útil. A `ReceiveMessages` API retorna uma lista das mensagens atualmente na fila de mensagens de entrada de um aplicativo.

------
#### [ C\$1\$1 ]

**Enviar mensagem**

```
AWS_WEAVERRUNTIME_API Result<void> SendMessage(
    Transaction& txn,
    const MessagePayload& payload,
    const MessageEndpoint& destination,
    MessageDeliveryType deliveryType = MessageDeliveryType::BestEffort
    ) noexcept;
```

**Receba mensagens**

```
AWS_WEAVERRUNTIME_API Result<MessageList> ReceiveMessages(
    Transaction& txn) noexcept;
```

------
#### [ Python ]

**Enviar mensagem**

```
api.send_message(
 txn, # Transaction
 payload, # api.MessagePayload
 destination, # api.MessageDestination
 api.MessageDeliveryType.BestEffort # api.MessageDeliveryType
)
```

**Receba mensagens**

```
api.receive_messages(
 txn, # Transaction
) -> api.MessageList
```

------

**Tópicos**
+ [Enviar mensagens](#working-with_messaging_using_send)
+ [Recebimento de mensagens](#working-with_messaging_using_receive)
+ [Respondendo ao remetente](#working-with_messaging_using_reply)

## Enviar mensagens
<a name="working-with_messaging_using_send"></a>

As mensagens consistem em uma transação (semelhante a outras chamadas da API Weaver), uma carga útil e um destino.

### Carga útil da mensagem
<a name="working-with_messaging_using_send_payload"></a>

A carga útil da mensagem é uma estrutura de dados flexível de até 256 bytes. Recomendamos o seguinte como uma prática recomendada para criar suas cargas de mensagens.

**Para criar a carga útil da mensagem**

1. Crie uma estrutura de dados (como a `struct` em C\$1\$1) que defina o conteúdo da mensagem.

1. Crie a carga útil da mensagem que contém os valores a serem enviados em sua mensagem.

1. Crie o objeto `MessagePayload`.

### Destino da mensagem
<a name="working-with_messaging_using_send_destination"></a>

O destino de uma mensagem é definido pelo `MessageEndpoint` objeto. Isso inclui um tipo de endpoint e uma ID de endpoint. O único tipo de endpoint atualmente suportado é`Partition`, que permite endereçar mensagens para outras partições na simulação. O ID do endpoint é o ID da partição do seu destino.

Você só pode fornecer 1 endereço de destino em uma mensagem. Crie e envie várias mensagens se quiser enviar mensagens para mais de uma partição ao mesmo tempo.

Para obter orientação sobre como resolver um endpoint de mensagem a partir de uma posição, consulte[Dicas para trabalhar com mensagens](working-with_messaging_tips.md).

### Envie a mensagem
<a name="working-with_messaging_using_send_send"></a>

Você pode usar a `SendMessage` API depois de criar os objetos de destino e de carga útil.

------
#### [ C\$1\$1 ]

```
Api::SendMessage(transaction, payload, destination, MessageDeliveryType::BestEffort);
```

------
#### [ Python ]

```
api.send_message(txn, payload, destination, api.MessageDeliveryType.BestEffort)
```

------

**Exemplo completo de envio de mensagens**  
O exemplo a seguir demonstra como você pode criar e enviar uma mensagem genérica. Este exemplo envia 16 mensagens individuais. Cada mensagem contém uma carga útil com um valor entre 0 e 15 e a marca de simulação atual.

**Example**  

```
// Message struct definition
struct MessageTickAndId
{
    uint32_t id;
    uint32_t tick;
};

Aws::WeaverRuntime::Result<void> SendMessages(Txn& txn) noexcept
{
     // Fetch the destination MessageEndpoint with the endpoint resolver
    WEAVERRUNTIME_TRY(
        Api::MessageEndpoint destination,
        Api::Utils::MessageEndpointResolver::ResolveFromPosition(
        txn,
            "MySpatialSimulation",
            Api::Vector2F32 {231.3, 654.0}
        )
    );
    Log::Info("destination: ", destination);

    WEAVERRUNTIME_TRY(auto tick, Api::CurrentTick(txn));

    uint16_t numSentMessages = 0;
    for (std::size_t i=0; i<16; i++)
    {
        // Create the message that'll be serialized into payload
        MessageTickAndId message {i, tick.value};
        
        // Create the payload out of the struct
        const Api::MessagePayload& payload = Api::Utils::CreateMessagePayload(
            reinterpret_cast<const std::uint8_t*>(&message), 
            sizeof(MessageTickAndId)
        );
        
        // Send the payload to the destination
        Result<void> result = Api::SendMessage(txn, payload, destination);
        if (result.has_failure())
        {
            // SendMessage has failure modes, log them
            auto error = result.as_failure().error();
            std::cout<< "SendMessage failed, ErrorCode: " << error << std::endl;
            continue;
        }
        
        numSentMessages++;
    }

    std::cout << numSentMessages << " messages is sent to endpoint" 
       << destination << std::endl;
    return Aws::WeaverRuntime::Success();
}
```

```
# Message data class
@dataclasses.dataclass
class MessageTickAndId:
    tick: int = 0
    id: int = 0
    
# send messages
def _send_messages(self, txn):
    tick = api.current_tick(txn)
    num_messages_to_send = 16

    # Fetch the destination MessageEndpoint with the endpoint resolver
    destination = api.utils.resolve_endpoint_from_domain_name_position(
       txn,
       "MySpatialSimulation",
       pos
   )
    Log.debug("Destination_endpoint = %s", destination_endpoint)

   for id in range(num_messages_to_send):
       # Message struct that'll be serialized into payload
        message_tick_and_id = MessageTickAndId(id = id, tick = tick.value)
        
       # Create the payload out of the struct
        message_tick_and_id_data = struct.pack(
           '<ii',
           message_tick_and_id.id,
           message_tick_and_id.tick
       )
        payload = api.MessagePayload(list(message_tick_and_id_data))

        # Send the payload to the destination
        Log.debug("Sending message: %s, endpoint: %s",
           message_tick_and_id,
           destination
       )
        api.send_message(
           txn,
           payload,
           destination,
           api.MessageDeliveryType.BestEffort
       )

    Log.info("Sent %s messages to %s", num_messages_to_send, destination)
    return True
```

## Recebimento de mensagens
<a name="working-with_messaging_using_receive"></a>

SimSpace Weaver entrega mensagens na fila de mensagens de entrada de uma partição. Use a `ReceiveMessages` API para obter um `MessageList` objeto que contém as mensagens da fila. Processe cada mensagem com a `ExtractMessage` API para obter os dados da mensagem.

**Example**  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
     // Fetch all the messages sent to the partition owned by the app
    WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn));
    std::cout << "Received" << messages.messages.size() << " messages" << std::endl;
    for (Api::Message& message : messages.messages)
    {
        std::cout << "Received message: " << message << std::endl;

         // Deserialize payload to the message struct
        const MessageTickAndId& receivedMessage 
            = Api::Utils::ExtractMessage<MessageTickAndId>(message);
        std::cout << "Received MessageTickAndId, Id: " << receivedMessage.id 
            <<", Tick: " << receivedMessage.tick << std::endl;
    }

    return Aws::WeaverRuntime::Success();
}
```

```
# process incoming messages
def _process_incoming_messages(self, txn):
    messages = api.receive_messages(txn)
    for message in messages:
        payload_list = message.payload.data
        payload_bytes = bytes(payload_list)
        message_tick_and_id_data_struct 
           = MessageTickAndId(*struct.unpack('<ii', payload_bytes))

        Log.debug("Received message. Header: %s, message: %s", 
                    message.header, message_tick_and_id_data_struct)

    Log.info("Received %s messages", len(messages))
    return True
```

## Respondendo ao remetente
<a name="working-with_messaging_using_reply"></a>

Cada mensagem recebida contém um cabeçalho com informações sobre o remetente original da mensagem. Você pode usar o message.header.source\$1endpoint para enviar uma resposta.

**Example**  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
     // Fetch all the messages sent to the partition owned by the app
    WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn));
    std::cout << "Received" << messages.messages.size() << " messages" << std::endl;
    for (Api::Message& message : messages.messages)
    {
        std::cout << "Received message: " << message << std::endl;

         // Deserialize payload to the message struct
        const MessageTickAndId& receivedMessage 
            = Api::Utils::ExtractMessage<MessageTickAndId>(message);
        std::cout << "Received MessageTickAndId, Id: " << receivedMessage.id 
            <<", Tick: " << receivedMessage.tick << std::endl;
        
        // Get the sender endpoint and payload to bounce the message back
        Api::MessageEndpoint& sender = message.header.source_endpoint;
        Api::MessagePayload& payload = message.payload;
        Api::SendMessage(txn, payload, sender);
    }

    return Aws::WeaverRuntime::Success();
}
```

```
# process incoming messages
def _process_incoming_messages(self, txn):
    messages = api.receive_messages(txn)
    for message in messages:
        payload_list = message.payload.data
        payload_bytes = bytes(payload_list)
        message_tick_and_id_data_struct 
           = MessageTickAndId(*struct.unpack('<ii', payload_bytes))

        Log.debug("Received message. Header: %s, message: %s", 
                    message.header, message_tick_and_id_data_struct)
       # Get the sender endpoint and payload 
       # to bounce the message back
       sender = message.header.source_endpoint
       payload = payload_list
       api.send_message(
           txn,
           payload_list,
           sender,
           api.MessageDeliveryType.BestEffort

    Log.info("Received %s messages", len(messages))
    return True
```

# Quando usar mensagens
<a name="working-with_messaging_when-to-use"></a>

O envio de mensagens SimSpace Weaver oferece outro padrão para a troca de informações entre aplicativos de simulação. As assinaturas fornecem um mecanismo de pull para ler dados de aplicativos ou áreas específicas da simulação; as mensagens fornecem um mecanismo push para enviar dados para aplicativos ou áreas específicas da simulação.

Abaixo estão dois casos de uso em que é mais útil enviar dados usando mensagens em vez de extrair ou ler dados por meio de uma assinatura.

**Example 1: Enviar um comando para outro aplicativo para alterar a posição de uma entidade**  

```
// Message struct definition
struct MessageMoveEntity
{
     uint64_t entityId;
    std::array<float, 3> destinationPos;
};

// Create the message 
MessageMoveEntity message {45, {236.67, 826.22, 0.0} };

// Create the payload out of the struct
const Api::MessagePayload& payload = Api::Utils::CreateMessagePayload(
    reinterpret_cast<const std::uint8_t*>(&message), 
    sizeof(MessageTickAndId)
);

// Grab the MessageEndpoint of the recipient app.
Api::MessageEndpoint destination = ...

// One way is to resolve it from the domain name and position
WEAVERRUNTIME_TRY(
    Api::MessageEndpoint destination,
    Api::Utils::MessageEndpointResolver::ResolveFromPosition(
    txn,
        "MySpatialSimulation",
        Api::Vector2F32 {200.0, 100.0}
    )
);

// Then send the message 
Api::SendMessage(txn, payload, destination);
```
No lado receptor, o aplicativo atualiza a posição da entidade e a grava no State Fabric.  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
    WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn));
    for (Api::Message& message : messages.messages)
    {
        std::cout << "Received message: " << message << std::endl;
         // Deserialize payload to the message struct
        const MessageMoveEntity& receivedMessage 
            = Api::Utils::ExtractMessage<MessageMoveEntity>(message);
            
        ProcessMessage(txn, receivedMessage);
    }

    return Aws::WeaverRuntime::Success();
}

void ProcessMessage(Txn& txn, const MessageMoveEntity& receivedMessage)
{
     // Get the entity corresponding to the entityId
    Entity entity = EntityFromEntityId (receivedMessage.entityId);
    
    // Update the position and write to StateFabric
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
            txn,
            entity,
            k_vector3f32TypeId, // type id of the entity
            reinterpret_cast<std::int8_t*>(&receivedMessage.destinationPos),
            sizeof(receivedMessage.destinationPos)));
    
}
```

**Example 2: Enviando uma mensagem de criação de entidade para um aplicativo espacial**  

```
struct WeaverMessage
{
    const Aws::WeaverRuntime::Api::TypeId messageTypeId;
};

const Aws::WeaverRuntime::Api::TypeId k_createEntityMessageTypeId = { 1 };

struct CreateEntityMessage : WeaverMessage
{
    const Vector3 position;
   const Aws::WeaverRuntime::Api::TypeId typeId;
}; 


CreateEntityMessage messageData { 
    k_createEntityMessageTypeId,                           
    Vector3{ position.GetX(), position.GetY(), position.GetZ() },
    Api::TypeId { 0 }
}

WEAVERRUNTIME_TRY(Api::MessageEndpoint destination, Api::Utils::MessageEndpointResolver::ResolveFromPosition(
    transaction, "MySpatialDomain", DemoFramework::ToVector2F32(position)
));

Api::MessagePayload payload = Api::Utils::CreateMessagePayload(
    reinterpret_cast<const uint8_t*>(&messageData),
    sizeof(CreateEntityMessage));
        
Api::SendMessage(transaction, payload, destination);
```
No lado receptor, o aplicativo cria uma nova entidade no State Fabric e atualiza sua posição.  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
    WEAVERRUNTIME_TRY(auto messageList, Api::ReceiveMessages(transaction));
    WEAVERRUNTIME_TRY(auto tick, Api::CurrentTick(transaction));
    for (auto& message : messageList.messages)
    {
        // cast to base WeaverMessage type to determine MessageTypeId
        WeaverMessage weaverMessageBase = Api::Utils::ExtractMessage<WeaverMessage>(message);
        if (weaverMessageBase.messageTypeId == k_createEntityMessageTypeId)
        {
            CreateEntityMessage createEntityMessageData =
                Api::Utils::ExtractMessage<CreateEntityMessage>(message);
        CreateActorFromMessage(transaction, createEntityMessageData));
        }
        else if (weaverMessageBase.messageTypeId == k_tickAndIdMessageTypeId)
        {
            ...
        }
    }
}

void ProcessMessage(Txn& txn, const CreateEntityMessage& receivedMessage)
{
    // Create entity
    WEAVERRUNTIME_TRY(
        Api::Entity entity,
        Api::CreateEntity(transaction, receivedMessage.typeId)
    );
    
    // Update the position and write to StateFabric
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        receivedMessage.typeId,
        reinterpret_cast<std::int8_t*>(&receivedMessage.position),
        sizeof(receivedMessage.position)));
}
```

# Dicas para trabalhar com mensagens
<a name="working-with_messaging_tips"></a>

## Resolver um endpoint a partir de uma posição ou nome de aplicativo
<a name="working-with_messaging_tips_resolve-endpoint"></a>

Você pode usar a `AllPartitions` função para obter os limites espaciais e o ID de domínio necessários para determinar a partição IDs e os destinos das mensagens. No entanto, se você souber a posição que deseja enviar uma mensagem, mas não o ID da partição, poderá usar a MessageEndpointResolver função.

```
/**
* Resolves MessageEndpoint's from various inputs
**/
class MessageEndpointResolver
{
    public:
    /**
    * Resolves MessageEndpoint from position information
    **/
    Result<MessageEndpoint> ResolveEndpointFromPosition(
        const DomainId& domainId,
        const weaver_vec3_f32_t& pos);

    /**
    * Resolves MessageEndpoint from custom app name
    **/
    Result<MessageEndpoint> ResolveEndpointFromCustomAppName(
        const DomainId& domainId,
        const char* agentName);
};
```

## Serializando e desserializando a carga útil da mensagem
<a name="working-with_messaging_tips_serialize-payload"></a>

Você pode usar as funções a seguir para criar e ler cargas de mensagens. Para obter mais informações, consulte MessagingUtils .h na biblioteca do SDK do aplicativo em seu sistema local.

```
/**
* Utility function to create MessagePayload from a custom type
*
* @return The @c MessagePayload.
*/
template <class T>
AWS_WEAVERRUNTIME_API MessagePayload CreateMessagePayload(const T& message) noexcept
{
    const std::uint8_t* raw_data = reinterpret_cast<const std::uint8_t*>(&message);

    MessagePayload payload;
    std::move(raw_data, raw_data + sizeof(T), std::back_inserter(payload.data));

    return payload;
}

/**
* Utility function to convert MessagePayload to custom type
*/
template <class T>
AWS_WEAVERRUNTIME_API T ExtractMessage(const MessagePayload& payload) noexcept
{
    return *reinterpret_cast<const T*>(payload.data.data());
}
```

# Erros de mensagens e solução de problemas
<a name="working-with_messaging_troubleshooting"></a>

Você pode enfrentar os seguintes erros ao usar a mensagem APIs.

## Erros de resolução de endpoints
<a name="working-with_messaging_troubleshooting_endpoint-resolution"></a>

Esses erros podem ocorrer antes que um aplicativo envie uma mensagem.

### Verificação do nome de domínio
<a name="working-with_messaging_troubleshooting_dns-check"></a>

Enviar uma mensagem para um endpoint inválido resulta no seguinte erro:

```
ManifoldError::InvalidArgument {"No DomainId found for the given domain name" }
```

Isso pode acontecer quando você tenta enviar uma mensagem para um aplicativo personalizado e esse aplicativo personalizado ainda não entrou na simulação. Use a `DescribeSimulation` API para garantir que seu aplicativo personalizado tenha sido lançado antes de você enviar uma mensagem para ele. Esse comportamento é o mesmo em SimSpace Weaver Local e Nuvem AWS o.

### Verificação de posição
<a name="working-with_messaging_troubleshooting_position-check"></a>

Tentar resolver um endpoint com um nome de domínio válido, mas com uma posição inválida, resulta no seguinte erro.

```
ManifoldError::InvalidArgument {"Could not resolve endpoint from domain : DomainId { value: domain-id } and position: Vector2F32 { x: x-position, y: y-position}" }
```

Sugerimos usar o `MessageEndpointResolver` na `MessageUtils` biblioteca contida no SDK do SimSpace Weaver aplicativo.

## Erros de envio de mensagens
<a name="working-with_messaging_troubleshooting_message-sending"></a>

Os erros a seguir podem ocorrer quando um aplicativo envia uma mensagem.

### Limite de envio de mensagens por aplicativo, por tick, excedido
<a name="working-with_messaging_troubleshooting_send-limit"></a>

O limite atual para o número de mensagens que podem ser enviadas por aplicativo por clique de simulação é 128. As chamadas subsequentes com o mesmo tick falharão com o seguinte erro: 

```
ManifoldError::CapacityExceeded {"At Max Outgoing Message capacity: {}", 128}
```

SimSpace Weaver tenta enviar mensagens não enviadas na próxima marca. Diminua a frequência de envio para resolver esse problema. Combine cargas de mensagens menores que o limite de 256 bytes para reduzir o número de mensagens de saída.

Esse comportamento é o mesmo em SimSpace Weaver Local e no Nuvem AWS. 

### Limite de tamanho da carga útil da mensagem excedido
<a name="working-with_messaging_troubleshooting_size-limit"></a>

O limite atual para o tamanho da carga útil da mensagem é 256 bytes em ambos SimSpace Weaver Local e no Nuvem AWS. Enviar uma mensagem com uma carga útil maior que 256 bytes resulta no seguinte erro:

```
ManifoldError::CapacityExceeded {"Message data too large! Max size: {}", 256}
```

SimSpace Weaver verifica cada mensagem e rejeita somente aquelas que excedem o limite. Por exemplo, se seu aplicativo tentar enviar 10 mensagens e 1 falhar na verificação, somente essa mensagem será rejeitada. SimSpace Weaver envia as outras 9 mensagens.

Esse comportamento é o mesmo em SimSpace Weaver Local e Nuvem AWS o.

### O destino é o mesmo que a origem
<a name="working-with_messaging_troubleshooting_dst-src-same"></a>

Os aplicativos não podem enviar mensagens para as partições de sua propriedade. Você receberá o erro a seguir se um aplicativo enviar uma mensagem para uma partição de sua propriedade.

```
ManifoldError::InvalidArgument { "Destination is the same as source" }
```

Esse comportamento é o mesmo em SimSpace Weaver Local e Nuvem AWS o.

### Mensagens de melhor esforço
<a name="working-with_messaging_troubleshooting_best-effort"></a>

SimSpace Weaver não garante a entrega da mensagem. O serviço tentará concluir a entrega das mensagens na simulação subsequente, mas as mensagens podem ser perdidas ou atrasadas.