

Aviso de fin de soporte: el 20 de mayo de 2026, AWS finalizará el soporte para AWS SimSpace Weaver. Después del 20 de mayo de 2026, ya no podrás acceder a la SimSpace Weaver consola ni a SimSpace Weaver los recursos. Para obtener más información, consulta [AWS SimSpace Weaver el fin del soporte](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html). 

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Trabajando con SimSpace Weaver
<a name="working-with"></a>

Este capítulo proporciona información y orientación para ayudarle a crear sus propias aplicaciones en SimSpace Weaver.

**Topics**
+ [Configuración de su simulación](working-with_configuring-simulation.md)
+ [Duración máxima de una simulación](working-with_max-duration.md)
+ [Desarrollo de aplicaciones](working-with_developing-apps.md)
+ [Desarrollo de aplicaciones de cliente](working-with_developing-client-applications.md)
+ [Obtenga la dirección IP y el número de puerto de una aplicación personalizada](working-with_get-ip.md)
+ [Lanzamiento del cliente de visualización de Unreal Engine](working-with_unreal-client.md)
+ [Desarrollo local en SimSpace Weaver](working-with_local-development.md)
+ [SDK de la aplicación AWS SimSpace Weaver](working-with_app-sdk.md)
+ [AWS SimSpace Weaver marco de demostración](working-with_demo-framework.md)
+ [Trabajar con Service Quotas](working-with_quotas.md)
+ [Depuración de simulaciones](working-with_debugging.md)
+ [Contenedores personalizados](working-with_custom-containers.md)
+ [Trabajo con Python](working-with_python.md)
+ [Compatibilidad con otros motores](working-with_engines.md)
+ [Uso de software con licencia con AWS SimSpace Weaver](working-with_byol.md)
+ [Administra tus recursos con AWS CloudFormation](working-with_cloudformation.md)
+ [Instantáneas](working-with_snapshots.md)
+ [Mensajería](working-with_messaging.md)

# Configuración de su simulación
<a name="working-with_configuring-simulation"></a>

Un **esquema (o **esquema) de** simulación** es un YAML- Archivo de texto con formato que especifica la configuración de una simulación. Puede utilizar el mismo esquema para iniciar varias simulaciones. El archivo de esquema se encuentra en la carpeta del proyecto de la simulación. Puede utilizar cualquier editor de texto para editar el archivo. SimSpace Weaver solo lee el esquema cuando inicia la simulación. Las modificaciones que realice en un archivo de esquema solo afectarán a las simulaciones nuevas que se inicien después de las modificaciones. 

Para configurar la simulación, edite el archivo de esquema de simulación (utilice el separador de rutas adecuado para su sistema operativo):

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

El esquema de simulación se carga al crear una nueva simulación. El script auxiliar de inicio rápido de su proyecto cargará el esquema como parte del proceso de creación de la simulación: 

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

Para obtener más información sobre la ejecución del script de inicio rápido, consulte [Tutorial introductorio](getting-started_detailed.md) el [Introducción](getting-started.md) capítulo de esta guía.

## Parámetros de configuración de la simulación
<a name="working-with_configuring-simulation_config-parameters"></a>

El esquema de simulación contiene información de arranque, que incluye:
+ **Propiedades de la simulación**[: versión del SDK y configuración de procesamiento (tipo y número de trabajadores)](w2aac51.md#glossary_worker)
+ **Relojes**: velocidad de graduación y tolerancias
+ **Estrategias de partición espacial**: topología espacial (como una cuadrícula), límites y grupos de ubicación (agrupación de particiones espaciales según los trabajadores)
+ **Dominios y sus aplicaciones**: bucket de aplicaciones, ruta y comando(s) de lanzamiento

SimSpace Weaver utiliza la configuración de su esquema para configurar y organizar las particiones espaciales, lanzar aplicaciones y hacer avanzar la simulación a la velocidad de aceleración especificada. 

**nota**  
El script de creación de proyectos del SDK de la SimSpace Weaver aplicación generará automáticamente un esquema de simulación basado en la aplicación de ejemplo.

En los siguientes temas se describen los parámetros del esquema de simulación. Para obtener una descripción completa del esquema de simulación, consulte [SimSpace Weaver referencia del esquema de simulación](schema-reference.md). 

**Topics**
+ [Parámetros de configuración de la simulación](#working-with_configuring-simulation_config-parameters)
+ [Versión de SDK](working-with_configuring-simulation_sdk-version.md)
+ [Propiedades de simulación](working-with_configuring-simulation_simulation-properties.md)
+ [Trabajadores](working-with_configuring-simulation_workers.md)
+ [Reloj](working-with_configuring-simulation_clock.md)
+ [Estrategias de partición](working-with_configuring-simulation_partitioning-strategies.md)
+ [Dominios](working-with_configuring-simulation_domains.md)

# Versión de SDK
<a name="working-with_configuring-simulation_sdk-version"></a>

El `sdk_version` campo especifica la versión para la SimSpace Weaver que está formateado el esquema. Valores válidos: `1.17`, `1.16`, `1.15`, `1.14`, `1.13`, `1.12`

**importante**  
El valor de `sdk_version` solo incluye el número de versión principal y el número de la primera versión secundaria. Por ejemplo, el valor `1.12` especifica todas las versiones, como `1.12.x`, `1.12.0`, `1.12.1` y `1.12.2`.

# Propiedades de simulación
<a name="working-with_configuring-simulation_simulation-properties"></a>

La sección `simulation_properties` del esquema especifica la configuración de registro y el tipo de datos para el campo de índice (normalmente la ubicación espacial) de las entidades.

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

El valor de `log_destination_service` determina la interpretación del valor de `log_destination_resource_name`. Actualmente el único valor admitido es `logs`. Esto significa que el valor de `log_destination_resource_name` es el nombre de un grupo de CloudWatch registros en Amazon Logs

**nota**  
El registro es opcional. Si no configura las propiedades de destino de los registros, la simulación no generará registros.

Solo es obligatoria la propiedad `default_entity_index_key_type`. El único valor válido es `Vector3<f32>`.

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

La `workers` sección especifica el tipo y el número de trabajadores que desea para la simulación. SimSpace Weaver usa sus propios tipos de trabajadores que se asignan a los tipos de EC2 instancias de Amazon. 

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

## Permitir simulaciones con varios trabajadores
<a name="working-with_configuring-simulation_workers_multi-worker"></a>

Puede crear una simulación que utilice más de un trabajador. De forma predeterminada, las simulaciones utilizan 1 trabajador. Debe modificar el esquema de simulación antes de iniciar la simulación. 

**nota**  
No se puede cambiar una simulación que ya se ha iniciado. Si desea habilitar la funcionalidad de varios trabajadores para una simulación en ejecución, primero debe detener y eliminar la simulación.

Para usar más de un trabajador, defina el número `desired` de instancias de cómputo en un valor superior a 1. Hay un número máximo de aplicaciones para cada trabajador. Para obtener más información, consulte[SimSpace Puntos finales y cuotas de Weaver](service-quotas.md). SimSpace Weaver solo utilizará más de un trabajador cuando el número de aplicaciones de un trabajador supere este límite. SimSpace Weaver puede colocar una aplicación en cualquiera de los trabajadores disponibles. No se garantiza la colocación de la aplicación en un trabajador específico. 

El siguiente fragmento de esquema muestra una configuración para una simulación que solicita 2 trabajadores. SimSpace Weaver intentará asignar el segundo trabajador si el número de aplicaciones supera el número máximo de aplicaciones para 1 trabajador.

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

# Reloj
<a name="working-with_configuring-simulation_clock"></a>

La sección `clock` especifica las propiedades del reloj de simulación. Actualmente, solo se puede configurar la **frecuencia de graduación** (el número de graduaciones por segundo que el reloj envía a las aplicaciones). La frecuencia de graduación es la velocidad máxima. La frecuencia de graduación efectiva podría ser inferior, ya que todas las operaciones (como las actualizaciones de entidades) de una graduación deben finalizar antes de que comience la siguiente. La frecuencia de graduación también se denomina **frecuencia de reloj**.

Los valores válidos de `tick_rate` dependen del `sdk_version` especificado en el esquema.

**Valores válidos para la frecuencia de graduación**
+ Versiones anteriores a `"1.14"`:
  + `10`
  + `15`
  + `30`
+ Versión `"1.14"` o posterior:
  + `"10"`
  + `"15"`
  + `"30"`
  + `"unlimited"`

    Para obtener más información, consulte [Frecuencia de graduación ilimitada](#working-with_configuring-simulation_clock_unlimited).

**importante**  
Para los esquemas con un valor `sdk_version` anterior a `"1.14"` el valor de `tick_rate` es un **entero**, como `30`.
Para los esquemas con un `sdk_version` de `"1.14"` o posterior, el valor de `tick_rate` es una **cadena**, como `"30"`. El valor **debe incluir comillas dobles**.  
Si convierte una versión `"1.12"` o un esquema `"1.13"` en una versión `"1.14"` o posterior, debe escribir el valor de `tick_rate` entre comillas dobles.

## Frecuencia de graduación ilimitada
<a name="working-with_configuring-simulation_clock_unlimited"></a>

Puede configurar `tick_rate` para que `"unlimited"` permita que la simulación se ejecute tan rápido como el código. Con una tasa de tics ilimitada, SimSpace Weaver envía el siguiente tic inmediatamente después de que todas las aplicaciones finalicen las confirmaciones del tic actual.

**importante**  
 SimSpace Weaver Las versiones anteriores a la 1.14.0 no admiten la tasa de activación ilimitada. El valor mínimo de `sdk_version` en el esquema es `"1.14"`.

**Frecuencia de graduación ilimitada en SimSpace Weaver Local**  
SimSpace Weaver Local implementa `"unlimited"` como si el esquema especificara una frecuencia de graduación de 10 kHz (10000). El efecto es el mismo que el de una frecuencia de graduación ilimitada en Nube de AWS. Aún debe especificar `tick_rate: "unlimited"` en su esquema. Para obtener más información acerca de SimSpace Weaver Local, consulte [Desarrollo local en SimSpace Weaver](working-with_local-development.md).

## Preguntas frecuentes acerca del reloj
<a name="working-with_configuring-simulation_clock_faq"></a>

### Q1 (P1). ¿Puedo cambiar una simulación iniciada para que utilice una frecuencia de graduación diferente?
<a name="working-with_configuring-simulation_clock_faq_q1"></a>

No se puede cambiar la tasa de activación de una simulación que ya existe en el Nube de AWS en ninguna fase de su ciclo de vida. Tampoco puede cambiar la tasa de activación de una simulación en ejecución en SimSpace Weaver Local. Puede configurar `tick_rate` en el esquema e iniciar una nueva simulación a partir de ese esquema.

### Q2 (P2). ¿Puedo ejecutar mi simulación con una frecuencia de graduación ilimitada en una versión anterior a la 1.14?
<a name="working-with_configuring-simulation_clock_faq_q2"></a>

No, la frecuencia de graduación ilimitada no es compatible con las versiones anteriores a la 1.14.0.

## Solución de errores del reloj
<a name="working-with_configuring-simulation_clock_troubleshooting"></a>

Si la simulación no se inicia, puede comprobar el valor de `"StartError"` en la salida de la **DescribeSimulation**API. Un valor de `tick_rate` no válido en el esquema generará los siguientes errores.

**nota**  
El resultado de error que se muestra aquí se muestra en varias líneas para mejorar la legibilidad. La salida de error real es una sola línea.
+ El `sdk_version` es anterior `"1.14"` y el valor de `tick_rate` es un entero no válido. Valores válidos: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"}]"
  ```
+ El `sdk_version` es anterior `"1.14"` y el valor de `tick_rate` es una cadena. 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\"}]"
  ```
+ El `sdk_version` es `"1.14"` o posterior y el valor de `tick_rate` es una cadena no vá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]\"}]"
  ```
+ El `sdk_version` es `"1.14"` o posterior y el valor de `tick_rate` es un número entero. 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\"}]"
  ```

# Estrategias de partición
<a name="working-with_configuring-simulation_partitioning-strategies"></a>

En la sección `partitioning_strategies` se especifican las propiedades de configuración de las particiones de las aplicaciones espaciales. Debe proporcionar su propio nombre para la estrategia de partición (un conjunto de propiedades en esta sección) y utilizarlo en la configuración de su aplicación espacial.

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

La propiedad `topology` especifica el tipo de sistema de coordenadas que utiliza la simulación. El valor `Grid` especifica una rejilla bidimensional (2D).

Para una `Grid` topología, el espacio de simulación se modela como un cuadro delimitador alineado con el eje. (AABB). Los límites de las coordenadas de cada eje de su AABB se especifican en la propiedad. `aabb_bounds` Todas las entidades que existen espacialmente en la simulación deben tener una posición dentro del AABB.

## Grupos de ubicación de cuadrícula
<a name="working-with_configuring-simulation_partitioning-strategies_placement-groups"></a>

Un **grupo de ubicación** es un conjunto de particiones de aplicaciones espaciales que desea colocar en el SimSpace Weaver mismo elemento de trabajo. Debe especificar el número y la disposición de los grupos de ubicaciones (en una cuadrícula) en la `grid_placement_groups` propiedad. SimSpace Weaver intentará distribuir uniformemente las particiones entre los grupos de colocación. Las áreas de propiedad de las aplicaciones espaciales con particiones en el mismo grupo de ubicación estarán espacialmente adyacentes.

Recomendamos que x\$1 y sea igual al número deseado de trabajadores. Si no es igual, SimSpace Weaver intentará equilibrar los grupos de colocación entre los trabajadores disponibles.

Si no especifica una configuración de grupo de colocación, SimSpace Weaver calculará una por usted.

# Dominios
<a name="working-with_configuring-simulation_domains"></a>

Debe proporcionar un nombre para un conjunto de propiedades de configuración de un dominio. La configuración de inicio de las aplicaciones de un dominio determina el tipo de dominio:
+ **`launch_apps_via_start_app_call`**: dominio personalizado
+ **`launch_apps_by_partitioning_strategy`**: dominio espacial
+ **`launch_apps_per_worker`**(no incluido en la aplicación de muestra): dominio de servicio

**importante**  
SimSpace Weaver admite hasta 5 dominios para cada simulación. Esto incluye todos los dominios espaciales, personalizados y de servicio.

```
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 Los proyectos de la versión 1.12.x del SDK de la aplicación utilizan cubos separados para los archivos.zip de la aplicación y el esquema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -esquemas- *lowercase-project-name* *account-number* *region*

**Topics**
+ [Configuración de la aplicación](working-with_configuring-simulation_domains_app-config.md)
+ [Configuración de dominios espaciales](working-with_configuring-simulation_domains_spatial.md)
+ [Puntos de conexión de red](working-with_configuring-simulation_domains_endpoints.md)
+ [Configuración de dominios de servicio](working-with_configuring-simulation_domains_service-domains.md)

# Configuración de la aplicación
<a name="working-with_configuring-simulation_domains_app-config"></a>

La configuración de una aplicación (`app_config`) se especifica como parte de la configuración de su dominio. Todos los tipos de dominios utilizan estas mismas propiedades de configuración de la aplicación.

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

**nota**  
SimSpace Weaver Los proyectos de la versión 1.12.x del SDK de la aplicación utilizan cubos separados para los archivos.zip de la aplicación y el esquema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -esquemas- *lowercase-project-name* *account-number* *region*

La propiedad `package` especifica el URI de S3 de un archivo zip de un bucket de S3. El archivo zip contiene el ejecutable de la aplicación (también denominado *binario*) y cualquier otro recurso que necesite (como bibliotecas). Cada instancia del ejecutable de la aplicación se ejecuta en un contenedor Docker en un dispositivo de trabajo. 

La propiedad `launch_command` especifica el nombre del ejecutable y cualquier opción de línea de comandos para ejecutar la aplicación. El valor de `launch_command` es una matriz. Cada símbolo de toda la cadena de comandos de lanzamiento es un elemento de la matriz.

**Ejemplo**
+ Para el comando de lanzamiento: `MyTestApp --option1 value1`
+ Especifique: `launch_command: ["MyTestApp", "-option1", "value1"]`.

La `required_resource_units` propiedad especifica el número de unidades de recursos de cómputo que se SimSpace Weaver deben asignar a esta aplicación. Una unidad de recursos informáticos es una cantidad fija de capacidad de procesamiento (vCPU) y memoria (RAM) de un trabajador. Puede aumentar este valor para aumentar la cantidad de potencia de cálculo disponible para la aplicación cuando se ejecuta en un trabajador. Hay un número limitado de unidades de recursos informáticos en cada trabajador. Para obtener más información, consulte [SimSpace Puntos finales y cuotas de Weaver](service-quotas.md).

# Configuración de dominios espaciales
<a name="working-with_configuring-simulation_domains_spatial"></a>

Para los dominios espaciales, debe especificar un `partitioning_strategy`. El valor de esta propiedad es el nombre que ha asignado a una estrategia de partición que ha definido en otra parte del 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 Los proyectos de la versión 1.12.x del SDK de la aplicación utilizan depósitos independientes para los archivos.zip de la aplicación y el esquema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -esquemas- *lowercase-project-name* *account-number* *region*

Una estrategia de particionamiento con una `Grid` topología (la única topología compatible en esta versión) permite organizar las particiones de aplicaciones espaciales de este dominio en una cuadrícula. SimSpace Weaver La propiedad `grid_partition` especifica el número de filas y columnas de la cuadrícula de particiones. 

SimSpace Weaver iniciará 1 instancia de la aplicación espacial para cada celda de la cuadrícula de particiones. Por ejemplo, si un dominio espacial tiene `grid_partition` valores `x: 2` y `y: 2` hay 2 \$1 2 = 4 particiones en el dominio espacial. SimSpace Weaver iniciará 4 instancias de la aplicación configuradas en el dominio espacial y asignará 1 partición a cada instancia de la aplicación.

**Temas**
+ [Requisitos de recursos para los dominios espaciales](#working-with_configuring-simulation_domains_spatial_resources)
+ [Múltiples dominios espaciales](#working-with_configuring-simulation_domains_spatial_multiple)
+ [Preguntas frecuentes sobre dominios espaciales](#working-with_configuring-simulation_domains_spatial_faq)
+ [Solución de problemas de dominios espaciales](#working-with_configuring-simulation_domains_spatial_troubleshooting)

## Requisitos de recursos para los dominios espaciales
<a name="working-with_configuring-simulation_domains_spatial_resources"></a>

Puede asignar hasta 17 unidades de recursos de procesamiento para cada trabajador. Usted especifica el número de unidades de recursos informáticos que utiliza cada aplicación espacial en la sección `app_config` de su dominio espacial.

**Example fragmento de esquema que muestra las unidades de recursos de cómputo de una aplicación 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 el número de unidades de recursos informáticos que requiere un dominio, multiplique el número de celdas de la cuadrícula (en su `grid_partition`, `x` \$1 `y`) por el número de unidades de recursos informáticos asignadas a las aplicaciones espaciales.

En el ejemplo anterior, el dominio `MySpatialDomain` especifica:
+ `x`: `2`
+ `y`: `2`
+ `compute`: `1`

La cuadrícula para `MySpatialDomain` tiene 2 \$1 2 = 4 celdas. El dominio espacial requiere 4 x 1 = 4 unidades de recursos informáticos.

El número total de unidades de recursos informáticos para todos los dominios especificados en el esquema debe ser inferior o igual al `desired` número de trabajadores multiplicado por el número máximo de unidades de recursos informáticos de cada trabajador (17).

## Múltiples dominios espaciales
<a name="working-with_configuring-simulation_domains_spatial_multiple"></a>

Puede configurar la simulación para que utilice más de un dominio espacial. Por ejemplo, puede usar un dominio espacial para controlar los actores principales de una simulación (como personas y automóviles) y un dominio espacial diferente para controlar el entorno.

También puede utilizar varios dominios espaciales para asignar distintos recursos a distintas partes de la simulación. Por ejemplo, si la simulación tiene un tipo de entidad que tiene 10 veces más instancias de entidad que otro tipo, puede crear diferentes dominios para gestionar cada tipo de entidad y asignar más recursos al dominio con más entidades.

**importante**  
SimSpace Weaver las versiones anteriores a la 1.14.0 no admiten varios dominios espaciales.

**importante**  
AWS SimSpace Weaver Localactualmente no admite varios dominios espaciales. Para obtener más información acerca de SimSpace Weaver Local, consulte [Desarrollo local en SimSpace Weaver](working-with_local-development.md).

**importante**  
SimSpace Weaver admite hasta 5 dominios para cada simulación. Esto incluye todos los dominios espaciales, personalizados y de servicio.

### Configurar varios dominios espaciales
<a name="working-with_configuring-simulation_domains_spatial_multiple_configure"></a>

Para configurar más de un dominio espacial, añada las demás definiciones de dominio espacial como secciones con nombres independientes en su esquema. Cada dominio debe especificar la clave `launch_apps_by_partitioning_strategy`. Consulte el siguiente esquema de ejemplo.

```
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
```

### Colocar dominios espaciales juntos
<a name="working-with_configuring-simulation_domains_spatial_multiple_placement"></a>

En algunos casos, es posible que desee colocar las particiones de un dominio espacial en los trabajadores junto a las particiones de otro dominio. Esto puede mejorar las características de rendimiento si esas particiones se suscriben entre sí a varios dominios.

Añada la clave de nivel superior `placement_constraints` a su esquema para especificar qué dominios SimSpace Weaver deben colocarse juntos. La clave `on_workers` requerida debe hacer referencia a una configuración de `workers` con nombre en el esquema.

**Example fragmento de esquema que muestra los dominios espaciales colocados juntos**  

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

**importante**  
Si utiliza grupos de ubicación:  
Asegúrese de que x\$1 y sea múltiplo de la cantidad de trabajadores.
Asegúrese de que los valores de los grupos de ubicación sean divisores comunes para las dimensiones de la cuadrícula de los dominios que coloque juntos.
Si **no utiliza** grupos de ubicación:  
Asegúrese de que 1 eje de las cuadrículas de su dominio espacial tenga un divisor común que sea igual al número de trabajadores.
Para obtener más información acerca de los grupos de ubicación, consulte [Estrategias de partición](working-with_configuring-simulation_partitioning-strategies.md#working-with_configuring-simulation_partitioning-strategies_placement-groups). 

## Preguntas frecuentes sobre dominios espaciales
<a name="working-with_configuring-simulation_domains_spatial_faq"></a>

### Q1 (P1). ¿Cómo puedo añadir otro dominio espacial a una simulación existente?
<a name="working-with_configuring-simulation_domains_spatial_faq_q1"></a>
+ **Para una simulación en ejecución**: no se puede cambiar la configuración de una simulación en ejecución. Cambie la configuración del dominio en el esquema, cargue el esquema y los archivos comprimidos de la aplicación e inicie una nueva simulación.
+ **Para una nueva simulación**: añada la configuración del dominio en el esquema, cargue el esquema y los archivos comprimidos de la aplicación e inicie una nueva simulación.

## Solución de problemas de dominios espaciales
<a name="working-with_configuring-simulation_domains_spatial_troubleshooting"></a>

Cuando intenta iniciar la simulación, pero la configuración de dominio no es válida, puede aparecer el siguiente mensaje de error:

```
"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].\"}]"
```

**Causas posibles**
+ El esquema asigna más unidades de recursos de cómputo a las aplicaciones de las que están disponibles para los trabajadores.
+ SimSpace Weaver no se puede determinar un acuerdo para agrupar los dominios en los trabajadores. Esto ocurre cuando se especifican varios dominios espaciales, pero no hay un divisor común o un múltiplo entre las cuadrículas de dominios (por ejemplo, entre una cuadrícula de 2x4 y una cuadrícula de 3x5).

# Puntos de conexión de red
<a name="working-with_configuring-simulation_domains_endpoints"></a>

Las aplicaciones personalizadas y de servicio pueden tener puntos de conexión de red a los que se pueden conectar los clientes externos. Debe especificar una lista de números de puerto como valor `ingress_ports` en. `endpoint_config` Estos números de puerto son TCP y UDP. La aplicación personalizada o de servicio debe enlazarse a los números de puerto que especifiques`ingress_ports`. SimSpace Weaver asigna dinámicamente los números de puerto en tiempo de ejecución y asigna estos puertos a los puertos dinámicos. Puede llamar a la API **describe-app** una vez que sus aplicaciones hayan empezado a encontrar los números de puerto dinámicos (reales). Para obtener más información, consulte [Obtenga la dirección IP y el número de puerto de una aplicación personalizadaObtenga la dirección IP y el número de puerto](working-with_get-ip.md) en el tutorial de inicio 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 Los proyectos de la versión 1.12.x del SDK de la aplicación utilizan cubos separados para los archivos.zip de la aplicación y el esquema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -esquemas- *lowercase-project-name* *account-number* *region*

**nota**  
`endpoint_config` es una propiedad opcional para aplicaciones personalizadas y aplicaciones de servicio. Si no especifica ningún `endpoint_config`, la aplicación no tendrá un punto de conexión de red.

# Configuración de dominios de servicio
<a name="working-with_configuring-simulation_domains_service-domains"></a>

La presencia de `launch_apps_per_worker:` en una configuración de dominio indica que se trata de un dominio de servicio que tiene aplicaciones de servicio. SimSpace Weaver inicia y detiene las aplicaciones de servicio por usted. Cuando se SimSpace Weaver inicia y detiene una aplicación, se considera que la aplicación tiene un *ciclo de vida gestionado*. SimSpace Weaver actualmente permite iniciar 1 o 2 aplicaciones de servicio en todos y cada uno de los trabajadores. 

**Example Ejemplo de un dominio configurado para lanzar una aplicación de servicio en cada trabajador**  

```
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 Ejemplo de un dominio configurado para lanzar dos aplicaciones de servicio en cada trabajador**  

```
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
```

# Duración máxima de una simulación
<a name="working-with_max-duration"></a>

Cada simulación AWS SimSpace Weaver tiene una configuración de *duración máxima* que especifica el tiempo máximo que se puede ejecutar la simulación. La duración máxima se proporciona como parámetro al iniciar una simulación. La [interfaz de programación de aplicaciones (API)](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html) de `StartSimulation` tiene un parámetro opcional `MaximumDuration`. El valor del parámetro es un número de minutos (m o M), horas (h o H) o días (d o D). Por ejemplo, `1h` o `1H` significa 1 hora. SimSpace Weaver detiene la simulación cuando alcanza este límite.

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

El valor válido más alto para `MaximumDuration` es `14D`, o su equivalente en horas (`336H`) o minutos (`20160M`).

## Valor predeterminado
<a name="working-with_max-duration_default-value"></a>

El parámetro `MaximumDuration` es opcional. Si no proporciona un valor, SimSpace Weaver utiliza un valor de`14D`.

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

El valor válido más bajo para `MaximumDuration` es un valor que es numéricamente equivalente a `0`. Por ejemplo, los valores `0M`, `0H` y `0D`, son todos numéricamente equivalentes a `0`.

Si proporciona el valor mínimo para una duración máxima, la simulación pasa inmediatamente al `STOPPING` estado en cuanto lo alcanza. `STARTED`

## Iniciar una simulación mediante la consola
<a name="working-with_max-duration_console"></a>

Puede proporcionar un valor para la **duración máxima** al iniciar una simulación en la [consola de SimSpace Weaver](https://console.aws.amazon.com/simspaceweaver). Introduzca el valor en el campo **Duración máxima** del formulario de **configuración de simulación** cuando seleccione **Iniciar simulación**.

**importante**  
Si no proporciona un valor para **Duración máxima**, SimSpace Weaver utiliza el [valor por defecto](#working-with_max-duration_default-value) (`14D`).

## El estado de una simulación que alcanza su duración máxima
<a name="working-with_max-duration_sim-state"></a>

Cuando detiene SimSpace Weaver automáticamente una simulación que alcanza su duración máxima, el **estado** de la simulación es `STOPPING` (si está en curso) o`STOPPED`. En la [consola de SimSpace Weaver](https://console.aws.amazon.com/simspaceweaver), el **estado objetivo** de la simulación aún es `STARTED`, porque ese fue el último estado solicitado por un usuario.

# Desarrollo de aplicaciones
<a name="working-with_developing-apps"></a>

SimSpace Weaver el desarrollo requiere una Amazon Linux 2 (AL2) entorno para crear aplicaciones porque sus simulaciones se ejecutan en Amazon Linux en el AWS Cloud. Si estás usando Windows, puede usar los scripts del SDK de la SimSpace Weaver aplicación para crear e iniciar un Docker contenedor que se ejecuta AL2 con las dependencias que necesita para crear SimSpace Weaver aplicaciones. También puedes lanzar un AL2 entorno utilizando Windows Subsystem for Linux (WSL), o utilice un nativo AL2 sistema. Para obtener más información, consulte [Configure su entorno local para SimSpace Weaver](setting-up_local.md).

**nota**  
Independientemente de cómo configure su entorno de desarrollo local, sus aplicaciones se ejecutan en Docker contenedores cuando los carga para ejecutarlos en Nube de AWS. **Las aplicaciones no tienen acceso directo al sistema operativo de host**.

**Flujo general de una SimSpace Weaver aplicación**

1. Crear una aplicación.

1. Bucle:

   1. Comience la actualización creando un `Transaction`.

      1. Salga del ciclo si la simulación se está cerrando.

   1. Procese los eventos de la entidad de suscripción y propiedad.

   1. Actualice la simulación.

   1. Envíe `Transaction` para finalizar la actualización.

1. Destruya la aplicación.

## Aplicación espacial
<a name="working-with_developing-apps_spatial-apps"></a>

Cada aplicación espacial tiene un área de propiedad que es una región espacial del mundo de la simulación. Las entidades ubicadas en el área de propiedad de una aplicación espacial se almacenan en la partición asignada a la aplicación. La aplicación espacial única tiene la propiedad total (permisos de lectura y escritura) de todas las entidades de la partición asignada. Ninguna otra aplicación puede escribir en esas entidades. La aplicación espacial avanza en el estado de sus entidades. Cada aplicación espacial posee solo 1 partición. SimSpace Weaver usa la ubicación espacial de una entidad para indexarla y asignarla a una partición de aplicación espacial.

El SDK de la SimSpace Weaver aplicación proporciona una aplicación de ejemplo. Puede encontrar el código fuente de la aplicación espacial de la aplicación de ejemplo en la siguiente carpeta (utilice el separador de rutas correcto para su sistema operativo): 

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

## Aplicaciones personalizadas
<a name="working-with_developing-apps_custom-apps"></a>

Puede crear y utilizar aplicaciones personalizadas para interactuar con la simulación. 

**Las aplicaciones personalizadas pueden**
+ Crear entidades
+ Suscribirse a otras particiones
+ Confirmar cambios

**Flujo general de una aplicación personalizada**

1. Crear una aplicación.

1. Suscribirse a una región específica de la simulación:

   1. Crear una `Transaction` para comenzar la primera actualización.

   1. Crear una suscripción para la región específica.

   1. Enviar `Transaction` para finalizar la primera actualización.

1. Bucle:

   1. Cree una `Transaction` para comenzar la actualización.

      1. Salga del ciclo si la simulación se está cerrando.

   1. El estado del proceso cambia.

   1. Envíe `Transaction` para finalizar la actualización.

1. Destruya la aplicación.

Una vez que una aplicación personalizada crea una entidad, debe transferirla a un dominio espacial para que la entidad exista espacialmente dentro de la simulación. SimSpace Weaver usa la ubicación espacial de la entidad para colocarla en la partición de aplicación espacial adecuada. La aplicación personalizada que creó la entidad no puede actualizar ni eliminar la entidad después de transferirla a un dominio espacial. 

El SDK de la SimSpace Weaver aplicación proporciona una aplicación de muestra. Puede usar las aplicaciones personalizadas incluidas en la aplicación de ejemplo como modelos para sus propias aplicaciones personalizadas. Puede encontrar el código fuente de la aplicación de visualización (una aplicación personalizada) de la aplicación de ejemplo en la siguiente carpeta (utilice el separador de rutas correcto para su sistema operativo):

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

# Desarrollo de aplicaciones de cliente
<a name="working-with_developing-client-applications"></a>

Algunas de las razones por las que podría querer conectar un cliente a una simulación son las siguientes:
+ Introducir información sobre el tráfico en tiempo real en una simulación a escala de ciudad.
+ Cree *human-in-the-loop*simulaciones en las que un operador humano controle algún aspecto de la simulación.
+ Hacer posible que los usuarios interactúen con la simulación, por ejemplo, en una simulación de entrenamiento.

Las aplicaciones personalizadas de estos ejemplos actúan como interfaz entre el estado de la simulación y el mundo exterior. Los clientes se conectan a las aplicaciones personalizadas para interactuar con la simulación. 

SimSpace Weaver no gestiona las aplicaciones cliente ni su comunicación con tus aplicaciones personalizadas. Usted es responsable del diseño, la creación, el funcionamiento y la seguridad de las aplicaciones cliente y de su comunicación con las aplicaciones personalizadas. SimSpace Weaver solo muestra una dirección IP y un número de puerto para cada una de tus aplicaciones personalizadas para que los clientes puedan conectarse a ellas. 

El SDK de la SimSpace Weaver aplicación proporciona clientes para su aplicación de muestra. Puede utilizar estos clientes como modelos para sus propias aplicaciones cliente. Puede encontrar el código fuente de los clientes de muestra en la siguiente carpeta: 

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

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

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

**importante**  
Proporcionamos estas instrucciones para su comodidad. Son para su uso con Windows Subsystem for Linux (WSL), y no son compatibles. Para obtener más información, consulte [Configure su entorno local para SimSpace Weaver](setting-up_local.md).

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

------

Para obtener más información sobre la creación y el uso de los clientes de aplicaciones de muestra, consulte los tutoriales de[Empezar con SimSpace Weaver](getting-started.md). 

# Obtenga la dirección IP y el número de puerto de una aplicación personalizada
<a name="working-with_get-ip"></a>

Para ver la simulación, debe crear una aplicación personalizada y conectarse a ella con un cliente. Para obtener más información, consulte los tutoriales de[Empezar con SimSpace Weaver](getting-started.md). Puede usar el siguiente procedimiento para obtener la dirección IP y el número de puerto de su aplicación personalizada. Utilice el separador de rutas adecuado para su sistema operativo (por ejemplo, `\` en Windows y `/` Linux).

**Para obtener su dirección IP y número de puerto**

1. Utilice la ** ListSimulations**API para obtener el nombre de la simulación.

   ```
   aws simspaceweaver list-simulations
   ```

   Ejemplo de salida:

   ```
   {
       "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. Utilice la ** DescribeSimulation**API para obtener una lista de los dominios de la simulación.

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

   Busque la sección `Domains` en la sección `LiveSimulationState` del resultado.

   Ejemplo de salida:

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

1. Use la ** ListApps**API para obtener una lista de aplicaciones personalizadas en un dominio. Por ejemplo, el nombre de dominio de la aplicación de visualización (personalizada) del proyecto de ejemplo es`MyViewDomain`. Busque el nombre de la aplicación en el resultado.

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

   Ejemplo de salida:

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

1. Usa la ** DescribeApp**API para obtener la dirección IP y el número de puerto. Para el proyecto de ejemplo, el nombre de dominio es `MyViewDomain` y el nombre de la aplicación es `ViewApp`. 

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

   La dirección IP y el número de puerto están en el bloque `EndpointInfo` del resultado. La dirección IP es el valor de `Address` y el número de puerto es el valor de `Actual`.

   Ejemplo de salida:

   ```
   {
       "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**  
El valor de `Declared` es el número de puerto al que debe enlazarse el código de la aplicación. El valor de `Actual` es el número de puerto al que se SimSpace Weaver exponen los clientes para que se conecten a tu aplicación. SimSpace Weaver asigna el `Declared` puerto al `Actual` puerto.

# Lanzamiento del cliente de visualización de Unreal Engine
<a name="working-with_unreal-client"></a>

 Navegue hasta: 

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

1. Ejecute uno de los siguientes comandos:
   + Docker: `python quick-start.py`
   + WSL: `python quick-start.py --al2`

1. Obtenga la dirección IP y el número de puerto «real». Estarán en la salida de la consola al ejecutar quick-start.py, o puede obtenerlos siguiendo los procedimientos que se indican en[Obtenga la dirección IP y el número de puerto de una aplicación personalizadaObtenga la dirección IP y el número de puerto](working-with_get-ip.md).

1.  Navegue hasta: 

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

1.  Ejecute los siguientes comandos para crear la biblioteca NNG: 

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

1.  En un **editor de texto**, abra `view_app_url.txt`. 

1.  Actualice la URL con la dirección IP y el número de puerto de tu aplicación de visualización: `tcp://ip-address:actual-port-number` (debería tener el aspecto de `tcp://198.51.100.135:1234`). 

1.  **En el **editor Unreal**, selecciona reproducir.** 

## Solución de problemas
<a name="working-with_unreal-client_troubleshooting"></a>
+  **El paso de CMake instalación de NNG falla y dice «Quizás necesite privilegios 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)
  ```
  +  **Solución:** `nng.lib` si `nng.so` existe en el directorio UnrealClient /lib, este error se puede ignorar de forma segura. Si no es así, intente ejecutar los comandos cmake build en una terminal con privilegios de administrador. 
+  **«CMake para encontrar un archivo de configuración de paquete proporcionado por 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.
  ```
  +  **Solución:** CMake tiene problemas para encontrar el `Findnng.cmake` archivo. Al construir con CMake, añada el argumento`-DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty`. Asegúrese de que el `Findnng.cmake` archivo sigue en el `ThirdParty` directorio antes de volver a ejecutar la CMake compilación. 

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

# Desarrollo local en SimSpace Weaver
<a name="working-with_local-development"></a>

Puede implementar sus SimSpace Weaver aplicaciones localmente para realizar pruebas y depuraciones rápidas.

**Requisitos**
+ Realice los pasos que se indican en [Configuración para SimSpace Weaver](setting-up.md).

**Topics**
+ [Paso 1: Lance su simulación local](working-with_local_launch.md)
+ [Paso 2: Vea su simulación local](working-with_local-development_view.md)
+ [Paso 3: Detenga la simulación local (opcional en Windows)](working-with_local-development_stop-sim.md)
+ [Solución de problemas de desarrollo local en SimSpace Weaver](working-with_local-development_troubleshooting.md)

# Paso 1: Lance su simulación local
<a name="working-with_local_launch"></a>

1. Navegue hasta

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

1. Ejecute el siguiente comando para crear e iniciar la simulación de forma local.

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

   Este script hará lo siguiente:

   1. Compilar el proyecto.
      +  `quick-start.py`llama a la `build_project` función definida en build.py. Este paso variará en función del proyecto. Para el PathfindingSample, CMake se usa. El comando CMake and Docker que se encuentra en build.py. 

   1. Lance su simulación local
      + El script lanzará un proceso local para cada partición espacial definida en el esquema.
      + El script lanzará un proceso para cada aplicación personalizada definida en el esquema.
      + Primero se lanzarán las aplicaciones espaciales, seguidas de las aplicaciones personalizadas, cada una en el orden en que aparecen en el esquema.

**importante**  
Cuando se inicie en un entorno que no sea compatible con la GUI, como una sesión SSH de consola, utilice la `--noappwindow` opción para redirigir todos los resultados al terminal actual.

**importante**  
Para los usuarios de Linux, el script asume que el sistema tiene el `xterm` comando. Si su distribución de Linux no tiene el `xterm` comando, utilice la `--noappwindow` opción para redirigir todos los resultados a la terminal actual.
+  -h, --help 
  +  Enumere estos parámetros. 
+  --limpiar 
  +  Elimine el contenido del directorio de compilación antes de compilar. 
+  --nobuild 
  +  Omita la reconstrucción del proyecto. 
+  --ninguna ventana de aplicación 
  +  No abras una ventana nueva para cada aplicación. En su lugar, redirige la salida estándar a la terminal actual. 
+  --archivo de registro 
  +  Escribe el resultado de la consola en un archivo de registros. 
+  --consoleclient 
  +  Conecta automáticamente el cliente de consola que aparece en la configuración. 
+  --esquema de esquema
  + Qué esquema utilizará esta invocación. El valor predeterminado es 'SCHEMA' en config.py. 

# Paso 2: Vea su simulación local
<a name="working-with_local-development_view"></a>

Para ver su simulación local, puede utilizar cualquiera de los clientes que se incluyen en el SimSpaceWeaverAppSdkDistributable. Para obtener más información sobre la creación y el uso de los clientes de muestra, consulte los tutoriales en[Empezar con SimSpace Weaver](getting-started.md).

Debe actualizar la dirección IP y el número de puerto del cliente para conectarse a la aplicación de visualización para su simulación local. Utilice siempre los siguientes valores con SimSpace Weaver Local:

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

Según el cliente que seleccione, puede actualizar la dirección IP y el número de puerto de la siguiente manera:
+ **Unreal**: cambie la URL en la línea 1 de `view_app_url.txt`
+ **Consola**: inicie el cliente con la dirección IP y la URL del número de puerto como parámetro

# Paso 3: Detenga la simulación local (opcional en Windows)
<a name="working-with_local-development_stop-sim"></a>

**nota**  
Este paso es obligatorio en Linux, pero opcional en Windows.

1.  Navegue hasta: 

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

1.  Ejecute el siguiente comando para detener la simulación local y eliminar cualquier recurso de memoria compartida. 

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

    Este script hará lo siguiente: 
   +  Detenga los procesos locales. 
   +  Elimine el objeto de memoria compartida (solo es necesario en Linux). 

**stop-and-deleteParámetros.py**
+  -h, --help 
  +  Enumere estos parámetros. 
+  --parar 
  +  Intente detener los procesos únicamente. 
+  --eliminar 
  +  Intente eliminar únicamente los recursos de memoria compartidos. 
+  --proceso 
  +  El nombre del proceso que se va a detener. Úselo si el nombre de su proceso no coincide con el nombre del paquete en el esquema. 
+  --esquema de esquema 
  +  Qué esquema utilizará esta invocación. El valor predeterminado es 'SCHEMA' en config.py. 

# Solución de problemas de desarrollo local en SimSpace Weaver
<a name="working-with_local-development_troubleshooting"></a>
+  **Linux: no se encuentra el comando xterm o no se puede abrir** 
  + Los scripts locales asumen que el comando xterm existe cuando se ejecuta en Linux. Si no dispone del comando xterm o lo ejecuta en un entorno que no admite la interfaz gráfica de usuario, utilice la `--noappwindow` opción cuando ejecute el script de inicio rápido.
+  **¡No se abre ninguna ventana de aplicaciones\$1** 
  +  Esto sucede cuando la simulación local se bloquea inmediatamente. Para ver el resultado de la consola tras el bloqueo, utilice las `--logfile` opciones `--noappwindow` o al ejecutar el script de inicio rápido. 
+  **¡La simulación no funciona una vez que se inicia la aplicación de visualización o se conecta el cliente de visualización\$1** 
  +  Ejecutar `—noappwindow` esta opción normalmente resuelve este tipo de problemas. De lo contrario, reiniciar varias veces también tiene éxito (aunque a un ritmo mucho menor). 

# SDK de la aplicación AWS SimSpace Weaver
<a name="working-with_app-sdk"></a>

El SDK de la SimSpace Weaver aplicación permite APIs controlar las entidades de la simulación y responder a SimSpace Weaver los eventos. Incluye el espacio de nombres siguiente: 
+ **API**: definiciones básicas de la API y su uso

Enlace con la siguiente biblioteca:
+ `libweaver_app_sdk_cxx_v1_full.so`

**importante**  
La biblioteca está disponible para la vinculación dinámica cuando ejecuta sus aplicaciones en Nube de AWS. No es necesario cargarlo con las aplicaciones.

**nota**  
El SDK de la SimSpace Weaver aplicación APIs controla los datos de la simulación. APIsSon independientes del SimSpace Weaver servicio APIs, que controla los recursos del SimSpace Weaver servicio (como las simulaciones, las aplicaciones y los relojes). AWS Para obtener más información, consulte [SimSpace Weaver Referencias de API](api-reference.md).

**Topics**
+ [Los métodos de la API devuelven un Result](working-with_app-sdk_return-result.md)
+ [Interactuar con el SDK de aplicación de nivel superior](working-with_app-sdk_top-level.md)
+ [Gestión de la simulación](working-with_app-sdk_sim.md)
+ [Suscripciones](working-with_app-sdk_sub.md)
+ [Entidades](working-with_app-sdk_ent.md)
+ [Eventos de entidad](working-with_app-sdk_events.md)
+ [Result y manejo de errores](working-with_app-sdk_result.md)
+ [Genéricos y tipos de dominio](working-with_app-sdk_generics.md)
+ [Operaciones diversas del SDK de la aplicación](working-with_app-sdk_misc.md)

# Los métodos de la API devuelven un Result
<a name="working-with_app-sdk_return-result"></a>

La mayoría de las funciones de la SimSpace Weaver API tienen un tipo de retorno`Aws::WeaverRuntime::Result<T>`. Si la función se ha ejecutado correctamente, `Result` contiene`T`. De lo contrario, `Result` contiene un código `Aws::WeaverRuntime::ErrorCode` que representa un código de error del Rust App SDK.

**Example Ejemplo**  

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

Este método:
+ Devuelve `Transaction` si se `BeginUpdate()` ejecuta correctamente.
+ Regresa `Aws::WeaverRuntime::ErrorCode` si `BeginUpdate()` falla.

# Interactuar con el SDK de aplicación de nivel superior
<a name="working-with_app-sdk_top-level"></a>

**Ciclo de vida**
+ El SDK de la SimSpace Weaver aplicación administra el ciclo de vida de la aplicación. No es necesario leer ni escribir el estado del ciclo de vida de una aplicación.

**Particiones**
+ Use `Result <PartitionSet> AssignedPartitions(Transaction& txn);` para obtener particiones propias.
+ Use `Result <PartitionSet> AllPartitions(Transaction& txn);` para obtener todas las particiones de la simulación.

# Gestión de la simulación
<a name="working-with_app-sdk_sim"></a>

En esta sección se describen las soluciones para las tareas comunes de administración de simulaciones.

**Topics**
+ [Iniciar una simulación](working-with_app-sdk_sim_start.md)
+ [Actualizar una simulación](working-with_app-sdk_sim_update.md)
+ [Finalizar una simulación](working-with_app-sdk_sim_terminate.md)

# Iniciar una simulación
<a name="working-with_app-sdk_sim_start"></a>

Use `CreateApplication()` para crear una aplicación.

**Example Ejemplo**  

```
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()));
```

# Actualizar una simulación
<a name="working-with_app-sdk_sim_update"></a>

Utilice las siguientes funciones de `BeginUpdate` para actualizar la aplicación:
+ `Result<Transaction> BeginUpdate(Application& app)`
+ `Result<bool> BeginUpdateWillBlock(Application& app)`: le indica si `BeginUpdate()` bloqueará o no bloqueará.

Use `Result<void> Commit(Transaction& txn)` para confirmar los cambios.

**Example Ejemplo**  

```
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();
}
```

# Finalizar una simulación
<a name="working-with_app-sdk_sim_terminate"></a>

Use `Result<void> DestroyApplication(Application&& app)` para finalizar la aplicación y la simulación.

Otras aplicaciones descubren que la simulación se cierra cuando reciben llamadas `ErrorCode::ShuttingDown` a `BeginUpdateWillBlock()` o `BeginUpdate()`. Cuando una aplicación recibe `ErrorCode::ShuttingDown`, puede llamar a `Result<void> DestroyApplication(Application&& app)` para que se cierre automáticamente.

**Example Ejemplo**  

```
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**  
Solo llama a `Result<void> DestroyApplication(Application&& app)` después de `Api::Commit()`. Destruir una aplicación durante una actualización puede provocar un comportamiento indefinido.

**importante**  
Debe llamar a `DestroyApplication()` antes de que se cierre el programa para asegurarse de que la aplicación informa que se ha cerrado correctamente.  
Si no llama a `DestroyApplication()` cuando el programa se cierra, el estado se considerará como `FATAL`.

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

Crea una suscripción con un área de suscripción y un ID de dominio. El ID de dominio representa el dominio propietario de esa área de suscripción. Un `BoundingBox2F32` describe el área de suscripción. Para crear una suscripción, utilice la siguiente función:

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

**Example Ejemplo**  

```
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();
}
```

Puede utilizar los datos de `Api::SubscriptionHandle` devueltos por `CreateSubscriptionBoundingBox2F32()` para modificar la suscripción. Se pasa como argumento a las siguientes funciones:

```
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>

Cuando una entidad entra `Load` APIs en el área `Api:Entity` de suscripción de la `Result<Api::Entity>` aplicación`CreateEntity()`, se llama al evento de cambio de propietario o viceversa (para obtener más información, consulte[Eventos de entidad](working-with_app-sdk_events.md)). `Store` Te recomendamos que rastrees tus `Api::Entity` objetos para poder usarlos con ellos APIs.

**Topics**
+ [Crear entidades](working-with_app-sdk_ent_create.md)
+ [Transferir una entidad a un dominio espacial](working-with_app-sdk_ent_transfer.md)
+ [Escribir y leer los datos del campo de la entidad](working-with_app-sdk_ent_readwrite.md)
+ [Almacenar la posición de una entidad](working-with_app-sdk_ent_store-position.md)
+ [Cargar la posición de una entidad](working-with_app-sdk_ent_load-position.md)

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

Use `CreateEntity()` para crear una entidad. Usted define el significado de `Api::TypeId` que pasa a esta función.

```
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**  
Los valores del 0 al 511 para `Api::BuiltinTypeId` están reservados. Tu entidad TypeID (`k_entityTypeId`en este ejemplo) debe tener un valor de 512 o superior.

# Transferir una entidad a un dominio espacial
<a name="working-with_app-sdk_ent_transfer"></a>

Después de que una aplicación o aplicación de servicio personalizada cree una entidad, la aplicación debe transferirla a un dominio espacial para que la entidad exista espacialmente en la simulación. Otras aplicaciones pueden leer las entidades de un dominio espacial y actualizarlas una aplicación espacial. Utilice la API `ModifyEntityDomain()` para transferir una entidad a un dominio espacial.

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

Si el valor de `DomainId` no coincide con el asignado a `Partition` de la aplicación que realiza la llamada, `DomainId` debe ser para un `DomainType::Spatial` `Domain`. La transferencia de propiedad a la nueva `Domain` se produce durante el `Commit(Transaction&&)`.Parámetros

`txn`  
La actual `Transaction`.

`entity`  
El `Entity` objetivo para el cambio de `Domain`.

`domainId`  
El `DomainId` de la `Domain` de destino para la `Entity`.

Esta API devuelve `Success` si el dominio de la entidad se ha modificado correctamente.

# Escribir y leer los datos del campo de la entidad
<a name="working-with_app-sdk_ent_readwrite"></a>

Todos los campos de datos de entidades son de tipo blob. Puede escribir hasta 1024 bytes de datos en una entidad. Le recomendamos que mantenga los blobs lo más pequeños posible, ya que los tamaños más grandes reducirán el rendimiento. Al escribir en un blob, se pasa SimSpace Weaver un puntero a los datos y a su longitud. Cuando lee un blob, SimSpace Weaver le proporciona un puntero y una longitud para leer. Todas las lecturas deben estar completas antes de que la aplicación llame a `Commit()`. Los punteros devueltos por una llamada de lectura se invalidan cuando la aplicación llama a `Commit()`.

**importante**  
No se admite la lectura de un puntero blob almacenado en caché después de `Commit()` y puede provocar un error en la simulación.
No se admite la escritura en un puntero de blob devuelto por una llamada de lectura y puede provocar un error en la simulación.

**Topics**
+ [Almacenar los datos de campo de una entidad](working-with_app-sdk_ent_readwrite_store.md)
+ [Cargar los datos de campo de una entidad](working-with_app-sdk_ent_readwrite_load.md)
+ [Cargar los datos de campo de las entidades eliminadas](working-with_app-sdk_ent_readwrite_load-removed.md)

# Almacenar los datos de campo de una entidad
<a name="working-with_app-sdk_ent_readwrite_store"></a>

Los siguientes ejemplos muestran cómo se pueden almacenar (escribir en la estructura de estados) los datos de campo de una entidad propiedad de la aplicación. Estos ejemplos usan la siguiente función:

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

El parámetro `Api::TypeId keyTypeId` representa el tipo de datos de los datos transferidos.

El parámetro `Api::TypeId keyTypeId` debe recibir la información correspondiente `Api::TypeId` de `Api::BuiltinTypeId`. Si no hay una conversión adecuada, puede usar `Api::BuiltinTypeId::Dynamic`.

Para tipos de datos complejos, utilice `Api::BuiltInTypeId::Dynamic`.

**nota**  
El valor de `FieldIndex index` debe ser mayor que cero. El valor 0 está reservado para la clave de índice (consulte `StoreEntityIndexKey()`).

**Example Ejemplo de uso de tipos de datos 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 Ejemplo de uso de un struct para guardar los datos**  

```
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));
}
```

# Cargar los datos de campo de una entidad
<a name="working-with_app-sdk_ent_readwrite_load"></a>

Los siguientes ejemplos muestran cómo se pueden cargar (leer desde la estructura de estados) los datos de campo de una entidad. Estos ejemplos usan la siguiente función:

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

El parámetro `Api::TypeId keyTypeId` debe recibir la información correspondiente `Api::TypeId` de `Api::BuiltinTypeId`. Si no hay una conversión adecuada, puede usar `Api::BuiltinTypeId::Dynamic`.

**nota**  
El valor del índice `FieldIndex` debe ser mayor que 0. El valor 0 está reservado para la clave de índice (consulte `StoreEntityIndexKey()`).

**Example Ejemplo de uso de tipos de datos 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 Ejemplo de uso de un struct para guardar los datos**  

```
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);
}
```

# Cargar los datos de campo de las entidades eliminadas
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

No puede cargar (leer de la estructura estatal) los datos de campo de las entidades que se han eliminado de las áreas de propiedad y suscripción de la aplicación. En el siguiente ejemplo, se produce un error porque `Api::LoadIndexKey()` llama a una entidad como resultado de un `Api::ChangeListAction::Remove`. El segundo ejemplo muestra una forma correcta de almacenar y cargar los datos de la entidad directamente en la aplicación.

**Example Ejemplo de código incorrecto**  

```
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 Ejemplo de una forma correcta de almacenar y cargar datos de entidades en la aplicación**  

```
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;
            }
        }
    }
    
    /* ... */
}
```

# Almacenar la posición de una entidad
<a name="working-with_app-sdk_ent_store-position"></a>

Puede almacenar (escribir en la estructura de estados) la posición de una entidad mediante una estructura de datos de enteros. Estos ejemplos usan la siguiente función:

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

**nota**  
Debe proporcionar `Api::BuiltinTypeId::Vector3F32` a `Api::StoreEntityIndexKey()`, como se muestra en los siguientes ejemplos.

**Example Ejemplo: uso de una matriz para representar la posición**  

```
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 Ejemplo de uso de un struct para representar la posición**  

```
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));
}
```

# Cargar la posición de una entidad
<a name="working-with_app-sdk_ent_load-position"></a>

Puede cargar (leer en la estructura de estados) la posición de una entidad mediante una estructura de datos de enteros. Estos ejemplos usan la siguiente función:

**nota**  
Debe proporcionar `Api::BuiltinTypeId::Vector3F32` a `Api::LoadEntityIndexKey()`, como se muestra en los siguientes ejemplos.

**Example Ejemplo: uso de una matriz para representar la posición**  

```
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 Ejemplo de uso de un struct para representar la posición**  

```
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 de entidad
<a name="working-with_app-sdk_events"></a>

Puede utilizar las siguientes funciones del SDK de la SimSpace Weaver aplicación para obtener todos los eventos de propiedad y suscripción:
+ `Result<OwnershipChangeList> OwnershipChanges(Transaction& txn) `
+ `Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn) `

Puede utilizar el marco de SimSpace Weaver demostración si necesita un procesamiento de eventos de entidades basado en llamadas. Para obtener más información, consulte el siguiente archivo de encabezado:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/DemoFramework/EntityEventProcessor.h`

También puede crear su propio procesamiento de eventos de entidad.

**Topics**
+ [Repasar los eventos de las entidades de su propiedad](working-with_app-sdk_events_own.md)
+ [Repasar los eventos de las entidades suscritas](working-with_app-sdk_events_sub.md)
+ [Repasar los eventos de las entidades de su propiedad](working-with_app-sdk_events_change.md)

# Repasar los eventos de las entidades de su propiedad
<a name="working-with_app-sdk_events_own"></a>

Use `OwnershipChanges()` para obtener una lista de eventos para las entidades en propiedad (entidades del área de propiedad de la aplicación). La función tiene la siguiente firma:

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

A continuación, recorra en iteraciones las entidades con un bucle, como se muestra en el siguiente ejemplo.

**Example Ejemplo**  

```
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`: la entidad está en el área y sus datos de posición y campo no han sufrido modificación.
+ `Remove`: la entidad se ha retirado del área.
+ `Add`: la entidad se ha agregado al área.
+ `Update`: la entidad se encuentra en el área y se ha modificado.
+ `Reject`: la aplicación no ha podido eliminar la entidad del área.

**nota**  
En el caso de un evento de `Reject`, la aplicación volverá a intentar la transferencia al marcar la casilla siguiente.

# Repasar los eventos de las entidades suscritas
<a name="working-with_app-sdk_events_sub"></a>

Use `AllSubscriptionEvents()` para obtener una lista de eventos para las entidades suscritas (entidades del área de suscripción de la aplicación). La función tiene la siguiente firma:

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

A continuación, recorra en iteraciones las entidades con un bucle, como se muestra en el siguiente ejemplo.

**Example Ejemplo**  

```
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`: la entidad está en el área y sus datos de posición y campo no han sufrido modificación.
+ `Remove`: la entidad se ha retirado del área.
+ `Add`: la entidad se ha agregado al área.
+ `Update`: la entidad se encuentra en el área y se ha modificado.
+ `Reject`: la aplicación no ha podido eliminar la entidad del área.

**nota**  
En el caso de un evento de `Reject`, la aplicación volverá a intentar la transferencia al marcar la casilla siguiente.

# Repasar los eventos de las entidades de su propiedad
<a name="working-with_app-sdk_events_change"></a>

Para ver los eventos en los que una entidad se mueve entre un área de propiedad y un área de suscripción, compare los cambios entre los eventos de suscripción y propiedad de la entidad actuales y anteriores.

Puede gestionar estos eventos leyendo:
+ `Api::SubscriptionChangeList`
+ `Api::OwnershipEvents`

A continuación, puede comparar los cambios con los datos almacenados anteriormente.

En el siguiente ejemplo, se muestra cómo se pueden gestionar los eventos de cambio de propiedad de una entidad. En este ejemplo se supone que, en el caso de las entidades que pasan de ser entidades suscritas a entidades de propiedad (en cualquier dirección), el remove/add event occurs first followed by the subscription remove/add evento de propiedad aparece en la casilla siguiente. 

**Example Ejemplo**  

```
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 y manejo de errores
<a name="working-with_app-sdk_result"></a>

La clase de `Aws::WeaverRuntime::Result<T>` usa una biblioteca `Outcome` de terceros. Puede usar el siguiente patrón para comprobar `Result` y atrapar los errores devueltos por las llamadas a la 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 instrucciones de control
<a name="working-with_app-sdk_result_macro"></a>

Dentro de una función con un tipo de retorno `Aws::WeaverRuntime::Result<T>`, puede utilizar la macro `WEAVERRUNTIME_TRY` en lugar del patrón de código anterior. La macro ejecutará la función que se le haya transferido. Si la función pasada falla, la macro hará que la función adjunta devuelva un error. Si la función pasada se ejecuta correctamente, la ejecución pasa a la siguiente línea. El siguiente ejemplo muestra una reescritura de la función de `DoBeginUpdate()` anterior. Esta versión utiliza la `WEAVERRUNTIME_TRY` macro en lugar de if-else estructura de control. Tenga en cuenta que el tipo de retorno de la función es `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();
}
```

Si `BeginUpdate()` falla, la macro `DoBeginUpdate()` vuelve antes de tiempo y se produce un error. Puede utilizar la macro `WEAVERRUNTIME_EXPECT_ERROR` para obtener el `Aws::WeaverRuntime::ErrorCode` de `BeginUpdate()`. En el siguiente ejemplo, se muestra cómo la función `Update()` llama a `DoBeginUpdate()` y obtiene el código de error en caso de error.

```
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);

    }
}
```

Puede hacer que el código de error `BeginUpdate()` esté disponible para una función que llama a `Update()` cambiando el tipo de retorno `Update()` a `Aws::WeaverRuntime::Result<void>`. Puede repetir este proceso para seguir enviando el código de error más abajo en la pila de llamadas.

# Genéricos y tipos de dominio
<a name="working-with_app-sdk_generics"></a>

El SDK de la SimSpace Weaver aplicación proporciona los tipos de datos de precisión simple `Api::Vector2F32` y`Api::BoundingBox2F32`, y la precisión doble `Api::Vector2F64` y. `Api::BoundingBox2F64` Estos tipos de datos son estructuras de datos pasivas sin métodos prácticos. Tenga en cuenta que la API solo usa `Api::Vector2F32` y `Api::BoundingBox2F32`. Puede usar estos tipos de datos para crear y modificar suscripciones.

El marco de SimSpace Weaver demostración proporciona una versión mínima del AzCore biblioteca matemática, que contiene `Vector3` y`Aabb`. Para obtener más información, consulte los archivos de encabezado en:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/AzCore/Math`

# Operaciones diversas del SDK de la aplicación
<a name="working-with_app-sdk_misc"></a>

**Topics**
+ [AllSubscriptionEvents y OwnershipChanges contienen eventos de la última llamada](working-with_app-sdk_misc_events-from-last-call.md)
+ [Libera los bloqueos de lectura después del procesamiento SubscriptionChangeList](working-with_app-sdk_misc_release-locks.md)
+ [Creación de una instancia de aplicación independiente para realizar pruebas](working-with_app-sdk_misc_testing-app.md)

# AllSubscriptionEvents y OwnershipChanges contienen eventos de la última llamada
<a name="working-with_app-sdk_misc_events-from-last-call"></a>

Los valores devuelven las llamadas a la última llamada `Api::AllSubscriptionEvents()` y `Api::OwnershipChanges()` contienen los eventos de la última llamada, **no los de la última graduación**. En el ejemplo siguiente, `secondSubscriptionEvents` y `secondOwnershipChangeList` están vacíos porque sus funciones se invocan inmediatamente después de las primeras llamadas.

Si espera 10 pasos y, a continuación, llama a `Api::AllSubscriptionEvents()` y`Api::OwnershipChanges()`, sus resultados contendrán tanto los eventos como los cambios de los últimos 10 dígitos (no del último).

**Example Ejemplo**  

```
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**  
La función `AllSubscriptionEvents()` está implementada pero la función `SubscriptionEvents()` **no está implementada**.

# Libera los bloqueos de lectura después del procesamiento SubscriptionChangeList
<a name="working-with_app-sdk_misc_release-locks"></a>

Al iniciar una actualización, hay segmentos de memoria compartida para los datos confirmados en otras particiones correspondientes a la marca anterior. Es posible que los lectores bloqueen estos segmentos de memoria compartida. Una aplicación no puede confirmarse por completo hasta que todos los lectores hayan liberado los bloqueos. Como optimización, una aplicación debería llamar a `Api::ReleaseReadLeases()` para liberar los bloqueos después de procesar los elementos de `Api::SubscriptionChangelist`. Esto reduce la contención en el momento de la confirmación. `Api::Commit()` publica las concesiones de lectura de forma predeterminada, pero se recomienda publicarlas manualmente después de procesar las actualizaciones de las suscripciones.

**Example Ejemplo**  

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

# Creación de una instancia de aplicación independiente para realizar pruebas
<a name="working-with_app-sdk_misc_testing-app"></a>

Puede utilizar `Api::CreateStandaloneApplication()` para crear una aplicación independiente para probar la lógica de la aplicación antes de ejecutar el código en una simulación real.

**Example Ejemplo**  

```
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 marco de demostración
<a name="working-with_demo-framework"></a>

El AWS SimSpace Weaver marco de demostración (marco de demostración) es una biblioteca de utilidades que puede utilizar para desarrollar SimSpace Weaver aplicaciones.

**El marco de demostración proporciona**
+ Ejemplos de código y patrones de programación para que los utilice y examine
+ Abstracciones y funciones de utilidad que agilizan el desarrollo de aplicaciones sencillas
+ Una forma más sencilla de probar las funciones experimentales del SDK de la SimSpace Weaver aplicación

Diseñamos el SDK de la SimSpace Weaver aplicación con un acceso de bajo nivel para ofrecer un mayor rendimiento. SimSpace Weaver APIs Por el contrario, diseñamos el marco de demostración para proporcionar abstracciones de alto nivel y SimSpace Weaver facilitar el acceso a APIs ellas. El coste que supone la facilidad de uso es un nivel de rendimiento inferior en comparación con el uso directo del SDK de la SimSpace Weaver aplicación. Las simulaciones que toleran un rendimiento inferior (como las que no requieren requisitos de rendimiento en tiempo real) pueden ser buenas candidatas para utilizar el marco de demostración. Le recomendamos que utilice la funcionalidad nativa del SDK de la aplicación SimSpace Weaver para aplicaciones complejas, ya que el marco de demostración no es un conjunto de herramientas completo.

**El marco de demostración incluye**
+ Ejemplos de código funcional que respaldan y demuestran lo siguiente:
  + Gestión del flujo de aplicaciones
  + Procesamiento de eventos de entidades basado en llamadas
+ Un conjunto de bibliotecas de utilidades de terceros:
  + spdlog (una biblioteca de registro)
  + Una versión mínima de AZCore (una biblioteca de matemáticas) que contiene únicamente:
    + Vector3
    + Aabb
  + cxxopts (una biblioteca de analizadores de opciones de línea de comandos)
+ Funciones de utilidad específicas de SimSpace Weaver

El marco de demostración consta de una biblioteca, archivos fuente y CMakeLists. Los archivos se incluyen en el paquete distribuible del SDK de la SimSpace Weaver aplicación.

# Trabajar con Service Quotas
<a name="working-with_quotas"></a>

En esta sección se describe cómo trabajar con las cuotas de servicio para SimSpace Weaver. **Las cuotas** también se denominan **límites**. Para obtener una lista de Service Quotas, consulte [SimSpace Puntos finales y cuotas de Weaver](service-quotas.md). Las APIs de esta sección son del conjunto de **aplicaciones APIs**. La aplicación APIs es diferente al servicio APIs. La aplicación APIs forma parte del SDK de la SimSpace Weaver aplicación. Puedes encontrar la documentación de la aplicación APIs en la carpeta SDK de la aplicación de tu sistema local:

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

**Topics**
+ [Obtener los límites de una aplicación](#working-with_quotas_get-app-limits)
+ [Obtener la cantidad de recursos que utiliza una aplicación](#working-with_quotas_get-app-resources)
+ [Restablecimiento de métricas](#working-with_quotas_reset-metrics)
+ [Superar un límite](#working-with_quotas_exceed-limit)
+ [Agotamiento de la memoria](#working-with_quotas_out-of-memory)
+ [Prácticas recomendadas](#working-with_quotas_best-practices)

## Obtener los límites de una aplicación
<a name="working-with_quotas_get-app-limits"></a>

Puede usar la API de la aplicación **RuntimeLimits** para consultar los límites de una aplicación.

```
Result<Limit> RuntimeLimit(Application& app, LimitType type)
```Parameters

**Application y aplicación**  
Una referencia a la aplicación

**Tipo de LimitType**  
Una enumeración con los siguientes tipos de límites:  

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

En el siguiente ejemplo, se consulta el límite de recuento de entidades.

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

## Obtener la cantidad de recursos que utiliza una aplicación
<a name="working-with_quotas_get-app-resources"></a>

Puede llamar a la API de la aplicación **RuntimeMetrics** para obtener la cantidad de recursos que utiliza una aplicación:

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

**Application y aplicación**  
Una referencia a la aplicación

La API devuelve una referencia a una struct que contiene las métricas. Una contramétrica contiene un valor total acumulado y solo aumenta. Una métrica de indicador contiene un valor que puede aumentar o disminuir. El tiempo de ejecución de la aplicación actualiza un contador cada vez que un evento aumenta el valor. El motor de ejecución solo actualiza los indicadores al llamar a la API. SimSpace Weaver garantiza que la referencia sea válida durante toda la vida útil de la aplicación. Las llamadas repetidas a la API no cambiarán la referencia.

```
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
}
```

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

La API de la aplicación **ResetRuntimeMetrics** restablece los valores de `AppRuntimeMetrics` struct.

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

En el siguiente ejemplo se muestra cómo hacer llamadas **ResetRuntimeMetrics** en la aplicación.

```
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));
}
```

## Superar un límite
<a name="working-with_quotas_exceed-limit"></a>

Una llamada a la API de una aplicación que supere un límite devolverá un `ErrorCode::CapacityExceeded`, excepto en el caso de las transferencias de entidades. SimSpace Weaver gestiona las transferencias de entidades de forma asíncrona como parte de las operaciones de **envío** y de la API de la aplicación **BeginUpdate**, por lo que no hay ninguna operación específica que devuelva un error si una transferencia falla debido al límite de transferencia de la entidad. Para detectar errores de transferencia, puedes comparar los valores actuales de `rejected_incoming_transfer_counter` y `rejected_outgoing_transfer_counter` (en `AppRuntimeMetrics` struct) con sus valores anteriores. Las entidades rechazadas no estarán en la partición, pero la aplicación podrá simularlas.

## Agotamiento de la memoria
<a name="working-with_quotas_out-of-memory"></a>

SimSpace Weaver utiliza un proceso de recolección de basura para limpiar y liberar la memoria liberada. Es posible escribir datos más rápido de lo que el recolector de basura puede liberar memoria. Si esto ocurre, las operaciones de escritura podrían superar el límite de memoria reservada de la aplicación. SimSpace Weaver devolverá un error interno con un mensaje que contiene `OutOfMemory` (y detalles adicionales). Para obtener más información, consulte [Distribuya las escrituras en el tiempo](#working-with_quotas_best-practices_spread-writes).

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

Las siguientes prácticas recomendadas son directrices generales para diseñar las aplicaciones de forma que no excedan los límites. Es posible que no se apliquen al diseño específico de su aplicación.

### Supervise con frecuencia y reduzca la velocidad
<a name="working-with_quotas_best-practices_monitor"></a>

Debe supervisar sus métricas con frecuencia y ralentizar las operaciones que estén cerca de alcanzar un límite.

### Evite sobrepasar los límites de suscripción y transferencia
<a name="working-with_quotas_best-practices_subscription-and-xfer"></a>

Si es posible, diseñe la simulación para reducir la cantidad de suscripciones remotas y transferencias de entidades. Puede usar grupos de ubicación para colocar varias particiones en el mismo trabajador y reducir la necesidad de transferencias de entidades remotas entre trabajadores. 

### Distribuya las escrituras en el tiempo
<a name="working-with_quotas_best-practices_spread-writes"></a>

La cantidad y el tamaño de las actualizaciones de una graduación pueden tener un impacto significativo en el tiempo y la memoria necesarios para confirmar una transacción. Los requisitos de memoria elevados pueden provocar que el tiempo de ejecución de la aplicación se quede sin memoria. Puedes repartir las escrituras a lo largo del tiempo para reducir el tamaño total medio de las actualizaciones por tilde. Esto puede ayudar a mejorar el rendimiento y evitar sobrepasar los límites. Le recomendamos que no escriba más de una media de 12 MB por graduación o 1,5 KB por entidad. 

# Depuración de simulaciones
<a name="working-with_debugging"></a>

Puede utilizar los siguientes métodos de para obtener información sobre sus simulaciones.

**Temas**
+ [Uso SimSpace Weaver Local y mira la salida de la consola](#working-with_debugging_use-local)
+ [Mira tus registros en Amazon CloudWatch Logs](#working-with_debugging_logs)
+ [Uso **describe** Llamadas a la API](#working-with_debugging_api)
+ [Conectar un cliente](#working-with_debugging_client)

## Uso SimSpace Weaver Local y mira la salida de la consola
<a name="working-with_debugging_use-local"></a>

Le recomendamos que desarrolle primero las simulaciones de forma local y, a continuación, las ejecute en el Nube de AWS. Puedes ver la salida de la consola directamente cuando ejecutas con SimSpace Weaver Local. Para obtener más información, consulte[Desarrollo local en SimSpace Weaver](working-with_local-development.md).

## Mira tus registros en Amazon CloudWatch Logs
<a name="working-with_debugging_logs"></a>

Cuando ejecutas la simulación en la consola, Nube de AWS la salida de tus aplicaciones se envía a las transmisiones de registro de Amazon CloudWatch Logs. La simulación también escribe otros datos de registro. Debe habilitar el registro en el esquema de simulación si desea que la simulación escriba datos de registro. Para obtener más información, consulte [SimSpace Weaver inicia sesión en Amazon CloudWatch Logs](cloudwatch-logs.md).

**aviso**  
La simulación puede producir grandes cantidades de datos de registro. Los datos de registro pueden crecer muy rápidamente. Debe vigilar sus registros de cerca y detener las simulaciones cuando ya no necesite que se ejecuten. El registro puede generar grandes costes.

## Uso **describe** Llamadas a la API
<a name="working-with_debugging_api"></a>

Puede utilizar el siguiente servicio APIs para obtener información sobre sus simulaciones en Nube de AWS.
+ **ListSimulations**— obtenga una lista de todas sus simulaciones en el Nube de AWS.  
**Example Ejemplo**  

  ```
  aws simspaceweaver list-simulations
  ```
+ **DescribeSimulation**: obtener detalles sobre una simulación.  
**Example Ejemplo**  

  ```
  aws simspaceweaver describe-simulation --simulation MySimulation
  ```
+ **DescribeApp**: obtener detalles sobre una aplicación.  
**Example Ejemplo**  

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

Para obtener más información sobre el SimSpace Weaver APIs, consulte[SimSpace Weaver Referencias de API](api-reference.md).

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

Puede conectar un cliente a una aplicación personalizada o de servicio en ejecución que haya definido `endpoint_config` en su esquema de simulación. El SDK de la SimSpace Weaver aplicación incluye clientes de muestra que puede usar para ver la aplicación de muestra. Puede consultar el código fuente de estos clientes de ejemplo y la aplicación de ejemplo para ver cómo puede crear sus propios clientes. Para obtener más información sobre cómo crear y ejecutar los clientes de muestra, consulta los tutoriales en[Empezar con SimSpace Weaver](getting-started.md).

Puede encontrar el código fuente de los clientes de muestra en la siguiente carpeta:
+ `sdk-folder\packaging-tools\clients\PathfindingSampleClients\`

# Depuración de simulaciones locales
<a name="working-with_debugging_local"></a>

Puede depurar sus aplicaciones de SimSpace Weaver Local con Microsoft Visual Studio. Para obtener más información sobre cómo depurar con 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). 

**Para depurar su simulación local**

1. Asegúrese de que `schema.yaml` está en su directorio de trabajo.

1. En **Visual Studio**, abra el menú contextual de cada aplicación que quieras depurar (por ejemplo, `PathfindingSampleLocalSpatial` o `PathfindingSampleLocalView`) y establezca el directorio de trabajo en la sección de depuración.

1. Abra el menú contextual de la aplicación que quiera depurar y seleccione **Establecer como proyecto de inicio**.

1. Seleccione F5 para empezar a depurar la aplicación.

Los requisitos para depurar una simulación son los mismos que para ejecutar una simulación con normalidad. Debe iniciar el número de aplicaciones espaciales especificado en el esquema. Por ejemplo, si su esquema especifica una cuadrícula de 2 x 2 e inicia una aplicación espacial en modo de depuración, la simulación no se ejecutará hasta que inicie 3 aplicaciones espaciales más (en modo de depuración o no en modo de depuración).

Para depurar una aplicación personalizada, primero debe iniciar las aplicaciones espaciales y, a continuación, iniciar la aplicación personalizada en el depurador.

Tenga en cuenta que la simulación se ejecuta al mismo ritmo. En cuanto una aplicación alcance un punto de interrupción, todas las demás se pausarán. Cuando continúe desde ese punto de interrupción, las demás aplicaciones continuarán.

# Contenedores personalizados
<a name="working-with_custom-containers"></a>

AWS SimSpace Weaver las aplicaciones se ejecutan en entornos contenerizados Amazon Linux 2 (AL2). En el Nube de AWS, SimSpace Weaver ejecuta sus simulaciones en contenedores Docker creados a partir de una `amazonlinux:2` imagen servida desde Amazon Elastic Container Registry (Amazon ECR). Puede crear una imagen de Docker personalizada, almacenarla en Amazon ECR y utilizarla para la simulación en lugar de la imagen de Docker predeterminada que le proporcionamos.

Puede usar un contenedor personalizado para administrar sus dependencias de software e incluir componentes de software adicionales que no estén en la imagen de Docker estándar. Por ejemplo, puede añadir al contenedor las bibliotecas de software disponibles públicamente que usa zu aplicación y solo colocar el código personalizado en el archivo zip de la aplicación.

**importante**  
Solo admitimos imágenes de AL2 Docker alojadas en repositorios de Amazon ECR, ya sea en Amazon ECR Public Gallery o en su registro privado de Amazon ECR. No admitimos las imágenes de Docker alojadas fuera de Amazon ECR. Para obtener más información sobre Amazon ECR, consulte la *[Documentación de Amazon Elastic Container Registry](https://docs.aws.amazon.com/ecr)*.

**Topics**
+ [Creación de un contenedor personalizado](working-with_custom-containers_create.md)
+ [Modificar un proyecto para usar un contenedor personalizado](working-with_custom-containers_modify-project.md)
+ [Preguntas frecuentes sobre contenedores personalizados](working-with_custom-containers_faq.md)
+ [Solución de problemas con contenedores personalizados](working-with_custom-containers_troubleshooting.md)

# Creación de un contenedor personalizado
<a name="working-with_custom-containers_create"></a>

En estas instrucciones se presupone que sabe utilizar Docker y Amazon Elastic Container Registry (Amazon ECR). Para obtener más información sobre Amazon ECR, consulte la *[Guía del usuario de Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide)*.

**Requisitos previos**
+ La identidad de IAM (uso o rol) que utiliza para realizar estas acciones tiene los permisos correctos para usar Amazon ECR
+ Docker está instalado en su sistema local.

**Para crear un contenedor personalizado**

1. Cree su `Dockerfile`.

   R `Dockerfile` Para ejecutar AWS SimSpace Weaver aplicaciones comienza con la Amazon Linux 2 imagen en Amazon ECR.

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

1. Compile su `Dockerfile`.

1. Cargue su imagen de contenedor en Amazon ECR.
   + [Utilice la Consola de administración de AWS.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html)
   + [Utilice la AWS Command Line Interface.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
**nota**  
Si recibe un error de `AccessDeniedException` al intentar subir la imagen de su contenedor a Amazon ECR, es posible que su identidad de IAM (usuario o rol) no tenga los permisos necesarios para usar Amazon ECR. Puede adjuntar la política `AmazonEC2ContainerRegistryPowerUser` AWS gestionada a su identidad de IAM y volver a intentarlo. Para más información sobre cómo adjuntar una política, consulte [Adición y eliminación de permisos de identidad de IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) en la *Guía del usuario de AWS Identity and Access Management *.

# Modificar un proyecto para usar un contenedor personalizado
<a name="working-with_custom-containers_modify-project"></a>

Estas instrucciones dan por sentado que ya sabes cómo utilizarla AWS SimSpace Weaver y quieres que tus flujos de trabajo de almacenamiento y desarrollo de aplicaciones sean Nube de AWS más eficientes.

**Requisitos previos**
+ Dispone de un contenedor personalizado en Amazon Elastic Container Registry (Amazon ECR). Para obtener más información acerca de la creación de un contenedor personalizado, consulte [Creación de un contenedor personalizado](working-with_custom-containers_create.md).

**Para modificar su proyecto para usar un contenedor personalizado**

1. Añada permisos al rol de aplicación de simulación de su proyecto para utilizar Amazon ECR.

   1. Si aún no dispone de una política de IAM con los siguientes permisos, cree la política. Le sugerimos `simspaceweaver-ecr` como nombre de política. Para obtener más información sobre cómo crear una política de IAM, consulte [Creación de políticas de IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) en la *Guía del usuario de AWS Identity and Access Management *.

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

   1. Buscar el nombre del rol de la aplicación de simulación de su proyecto:

      1. En un editor de texto, abre la CloudFormation plantilla:

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

      1. Busque la propiedad `RoleName` que aparece debajo de `WeaverAppRole`. El valor es el nombre del rol de la aplicación de simulación de su proyecto.  
**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. Adjunte la política de `simspaceweaver-ecr` al rol de la aplicación de simulación del proyecto. Para más información sobre cómo adjuntar una política, consulte [Adición y eliminación de permisos de identidad de IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) en la *Guía del usuario de AWS Identity and Access Management *. 

   1. Navegue hasta el siguiente comando `sdk-folder` y ejecútelo para actualizar la SimSpace Weaver pila de muestras:

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

1. Especifique las imágenes del contenedor en el esquema de simulación del proyecto.
   + Puede añadir la propiedad`default_image` opcional bajo `simulation_properties` para especificar una imagen de contenedor personalizada predeterminada para todos los dominios.
   + Agregue la propiedad `image` a `app_config` para un dominio para el que desee utilizar una imagen contenedora personalizada. Especifique el URI del repositorio de Amazon ECR como valor. Puede especificar una imagen diferente para cada dominio.
     + Si `image` no se especifica para un dominio y `default_image` se especifica, las aplicaciones de ese dominio utilizan la imagen predeterminada.
     + Si `image` no se especifica para un dominio ni `default_image` se especifica, las aplicaciones de ese dominio se ejecutan en un SimSpace Weaver contenedor estándar.  
**Example Fragmento de esquema que incluye una configuración de contenedor personalizada**  

   ```
   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. Cree y cargue su proyecto como de costumbre.

# Preguntas frecuentes sobre contenedores personalizados
<a name="working-with_custom-containers_faq"></a>

## Q1 (P1). ¿Qué hago si quiero cambiar el contenido de mi contenedor?
<a name="working-with_custom-containers_faq_q1"></a>
+ **Para una simulación en ejecución**: no se puede cambiar el contenedor de una simulación en ejecución. Debe crear un contenedor nuevo e iniciar una nueva simulación que utilice ese contenedor.
+ **Para una nueva simulación**: cree un contenedor nuevo, cárguelo en Amazon Elastic Container Registry (Amazon ECR) e inicie una nueva simulación que utilice ese contenedor.

## Q2 (P2). ¿Cómo puedo cambiar la imagen del contenedor para mi simulación?
<a name="working-with_custom-containers_faq_q2"></a>
+ **Para una simulación en ejecución**: no se puede cambiar el contenedor de una simulación en ejecución. Debe iniciar una nueva simulación que utilice ese nuevo contenedor.
+ **Para una nueva simulación**: especifique la nueva imagen del contenedor en el esquema de simulación del proyecto. Para obtener más información, consulte [Modificar un proyecto para usar un contenedor personalizado](working-with_custom-containers_modify-project.md).

# Solución de problemas con contenedores personalizados
<a name="working-with_custom-containers_troubleshooting"></a>

**Topics**
+ [AccessDeniedException al subir la imagen a Amazon Elastic Container Registry (Amazon ECR)](working-with_custom-containers_troubleshooting_access-denied.md)
+ [No se puede iniciar una simulación que utiliza un contenedor personalizado](working-with_custom-containers_troubleshooting_no-start.md)

# AccessDeniedException al subir la imagen a Amazon Elastic Container Registry (Amazon ECR)
<a name="working-with_custom-containers_troubleshooting_access-denied"></a>

Si recibe un error de `AccessDeniedException` al intentar subir la imagen de su contenedor a Amazon ECR, es posible que su identidad de IAM (usuario o rol) no tenga los permisos necesarios para usar Amazon ECR. Puede adjuntar la política `AmazonEC2ContainerRegistryPowerUser` AWS gestionada a su identidad de IAM y volver a intentarlo. Para más información sobre cómo adjuntar una política, consulte [Adición y eliminación de permisos de identidad de IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) en la *Guía del usuario de AWS Identity and Access Management *.

# No se puede iniciar una simulación que utiliza un contenedor personalizado
<a name="working-with_custom-containers_troubleshooting_no-start"></a>

**Consejos para la solución de problemas**
+ Si el registro está activado para la simulación, compruebe los registros de errores.
+ Pruebe la simulación sin un contenedor personalizado.
+ Pruebe la simulación localmente. Para obtener más información, consulte [Desarrollo local en SimSpace Weaver](working-with_local-development.md).

# Trabajo con Python
<a name="working-with_python"></a>

Puedes usar Python para tus SimSpace Weaver aplicaciones y tu cliente. El kit de desarrollo de software Python (SDK de Python) se incluye como parte del paquete distribuible del SDK de SimSpace Weaver aplicaciones estándar. El desarrollo con Python funciona de forma similar al desarrollo en los demás lenguajes compatibles.

**importante**  
SimSpace Weaver solo es compatible con la versión 3.9 de Python.

**importante**  
SimSpace Weaver la compatibilidad con Python requiere la SimSpace Weaver versión 1.15.0 o posterior.

**Topics**
+ [Crear un proyecto de Python](working-with_python_create-project.md)
+ [Inicio de una simulación de Python](working-with_python_start-sim.md)
+ [Cliente Python de muestra](working-with_python_client.md)
+ [Preguntas frecuentes sobre el uso de Python](working-with_python_faq.md)
+ [Solución de problemas relacionados con Python](working-with_python_troubleshooting.md)

# Crear un proyecto de Python
<a name="working-with_python_create-project"></a>

## Contenedor de Python personalizado
<a name="working-with_python_create-project_container"></a>

Para ejecutar su SimSpace Weaver simulación basada en Python en Nube de AWS, puede crear un contenedor personalizado que incluya las dependencias necesarias. Para obtener más información, consulte [Contenedores personalizados](working-with_custom-containers.md). 

Un contenedor de Python personalizado debe incluir lo siguiente:
+ gcc
+ openssl-devel
+ bzip2-devel
+ libffi-devel
+ wget
+ tar
+ gzip
+ make
+ Python (versión 3.9)

Si utiliza la plantilla `PythonBubblesSample` para crear su proyecto, puede ejecutar el script `quick-start.py` (ubicado en la carpeta `tools` de su proyecto) para crear una imagen de Docker con las dependencias necesarias. El script carga la imagen en Amazon Elastic Container Registry (Amazon ECR).

El script usa `quick-start.py` para hacer el siguiente `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
```

Puede añadir sus propias dependencias a `Dockerfile`:

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

El archivo `requirements.txt` contiene una lista de los paquetes de Python necesarios para la simulación de ejemplo`PythonBubblesSample`:

```
Flask==2.1.1
```

Puede añadir sus propias dependencias de paquetes de Python a `requirements.txt`:

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

Las `Dockerfile` y `requirements.txt` están en la carpeta `tools` de su proyecto.

**importante**  
Técnicamente, no tiene que usar un contenedor personalizado con su simulación de Python, pero le recomendamos encarecidamente que utilice un contenedor personalizado. El contenedor estándar de Amazon Linux 2 (AL2) que proporcionamos no tiene Python. Por lo tanto, si no utilizas un contenedor personalizado que tenga Python, debes incluir Python y las dependencias necesarias en cada archivo zip de la aplicación en el que cargues. SimSpace Weaver

# Inicio de una simulación de Python
<a name="working-with_python_start-sim"></a>

Puede iniciar la simulación basada en Python del mismo modo que una SimSpace Weaver simulación normal, tanto en SimSpace Weaver Local y en el SimSpace Weaver . Nube de AWS Para obtener más información, consulte los tutoriales en[Empezar con SimSpace Weaver](getting-started.md).

`PythonBubblesSample` incluye su propio cliente de muestra de Python. Para obtener más información, consulte [Cliente Python de muestra](working-with_python_client.md). 

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

Si utiliza la plantilla `PythonBubblesSample` para crear un proyecto, su proyecto contiene un cliente de muestra de Python. Puede usar el cliente de muestra para ver la simulación de `PythonBubblesSample`. También puede usar el cliente de ejemplo como punto de partida para crear su propio cliente de Python.

En el siguiente procedimiento, se da por sentado que ha creado un proyecto `PythonBubblesSample` y ha iniciado su simulación.

**Para iniciar el cliente Python**

1. En una **ventana de línea de comandos**, vaya a la carpeta del proyecto de `PyBubbleClient` ejemplo.

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

1. Ejecute el cliente Python.

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

**Parámetros**  
**host**  
La dirección IP de la simulación. Para iniciar una simulación en Nube de AWS, puede buscar la dirección IP de la simulación en la [SimSpace Weaver consola](https://console.aws.amazon.com/simspaceweaver) o seguir el procedimiento [Obtenga la dirección IP y el número de puerto de una aplicación personalizadaObtenga la dirección IP y el número de puerto](working-with_get-ip.md) del tutorial de inicio rápido. Para una simulación local, use `127.0.0.1` como dirección IP.  
**port**  
El número de puerto de la simulación. Para una simulación iniciada en Nube de AWS, este es el número de `Actual` puerto. Puede encontrar el número de puerto de la simulación en la [consola de SimSpace Weaver](https://console.aws.amazon.com/simspaceweaver) o utilizar el procedimiento [Obtenga la dirección IP y el número de puerto de una aplicación personalizadaObtenga la dirección IP y el número de puerto](working-with_get-ip.md) del tutorial de inicio rápido. Para una simulación local, use `7000` como número de puerto.  
**simsize**  
El número máximo de entidades que se mostrarán en el cliente.

# Preguntas frecuentes sobre el uso de Python
<a name="working-with_python_faq"></a>

## Q1 (P1). ¿Qué versiones de Python son compatibles?
<a name="working-with_python_faq_q1"></a>

SimSpace Weaver solo es compatible con la versión 3.9 de Python.

# Solución de problemas relacionados con Python
<a name="working-with_python_troubleshooting"></a>

**Topics**
+ [Error durante la creación de un contenedor personalizado](working-with_python_troubleshooting_create-container-failure.md)
+ [La simulación de Python no se inicia](working-with_python_troubleshooting_no-start.md)
+ [Un cliente de visualización o simulación de Python arroja un ModuleNotFound error](working-with_python_troubleshooting_module-not-found.md)

# Error durante la creación de un contenedor personalizado
<a name="working-with_python_troubleshooting_create-container-failure"></a>

Si aparece un error `no basic auth credentials` después de ejecutar `quick-start.py`, es posible que haya un problema con las credenciales temporales de Amazon ECR. Ejecute el siguiente comando con su Región de AWS ID y número de AWS cuenta:

```
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**  
Asegúrese de que el Región de AWS que especifique es el mismo que utilizó para la simulación. Utilice uno de los Regiones de AWS que SimSpace Weaver sea compatible. Para obtener más información, consulte [SimSpace Puntos finales y cuotas de Weaver](service-quotas.md).

Después de ejecutar el comando `aws ecr`, vuelva a ejecutar `quick-start.py`.

**Otros recursos de solución de problemas que comprobar**
+ [Solución de problemas con contenedores personalizados](working-with_custom-containers_troubleshooting.md)
+ [Solución de problemas de Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/troubleshooting.html) en la *Guía del usuario de Amazon ECR*
+ [Configuración con Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html) en la *Guía del usuario de Amazon ECR*

# La simulación de Python no se inicia
<a name="working-with_python_troubleshooting_no-start"></a>

Es posible que aparezca un error de `Unable to start app` en el registro de administración de la simulación. Esto puede ocurrir si se produce un error al crear el contenedor personalizado. Para obtener más información, consulte [Error durante la creación de un contenedor personalizado](working-with_python_troubleshooting_create-container-failure.md). Para obtener más información acerca de los registros, consulte [SimSpace Weaver inicia sesión en Amazon CloudWatch Logs](cloudwatch-logs.md).

Si está seguro de que su contenedor no tiene ningún problema, compruebe el código fuente de Python de su aplicación. Puede usar… SimSpace Weaver Local para probar tu aplicación. Para obtener más información, consulte [Desarrollo local en SimSpace Weaver](working-with_local-development.md).

# Un cliente de visualización o simulación de Python arroja un ModuleNotFound error
<a name="working-with_python_troubleshooting_module-not-found"></a>

Python arroja un error `ModuleNotFound` cuando no puede encontrar un paquete de Python necesario.

Si su simulación está en Nube de AWS, asegúrese de que su contenedor personalizado tenga todas las dependencias necesarias enumeradas en su`requirements.txt`. Recuerde `quick-start.py` volver a ejecutar si edita `requirements.txt`.

Si aparece el error del cliente `PythonBubblesSample`, utilice `pip` para instalar el paquete indicado:

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

# Compatibilidad con otros motores
<a name="working-with_engines"></a>

Puedes usar tu propia personalización C\$1\$1 motor con SimSpace Weaver. Actualmente estamos desarrollando la compatibilidad para los siguientes motores. Hay documentación independiente para cada uno de estos motores.

**importante**  
Las integraciones con los motores que se enumeran aquí son experimentales. Están disponibles para una vista previa.

**Motores**
+ [Unity](#working-with_engines_unity)(versión mínima 2022.3.19.F1)
+ [Unreal Engine](#working-with_engines_unreal) (versión 5.0 como mínimo)

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

Debe tener el Unity el entorno de desarrollo ya estaba instalado antes de crear SimSpace Weaver simulaciones con Unity. Para obtener más información, consulte las instrucciones por separado:

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

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

Debe crear un Unreal Engine servidor dedicado a partir del código fuente. SimSpaceWeaverAppSdkDistributable Incluye una versión del PathfindingSample para Unreal Engine. Para obtener más información, consulte las instrucciones separadas: 

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

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

AWS SimSpace Weaver le permite crear simulaciones con el motor de simulación y el contenido que elija. En relación con su uso SimSpace Weaver, usted es responsable de obtener, mantener y cumplir los términos de la licencia de cualquier software o contenido que utilice en sus simulaciones. Compruebe que el acuerdo de licencia le permite implementar el software y el contenido en un entorno de alojamiento virtual.

# Administra tus recursos con AWS CloudFormation
<a name="working-with_cloudformation"></a>

Puede utilizarlos AWS CloudFormation para gestionar sus AWS SimSpace Weaver recursos. CloudFormation es un AWS servicio independiente que le ayuda a especificar, aprovisionar y administrar su AWS infraestructura como código. Con CloudFormation él, crea un archivo JSON o YAML, denominado *[plantilla](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-templates template)*. La plantilla especifica los detalles de la infraestructura. CloudFormation utiliza la plantilla para aprovisionar la infraestructura como una sola unidad, denominada *[pila](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#w2ab1b5c15b9)*. Cuando eliminas tu pila, puedes hacer que CloudFormation borres todo lo que haya en la pila al mismo tiempo. Puede administrar su plantilla mediante procesos de administración de código fuente estándar (por ejemplo, rastrearla en un sistema de control de versiones como [Git](https://git-scm.com/)). Para obtener más información al respecto CloudFormation, consulta la [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide).

**Su recurso de simulación**  
En AWS, un *recurso* es una entidad con la que puede trabajar. Los ejemplos incluyen una EC2 instancia de Amazon, un bucket de Amazon S3 o un rol de IAM. Su SimSpace Weaver simulación es un recurso. En las configuraciones, normalmente se especifica un AWS recurso en el formulario`AWS::service::resource`. Para SimSpace Weaver, especifique su recurso de simulación como`AWS::SimSpaceWeaver::Simulation`. Para obtener más información sobre el recurso de simulación en CloudFormation, consulte la [SimSpace Weaver](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-simspaceweaver-simulation.html)sección de la *Guía del AWS CloudFormation usuario*.

**¿Cómo puedo usarlo CloudFormation con SimSpace Weaver?**  
Puede crear una CloudFormation plantilla que especifique los AWS recursos que desea aprovisionar. La plantilla puede especificar una arquitectura completa, parte de una arquitectura o una solución pequeña. Por ejemplo, puede especificar una arquitectura para su SimSpace Weaver solución que incluya buckets de Amazon S3, permisos de IAM, una base de datos compatible en Amazon Relational Database Service o Amazon DynamoDB y su recurso. `Simulation` A continuación, puede utilizarlos CloudFormation para aprovisionar todos esos recursos como una unidad y al mismo tiempo.

**Example plantilla que crea recursos de IAM e inicia una simulación**  
La siguiente plantilla de ejemplo crea un rol de IAM y los permisos que SimSpace Weaver necesita para realizar acciones en su cuenta. Los scripts del SDK de la SimSpace Weaver aplicación crean el rol y los permisos en un proyecto específico Región de AWS , pero puedes usar una CloudFormation plantilla para implementar la simulación en otro Región de AWS sin tener que volver a ejecutar los scripts. Por ejemplo, puede hacerlo para configurar una simulación de copia de seguridad con fines de recuperación de desastres.  
En este ejemplo, el nombre original de la simulación es `MySimulation`. Ya existe un depósito para el esquema en el que Región de AWS CloudFormation se construirá la pila. El bucket contiene una versión del esquema que está correctamente configurada para ejecutar la simulación en Región de AWS. Recuerde que el esquema especifica la ubicación de los archivos zip de la aplicación, que es un bucket de Amazon S3 en el mismo Región de AWS que la simulación. La aplicación comprime el depósito y los archivos deben existir ya en él Región de AWS cuando se cree la CloudFormation pila; de lo contrario, la simulación no se iniciará. Tenga en cuenta que el nombre del depósito de este ejemplo incluye el Región de AWS, pero eso no determina dónde se encuentra realmente el depósito. Debe asegurarse de que el bucket esté realmente dentro Región de AWS (puede comprobar las propiedades del bucket en la consola de Amazon S3, con Amazon S3 APIs o con los comandos de Amazon S3 en AWS CLI).  
En este ejemplo, se utilizan algunas funciones y parámetros integrados CloudFormation para sustituir variables. Para obtener más información, consulte la [referencia sobre las funciones intrínsecas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) y [la referencia sobre los pseudoparámetros](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) en la *Guía del usuario de 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'
```

# Uso de instantáneas con AWS CloudFormation
<a name="working-with_cloudformation_snapshots"></a>

Una [instantánea](working-with_snapshots.md) es una copia de seguridad de una simulación. En el siguiente ejemplo, se inicia una nueva simulación a partir de una instantánea en lugar de a partir de un esquema. La instantánea de este ejemplo se creó a partir de una simulación de proyecto del SDK de una SimSpace Weaver aplicación. CloudFormation crea el nuevo recurso de simulación y lo inicializa con los datos de la instantánea. La nueva simulación puede tener una `MaximumDuration` diferente a la original.

Le recomendamos que cree y utilice una copia del rol de aplicación de la simulación original. El rol de aplicación de la simulación original podría eliminarse si elimina la pila de esa simulación CloudFormation .

```
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"
```

# Instantáneas
<a name="working-with_snapshots"></a>

Puede crear una *instantánea* para hacer una copia de seguridad de los datos de la entidad de simulación en cualquier momento. SimSpace Weaver crea un archivo .zip en un bucket de Amazon S3. Puede crear una nueva simulación con la instantánea. SimSpace Weaver inicializa el State Fabric de la nueva simulación con los datos de la entidad almacenados en la instantánea, inicia las aplicaciones espaciales y de servicio que estaban en ejecución cuando se creó la instantánea y ajusta el reloj a la hora correspondiente. SimSpace Weaver obtiene la configuración de la simulación a partir de la instantánea y no de un archivo de esquema. Los archivos .zip de la aplicación deben estar en la misma ubicación en Amazon S3 que en la simulación original. Debe iniciar cualquier aplicación personalizada por separado.

**Temas**
+ [Casos de uso de instantáneas](#working-with_snapshots_use-cases)
+ [Utilice la SimSpace Weaver consola para trabajar con instantáneas](working-with_snapshots_console.md)
+ [Utilice el AWS CLI para trabajar con instantáneas](working-with_snapshots_cli.md)
+ [Uso de instantáneas con AWS CloudFormation](working-with_cloudformation_snapshots.md)
+ [Preguntas frecuentes sobre instantáneas](working-with_snapshots_faq.md)

## Casos de uso de instantáneas
<a name="working-with_snapshots_use-cases"></a>

### Regrese a un estado anterior y explore los escenarios de ramificación
<a name="working-with_snapshots_use-case_branching"></a>

Puede crear una instantánea de la simulación para guardarla en un estado específico. A continuación, puede crear varias simulaciones nuevas a partir de esa instantánea y explorar diferentes escenarios que podrían derivarse de ese estado.

### Prácticas recomendadas de recuperación de desastres y seguridad
<a name="working-with_snapshots_use-cases_best-practice"></a>

Le recomendamos que haga copias de seguridad de la simulación con regularidad, especialmente en el caso de simulaciones que se ejecuten durante más de 1 hora o en las que intervengan varios trabajadores. Las copias de seguridad pueden ayudarle a recuperarse de desastres e incidentes de seguridad. Las instantáneas permiten hacer copias de seguridad de la simulación. Las instantáneas requieren que los archivos.zip de la aplicación estén en la misma ubicación de Amazon S3 que antes. Si necesita poder mover los archivos.zip de la aplicación a otra ubicación, debe utilizar una solución de copia de seguridad personalizada. 

Para obtener más información sobre otras prácticas recomendadas, consulte [Mejores prácticas al trabajar con SimSpace Weaver](best-practices.md) y [Prácticas recomendadas de seguridad para SimSpace Weaver](security_best-practices.md).

### Ampliar la duración de la simulación
<a name="working-with_snapshots_use-cases_extend-duration"></a>

El *recurso de simulación* es la representación de la simulación en SimSpace Weaver. Todos los recursos de simulación tienen una configuración `MaximumDuration`. Una simulación se detiene automáticamente cuando alcanza su `MaximumDuration`. El valor máximo de `MaximumDuration` es `14D` (14 días). 

Si necesita que la simulación persista durante más tiempo que el `MaximumDuration` de su recurso de simulación, puede crear una instantánea antes de que el recurso de simulación llegue a su `MaximumDuration`. Puede iniciar una nueva simulación (crear un nuevo recurso de simulación) con la instantánea. SimSpace Weaver inicializa los datos de la entidad a partir de la instantánea, inicia las mismas aplicaciones espaciales y de servicio que se ejecutaban anteriormente y restaura el reloj. Puede iniciar sus aplicaciones personalizadas y realizar cualquier inicialización personalizada adicional. Puede establecer el nuevo recurso `MaximumDuration` de simulación en un valor diferente al iniciarlo.

# Utilice la SimSpace Weaver consola para trabajar con instantáneas
<a name="working-with_snapshots_console"></a>

Puede utilizar la SimSpace Weaver consola para crear una instantánea de la simulación.

**Topics**
+ [Crear una instantánea](#working-with_snapshots_console_create)
+ [Iniciar una simulación a partir de una instantánea](#working-with_snapshots_console_start)

## Utilice la consola para crear una instantánea
<a name="working-with_snapshots_console_create"></a>

**Para crear una instantánea**

1. Inicie sesión en la [SimSpace Weaver consola Consola de administración de AWS y conéctese a ella](https://console.aws.amazon.com/simspaceweaver).

1. En el panel de navegación, seleccione **Simulaciones**.

1. Seleccione el botón de opción situado junto al nombre de la simulación. El **estado** de la simulación debe ser **Iniciado**. 

1. En la parte superior de la página, seleccione **Crear instantánea**.

1. En **Configuración de instantáneas**, en **Destino de la instantánea**, introduzca el URI de Amazon S3 de un depósito o un depósito y una carpeta en los que desee SimSpace Weaver crear la instantánea. Puede elegir **Browse S3** si prefiere buscar entre los buckets disponibles y seleccionar una ubicación.
**importante**  
El bucket de Amazon S3 debe estar en el mismo Región de AWS que la simulación.
**nota**  
SimSpace Weaver crea una `snapshot` carpeta dentro del destino de la instantánea seleccionada. SimSpace Weaver crea el archivo.zip de la instantánea en esa `snapshot` carpeta.

1. Seleccione **Create snapshot (Crear instantánea)**.

## Utilice la consola para iniciar una simulación a partir de una instantánea
<a name="working-with_snapshots_console_start"></a>

Para iniciar una simulación a partir de una instantánea, el archivo .zip de la instantánea debe estar en un bucket de Amazon S3 al que pueda acceder la simulación. La simulación usa los permisos definidos en el rol de la aplicación que seleccionó al iniciar la simulación. Todos los archivos .zip de la aplicación de la simulación original deben estar en las mismas ubicaciones que cuando se creó la instantánea.

**Iniciar una simulación a partir de una instantánea**

1. Inicie sesión en la [SimSpace Weaver consola Consola de administración de AWS](https://console.aws.amazon.com/simspaceweaver) y conéctese a ella.

1. En el panel de navegación, seleccione **Simulaciones**.

1. En la parte superior de la página, seleccione **Iniciar simulación**.

1. En **Configuración de simulación**, escriba un nombre y una descripción opcional para la simulación. El nombre de la simulación debe ser exclusivo de su Cuenta de AWS.

1. Para el **método de inicio de la simulación**, seleccione **Usar una instantánea en Amazon S3**.

1. En el caso del **URI de Amazon S3 para la instantánea**, introduzca el URI de Amazon S3 del archivo de instantáneas o seleccione **Browse S3** para buscar y seleccionar el archivo.
**importante**  
El bucket de Amazon S3 debe estar en el mismo Región de AWS que la simulación.

1. Para el **rol de IAM**, seleccione el rol de aplicación que usará la simulación.

1. En **Duración máxima**, introduzca la cantidad máxima de tiempo durante la que debe ejecutarse el recurso de simulación. El valor máximo es `14D`. Para obtener más información acerca de la duración máxima, consulte [.](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)

1. En **Etiquetas *(opcional)***, elija **Añadir nueva etiqueta** si desea añadir una etiqueta.

1. Seleccione **Iniciar simulación**.

# Utilice el AWS CLI para trabajar con instantáneas
<a name="working-with_snapshots_cli"></a>

Puede utilizar el AWS CLI para llamar al SimSpace Weaver APIs desde una línea de comandos. Debe tener el AWS CLI instalado y configurado correctamente. Para obtener más información, consulte [Instalación o actualización de la última versión de la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) en la *Guía del AWS Command Line Interface usuario de la versión 2*.

**Topics**
+ [Crear una instantánea](#working-with_snapshots_cli_create)
+ [Iniciar una simulación a partir de una instantánea](#working-with_snapshots_cli_start)

## Utilice el AWS CLI para crear una instantánea
<a name="working-with_snapshots_cli_create"></a>

**Para crear una instantánea**
+ En una **línea de comandos**, llame a la API `CreateSnapshot`.

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

  **Parámetros**  
Simulación  
El nombre de una simulación iniciada. Se puede utilizar `aws simspaceweaver list-simulations` para ver los nombres y estados de las simulaciones.  
destination  
Una cadena que especifica el bucket de Amazon S3 de destino y el prefijo de clave de objeto opcional para el archivo de instantáneas. El prefijo de la clave de objeto suele ser una carpeta del depósito. SimSpace Weaver crea la instantánea dentro de una `snapshot` carpeta en este destino.   
El bucket de Amazon S3 debe estar en el mismo Región de AWS que la simulación.

  **Ejemplo**

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

Para obtener más información sobre la `CreateSnapshot` API, consulte [CreateSnapshot](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_CreateSnapshot.html)la *referencia de la AWS SimSpace Weaver API*.

## Utilice la AWS CLI para iniciar una simulación a partir de una instantánea
<a name="working-with_snapshots_cli_start"></a>

**Iniciar una simulación a partir de una instantánea**
+ En una **línea de comandos**, llame a la API `StartSimulation`.

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

  **Parámetros**  
nombre  
El nombre de la nueva simulación. El nombre de la simulación debe ser único en su Cuenta de AWS. Se puede utilizar `aws simspaceweaver list-simulations` para ver los nombres de las simulaciones existentes.  
role-arn  
El nombre de recurso de Amazon (ARN) del rol de aplicación que usará la simulación.  
snapshot-s3-location  
Una cadena que especifica el bucket de Amazon S3 y la clave de objeto para el archivo de instantáneas.  
El bucket de Amazon S3 debe estar en el mismo Región de AWS que la simulación.

  **Ejemplo**

  ```
  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 obtener más información sobre la `StartSimulation` API, consulte [StartSimulation](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)la *referencia de la AWS SimSpace Weaver API*.

# Preguntas frecuentes sobre instantáneas
<a name="working-with_snapshots_faq"></a>

**¿Mi simulación sigue ejecutándose durante una instantánea?**  
Sus recursos de simulación seguirán funcionando durante una instantánea y seguirá recibiendo los cargos de facturación durante ese tiempo. El tiempo se tiene en cuenta para la duración máxima de la simulación. Sus aplicaciones no reciben marcas mientras la instantánea está en curso. Si el estado del reloj era `STARTED` cuando se inició la creación de la instantánea, el reloj seguirá indicando el estado `STARTED`. Sus aplicaciones vuelven a recibir marcas una vez finalizada la instantánea. Si el estado de tu reloj era `STOPPED`, el estado de tu reloj seguirá siendo `STOPPED`. Tenga en cuenta que se está ejecutando una simulación con un estado `STARTED` aunque el estado del reloj sea `STOPPED`.

**¿Qué ocurre si hay una instantánea en curso y mi simulación alcanza su duración máxima?**  
La simulación finalizará la instantánea y, a continuación, se detendrá en cuanto finalice el proceso de la instantánea (con éxito o sin éxito). Le recomendamos que pruebe el proceso de captura de pantalla de antemano para saber cuánto tarda, el tamaño del archivo de instantáneas que puede esperar y si debe completarse correctamente.

**¿Qué ocurre si detengo una simulación que tiene una instantánea en curso?**  
Una instantánea en curso se detiene inmediatamente cuando se detiene la simulación. No creará un archivo de instantáneas.

**¿Cómo puedo detener una instantánea en curso?**  
La única forma de detener una instantánea en curso es detener la simulación. **No puede reiniciar una simulación después de detenerla.**

**¿Cuánto tiempo llevará completar la instantánea?**  
El tiempo necesario para crear una instantánea depende de la simulación. Le recomendamos que pruebe el proceso de captura de imágenes de antemano para saber cuánto tardará en realizarse la simulación.

**¿Qué tamaño tendrá mi archivo de instantáneas?**  
El tamaño de un archivo de instantánea depende de la simulación. Le recomendamos que pruebe el proceso de captura de imágenes de antemano para saber cuánto tardará en realizarse la simulación.

# Mensajería
<a name="working-with_messaging"></a>

La API de mensajería simplifica la comunicación entre aplicaciones dentro de la simulación. APIs enviar y recibir mensajes forman parte del SDK de la SimSpace Weaver aplicación. Actualmente, la mensajería utiliza un enfoque de máximo esfuerzo para enviar y recibir mensajes. SimSpace Weaver intenta send/receive enviar los mensajes al siguiente paso de la simulación, pero no hay garantías de entrega, pedido o hora de llegada.

**Temas**
+ [Casos de uso para enviar mensajes](#working-with_messaging_use-cases)
+ [Uso de la mensajería APIs](working-with_messaging_using.md)
+ [¿Cuándo usar la mensajería](working-with_messaging_when-to-use.md)
+ [Consejos para trabajar con la mensajería](working-with_messaging_tips.md)
+ [Errores de mensajería y solución de problemas](working-with_messaging_troubleshooting.md)

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

**Comuníquese entre aplicaciones de simulación**  
Utilice la API de mensajería para comunicarse entre las aplicaciones de la simulación. Úsela para cambiar el estado de las entidades a distancia, cambiar el comportamiento de las entidades o transmitir información a toda la simulación.

**Confirme la recepción de un mensaje**  
Los mensajes enviados contienen información sobre el remitente en el encabezado del mensaje. Use esta información para enviar una respuesta de acuse de recibo al recibir un mensaje.

**Reenvía los datos recibidos por una aplicación personalizada a otras aplicaciones de la simulación**  
La mensajería no reemplaza la forma en que los clientes se conectan a las aplicaciones personalizadas que se ejecutan en ellas SimSpace Weaver. Sin embargo, la mensajería permite a los usuarios reenviar datos de aplicaciones personalizadas que reciben datos de clientes a otras aplicaciones que no tienen una conexión externa. El flujo de mensajes también puede funcionar a la inversa, lo que permite que las aplicaciones sin conexión externa reenvíen los datos a una aplicación personalizada y luego a un cliente. 

# Uso de la mensajería APIs
<a name="working-with_messaging_using"></a>

Los mensajes APIs están incluidos en el SDK de la SimSpace Weaver aplicación (versión mínima 1.16.0). La mensajería es compatible con C\$1\$1, Python y nuestras integraciones con Unreal Engine 5 y Unity.

Hay dos funciones que gestionan las transacciones de mensajes: `SendMessage` y. `ReceiveMessages` Todos los mensajes enviados contienen un destino y una carga útil. La `ReceiveMessages` API devuelve una lista de los mensajes que se encuentran actualmente en la cola de mensajes entrantes de una aplicación.

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

**Enviar mensaje**

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

**Recibir mensajes**

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

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

**Enviar mensaje**

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

**Recibir mensajes**

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

------

**Temas**
+ [Envío de mensajes](#working-with_messaging_using_send)
+ [Recepción de mensajes](#working-with_messaging_using_receive)
+ [Responder al remitente](#working-with_messaging_using_reply)

## Envío de mensajes
<a name="working-with_messaging_using_send"></a>

Los mensajes constan de una transacción (similar a otras llamadas a la API de Weaver), una carga útil y un destino.

### Carga útil de mensaje
<a name="working-with_messaging_using_send_payload"></a>

La carga útil del mensaje es una estructura de datos flexible de hasta 256 bytes. Te recomendamos lo siguiente como práctica recomendada para crear tus cargas útiles de mensajes.

**Para crear la carga útil del mensaje**

1. Cree una estructura de datos (por ejemplo, `struct` en C\$1\$1) que defina el contenido del mensaje.

1. Cree la carga útil del mensaje que contenga los valores que desee enviar en el mensaje.

1. Cree el objeto `MessagePayload`.

### Destino del mensaje
<a name="working-with_messaging_using_send_destination"></a>

El destino de un mensaje lo define el `MessageEndpoint` objeto. Esto incluye un tipo de punto final y un identificador de punto final. El único tipo de punto final que se `Partition` admite actualmente es el que permite dirigir los mensajes a otras particiones de la simulación. El ID del punto final es el ID de la partición del destino de destino.

Solo puede proporcionar una dirección de destino en un mensaje. Cree y envíe varios mensajes si desea enviar mensajes a más de una partición al mismo tiempo.

Para obtener instrucciones sobre cómo resolver un punto final de un mensaje desde una posición, consulte[Consejos para trabajar con la mensajería](working-with_messaging_tips.md).

### Envíe el mensaje
<a name="working-with_messaging_using_send_send"></a>

Puedes usar la `SendMessage` API después de crear los objetos de destino y carga útil.

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

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

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

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

------

**Ejemplo completo de envío de mensajes**  
El siguiente ejemplo demuestra cómo se puede crear y enviar un mensaje genérico. En este ejemplo se envían 16 mensajes individuales. Cada mensaje contiene una carga útil con un valor entre 0 y 15, y el tic de simulación actual.

**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
```

## Recepción de mensajes
<a name="working-with_messaging_using_receive"></a>

SimSpace Weaver entrega los mensajes a la cola de mensajes entrantes de una partición. Usa la `ReceiveMessages` API para obtener un `MessageList` objeto que contenga los mensajes de la cola. Procesa cada mensaje con la `ExtractMessage` API para obtener los datos del mensaje.

**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
```

## Responder al remitente
<a name="working-with_messaging_using_reply"></a>

Cada mensaje recibido contiene un encabezado con información sobre el remitente original del mensaje. Puedes usar message.header.source\$1endpoint para enviar una respuesta.

**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
```

# ¿Cuándo usar la mensajería
<a name="working-with_messaging_when-to-use"></a>

La mensajería interna SimSpace Weaver ofrece otro patrón de intercambio de información entre aplicaciones de simulación. Las suscripciones proporcionan un mecanismo de extracción para leer datos de aplicaciones o áreas específicas de la simulación; los mensajes proporcionan un mecanismo de inserción para enviar datos a aplicaciones o áreas específicas de la simulación.

A continuación, se muestran dos casos de uso en los que resulta más útil enviar datos mediante mensajería en lugar de extraerlos o leerlos a través de una suscripción.

**Example 1: Enviar un comando a otra aplicación para cambiar la posición de una entidad**  

```
// 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);
```
En el lado receptor, la aplicación actualiza la posición de la entidad y la escribe en 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: Enviar un mensaje de creación de entidad a una aplicación 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);
```
En cuanto a la recepción, la aplicación crea una nueva entidad en el State Fabric y actualiza su posición.  

```
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)));
}
```

# Consejos para trabajar con la mensajería
<a name="working-with_messaging_tips"></a>

## Resolver un punto final a partir de una posición o el nombre de una aplicación
<a name="working-with_messaging_tips_resolve-endpoint"></a>

Puede usar la `AllPartitions` función para obtener los límites espaciales y el ID de dominio que necesita para determinar la partición IDs y el destino de los mensajes. Sin embargo, si conoce la posición a la que desea enviar el mensaje, pero no su ID de partición, puede utilizar la MessageEndpointResolver función.

```
/**
* 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);
};
```

## Serializar y deserializar la carga útil del mensaje
<a name="working-with_messaging_tips_serialize-payload"></a>

Puede utilizar las siguientes funciones para crear y leer las cargas útiles de los mensajes. Para obtener más información, consulta MessagingUtils .h en la biblioteca del SDK de aplicaciones de tu 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());
}
```

# Errores de mensajería y solución de problemas
<a name="working-with_messaging_troubleshooting"></a>

Es posible que se produzcan los siguientes errores al usar la mensajería APIs.

## Errores de resolución de terminales
<a name="working-with_messaging_troubleshooting_endpoint-resolution"></a>

Estos errores pueden producirse antes de que una aplicación envíe un mensaje.

### Verificación del nombre de dominio
<a name="working-with_messaging_troubleshooting_dns-check"></a>

Al enviar un mensaje a un punto final no válido, se produce el siguiente error:

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

Esto puede ocurrir cuando intentas enviar un mensaje a una aplicación personalizada y esa aplicación personalizada aún no se ha unido a la simulación. Usa la `DescribeSimulation` API para asegurarte de que la aplicación personalizada se haya lanzado antes de enviarle un mensaje. Este comportamiento es el mismo en SimSpace Weaver Local y en Nube de AWS.

### Verificación de posición
<a name="working-with_messaging_troubleshooting_position-check"></a>

Al intentar resolver un punto final con un nombre de dominio válido pero una posición no válida, se produce el siguiente error.

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

Te sugerimos que utilices el que se encuentra `MessageEndpointResolver` en la `MessageUtils` biblioteca incluida en el SDK de la SimSpace Weaver aplicación.

## Errores al enviar mensajes
<a name="working-with_messaging_troubleshooting_message-sending"></a>

Se pueden producir los siguientes errores cuando una aplicación envía un mensaje.

### Se ha superado el límite de envío de mensajes por aplicación y por marca
<a name="working-with_messaging_troubleshooting_send-limit"></a>

El límite actual de mensajes que se pueden enviar por aplicación y por marca de simulación es de 128. Las llamadas subsiguientes con la misma marca fallarán y se mostrará el siguiente error: 

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

SimSpace Weaver intenta enviar los mensajes no enviados en la siguiente casilla. Reduzca la frecuencia de envío para resolver este problema. Combine las cargas útiles de mensajes inferiores al límite de 256 bytes para reducir el número de mensajes salientes.

Este comportamiento es el mismo dentro SimSpace Weaver Local y dentro del. Nube de AWS

### Se ha superado el límite de tamaño de carga útil de los mensajes
<a name="working-with_messaging_troubleshooting_size-limit"></a>

El límite actual para el tamaño de la carga útil de los mensajes es de 256 bytes tanto en el como SimSpace Weaver Local en el. Nube de AWS Al enviar un mensaje con una carga útil superior a 256 bytes, se produce el siguiente error:

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

SimSpace Weaver comprueba cada mensaje y solo rechaza los que superan el límite. Por ejemplo, si tu aplicación intenta enviar 10 mensajes y uno no supera la comprobación, solo se rechazará ese mensaje. SimSpace Weaver envía los 9 mensajes restantes.

Este comportamiento es el mismo en SimSpace Weaver Local y en Nube de AWS.

### El destino es el mismo que el origen
<a name="working-with_messaging_troubleshooting_dst-src-same"></a>

Las aplicaciones no pueden enviar mensajes a las particiones de su propiedad. Si una aplicación envía un mensaje a una partición de su propiedad, aparece el siguiente error.

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

Este comportamiento es el mismo en SimSpace Weaver Local y en Nube de AWS.

### Mensajes de Best Esfuerzo
<a name="working-with_messaging_troubleshooting_best-effort"></a>

SimSpace Weaver no garantiza la entrega del mensaje. El servicio intentará completar la entrega de los mensajes al marcar la siguiente casilla de simulación, pero es posible que los mensajes se pierdan o se retrasen.