

Hinweis zum Ende des Supports: Am 20. Mai 2026 AWS endet der Support für AWS SimSpace Weaver. Nach dem 20. Mai 2026 können Sie nicht mehr auf die SimSpace Weaver Konsole oder SimSpace Weaver die Ressourcen zugreifen. Weitere Informationen finden Sie unter [AWS SimSpace Weaver Ende des Supports](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html). 

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Arbeiten mit SimSpace Weaver
<a name="working-with"></a>

Dieses Kapitel enthält Informationen und Anleitungen, die Ihnen beim Erstellen Ihrer eigenen Anwendungen helfen sollen SimSpace Weaver.

**Topics**
+ [Konfiguration Ihrer Simulation](working-with_configuring-simulation.md)
+ [Maximale Dauer einer Simulation](working-with_max-duration.md)
+ [Apps entwickeln](working-with_developing-apps.md)
+ [Entwicklung von Kundenanwendungen](working-with_developing-client-applications.md)
+ [Rufen Sie die IP-Adresse und die Portnummer einer benutzerdefinierten App ab](working-with_get-ip.md)
+ [Den Unreal Engine View Client starten](working-with_unreal-client.md)
+ [Lokale Entwicklung in SimSpace Weaver](working-with_local-development.md)
+ [AWS SimSpace Weaver App-SDK](working-with_app-sdk.md)
+ [AWS SimSpace Weaver Demo-Framework](working-with_demo-framework.md)
+ [Mit Servicekontingenten arbeiten](working-with_quotas.md)
+ [Simulationen debuggen](working-with_debugging.md)
+ [Maßgeschneiderte Behälter](working-with_custom-containers.md)
+ [Verwenden von Python](working-with_python.md)
+ [Support für andere Motoren](working-with_engines.md)
+ [Verwendung von lizenzierter Software mit AWS SimSpace Weaver](working-with_byol.md)
+ [Verwaltung Ihrer Ressourcen mit AWS CloudFormation](working-with_cloudformation.md)
+ [Snapshots](working-with_snapshots.md)
+ [Messaging](working-with_messaging.md)

# Konfiguration Ihrer Simulation
<a name="working-with_configuring-simulation"></a>

Ein **Simulationsschema** (oder **Schema**) ist ein YAML-formatierte Textdatei, die die Konfiguration für eine Simulation spezifiziert. Sie können dasselbe Schema verwenden, um mehrere Simulationen zu starten. Die Schemadatei befindet sich im Projektordner für Ihre Simulation. Sie können einen beliebigen Texteditor verwenden, um die Datei zu bearbeiten. SimSpace Weaver liest Ihr Schema nur, wenn die Simulation gestartet wird. Alle Änderungen, die Sie an einer Schemadatei vornehmen, wirken sich nur auf neue Simulationen aus, die Sie nach den Änderungen starten. 

Um Ihre Simulation zu konfigurieren, bearbeiten Sie Ihre Simulationsschemadatei (verwenden Sie das entsprechende Pfadtrennzeichen für Ihr Betriebssystem):

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

Sie laden das Simulationsschema hoch, wenn Sie eine neue Simulation erstellen. Das Schnellstart-Hilfsskript für Ihr Projekt lädt das Schema als Teil des Prozesses zur Erstellung Ihrer Simulation hoch: 

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

Weitere Informationen zum Ausführen des Schnellstart-Skripts finden Sie [Ausführliches Tutorial](getting-started_detailed.md) im [Erste Schritte](getting-started.md) Kapitel dieses Handbuchs.

## Konfigurationsparameter für die Simulation
<a name="working-with_configuring-simulation_config-parameters"></a>

Das Simulationsschema enthält Bootstrapping-Informationen, darunter:
+ **Simulationseigenschaften** [— SDK-Version und Rechenkonfiguration (Typ und Anzahl der Worker)](w2aac51.md#glossary_worker)
+ **Uhren** — Taktrate und Toleranzen
+ **Strategien zur räumlichen Aufteilung** — räumliche Topologie (z. B. ein Raster), Grenzen und Platzierungsgruppen (räumliche Unterteilung nach Arbeitskräften)
+ **Domänen und ihre Apps** — App-Bucket, Pfad und Startbefehl (e)

SimSpace Weaver verwendet Ihre Schemakonfiguration, um räumliche Partitionen zu konfigurieren und anzuordnen, Apps zu starten und die Simulation mit der angegebenen Tick-Rate voranzutreiben. 

**Anmerkung**  
Das Skript zum Erstellen eines Projekts im SimSpace Weaver App-SDK generiert automatisch ein Simulationsschema für Sie, das auf der Beispielanwendung basiert.

In den folgenden Themen werden die Parameter im Simulationsschema beschrieben. Eine vollständige Beschreibung des Simulationsschemas finden Sie unter[SimSpace Weaver Referenz zum Simulationsschema](schema-reference.md). 

**Topics**
+ [Konfigurationsparameter für die Simulation](#working-with_configuring-simulation_config-parameters)
+ [SDK-Version](working-with_configuring-simulation_sdk-version.md)
+ [Eigenschaften der Simulation](working-with_configuring-simulation_simulation-properties.md)
+ [Worker](working-with_configuring-simulation_workers.md)
+ [Uhr](working-with_configuring-simulation_clock.md)
+ [Partitionierungsstrategien](working-with_configuring-simulation_partitioning-strategies.md)
+ [Domains](working-with_configuring-simulation_domains.md)

# SDK-Version
<a name="working-with_configuring-simulation_sdk-version"></a>

Das `sdk_version` Feld gibt die Version an SimSpace Weaver , für die das Schema formatiert ist. Zulässige Werte: `1.17`, `1.16`, `1.15`, `1.14`, `1.13`, `1.12`

**Wichtig**  
Der Wert von beinhaltet `sdk_version` nur die Hauptversionsnummer und die erste Nebenversionsnummer. Der Wert `1.12` gibt beispielsweise alle Versionen an`1.12.x`, z. B. `1.12.0``1.12.1`, und`1.12.2`.

# Eigenschaften der Simulation
<a name="working-with_configuring-simulation_simulation-properties"></a>

Der `simulation_properties` Abschnitt Ihres Schemas spezifiziert die Protokollierungskonfiguration und einen Datentyp für das Indexfeld (normalerweise die räumliche Position) von Entitäten.

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

Der Wert von `log_destination_service` bestimmt die Interpretation des Werts von`log_destination_resource_name`. Derzeit wird als einziger Wert unterstütz `logs`. Das bedeutet, dass der `log_destination_resource_name` Wert von der Name einer Protokollgruppe in Amazon CloudWatch Logs ist.

**Anmerkung**  
Die Protokollierung ist optional. Wenn Sie die Eigenschaften des Protokollziels nicht konfigurieren, erzeugt Ihre Simulation keine Protokolle.

Nur die `default_entity_index_key_type`-Eigenschaft ist erforderlich. Der einzige gültige Wert ist `Vector3<f32>`.

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

`workers`In diesem Abschnitt werden die Art und Anzahl der Arbeiter angegeben, die Sie für Ihre Simulation verwenden möchten. SimSpace Weaver verwendet eigene Worker-Typen, die EC2 Amazon-Instance-Typen zugeordnet sind. 

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

## Aktivierung von Simulationen mit mehreren Mitarbeitern
<a name="working-with_configuring-simulation_workers_multi-worker"></a>

Sie können eine Simulation erstellen, die mehr als einen Worker verwendet. Standardmäßig verwenden Simulationen 1 Worker. Sie müssen Ihr Simulationsschema ändern, bevor Sie die Simulation starten. 

**Anmerkung**  
Sie können eine Simulation, die bereits gestartet wurde, nicht ändern. Wenn Sie Multi-Worker für eine laufende Simulation aktivieren möchten, müssen Sie die Simulation zuerst beenden und löschen.

Um mehr als einen Worker zu verwenden, setzen Sie die `desired` Anzahl der Recheninstanzen auf einen Wert größer als 1. Es gibt eine maximale Anzahl von Apps für jeden Worker. Weitere Informationen finden Sie unter[SimSpace Weaver-Endpunkte und Kontingente](service-quotas.md). SimSpace Weaver verwendet nur dann mehr als einen Worker, wenn die Anzahl der Apps auf einem Worker diesen Grenzwert überschreitet. SimSpace Weaver kann eine App auf jedem der verfügbaren Mitarbeiter platzieren. Die Platzierung einer App bei einem bestimmten Mitarbeiter ist nicht garantiert. 

Der folgende Schemaausschnitt zeigt eine Konfiguration für eine Simulation, die 2 Worker anfordert. SimSpace Weaver versucht, den zweiten Worker zuzuweisen, wenn die Anzahl der Apps die maximale Anzahl von Apps für einen Worker überschreitet.

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

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

Der `clock` Abschnitt spezifiziert die Eigenschaften der Simulationsuhr. Derzeit können Sie nur die **Tick-Rate** konfigurieren (die Anzahl der Ticks pro Sekunde, die die Uhr an Apps sendet). Die Tickrate ist eine maximale Rate. Die effektive Tickrate könnte niedriger sein, da alle Operationen (wie Entitätsaktualisierungen) für einen Tick abgeschlossen sein müssen, bevor der nächste Tick beginnen kann. Die Tickrate wird auch als **Taktrate** bezeichnet.

Die gültigen Werte für `tick_rate` hängen von den in Ihrem Schema `sdk_version` angegebenen Werten ab.

**Gültige Werte für die Tickrate**
+ Versionen vor`"1.14"`:
  + `10`
  + `15`
  + `30`
+ Version `"1.14"` oder später:
  + `"10"`
  + `"15"`
  + `"30"`
  + `"unlimited"`

    Weitere Informationen finden Sie unter [Unbegrenzte Tickrate](#working-with_configuring-simulation_clock_unlimited).

**Wichtig**  
Bei Schemas, bei denen `sdk_version` ein Wert vor `"1.14"` dem Wert von eine **Ganzzahl `tick_rate`** ist, z. B. `30`
Bei Schemas mit einem `sdk_version` `"1.14"` oder einem späteren Wert `tick_rate` ist der Wert von eine **Zeichenfolge**, z. B. `"30"` Der Wert **muss die doppelten Anführungszeichen enthalten**.  
Wenn Sie eine Version `"1.12"` oder ein `"1.13"` Schema in Version `"1.14"` oder höher konvertieren, müssen Sie den Wert von `tick_rate` in doppelte Anführungszeichen setzen.

## Unbegrenzte Tickrate
<a name="working-with_configuring-simulation_clock_unlimited"></a>

Sie können den Wert `tick_rate` auf setzen`"unlimited"`, damit Ihre Simulation so schnell ausgeführt werden kann, wie Ihr Code ausgeführt werden kann. Bei einer unbegrenzten Tick-Rate wird der nächste Tick sofort SimSpace Weaver gesendet, nachdem alle Apps die Commits für den aktuellen Tick abgeschlossen haben.

**Wichtig**  
Eine unbegrenzte Tick-Rate wird in SimSpace Weaver Versionen vor 1.14.0 nicht unterstützt. Der Mindestwert von `sdk_version` im Schema ist. `"1.14"`

**Unbegrenzte Tick-Rate in SimSpace Weaver Local**  
SimSpace Weaver Localimplementiert, `"unlimited"` als ob das Schema eine Tick-Rate von 10 kHz (10000) spezifiziert hätte. Der Effekt ist derselbe wie eine unbegrenzte Tick-Rate in der AWS Cloud. Sie geben immer noch `tick_rate: "unlimited"` in Ihrem Schema an. Mehr über SimSpace Weaver Local erfahren Sie unter [Lokale Entwicklung in SimSpace Weaver](working-with_local-development.md).

## Häufig gestellte Fragen zur Uhr
<a name="working-with_configuring-simulation_clock_faq"></a>

### F1. Kann ich eine STARTET-Simulation so ändern, dass sie eine andere Tickrate verwendet?
<a name="working-with_configuring-simulation_clock_faq_q1"></a>

Sie können die Tick-Rate einer Simulation, die bereits in einer Phase ihres Lebenszyklus vorhanden ist, nicht ändern. AWS Cloud Sie können auch nicht die Tick-Rate einer Simulation ändern, die gerade läuftSimSpace Weaver Local. Sie können das `tick_rate` im Schema festlegen und von diesem Schema aus eine neue Simulation starten.

### F2. Kann ich meine Simulation mit einer unbegrenzten Tick-Rate in einer Version vor 1.14 ausführen?
<a name="working-with_configuring-simulation_clock_faq_q2"></a>

Nein, eine unbegrenzte Tickrate wird in Versionen vor 1.14.0 nicht unterstützt.

## Behebung von Uhrfehlern
<a name="working-with_configuring-simulation_clock_troubleshooting"></a>

Wenn Ihre Simulation nicht gestartet werden kann, können Sie den Wert von `"StartError"` in der Ausgabe der **DescribeSimulation**API überprüfen. Ein ungültiger `tick_rate` Wert in Ihrem Schema führt zu den folgenden Fehlern.

**Anmerkung**  
Die hier gezeigte Fehlerausgabe wird zur besseren Lesbarkeit in mehreren Zeilen angezeigt. Die tatsächliche Fehlerausgabe ist einzeilig.
+ Der `sdk_version` ist älter als `"1.14"` und der Wert von `tick_rate` ist eine ungültige Ganzzahl. Zulässige Werte: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"}]"
  ```
+ Der `sdk_version` ist früher als `"1.14"` und der Wert von `tick_rate` ist eine Zeichenfolge. Zulässige Werte: `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\"}]"
  ```
+ Das `sdk_version` ist `"1.14"` oder später und der Wert von `tick_rate` ist eine ungültige Zeichenfolge. Zulässige Werte: `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"}]"
  ```
+ Das `sdk_version` ist `"1.14"` oder später und der Wert von `tick_rate` ist eine Ganzzahl. Zulässige Werte: `"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\"}]"
  ```

# Partitionierungsstrategien
<a name="working-with_configuring-simulation_partitioning-strategies"></a>

`partitioning_strategies`In diesem Abschnitt werden die Konfigurationseigenschaften für die Partitionen von räumlichen Apps angegeben. Sie geben Ihren eigenen Namen für eine Partitionierungsstrategie an (eine Reihe von Eigenschaften in diesem Abschnitt) und verwenden ihn in Ihrer Spatial-App-Konfiguration.

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

Die `topology` Eigenschaft gibt den Typ des Koordinatensystems an, das in Ihrer Simulation verwendet wird. Der Wert `Grid` gibt ein 2-dimensionales (2D) Gitter an.

Bei einer `Grid` Topologie wird der Simulationsraum als achsenausgerichteter Begrenzungsrahmen modelliert (AABB). Sie geben die Koordinatengrenzen für jede Achse Ihres AABB in der `aabb_bounds` Eigenschaft an. Alle Entitäten, die in Ihrer Simulation räumlich existieren, müssen eine Position innerhalb des AABB haben.

## Gruppen zur Rasterplatzierung
<a name="working-with_configuring-simulation_partitioning-strategies_placement-groups"></a>

Eine **Platzierungsgruppe** ist eine Sammlung von räumlichen App-Partitionen, die Sie auf demselben Worker platzieren möchten SimSpace Weaver . Sie geben die Anzahl und Anordnung der Platzierungsgruppen (in einem Raster) in der `grid_placement_groups` Eigenschaft an. SimSpace Weaver versucht, die Partitionen gleichmäßig auf die Platzierungsgruppen zu verteilen. Die Eigentumsbereiche von Apps mit räumlichen Daten und Partitionen in derselben Platzierungsgruppe werden räumlich nebeneinander liegen.

Wir empfehlen, dass x \$1 y der gewünschten Anzahl von Mitarbeitern entspricht. Wenn es nicht gleich ist, SimSpace Weaver wird versucht, Ihre Platzierungsgruppen auf die verfügbaren Arbeitskräfte aufzuteilen.

Wenn Sie keine Platzierungsgruppenkonfiguration angeben, SimSpace Weaver wird eine für Sie berechnet.

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

Sie geben einen Namen für eine Reihe von Konfigurationseigenschaften für eine Domäne an. Die Starteinstellung für Apps in einer Domain bestimmt den Typ der Domain:
+ **`launch_apps_via_start_app_call`**— benutzerdefinierte Domain
+ **`launch_apps_by_partitioning_strategy`**— räumliche Domäne
+ **`launch_apps_per_worker`**(nicht in der Beispielanwendung enthalten) — Dienstdomäne

**Wichtig**  
SimSpace Weaver unterstützt bis zu 5 Domänen für jede Simulation. Dies umfasst alle räumlichen, benutzerdefinierten und Dienstdomänen.

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

**Anmerkung**  
SimSpace Weaver App SDK-Projekte der Version 1.12.x verwenden separate Buckets für die ZIP-Dateien der App und das Schema:  
Weber- - -app-zips- *lowercase-project-name* *account-number* *region*
Weber- - -Schemas- *lowercase-project-name* *account-number* *region*

**Topics**
+ [Konfiguration der App](working-with_configuring-simulation_domains_app-config.md)
+ [Konfiguration von räumlichen Domänen](working-with_configuring-simulation_domains_spatial.md)
+ [Netzwerk-Endpunkte](working-with_configuring-simulation_domains_endpoints.md)
+ [Konfiguration von Dienstdomänen](working-with_configuring-simulation_domains_service-domains.md)

# Konfiguration der App
<a name="working-with_configuring-simulation_domains_app-config"></a>

Sie geben die Konfiguration einer App (`app_config`) als Teil der Konfiguration für ihre Domain an. Alle Arten von Domänen verwenden dieselben App-Konfigurationseigenschaften.

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

**Anmerkung**  
SimSpace Weaver App SDK-Projekte der Version 1.12.x verwenden separate Buckets für die ZIP-Dateien der App und das Schema:  
Weber- - -app-zips- *lowercase-project-name* *account-number* *region*
Weber- - -Schemas- *lowercase-project-name* *account-number* *region*

Die `package` Eigenschaft spezifiziert den S3-URI einer Zip-Datei in einem S3-Bucket. Die ZIP-Datei enthält die ausführbare Datei der App (auch als *Binärdatei* bezeichnet) und alle anderen Ressourcen, die sie benötigt (z. B. Bibliotheken). Jede Instanz der ausführbaren App wird in einem Docker Container auf einem Worker ausgeführt. 

Die `launch_command` Eigenschaft gibt den Namen der ausführbaren Datei und alle Befehlszeilenoptionen zum Ausführen der App an. Der Wert von `launch_command` ist ein Array. Jedes Token der gesamten Startbefehlszeichenfolge ist ein Element im Array.

**Beispiel**
+ Für den Startbefehl: `MyTestApp --option1 value1`
+ Geben Sie an: `launch_command: ["MyTestApp", "-option1", "value1"]`

Die `required_resource_units` Eigenschaft gibt die Anzahl der Rechenressourceneinheiten an, die dieser App zugewiesen werden SimSpace Weaver sollen. Eine Rechenressourceneinheit ist eine feste Menge an Verarbeitungskapazität (vCPU) und Arbeitsspeicher (RAM) auf einem Worker. Sie können diesen Wert erhöhen, um die Rechenleistung zu erhöhen, die der App zur Verfügung steht, wenn sie auf einem Worker ausgeführt wird. Jeder Worker verfügt über eine begrenzte Anzahl von Rechenressourceneinheiten. Weitere Informationen finden Sie unter [SimSpace Weaver-Endpunkte und Kontingente](service-quotas.md).

# Konfiguration von räumlichen Domänen
<a name="working-with_configuring-simulation_domains_spatial"></a>

Für räumliche Domänen müssen Sie eine angeben`partitioning_strategy`. Der Wert dieser Eigenschaft ist der Name, den Sie einer Partitionierungsstrategie gegeben haben, die Sie in einem anderen Teil des Schemas definiert haben. 

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

**Anmerkung**  
SimSpace Weaver App SDK-Projekte der Version 1.12.x verwenden separate Buckets für die ZIP-Dateien der App und das Schema:  
Weber- - -app-zips- *lowercase-project-name* *account-number* *region*
Weber- - -Schemas- *lowercase-project-name* *account-number* *region*

Eine Partitionierungsstrategie mit einer `Grid` Topologie (die einzige Topologie, die in dieser Version unterstützt wird) zielt darauf ab, räumliche App-Partitionen dieser Domain in einem Raster SimSpace Weaver anzuordnen. Die `grid_partition` Eigenschaft gibt die Anzahl der Zeilen und Spalten des Partitionsrasters an. 

SimSpace Weaver startet für jede Zelle im Partitionsraster eine Instanz der Spatial-App. Wenn eine räumliche Domäne beispielsweise `grid_partition` Werte hat `x: 2` und `y: 2` es 2\$1 2 = 4 Partitionen in der räumlichen Domäne gibt. SimSpace Weaver startet 4 Instanzen der App, die in der räumlichen Domäne konfiguriert sind, und weist jeder App-Instanz eine Partition zu.

**Topics**
+ [Ressourcenanforderungen für räumliche Domänen](#working-with_configuring-simulation_domains_spatial_resources)
+ [Mehrere räumliche Domänen](#working-with_configuring-simulation_domains_spatial_multiple)
+ [Häufig gestellte Fragen zu räumlichen Domänen](#working-with_configuring-simulation_domains_spatial_faq)
+ [Problembehandlung bei räumlichen Domänen](#working-with_configuring-simulation_domains_spatial_troubleshooting)

## Ressourcenanforderungen für räumliche Domänen
<a name="working-with_configuring-simulation_domains_spatial_resources"></a>

Sie können jedem Mitarbeiter bis zu 17 Rechenressourceneinheiten zuweisen. Sie geben im `app_config` Abschnitt Ihrer räumlichen Domäne die Anzahl der Rechenressourceneinheiten an, die jede Geodaten-App verwendet.

**Example Schemaausschnitt, der die Rechenressourceneinheiten für eine Geodaten-App zeigt**  

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

Um die Anzahl der Rechenressourceneinheiten zu berechnen, die eine Domain benötigt, multiplizieren Sie die Anzahl der Zellen in Ihrem Grid (in Ihrem`grid_partition`, `x` \$1`y`) mit der Anzahl der Rechenressourceneinheiten, die den Geo-Apps zugewiesen sind.

Für das vorherige Beispiel `MySpatialDomain` gibt die Domäne Folgendes an:
+ `x`: `2`
+ `y`: `2`
+ `compute`: `1`

Das Raster für `MySpatialDomain` hat 2 \$1 2 = 4 Zellen. Die räumliche Domäne benötigt 4 \$1 1 = 4 Rechenressourceneinheiten.

Die Gesamtzahl der Rechenressourceneinheiten für alle in Ihrem Schema angegebenen Domänen muss kleiner oder gleich der `desired` Anzahl der Worker multipliziert mit der maximalen Anzahl von Rechenressourceneinheiten für jeden Worker (17) sein.

## Mehrere räumliche Domänen
<a name="working-with_configuring-simulation_domains_spatial_multiple"></a>

Sie können Ihre Simulation so konfigurieren, dass mehr als eine räumliche Domäne verwendet wird. Sie können beispielsweise einen räumlichen Bereich verwenden, um die Hauptakteure einer Simulation (z. B. Menschen und Autos) zu steuern, und einen anderen räumlichen Bereich, um die Umgebung zu kontrollieren.

Sie können auch mehrere räumliche Domänen verwenden, um verschiedenen Teilen Ihrer Simulation unterschiedliche Ressourcen zuzuweisen. Wenn Ihre Simulation beispielsweise einen Entitätstyp hat, der zehnmal mehr Entitätsinstanzen als ein anderer Typ hat, können Sie verschiedene Domänen erstellen, um jeden Entitätstyp zu behandeln, und der Domäne mit mehr Entitäten mehr Ressourcen zuweisen.

**Wichtig**  
SimSpace Weaver Versionen vor 1.14.0 unterstützen nicht mehrere räumliche Domänen.

**Wichtig**  
AWS SimSpace Weaver Localunterstützt derzeit nicht mehrere räumliche Domänen. Mehr über SimSpace Weaver Local erfahren Sie unter [Lokale Entwicklung in SimSpace Weaver](working-with_local-development.md).

**Wichtig**  
SimSpace Weaver unterstützt bis zu 5 Domänen für jede Simulation. Dies umfasst alle räumlichen, benutzerdefinierten und Dienstdomänen.

### Konfigurieren Sie mehrere räumliche Domänen
<a name="working-with_configuring-simulation_domains_spatial_multiple_configure"></a>

Um mehr als eine räumliche Domäne zu konfigurieren, fügen Sie die anderen räumlichen Domänendefinitionen als separate benannte Abschnitte in Ihrem Schema hinzu. Jede Domäne muss den `launch_apps_by_partitioning_strategy` Schlüssel angeben. Sehen Sie sich das folgende Beispielschema an.

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

### Räumliche Domänen zusammenfügen
<a name="working-with_configuring-simulation_domains_spatial_multiple_placement"></a>

In einigen Szenarien möchten Sie möglicherweise Partitionen für eine räumliche Domäne auf Workern neben Partitionen aus einer anderen Domäne platzieren. Dies kann die Leistungsmerkmale verbessern, wenn diese Partitionen domänenübergreifende Abonnements für einander erstellen.

Fügen Sie Ihrem Schema den Schlüssel `placement_constraints` der obersten Ebene hinzu, um anzugeben, welche Domänen zusammen platziert SimSpace Weaver werden sollen. Der erforderliche `on_workers` Schlüssel muss sich auf eine benannte `workers` Konfiguration im Schema beziehen.

**Example Schemaausschnitt, der zusammengesetzte räumliche Domänen zeigt**  

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

**Wichtig**  
Wenn Sie Platzierungsgruppen verwenden:  
Stellen Sie sicher, dass x \$1 y ein Vielfaches der Anzahl der Mitarbeiter ist.
Stellen Sie sicher, dass die Werte der Platzierungsgruppen gemeinsame Teiler für die Rastermaße der Domänen sind, die Sie zusammen platzieren.
Wenn Sie **keine Platzierungsgruppen verwenden**:  
Stellen Sie sicher, dass eine Achse Ihrer räumlichen Domänengitter einen gemeinsamen Teiler hat, der der Anzahl der Arbeiter entspricht.
Weitere Informationen zu Platzierungsgruppen finden Sie unter. [Partitionierungsstrategien](working-with_configuring-simulation_partitioning-strategies.md#working-with_configuring-simulation_partitioning-strategies_placement-groups)

## Häufig gestellte Fragen zu räumlichen Domänen
<a name="working-with_configuring-simulation_domains_spatial_faq"></a>

### F1. Wie kann ich einer vorhandenen Simulation eine weitere räumliche Domäne hinzufügen?
<a name="working-with_configuring-simulation_domains_spatial_faq_q1"></a>
+ **Für eine laufende Simulation** — Sie können die Konfiguration für eine laufende Simulation nicht ändern. Ändern Sie die Domänenkonfiguration im Schema, laden Sie das Schema und die App-Zip-Dateien hoch und starten Sie eine neue Simulation.
+ **Für eine neue Simulation** — Fügen Sie die Domänenkonfiguration zum Schema hinzu, laden Sie das Schema und die App-Zip-Dateien hoch und starten Sie die neue Simulation.

## Problembehandlung bei räumlichen Domänen
<a name="working-with_configuring-simulation_domains_spatial_troubleshooting"></a>

Möglicherweise wird der folgende Fehler angezeigt, wenn Sie versuchen, Ihre Simulation zu starten, Ihre Domänenkonfiguration jedoch ungültig ist.

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

**Mögliche Ursachen**
+ Das Schema weist Apps mehr Rechenressourceneinheiten zu, als Workern zur Verfügung stehen.
+ SimSpace Weaver kann keine Vereinbarung treffen, um Domänen auf Workern zusammen zu platzieren. Dies ist der Fall, wenn Sie mehrere räumliche Domänen angeben, es aber keinen gemeinsamen Teiler oder kein Vielfaches zwischen den Domänenrastern gibt (z. B. zwischen einem 2x4-Raster und einem 3x5-Raster).

# Netzwerk-Endpunkte
<a name="working-with_configuring-simulation_domains_endpoints"></a>

Benutzerdefinierte Apps und Service-Apps können Netzwerkendpunkte haben, mit denen externe Clients eine Verbindung herstellen können. Sie geben eine Liste von Portnummern als Wert für `ingress_ports` in an`endpoint_config`. Bei diesen Portnummern handelt es sich sowohl um TCP als auch um UDP. Die benutzerdefinierte App oder die Service-App sollte sich an die Portnummern binden, die Sie in angeben`ingress_ports`. SimSpace Weaver weist zur Laufzeit dynamisch Portnummern zu und ordnet diese Ports den dynamischen Ports zu. Sie können die **describe-app** API aufrufen, nachdem Ihre Apps begonnen haben, die dynamischen (tatsächlichen) Portnummern zu finden. Weitere Informationen finden Sie [Rufen Sie die IP-Adresse und die Portnummer einer benutzerdefinierten App abHolen Sie sich die IP-Adresse und die Portnummer](working-with_get-ip.md) im Schnellstart-Tutorial.

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

**Anmerkung**  
SimSpace Weaver App SDK-Projekte der Version 1.12.x verwenden separate Buckets für die .zip-Dateien der App und das Schema:  
Weber- - -app-zips- *lowercase-project-name* *account-number* *region*
Weber- - -Schemas- *lowercase-project-name* *account-number* *region*

**Anmerkung**  
`endpoint_config`ist eine optionale Eigenschaft für benutzerdefinierte Apps und Service-Apps. Wenn Sie keinen angeben, hat die App keinen Netzwerkendpunkt. `endpoint_config`

# Konfiguration von Dienstdomänen
<a name="working-with_configuring-simulation_domains_service-domains"></a>

Das Vorhandensein von `launch_apps_per_worker:` in einer Domänenkonfiguration weist darauf hin, dass es sich um eine Dienstdomäne mit Service-Apps handelt. SimSpace Weaver startet und stoppt Service-Apps für Sie. Beim SimSpace Weaver Starten und Beenden einer App wird davon ausgegangen, dass die App über einen *verwalteten Lebenszyklus verfügt*. SimSpace Weaver unterstützt derzeit das Starten von 1 oder 2 Service-Apps für jeden einzelnen Mitarbeiter. 

**Example Beispiel für eine Domain, die so konfiguriert ist, dass sie auf jedem Worker 1 Service-App startet**  

```
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 Beispiel für eine Domain, die so konfiguriert ist, dass sie 2 Service-Apps auf jedem Worker startet**  

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

# Maximale Dauer einer Simulation
<a name="working-with_max-duration"></a>

Jede Simulation in AWS SimSpace Weaver hat eine Einstellung für die *maximale Dauer*, die angibt, wie lange die Simulation maximal ausgeführt werden kann. Sie geben die maximale Dauer als Parameter an, wenn Sie eine Simulation starten. Die [`StartSimulation`Anwendungsprogrammierschnittstelle (API)](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html) hat einen optionalen Parameter`MaximumDuration`. Der Wert des Parameters ist eine Anzahl von Minuten (m oder M), Stunden (h oder H) oder Tagen (d oder D). Zum Beispiel `1H` bedeutet `1h` oder 1 Stunde. SimSpace Weaver stoppt Ihre Simulation, wenn sie dieses Limit erreicht.

## Maximaler Wert
<a name="working-with_max-duration_max-value"></a>

Der höchste gültige Wert für `MaximumDuration` ist `14D` oder sein Äquivalent in Stunden (`336H`) oder Minuten (`20160M`).

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

Der Parameter `MaximumDuration` ist optional. Wenn Sie keinen Wert angeben, wird ein Wert von SimSpace Weaver verwendet`14D`.

## Mindestwert
<a name="working-wtih_max-duration_min-value"></a>

Der niedrigste gültige Wert für `MaximumDuration` ist ein Wert, der numerisch entspricht`0`. Beispielsweise sind die Werte`0M`, und `0H``0D`, alle numerisch äquivalent zu. `0`

Wenn Sie den Mindestwert für die maximale Dauer angeben, geht Ihre Simulation sofort in den `STOPPING` Status über, sobald sie den `STARTED` Status erreicht.

## Starten einer Simulation mit der Konsole
<a name="working-with_max-duration_console"></a>

Sie können einen Wert für die **maximale Dauer** angeben, wenn Sie eine Simulation in der [SimSpace Weaver Konsole](https://console.aws.amazon.com/simspaceweaver) starten. Geben Sie den Wert in das Feld **Maximale Dauer** des Formulars **Simulationseinstellungen** ein, wenn Sie **Simulation starten** wählen.

**Wichtig**  
Wenn Sie keinen Wert für **Maximale Dauer** angeben, SimSpace Weaver wird der [Standardwert](#working-with_max-duration_default-value) (`14D`) verwendet.

## Der Status einer Simulation, die ihre maximale Dauer erreicht
<a name="working-with_max-duration_sim-state"></a>

Wenn eine Simulation, die ihre maximale Dauer erreicht hat, SimSpace Weaver automatisch beendet wird, lautet der **Status** der Simulation `STOPPING` (falls in Bearbeitung) oder`STOPPED`. In der [SimSpace Weaver Konsole](https://console.aws.amazon.com/simspaceweaver) wird der **Zielstatus** der Simulation immer noch angezeigt`STARTED`, da dies der letzte von einem Benutzer angeforderte Status war.

# Apps entwickeln
<a name="working-with_developing-apps"></a>

SimSpace Weaver Entwicklung erfordert eine Amazon Linux 2 (AL2) Umgebung zum Erstellen von Apps, auf der Ihre Simulationen ausgeführt werden Amazon Linux in der AWS Cloud. Wenn du verwendest Windows, können Sie Skripts im SimSpace Weaver App-SDK verwenden, um eine zu erstellen und zu starten Docker Container, der läuft AL2 mit den Abhängigkeiten, die Sie zum Erstellen von SimSpace Weaver Apps benötigen. Sie können auch eine starten AL2 Umgebung unter Verwendung Windows Subsystem for Linux (WSL), oder verwende ein natives AL2 System. Weitere Informationen finden Sie unter [Richten Sie Ihre lokale Umgebung ein für SimSpace Weaver](setting-up_local.md).

**Anmerkung**  
Unabhängig davon, wie Sie Ihre lokale Entwicklungsumgebung konfigurieren, laufen Ihre Apps in Docker Container, wenn Sie sie hochladen, um sie in der auszuführen AWS Cloud. **Ihre Apps haben keinen direkten Zugriff auf das Host-Betriebssystem**.

**Allgemeiner Ablauf einer SimSpace Weaver App**

1. Erstellen Sie eine -Anwendung.

1. Schleife:

   1. Beginnen Sie das Update, indem Sie eine erstellen`Transaction`.

      1. Beenden Sie die Schleife, wenn die Simulation beendet wird.

   1. Verarbeiten Sie Ereignisse im Zusammenhang mit Abonnements und Eigentümerschaften.

   1. Aktualisieren Sie die Simulation.

   1. Bestätigen Sie die`Transaction`, um das Update zu beenden.

1. Zerstören Sie die Anwendung.

## Räumliche Apps
<a name="working-with_developing-apps_spatial-apps"></a>

Jede Geo-App hat einen Eigentumsbereich, der eine räumliche Region der Simulationswelt darstellt. Entitäten, die sich im Besitzbereich einer Geo-App befinden, werden in der der App zugewiesenen Partition gespeichert. Die einzelne Spatial-App besitzt die volle Eigentümerschaft (Lese- und Schreibberechtigungen) für alle Entitäten innerhalb der ihr zugewiesenen Partition. Keine anderen Apps können in diese Entitäten schreiben. Die Spatial-App verbessert den Status ihrer Entitäten. Jede Geo-App besitzt nur eine Partition. SimSpace Weaver verwendet den räumlichen Standort einer Entität, um sie zu indizieren und einer räumlichen App-Partition zuzuweisen.

Das SimSpace Weaver App-SDK stellt eine Beispielanwendung bereit. Sie finden den Quellcode für die Spatial-App der Beispielanwendung im folgenden Ordner (verwenden Sie das richtige Pfadtrennzeichen für Ihr Betriebssystem): 

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

## Benutzerdefinierte Apps
<a name="working-with_developing-apps_custom-apps"></a>

Sie erstellen und verwenden benutzerdefinierte Apps, um mit der Simulation zu interagieren. 

**Benutzerdefinierte Apps können**
+ Entitäten erstellen
+ Abonnieren Sie andere Partitionen
+ Änderungen übernehmen

**Allgemeiner Ablauf einer benutzerdefinierten App**

1. Erstellen Sie eine -Anwendung.

1. Abonnieren Sie eine bestimmte Region in der Simulation:

   1. Erstellen Sie eine`Transaction`, um mit dem ersten Update zu beginnen.

   1. Erstellen Sie ein Abonnement für die spezifische Region.

   1. Bestätigen Sie die`Transaction`, um das erste Update zu beenden.

1. Schleife:

   1. Erstellen Sie eine`Transaction`, um mit dem Update zu beginnen.

      1. Beenden Sie die Schleife, wenn die Simulation beendet wird.

   1. Änderungen des Prozessstatus.

   1. Bestätigen Sie die`Transaction`, um das Update zu beenden.

1. Zerstören Sie die Anwendung.

Nachdem eine benutzerdefinierte App eine Entität erstellt hat, muss sie die Entität in eine räumliche Domäne übertragen, damit die Entität räumlich innerhalb der Simulation existiert. SimSpace Weaver verwendet die räumliche Position der Entität, um die Entität in der entsprechenden räumlichen App-Partition zu platzieren. Die benutzerdefinierte App, mit der die Entität erstellt wurde, kann die Entität nicht aktualisieren oder löschen, nachdem sie in eine räumliche Domäne übertragen wurde. 

Das SimSpace Weaver App-SDK stellt eine Beispielanwendung bereit. Sie können die in der Beispielanwendung enthaltenen benutzerdefinierten Apps als Modelle für Ihre eigenen benutzerdefinierten Apps verwenden. Sie finden den Quellcode für die View-App (eine benutzerdefinierte App) der Beispielanwendung im folgenden Ordner (verwenden Sie das richtige Pfadtrennzeichen für Ihr Betriebssystem):

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

# Entwicklung von Kundenanwendungen
<a name="working-with_developing-client-applications"></a>

Zu den Gründen, aus denen Sie einen Client mit einer Simulation verbinden möchten, gehören:
+ Integrieren Sie Verkehrsinformationen in Echtzeit in eine Simulation im Stadtmaßstab.
+ Erstellen Sie *human-in-the-loop*Simulationen, bei denen ein menschlicher Bediener einen Teil der Simulation kontrolliert.
+ Ermöglichen Sie Benutzern die Interaktion mit der Simulation, z. B. bei einer Trainingssimulation.

Die benutzerdefinierten Apps in diesen Beispielen dienen als Schnittstelle zwischen dem Simulationsstatus und der Außenwelt. Die Clients stellen eine Verbindung zu den benutzerdefinierten Apps her, um mit der Simulation zu interagieren. 

SimSpace Weaver kümmert sich nicht um die Client-Anwendungen und deren Kommunikation mit Ihren benutzerdefinierten Apps. Sie sind verantwortlich für das Design, die Erstellung, den Betrieb und die Sicherheit Ihrer Client-Anwendungen und deren Kommunikation mit Ihren benutzerdefinierten Apps. SimSpace Weaver gibt nur eine IP-Adresse und eine Portnummer für jede Ihrer benutzerdefinierten Apps bekannt, sodass Clients eine Verbindung zu ihnen herstellen können. 

Das SimSpace Weaver App-SDK stellt Clients für seine Beispielanwendung bereit. Sie können diese Clients als Modelle für Ihre eigenen Client-Anwendungen verwenden. Sie finden den Quellcode für die Beispielanwendungsclients im folgenden Ordner: 

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

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

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

**Wichtig**  
Wir stellen Ihnen diese Anweisungen der Einfachheit halber zur Verfügung. Sie sind zur Verwendung mit Windows Subsystem for Linux (WSL), und werden nicht unterstützt. Weitere Informationen finden Sie unter [Richten Sie Ihre lokale Umgebung ein für SimSpace Weaver](setting-up_local.md).

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

------

Weitere Informationen zum Erstellen und Verwenden der Beispielanwendungsclients finden Sie in [Erste Schritte mit SimSpace Weaver](getting-started.md) den Tutorials unter. 

# Rufen Sie die IP-Adresse und die Portnummer einer benutzerdefinierten App ab
<a name="working-with_get-ip"></a>

Um Ihre Simulation anzusehen, erstellen Sie eine benutzerdefinierte App und stellen mit einem Client eine Verbindung zu ihr her. Weitere Informationen finden Sie in den Tutorials unter[Erste Schritte mit SimSpace Weaver](getting-started.md). Sie können das folgende Verfahren verwenden, um die IP-Adresse und Portnummer Ihrer benutzerdefinierten App abzurufen. Verwenden Sie das entsprechende Pfadtrennzeichen für Ihr Betriebssystem (z. B. `\` unter Windows und `/` unter Linux).

**Um Ihre IP-Adresse und Portnummer zu erhalten**

1. Verwenden Sie die ** ListSimulations**API, um den Namen Ihrer Simulation abzurufen.

   ```
   aws simspaceweaver list-simulations
   ```

   Beispielausgabe:

   ```
   {
       "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. Verwenden Sie die ** DescribeSimulation**API, um eine Liste der Domänen in Ihrer Simulation abzurufen.

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

   Suchen Sie im `Domains` `LiveSimulationState` Abschnitt der Ausgabe nach dem Abschnitt.

   Beispielausgabe:

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

1. Verwenden Sie die ** ListApps**API, um eine Liste der benutzerdefinierten Apps in einer Domain abzurufen. Der Domainname für die View-App (benutzerdefiniert) im Beispielprojekt lautet beispielsweise`MyViewDomain`. Suchen Sie in der Ausgabe nach dem Namen der App.

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

   Beispielausgabe:

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

1. Verwenden Sie die ** DescribeApp**API, um die IP-Adresse und die Portnummer abzurufen. Für das Beispielprojekt lautet der Domainname `MyViewDomain` und der App-Name`ViewApp`. 

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

   Die IP-Adresse und die Portnummer befinden sich im `EndpointInfo` Block in der Ausgabe. Die IP-Adresse ist der Wert von `Address` und die Portnummer ist der Wert von`Actual`.

   Beispielausgabe:

   ```
   {
       "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"
   }
   ```
**Anmerkung**  
Der Wert von `Declared` ist die Portnummer, an die Ihr App-Code gebunden werden soll. Der Wert von `Actual` ist die Portnummer, über SimSpace Weaver die Clients eine Verbindung zu Ihrer App herstellen können. SimSpace Weaver ordnet den `Declared` Port dem Port zu. `Actual`

# Den Unreal Engine View Client starten
<a name="working-with_unreal-client"></a>

 Navigiere zu: 

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

1. Führen Sie einen der folgenden Befehle aus:
   + Docker: `python quick-start.py`
   + WSL: `python quick-start.py --al2`

1. Ermitteln Sie die IP-Adresse und die „tatsächliche“ Portnummer. Diese befinden sich in der Konsolenausgabe, wenn Sie quick-start.py ausführen, oder rufen Sie sie ab, indem Sie den Anweisungen unter folgen[Rufen Sie die IP-Adresse und die Portnummer einer benutzerdefinierten App abHolen Sie sich die IP-Adresse und die Portnummer](working-with_get-ip.md).

1.  Navigieren Sie zu: 

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

1.  Führen Sie die folgenden Befehle aus, um die NNG-Bibliothek zu erstellen: 

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

1.  Öffnen `view_app_url.txt` Sie in einem **Texteditor**. 

1.  Aktualisieren Sie die URL mit der IP-Adresse und der Portnummer für Ihre View-App: `tcp://ip-address:actual-port-number` (sie sollte so aussehen`tcp://198.51.100.135:1234`). 

1.  Wählen Sie im **Unreal Editor** die Option **Abspielen**. 

## Fehlerbehebung
<a name="working-with_unreal-client_troubleshooting"></a>
+  **Der CMake NNG-Installationsschritt schlägt mit der Meldung „Möglicherweise benötige ich Administratorrechte“ fehl:** 

  ```
  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)
  ```
  +  **Lösung:** Falls `nng.lib` er im Verzeichnis UnrealClient /lib `nng.so` existiert, kann dieser Fehler getrost ignoriert werden. Falls nicht, versuchen Sie, die Befehle cmake build in einem Terminal mit Administratorrechten auszuführen. 
+  **„CMake um eine von nng bereitgestellte Paketkonfigurationsdatei zu finden“:** 

  ```
  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.
  ```
  +  **Lösung:** CMake hat Probleme, die `Findnng.cmake` Datei zu finden. Wenn Sie mit bauen CMake, fügen Sie das Argument hinzu`-DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty`. Stellen Sie sicher, dass sich die `Findnng.cmake` Datei noch im `ThirdParty` Verzeichnis befindet, bevor Sie den CMake Build erneut ausführen. 

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

# Lokale Entwicklung in SimSpace Weaver
<a name="working-with_local-development"></a>

Sie können Ihre SimSpace Weaver Anwendungen lokal bereitstellen, um sie schnell zu testen und zu debuggen.

**Voraussetzungen**
+ Führen Sie die Schritte unter [Einrichtung für SimSpace Weaver](setting-up.md) aus.

**Topics**
+ [Schritt 1: Starten Sie Ihre lokale Simulation](working-with_local_launch.md)
+ [Schritt 2: Sehen Sie sich Ihre lokale Simulation an](working-with_local-development_view.md)
+ [Schritt 3: Beenden Sie Ihre lokale Simulation (optional unter Windows)](working-with_local-development_stop-sim.md)
+ [Problembehebung bei der lokalen Entwicklung in SimSpace Weaver](working-with_local-development_troubleshooting.md)

# Schritt 1: Starten Sie Ihre lokale Simulation
<a name="working-with_local_launch"></a>

1. Navigieren Sie zu

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

1. Führen Sie den folgenden Befehl aus, um Ihre Simulation lokal zu erstellen und zu starten.

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

   Dieses Skript führt Folgendes aus:

   1. Erstellen Sie das Projekt.
      +  `quick-start.py`ruft die in build.py definierte `build_project` Funktion auf. Dieser Schritt variiert je nach Projekt. Für das PathfindingSample, CMake wird verwendet. Den CMake und Docker-Befehl finden Sie in der Datei build.py. 

   1. Starten Sie Ihre lokale Simulation
      + Das Skript startet einen lokalen Prozess für jede im Schema definierte räumliche Partition.
      + Das Skript startet einen Prozess für jede im Schema definierte benutzerdefinierte App.
      + Die räumlichen Apps werden zuerst gestartet, gefolgt von den benutzerdefinierten Apps — jeweils in der Reihenfolge, in der sie im Schema erscheinen.

**Wichtig**  
Verwenden Sie beim Starten in einer Umgebung, die keine grafische Benutzeroberfläche unterstützt, z. B. in einer SSH-Sitzung auf der Konsole, die `--noappwindow` Option, um die gesamte Ausgabe an das aktuelle Terminal umzuleiten.

**Wichtig**  
Für Linux-Benutzer geht das Skript davon aus, dass Ihr System über den `xterm` Befehl verfügt. Wenn Ihre Linux-Distribution den `xterm` Befehl nicht hat, verwenden Sie die `--noappwindow` Option, um die gesamte Ausgabe an das aktuelle Terminal umzuleiten.
+  -h, --help 
  +  Führen Sie diese Parameter auf. 
+  --sauber 
  +  Löscht den Inhalt des Build-Verzeichnisses vor dem Erstellen. 
+  --nobuild 
  +  Überspringe den Neuaufbau des Projekts. 
+  -- kein App-Fenster 
  +  Öffne nicht für jede App ein neues Fenster. Leite stattdessen den Stdout zum aktuellen Terminal um. 
+  --logdatei 
  +  Schreibt die Konsolenausgabe in eine Protokolldatei. 
+  --consoleclient 
  +  Stellt automatisch eine Verbindung zum in der Konfiguration aufgelisteten Konsolen-Client her. 
+  --schema SCHEMA
  + Welches Schema dieser Aufruf verwenden wird. Standardmäßig ist 'SCHEMA' in config.py. 

# Schritt 2: Sehen Sie sich Ihre lokale Simulation an
<a name="working-with_local-development_view"></a>

Um Ihre lokale Simulation anzusehen, können Sie jeden der Clients verwenden, die im Lieferumfang von enthalten sind SimSpaceWeaverAppSdkDistributable. Weitere Informationen zum Erstellen und Verwenden der Beispielclients finden Sie in den Tutorials unter[Erste Schritte mit SimSpace Weaver](getting-started.md).

Sie müssen die IP-Adresse und die Portnummer im Client aktualisieren, um eine Verbindung zur View-App für Ihre lokale Simulation herzustellen. Verwenden Sie immer die folgenden Werte mit SimSpace Weaver Local:

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

Je nachdem, welchen Client Sie auswählen, können Sie die IP-Adresse und die Portnummer wie folgt aktualisieren:
+ **Unreal** — Ändern Sie die URL in Zeile 1 von `view_app_url.txt`
+ **Konsole** — Starten Sie den Client mit der IP-Adresse und der Portnummer (URL) als Parameter

# Schritt 3: Beenden Sie Ihre lokale Simulation (optional unter Windows)
<a name="working-with_local-development_stop-sim"></a>

**Anmerkung**  
Dieser Schritt ist unter Linux erforderlich, unter Windows jedoch optional.

1.  Navigiere zu: 

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

1.  Führen Sie den folgenden Befehl aus, um Ihre lokale Simulation zu beenden und alle gemeinsam genutzten Speicherressourcen zu löschen. 

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

    Dieses Skript führt Folgendes aus: 
   +  Stoppen Sie die lokalen Prozesse. 
   +  Löschen Sie das gemeinsam genutzte Speicherobjekt (nur unter Linux erforderlich). 

**stop-and-delete.py-Parameter**
+  -h, --help 
  +  Führen Sie diese Parameter auf. 
+  --stop 
  +  Versuche nur, die Prozesse zu stoppen. 
+  --löschen 
  +  Versuchen Sie nur, die gemeinsam genutzten Speicherressourcen zu löschen. 
+  --process 
  +  Der Name des Prozesses, der gestoppt werden soll. Verwenden Sie diesen Wert, wenn Ihr Prozessname nicht mit dem Paketnamen im Schema übereinstimmt. 
+  --schema SCHEMA 
  +  Welches Schema dieser Aufruf verwenden wird. Standardmäßig ist der Wert 'SCHEMA' in config.py. 

# Problembehebung bei der lokalen Entwicklung in SimSpace Weaver
<a name="working-with_local-development_troubleshooting"></a>
+  **Linux: Xterm-Befehl nicht gefunden/kann nicht geöffnet werden** 
  + Die lokalen Skripts gehen davon aus, dass der Befehl xterm existiert, wenn er unter Linux ausgeführt wird. Wenn Sie nicht über den Befehl xterm verfügen oder in einer Umgebung arbeiten, die die grafische Benutzeroberfläche nicht unterstützt, verwenden Sie die `--noappwindow` Option, wenn Sie das Schnellstartskript ausführen.
+  **Es werden keine App-Fenster geöffnet\$1** 
  +  Dies passiert, wenn die lokale Simulation sofort abstürzt. Um die Konsolenausgabe nach dem Absturz zu sehen, verwenden Sie beim Ausführen des Schnellstart-Skripts die `--logfile` Optionen `--noappwindow` oder. 
+  **Die Simulation tickt nicht mehr, nachdem die View-App gestartet oder der View-Client eine Verbindung hergestellt hat\$1** 
  +  Wenn Sie diese `—noappwindow` Option verwenden, werden diese Probleme in der Regel behoben. Andernfalls ist ein mehrmaliger Neustart ebenfalls erfolgreich (wenn auch mit einer viel geringeren Geschwindigkeit). 

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

Das SimSpace Weaver App-SDK bietet APIs die Möglichkeit, die Entitäten in Ihrer Simulation zu steuern und auf SimSpace Weaver Ereignisse zu reagieren. Es umfasst den folgenden Namespace: 
+ **API** — Kerndefinitionen der API und ihrer Verwendung

Link zur folgenden Bibliothek:
+ `libweaver_app_sdk_cxx_v1_full.so`

**Wichtig**  
Die Bibliothek ist für dynamisches Verknüpfen verfügbar, wenn Sie Ihre Apps in der ausführen AWS Cloud. Sie müssen es nicht zusammen mit Ihren Apps hochladen.

**Anmerkung**  
Das SimSpace Weaver App-SDK APIs steuert die Daten in Ihrer Simulation. Diese APIs sind unabhängig vom SimSpace Weaver Dienst APIs, der Ihre SimSpace Weaver Serviceressourcen (wie Simulationen, Apps und Uhren) steuert. AWS Weitere Informationen finden Sie unter [SimSpace Weaver API-Referenzen](api-reference.md).

**Topics**
+ [API-Methoden geben a zurück Result](working-with_app-sdk_return-result.md)
+ [Interaktion mit dem App-SDK auf oberster Ebene](working-with_app-sdk_top-level.md)
+ [Verwaltung der Simulation](working-with_app-sdk_sim.md)
+ [Subscriptions (Abonnements)](working-with_app-sdk_sub.md)
+ [Entitäten](working-with_app-sdk_ent.md)
+ [Ereignisse der Entität](working-with_app-sdk_events.md)
+ [Result und Fehlerbehandlung](working-with_app-sdk_result.md)
+ [Generika und Domaintypen](working-with_app-sdk_generics.md)
+ [Verschiedene App-SDK-Operationen](working-with_app-sdk_misc.md)

# API-Methoden geben a zurück Result
<a name="working-with_app-sdk_return-result"></a>

Die meisten SimSpace Weaver API-Funktionen haben einen Rückgabetyp`Aws::WeaverRuntime::Result<T>`. Wenn die Funktion erfolgreich ausgeführt wurde, `Result` enthält der`T`. Andernfalls `Result` enthält der einen`Aws::WeaverRuntime::ErrorCode`, der einen Fehlercode aus dem Rust App SDK.

**Example Beispiel**  

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

Diese Methode:
+ Gibt zurück`Transaction`, wenn die `BeginUpdate()` Ausführung erfolgreich war.
+ Gibt zurück, `Aws::WeaverRuntime::ErrorCode` wenn ein `BeginUpdate()` Fehler auftritt.

# Interaktion mit dem App-SDK auf oberster Ebene
<a name="working-with_app-sdk_top-level"></a>

**Lebenszyklus**
+ Das SimSpace Weaver App-SDK verwaltet den App-Lebenszyklus. Sie müssen den Lebenszyklusstatus einer App nicht lesen oder schreiben.

**Partitionen**
+ Wird verwendet`Result <PartitionSet> AssignedPartitions(Transaction& txn);`, um eigene Partitionen abzurufen.
+ Wird verwendet`Result <PartitionSet> AllPartitions(Transaction& txn);`, um alle Partitionen in der Simulation abzurufen.

# Verwaltung der Simulation
<a name="working-with_app-sdk_sim"></a>

In diesem Abschnitt werden Lösungen für häufig auftretende Aufgaben des Simulationsmanagements beschrieben.

**Topics**
+ [Starten Sie eine Simulation](working-with_app-sdk_sim_start.md)
+ [Aktualisieren Sie eine Simulation](working-with_app-sdk_sim_update.md)
+ [Beendet eine Simulation](working-with_app-sdk_sim_terminate.md)

# Starten Sie eine Simulation
<a name="working-with_app-sdk_sim_start"></a>

Verwenden Sie`CreateApplication()`, um eine App zu erstellen.

**Example Beispiel**  

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

# Aktualisieren Sie eine Simulation
<a name="working-with_app-sdk_sim_update"></a>

Verwenden Sie die folgenden `BeginUpdate` Funktionen, um die App zu aktualisieren:
+ `Result<Transaction> BeginUpdate(Application& app)`
+ `Result<bool> BeginUpdateWillBlock(Application& app)`— sagt dir, ob blockiert `BeginUpdate()` wird oder nicht.

Wird verwendet`Result<void> Commit(Transaction& txn)`, um die Änderungen zu übernehmen.

**Example Beispiel**  

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

# Beendet eine Simulation
<a name="working-with_app-sdk_sim_terminate"></a>

Wird verwendet`Result<void> DestroyApplication(Application&& app)`, um die App und die Simulation zu beenden.

Andere Apps stellen fest, dass die Simulation beendet wird, wenn sie `ErrorCode::ShuttingDown` von ihren Anrufen an `BeginUpdateWillBlock()` oder `BeginUpdate()` empfangen. Wenn eine App empfängt`ErrorCode::ShuttingDown`, kann sie anrufen, um sich selbst `Result<void> DestroyApplication(Application&& app)` zu beenden.

**Example Beispiel**  

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

**Wichtig**  
Rufen Sie erst `Result<void> DestroyApplication(Application&& app)` danach an`Api::Commit()`. Das Zerstören einer Anwendung während eines Updates kann zu undefiniertem Verhalten führen.

**Wichtig**  
Sie müssen `DestroyApplication()` vor dem Beenden des Programms anrufen, um sicherzustellen, dass die Anwendung als erfolgreich beendet gemeldet wird.  
`DestroyApplication()`Wenn Sie beim Beenden des Programms nicht aufrufen, wird der Status als betrachtet. `FATAL`

# Subscriptions (Abonnements)
<a name="working-with_app-sdk_sub"></a>

Sie erstellen ein Abonnement mit einem Abonnementbereich und einer Domain-ID. Die Domain-ID steht für die Domain, der dieser Abonnementbereich gehört. A `BoundingBox2F32` beschreibt den Abonnementbereich. Verwenden Sie die folgende Funktion, um ein Abonnement zu erstellen:

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

**Example Beispiel**  

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

Sie können das `Api::SubscriptionHandle` zurückgegebene von verwenden`CreateSubscriptionBoundingBox2F32()`, um das Abonnement zu ändern. Sie übergeben es als Argument an die folgenden Funktionen:

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

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

# Entitäten
<a name="working-with_app-sdk_ent"></a>

Wenn eine Entität den Abonnementbereich `Api:Entity` der App betritt`CreateEntity()`, rufen Sie das Ereignis auf `Store` und `Load` APIs verwenden dabei das Ereignis, das von einem Eigentümerwechsel `Result<Api::Entity>` zurückgegeben wurde (weitere Informationen finden Sie unter[Ereignisse der Entität](working-with_app-sdk_events.md)). Wir empfehlen, dass Sie Ihre `Api::Entity` Objekte nachverfolgen, damit Sie sie zusammen mit ihnen verwenden können APIs.

**Topics**
+ [Entitäten erstellen](working-with_app-sdk_ent_create.md)
+ [Eine Entität in eine räumliche Domäne übertragen](working-with_app-sdk_ent_transfer.md)
+ [Daten aus Entitätsfeldern schreiben und lesen](working-with_app-sdk_ent_readwrite.md)
+ [Speichert die Position einer Entität](working-with_app-sdk_ent_store-position.md)
+ [Lädt die Position einer Entität](working-with_app-sdk_ent_load-position.md)

# Entitäten erstellen
<a name="working-with_app-sdk_ent_create"></a>

Wird verwendet`CreateEntity()`, um eine Entität zu erstellen. Sie definieren die Bedeutung dessen`Api::TypeId`, was Sie an diese Funktion übergeben.

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

**Anmerkung**  
Die Werte 0-511 für `Api::BuiltinTypeId` sind reserviert. Ihre Entität TypeID (`k_entityTypeId`in diesem Beispiel) muss einen Wert von 512 oder höher haben.

# Eine Entität in eine räumliche Domäne übertragen
<a name="working-with_app-sdk_ent_transfer"></a>

Nachdem eine benutzerdefinierte App oder Service-App eine Entität erstellt hat, muss die App die Entität in eine räumliche Domäne übertragen, damit die Entität räumlich in der Simulation existiert. Entitäten in einer räumlichen Domäne können von anderen Apps gelesen und von einer räumlichen App aktualisiert werden. Verwenden Sie die `ModifyEntityDomain()` API, um eine Entität in eine räumliche Domäne zu übertragen.

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

Wenn das `DomainId` nicht mit dem der aufrufenden App zugewiesenen `Partition` übereinstimmt, `DomainId` muss das für a sein `DomainType::Spatial``Domain`. Die Eigentumsübertragung auf die neue Version `Domain` erfolgt während der`Commit(Transaction&&)`.Parameter

`txn`  
Das aktuelle`Transaction`.

`entity`  
Das Ziel `Entity` für die Änderung von`Domain`.

`domainId`  
Das `DomainId` Ziel `Domain` für die`Entity`.

Diese API gibt zurück`Success`, ob die Entitätsdomäne erfolgreich geändert wurde.

# Daten aus Entitätsfeldern schreiben und lesen
<a name="working-with_app-sdk_ent_readwrite"></a>

Alle Entitätsdatenfelder sind Blob-Typen. Sie können bis zu 1.024 Byte an Daten in eine Entität schreiben. Wir empfehlen, Blobs so klein wie möglich zu halten, da größere Größen die Leistung beeinträchtigen. Wenn Sie in ein Blob schreiben, übergeben Sie SimSpace Weaver einen Zeiger auf die Daten und deren Länge. Wenn Sie aus einem Blob lesen, SimSpace Weaver erhalten Sie einen Zeiger und eine Länge zum Lesen. Alle Lesevorgänge müssen abgeschlossen sein, bevor die App aufgerufen `Commit()` wird. Von einem Leseaufruf zurückgegebene Zeiger werden ungültig, wenn die App aufruft. `Commit()`

**Wichtig**  
Das Lesen von einem zwischengespeicherten Blob-Pointer nach a `Commit()` wird nicht unterstützt und kann dazu führen, dass die Simulation fehlschlägt.
Das Schreiben in einen Blob-Zeiger, der von einem Leseaufruf zurückgegeben wurde, wird nicht unterstützt und kann dazu führen, dass die Simulation fehlschlägt.

**Topics**
+ [Speichern Sie die Felddaten einer Entität](working-with_app-sdk_ent_readwrite_store.md)
+ [Lädt die Felddaten einer Entität](working-with_app-sdk_ent_readwrite_load.md)
+ [Die Felddaten der entfernten Entitäten werden geladen](working-with_app-sdk_ent_readwrite_load-removed.md)

# Speichern Sie die Felddaten einer Entität
<a name="working-with_app-sdk_ent_readwrite_store"></a>

Die folgenden Beispiele zeigen, wie Sie die Felddaten einer Entität speichern (in die State Fabric schreiben) können, deren Eigentümer die App ist. In diesen Beispielen wird die folgende Funktion verwendet:

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

Der `Api::TypeId keyTypeId` Parameter repräsentiert den Datentyp der übergebenen Daten.

Der `Api::TypeId keyTypeId` Parameter sollte das entsprechende Formular `Api::TypeId` erhalten`Api::BuiltinTypeId`. Wenn es keine entsprechende Konvertierung gibt, können Sie verwenden`Api::BuiltinTypeId::Dynamic`.

Verwenden Sie für komplexe Datentypen`Api::BuiltInTypeId::Dynamic`.

**Anmerkung**  
Der Wert von `FieldIndex index` muss größer als 0 sein. Der Wert 0 ist für den Indexschlüssel reserviert (siehe`StoreEntityIndexKey()`).

**Example Beispiel für die Verwendung primitiver Datentypen**  

```
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 Beispiel mit einem struct um die Daten zu speichern**  

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

# Lädt die Felddaten einer Entität
<a name="working-with_app-sdk_ent_readwrite_load"></a>

Die folgenden Beispiele zeigen, wie Sie die Felddaten einer Entität laden (aus der State Fabric lesen) können. In diesen Beispielen wird die folgende Funktion verwendet:

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

Der `Api::TypeId keyTypeId` Parameter sollte das entsprechende Format `Api::TypeId` von erhalten`Api::BuiltinTypeId`. Wenn es keine entsprechende Konvertierung gibt, können Sie verwenden`Api::BuiltinTypeId::Dynamic`.

**Anmerkung**  
Der Wert des `FieldIndex` Index muss größer als 0 sein. Der Wert 0 ist für den Indexschlüssel reserviert (siehe`StoreEntityIndexKey()`).

**Example Beispiel für die Verwendung primitiver Datentypen**  

```
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 Beispiel mit einem struct um die Daten zu speichern**  

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

# Die Felddaten der entfernten Entitäten werden geladen
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

Sie können keine Entitätsfelddaten für Entitäten laden (aus der State Fabric lesen), die aus dem Besitz- und Abonnementbereich der App entfernt wurden. Das folgende Beispiel führt zu einem Fehler, da es eine Entität als Ergebnis eines aufruft `Api::LoadIndexKey()``Api::ChangeListAction::Remove`. Das zweite Beispiel zeigt eine korrekte Methode zum Speichern und Laden von Entitätsdaten direkt in der App.

**Example Beispiel für falschen Code**  

```
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 Beispiel für eine korrekte Methode zum Speichern und Laden von Entitätsdaten in der App**  

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

# Speichert die Position einer Entität
<a name="working-with_app-sdk_ent_store-position"></a>

Sie können die Position einer Entität mithilfe einer Integer-Datenstruktur speichern (in die State Fabric schreiben). In diesen Beispielen wird die folgende Funktion verwendet:

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

**Anmerkung**  
Sie `Api::BuiltinTypeId::Vector3F32` müssen angeben`Api::StoreEntityIndexKey()`, wie in den folgenden Beispielen gezeigt.

**Example Beispiel für die Verwendung eines Arrays zur Darstellung der Position**  

```
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 Beispiel mit einem struct um die Position darzustellen**  

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

# Lädt die Position einer Entität
<a name="working-with_app-sdk_ent_load-position"></a>

Sie können die Position einer Entität mithilfe einer Integer-Datenstruktur laden (aus der State Fabric lesen). In diesen Beispielen wird die folgende Funktion verwendet:

**Anmerkung**  
Sie `Api::BuiltinTypeId::Vector3F32` müssen angeben`Api::LoadEntityIndexKey()`, wie in den folgenden Beispielen gezeigt.

**Example Beispiel für die Verwendung eines Arrays zur Darstellung der Position**  

```
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 Beispiel mit einem struct um die Position darzustellen**  

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

# Ereignisse der Entität
<a name="working-with_app-sdk_events"></a>

Sie können die folgenden Funktionen im SimSpace Weaver App-SDK verwenden, um alle Eigentums- und Abonnementereignisse abzurufen:
+ `Result<OwnershipChangeList> OwnershipChanges(Transaction& txn) `
+ `Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn) `

Sie können das SimSpace Weaver Demo-Framework verwenden, wenn Sie eine rückrufgesteuerte Verarbeitung von Entitätsereignissen benötigen. Weitere Informationen finden Sie in der folgenden Header-Datei:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/DemoFramework/EntityEventProcessor.h`

Sie können auch Ihre eigene Entitäts-Eventverarbeitung erstellen.

**Topics**
+ [Iterieren Sie Ereignisse für eigene Entitäten](working-with_app-sdk_events_own.md)
+ [Iterieren Sie Ereignisse für abonnierte Entitäten](working-with_app-sdk_events_sub.md)
+ [Führen Sie Iterationen durch Ereignisse zum Eigentümerwechsel für Entitäten durch](working-with_app-sdk_events_change.md)

# Iterieren Sie Ereignisse für eigene Entitäten
<a name="working-with_app-sdk_events_own"></a>

Wird verwendet`OwnershipChanges()`, um eine Liste von Ereignissen für eigene Entitäten (Entitäten im Eigentumsbereich der App) abzurufen. Die Funktion hat die folgende Signatur:

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

Iterieren Sie dann mit einer Schleife durch die Entitäten, wie im folgenden Beispiel gezeigt.

**Example Beispiel**  

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

**Ereignistypen**
+ `None`— Die Entität befindet sich in dem Bereich und ihre Positions- und Felddaten wurden nicht geändert.
+ `Remove`— Die Entität wurde aus dem Bereich entfernt.
+ `Add`— Die Entität wurde dem Bereich hinzugefügt.
+ `Update`— Die Entität befindet sich in dem Bereich und wurde geändert.
+ `Reject`— Die App konnte die Entität nicht aus dem Bereich entfernen.

**Anmerkung**  
Im Falle eines `Reject` Ereignisses versucht die App beim nächsten Häkchen erneut, die Übertragung durchzuführen.

# Iterieren Sie Ereignisse für abonnierte Entitäten
<a name="working-with_app-sdk_events_sub"></a>

Wird verwendet`AllSubscriptionEvents()`, um eine Liste von Ereignissen für abonnierte Entitäten (Entitäten im Abonnementbereich der App) abzurufen. Die Funktion hat die folgende Signatur:

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

Iterieren Sie dann mit einer Schleife durch die Entitäten, wie im folgenden Beispiel gezeigt.

**Example Beispiel**  

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

**Ereignistypen**
+ `None`— Die Entität befindet sich in dem Bereich und ihre Positions- und Felddaten wurden nicht geändert.
+ `Remove`— Die Entität wurde aus dem Bereich entfernt.
+ `Add`— Die Entität wurde dem Bereich hinzugefügt.
+ `Update`— Die Entität befindet sich in dem Bereich und wurde geändert.
+ `Reject`— Die App konnte die Entität nicht aus dem Bereich entfernen.

**Anmerkung**  
Im Falle eines `Reject` Ereignisses versucht die App beim nächsten Häkchen erneut, die Übertragung durchzuführen.

# Führen Sie Iterationen durch Ereignisse zum Eigentümerwechsel für Entitäten durch
<a name="working-with_app-sdk_events_change"></a>

Um Ereignisse zu ermitteln, bei denen eine Entität zwischen einem Eigentümerbereich und einem Abonnementbereich wechselt, vergleichen Sie die Änderungen zwischen den aktuellen und früheren Eigentümerschafts- und Abonnementereignissen der Entität.

Sie können mit diesen Ereignissen umgehen, indem Sie Folgendes lesen:
+ `Api::SubscriptionChangeList`
+ `Api::OwnershipEvents`

Anschließend können Sie die Änderungen mit zuvor gespeicherten Daten vergleichen.

Das folgende Beispiel zeigt, wie Sie mit Ereignissen umgehen können, bei denen sich die Eigentümerschaft einer Entität ändert. In diesem Beispiel wird davon ausgegangen, dass bei Entitäten, die zwischen abonnierten Entitäten und eigenen Entitäten (in beide Richtungen) wechseln, das remove/add event occurs first followed by the subscription remove/add Eigentümerereignis im nächsten Tick stattfindet. 

**Example Beispiel**  

```
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 und Fehlerbehandlung
<a name="working-with_app-sdk_result"></a>

Die `Aws::WeaverRuntime::Result<T>` Klasse verwendet eine `Outcome` Bibliothek eines Drittanbieters. Sie können das folgende Muster verwenden, um die von API-Aufrufen zurückgegebenen Fehler zu überprüfen `Result` und abzufangen.

```
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 Steueranweisungs-Makro
<a name="working-with_app-sdk_result_macro"></a>

In einer Funktion mit einem Rückgabetyp `Aws::WeaverRuntime::Result<T>` können Sie das `WEAVERRUNTIME_TRY` Makro anstelle des vorherigen Codemusters verwenden. Das Makro führt die ihm übergebene Funktion aus. Wenn die übergebene Funktion fehlschlägt, veranlasst das Makro, dass die umschließende Funktion einen Fehler zurückgibt. Wenn die übergebene Funktion erfolgreich ist, wird die Ausführung mit der nächsten Zeile fortgesetzt. Das folgende Beispiel zeigt eine Neuschreibung der vorherigen Funktion. `DoBeginUpdate()` Diese Version verwendet das `WEAVERRUNTIME_TRY` Makro anstelle von if-else Kontrollstruktur. Beachten Sie, dass der Rückgabetyp der Funktion ist`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();
}
```

Wenn ein `BeginUpdate()` Fehler auftritt, `DoBeginUpdate()` kehrt das Makro mit einem Fehler vorzeitig zurück. Sie können das `WEAVERRUNTIME_EXPECT_ERROR` Makro verwenden, um das `Aws::WeaverRuntime::ErrorCode` von abzurufen`BeginUpdate()`. Das folgende Beispiel zeigt, wie die `Update()` Funktion bei einem Fehler den Fehlercode aufruft `DoBeginUpdate()` und abruft.

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

    }
}
```

Sie können den Fehlercode von `BeginUpdate()` available in eine Funktion umwandeln, die sie aufruft, `Update()` indem Sie den Rückgabetyp `Update()` auf ändern`Aws::WeaverRuntime::Result<void>`. Sie können diesen Vorgang wiederholen, um den Fehlercode weiter unten in der Aufrufliste zu senden.

# Generika und Domaintypen
<a name="working-with_app-sdk_generics"></a>

Das SimSpace Weaver App-SDK stellt die Datentypen mit einfacher Genauigkeit `Api::Vector2F32` und und `Api::BoundingBox2F32` die Datentypen mit doppelter `Api::Vector2F64` Genauigkeit und bereit. `Api::BoundingBox2F64` Bei diesen Datentypen handelt es sich um passive Datenstrukturen ohne praktische Methoden. Beachten Sie, dass die API nur `Api::Vector2F32` und verwendet`Api::BoundingBox2F32`. Sie können diese Datentypen verwenden, um Abonnements zu erstellen und zu ändern.

Das SimSpace Weaver Demo-Framework bietet eine Minimalversion von AzCore Mathe-Bibliothek, die `Vector3` und enthält`Aabb`. Weitere Informationen finden Sie in den Header-Dateien unter:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/AzCore/Math`

# Verschiedene App-SDK-Operationen
<a name="working-with_app-sdk_misc"></a>

**Topics**
+ [AllSubscriptionEvents and OwnershipChanges enthalten Ereignisse aus dem letzten Aufruf](working-with_app-sdk_misc_events-from-last-call.md)
+ [Löst Lesesperren nach der Verarbeitung SubscriptionChangeList](working-with_app-sdk_misc_release-locks.md)
+ [Erstellen Sie eine eigenständige App-Instanz zum Testen](working-with_app-sdk_misc_testing-app.md)

# AllSubscriptionEvents and OwnershipChanges enthalten Ereignisse aus dem letzten Aufruf
<a name="working-with_app-sdk_misc_events-from-last-call"></a>

Die Rückgabewerte von Aufrufen `Api::AllSubscriptionEvents()` und `Api::OwnershipChanges()` enthalten Ereignisse des letzten Aufrufs, **nicht des letzten Ticks**. Im folgenden Beispiel `secondOwnershipChangeList` sind sie leer, `secondSubscriptionEvents` weil ihre Funktionen unmittelbar nach den ersten Aufrufen aufgerufen werden.

Wenn Sie 10 Ticks warten und dann `Api::AllSubscriptionEvents()` and aufrufen`Api::OwnershipChanges()`, enthalten ihre Ergebnisse sowohl Ereignisse als auch Änderungen der letzten 10 Ticks (nicht des letzten Ticks).

**Example Beispiel**  

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

**Anmerkung**  
Die Funktion `AllSubscriptionEvents()` ist implementiert, aber die Funktion `SubscriptionEvents()` ist **nicht implementiert**.

# Löst Lesesperren nach der Verarbeitung SubscriptionChangeList
<a name="working-with_app-sdk_misc_release-locks"></a>

Wenn Sie mit einem Update beginnen, gibt es gemeinsame Speichersegmente für die übergebenen Daten in anderen Partitionen für den vorherigen Tick. Diese gemeinsam genutzten Speichersegmente werden möglicherweise von Lesern gesperrt. Eine App kann erst dann vollständig festgeschrieben werden, wenn alle Leser die Sperren aufgehoben haben. Zur Optimierung sollte eine App aufrufen, um die Sperren `Api::ReleaseReadLeases()` nach der Verarbeitung von `Api::SubscriptionChangelist` Elementen aufzuheben. Dadurch werden Konflikte beim Festschreiben reduziert. `Api::Commit()`veröffentlicht die Read-Leases standardmäßig, aber es hat sich bewährt, sie nach der Verarbeitung von Abonnement-Updates manuell freizugeben.

**Example Beispiel**  

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

# Erstellen Sie eine eigenständige App-Instanz zum Testen
<a name="working-with_app-sdk_misc_testing-app"></a>

Sie können `Api::CreateStandaloneApplication()` damit eine eigenständige App erstellen, um die Anwendungslogik zu testen, bevor Sie den Code in einer tatsächlichen Simulation ausführen.

**Example Beispiel**  

```
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 Demo-Framework
<a name="working-with_demo-framework"></a>

Das AWS SimSpace Weaver Demo-Framework (Demo-Framework) ist eine Bibliothek von Hilfsprogrammen, mit denen Sie SimSpace Weaver Apps entwickeln können.

**Das Demo-Framework bietet**
+ Codebeispiele und Programmiermuster, die Sie verwenden und untersuchen können
+ Abstraktionen und Hilfsfunktionen, die die Entwicklung einfacher Apps vereinfachen
+ Eine einfachere Möglichkeit, experimentelle Funktionen des App-SDK zu testen SimSpace Weaver 

Wir haben das SimSpace Weaver App-SDK mit einfachem Zugriff entwickelt, SimSpace Weaver APIs um eine höhere Leistung zu erzielen. Im Gegensatz dazu haben wir das Demo-Framework so konzipiert, dass es Abstraktionen auf höherer Ebene und den Zugriff darauf bietet, was APIs die Bedienung erleichtert SimSpace Weaver . Der Preis für die Benutzerfreundlichkeit ist ein geringeres Leistungsniveau als bei der direkten Verwendung des SimSpace Weaver App-SDK. Simulationen, die eine geringere Leistung tolerieren können (z. B. solche ohne Echtzeit-Leistungsanforderungen), könnten sich für die Verwendung des Demo-Frameworks eignen. Wir empfehlen, die systemeigenen Funktionen des SimSpace Weaver App-SDK für komplexe Anwendungen zu verwenden, da das Demo-Framework kein vollständiges Toolkit ist.

**Das Demo-Framework umfasst**
+ Funktionierende Codebeispiele, die Folgendes unterstützen und demonstrieren:
  + Verwaltung des Anwendungsflusses
  + Verarbeitung von Entitätsereignissen durch Rückrufe
+ Eine Reihe von Dienstprogrammbibliotheken von Drittanbietern:
  + spdlog (eine Logging-Bibliothek)
  + Eine Minimalversion von AZCore (eine Mathe-Bibliothek), die nur Folgendes enthält:
    + Vector3
    + Aabb
  + cxxopts (eine Parser-Bibliothek für Befehlszeilenoptionen)
+ Spezifische Hilfsfunktionen für SimSpace Weaver

Das Demo-Framework besteht aus einer Bibliothek, Quelldateien und CMakeLists. Die Dateien sind im verteilbaren SimSpace Weaver App-SDK-Paket enthalten.

# Mit Servicekontingenten arbeiten
<a name="working-with_quotas"></a>

In diesem Abschnitt wird beschrieben, wie Sie mit den Servicekontingenten für arbeiten SimSpace Weaver. **Kontingente** werden auch als **Limits** bezeichnet. Eine Liste der Dienstkontingente finden Sie unter[SimSpace Weaver-Endpunkte und Kontingente](service-quotas.md). Die APIs in diesem Abschnitt enthaltenen Daten stammen aus dem **App-Set APIs**. Apps APIs unterscheiden sich von dem Service APIs. Die Apps APIs sind Teil des SimSpace Weaver App-SDK. Sie finden die Dokumentation für die App APIs im App-SDK-Ordner auf Ihrem lokalen System:

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

**Topics**
+ [Holen Sie sich die Grenzwerte für eine App](#working-with_quotas_get-app-limits)
+ [Ruft die Menge der von einer App verwendeten Ressourcen ab](#working-with_quotas_get-app-resources)
+ [Metriken zurücksetzen](#working-with_quotas_reset-metrics)
+ [Überschreitung eines Limits](#working-with_quotas_exceed-limit)
+ [Der Speicher geht zur Neige](#working-with_quotas_out-of-memory)
+ [Best Practices](#working-with_quotas_best-practices)

## Holen Sie sich die Grenzwerte für eine App
<a name="working-with_quotas_get-app-limits"></a>

Sie können die **RuntimeLimits** App-API verwenden, um die Grenzwerte für eine App abzufragen.

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

**Applicationund App**  
Ein Verweis auf die App.

**LimitType-Typ**  
Eine Aufzählung mit den folgenden Limittypen:  

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

Im folgenden Beispiel wird das Limit für die Anzahl der Entitäten abgefragt.

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

## Ruft die Menge der von einer App verwendeten Ressourcen ab
<a name="working-with_quotas_get-app-resources"></a>

Sie können die **RuntimeMetrics** App-API aufrufen, um die Menge der von einer App verwendeten Ressourcen abzurufen:

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

**Applicationund App**  
Ein Verweis auf die App.

Die API gibt einen Verweis auf a zurück, der struct die Metriken enthält. Eine Zählermetrik enthält einen laufenden Gesamtwert und nimmt nur zu. Eine Messmetrik enthält einen Wert, der steigen oder sinken kann. Die Anwendungslaufzeit aktualisiert einen Zähler, wenn ein Ereignis den Wert erhöht. Die Runtime aktualisiert die Messgeräte nur, wenn Sie die API aufrufen. SimSpace Weaver garantiert, dass die Referenz für die gesamte Lebensdauer der App gültig ist. Wiederholte Aufrufe der API ändern die Referenz nicht.

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

## Metriken zurücksetzen
<a name="working-with_quotas_reset-metrics"></a>

Die **ResetRuntimeMetrics** App-API setzt die Werte in der `AppRuntimeMetrics` struct zurück.

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

Das folgende Beispiel zeigt, wie Sie Ihre App aufrufen **ResetRuntimeMetrics** können.

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

## Überschreitung eines Limits
<a name="working-with_quotas_exceed-limit"></a>

Bei einem App-API-Aufruf, der ein Limit überschreitet, wird ein zurückgegeben`ErrorCode::CapacityExceeded`, außer bei Entitätsübertragungen. SimSpace Weaver verarbeitet Entitätsübertragungen asynchron im Rahmen von **Commit** - und **BeginUpdate** App-API-Vorgängen, sodass es keinen bestimmten Vorgang gibt, der einen Fehler zurückgibt, wenn eine Übertragung aufgrund des Limits für die Übertragung von Entitäten fehlschlägt. Um Übertragungsfehler zu erkennen, können Sie die aktuellen Werte von `rejected_incoming_transfer_counter` und `rejected_outgoing_transfer_counter` (in `AppRuntimeMetrics`struct) mit ihren vorherigen Werten vergleichen. Abgelehnte Entitäten werden sich nicht in der Partition befinden, aber die App kann sie trotzdem simulieren.

## Der Speicher geht zur Neige
<a name="working-with_quotas_out-of-memory"></a>

SimSpace Weaver verwendet einen Garbage-Collector-Prozess, um freigegebenen Speicher zu bereinigen und freizugeben. Es ist möglich, Daten schneller zu schreiben, als der Garbage-Collector Speicher freigeben kann. In diesem Fall können Schreibvorgänge das für die App reservierte Speicherlimit überschreiten. SimSpace Weaver gibt einen internen Fehler mit einer Meldung zurück, die `OutOfMemory` (und zusätzliche Details) enthält. Weitere Informationen finden Sie unter [Schreibvorgänge über einen bestimmten Zeitraum verteilen](#working-with_quotas_best-practices_spread-writes).

## Best Practices
<a name="working-with_quotas_best-practices"></a>

Die folgenden bewährten Methoden sind allgemeine Richtlinien für die Gestaltung Ihrer Apps, um zu vermeiden, dass Grenzwerte überschritten werden. Sie gelten möglicherweise nicht für Ihr spezifisches App-Design.

### Überwachen Sie häufig und verlangsamen Sie die Geschwindigkeit
<a name="working-with_quotas_best-practices_monitor"></a>

Sie sollten Ihre Messwerte häufig überwachen und Abläufe, die kurz vor dem Erreichen eines Grenzwerts stehen, verlangsamen.

### Vermeiden Sie es, die Abonnement- und Übertragungslimits zu überschreiten
<a name="working-with_quotas_best-practices_subscription-and-xfer"></a>

Wenn möglich, sollten Sie Ihre Simulation so gestalten, dass die Anzahl der Fernabonnements und Objektübertragungen reduziert wird. Sie können Platzierungsgruppen verwenden, um mehrere Partitionen auf demselben Worker zu platzieren und so die Notwendigkeit von Entitätsübertragungen zwischen Workern aus der Ferne zu reduzieren. 

### Schreibvorgänge über einen bestimmten Zeitraum verteilen
<a name="working-with_quotas_best-practices_spread-writes"></a>

Die Anzahl und Größe der Aktualisierungen in einem Tick können erhebliche Auswirkungen auf den Zeit- und Speicherbedarf haben, der für die Durchführung einer Transaktion erforderlich ist. Große Speicheranforderungen können dazu führen, dass der Laufzeit der Anwendung nicht mehr genügend Arbeitsspeicher zur Verfügung steht. Sie können Schreibvorgänge über einen längeren Zeitraum verteilen, um die durchschnittliche Gesamtgröße der Updates pro Tick zu verringern. Dies kann dazu beitragen, die Leistung zu verbessern und zu verhindern, dass Grenzwerte überschritten werden. Wir empfehlen, dass Sie nicht mehr als durchschnittlich 12 MB pro Tick oder 1,5 KB für jede Entität schreiben. 

# Simulationen debuggen
<a name="working-with_debugging"></a>

Sie können die folgenden Methoden verwenden, um Informationen zu Ihren Simulationen zu erhalten.

**Themen**
+ [Verwenden Sie SimSpace Weaver Local und schauen Sie sich die Konsolenausgabe an](#working-with_debugging_use-local)
+ [Sehen Sie sich Ihre Logs in Amazon CloudWatch Logs an](#working-with_debugging_logs)
+ [Verwenden Sie **Beschreiben** API-Aufrufe](#working-with_debugging_api)
+ [Einen Client Connect](#working-with_debugging_client)

## Verwenden Sie SimSpace Weaver Local und schauen Sie sich die Konsolenausgabe an
<a name="working-with_debugging_use-local"></a>

Wir empfehlen, dass Sie Ihre Simulationen zuerst lokal entwickeln und sie dann in der ausführen AWS Cloud. Sie können die Konsolenausgabe direkt anzeigen, wenn Sie mit SimSpace Weaver Local. Weitere Informationen finden Sie unter[Lokale Entwicklung in SimSpace Weaver](working-with_local-development.md).

## Sehen Sie sich Ihre Logs in Amazon CloudWatch Logs an
<a name="working-with_debugging_logs"></a>

Wenn Sie Ihre Simulation in AWS Cloud der Konsole ausführen, wird die Ausgabe Ihrer Apps an Protokollstreams in Amazon CloudWatch Logs gesendet. Ihre Simulation schreibt auch andere Protokolldaten. Sie müssen die Protokollierung in Ihrem Simulationsschema aktivieren, wenn Sie möchten, dass Ihre Simulation Protokolldaten schreibt. Weitere Informationen finden Sie unter [SimSpace Weaver loggt sich in Amazon CloudWatch Logs ein](cloudwatch-logs.md).

**Warnung**  
Ihre Simulation kann große Mengen an Protokolldaten erzeugen. Die Protokolldaten können sehr schnell anwachsen. Sie sollten Ihre Protokolle genau beobachten und Ihre Simulationen beenden, wenn Sie sie nicht mehr benötigen. Die Protokollierung kann hohe Kosten verursachen.

## Verwenden Sie **Beschreiben** API-Aufrufe
<a name="working-with_debugging_api"></a>

Sie können den folgenden Service nutzen APIs , um Informationen zu Ihren Simulationen in der zu erhalten AWS Cloud.
+ **ListSimulations**— Holen Sie sich eine Liste all Ihrer Simulationen in der AWS Cloud.  
**Example Beispiel**  

  ```
  aws simspaceweaver list-simulations
  ```
+ **DescribeSimulation**— Details zu einer Simulation abrufen.  
**Example Beispiel**  

  ```
  aws simspaceweaver describe-simulation --simulation MySimulation
  ```
+ **DescribeApp**— Details zu einer App abrufen.  
**Example Beispiel**  

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

Weitere Informationen über die finden SimSpace Weaver APIs Sie unter[SimSpace Weaver API-Referenzen](api-reference.md).

## Einen Client Connect
<a name="working-with_debugging_client"></a>

Sie können einen Client mit einer laufenden benutzerdefinierten App oder einer Service-App verbinden, die Sie mit einem `endpoint_config` in Ihrem Simulationsschema definiert haben. Das SimSpace Weaver App-SDK enthält Beispielclients, mit denen Sie die Beispielanwendung anzeigen können. Sie können sich den Quellcode für diese Beispielclients und die Beispielanwendung ansehen, um zu sehen, wie Sie Ihre eigenen Clients erstellen können. Weitere Informationen zum Erstellen und Ausführen der Beispielclients finden Sie in den Tutorials unter[Erste Schritte mit SimSpace Weaver](getting-started.md).

Den Quellcode für die Beispielclients finden Sie im folgenden Ordner:
+ `sdk-folder\packaging-tools\clients\PathfindingSampleClients\`

# Debuggen lokaler Simulationen
<a name="working-with_debugging_local"></a>

Sie können Ihre SimSpace Weaver Local Apps mit Microsoft Visual Studio debuggen. [Weitere Informationen zum Debuggen mit finden Sie Visual Studio unter. Microsoft Visual Studio documentation](https://learn.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour) 

**So debuggen Sie Ihre lokale Simulation**

1. Stellen Sie sicher, dass Sie `schema.yaml` sich in Ihrem Arbeitsverzeichnis befinden.

1. Öffnen Sie in das Kontextmenü für jede App **Visual Studio**, die Sie debuggen möchten (z. B. `PathfindingSampleLocalSpatial` oder`PathfindingSampleLocalView`), und legen Sie das Arbeitsverzeichnis im Debugging-Bereich fest.

1. Öffnen Sie das Kontextmenü für die App, die Sie debuggen möchten, und wählen Sie **Als Startprojekt festlegen** aus.

1. Wählen SieF5, ob Sie mit dem Debuggen der App beginnen möchten.

Die Anforderungen für das Debuggen einer Simulation entsprechen den Anforderungen für die normale Ausführung einer Simulation. Sie müssen mit der Anzahl von Geo-Apps beginnen, die im Schema angegeben ist. Wenn Ihr Schema beispielsweise ein 2x2-Raster angibt und Sie eine Geo-App im Debug-Modus starten, wird die Simulation erst ausgeführt, wenn Sie 3 weitere Spatial-Apps starten (im Debug-Modus oder nicht im Debug-Modus).

Um eine benutzerdefinierte App zu debuggen, müssen Sie zuerst Ihre Geo-Apps und dann die benutzerdefinierte App im Debugger starten.

Beachten Sie, dass Ihre Simulation im Lockstep ausgeführt wird. Sobald eine App einen Breakpoint erreicht, werden alle anderen Apps pausiert. Wenn Sie von diesem Breakpoint aus weitermachen, werden die anderen Apps fortgesetzt.

# Maßgeschneiderte Behälter
<a name="working-with_custom-containers"></a>

AWS SimSpace Weaver Apps werden in containerisierten Amazon Linux 2 (AL2) Umgebungen ausgeführt. In der werden Ihre Simulationen in Docker-Containern SimSpace Weaver ausgeführt AWS Cloud, die auf einem `amazonlinux:2` Image basieren, das von Amazon Elastic Container Registry (Amazon ECR) bereitgestellt wird. Sie können ein benutzerdefiniertes Docker-Image erstellen, es in Amazon ECR speichern und dieses Image anstelle des von uns bereitgestellten Standard-Docker-Images für Ihre Simulation verwenden.

Sie können einen benutzerdefinierten Container verwenden, um Ihre Softwareabhängigkeiten zu verwalten und zusätzliche Softwarekomponenten einzubeziehen, die nicht im Standard-Docker-Image enthalten sind. Sie können beispielsweise die öffentlich verfügbaren Softwarebibliotheken, die Ihre App verwendet, zum Container hinzufügen und nur Ihren benutzerdefinierten Code in die Zip-Datei der App einfügen.

**Wichtig**  
Wir unterstützen nur AL2 Docker-Images, die in Amazon ECR-Repositorys gehostet werden, entweder in der Amazon ECR Public Gallery oder in Ihrer privaten Amazon ECR-Registrierung. Wir unterstützen keine Docker-Images, die außerhalb von Amazon ECR gehostet werden. Weitere Informationen zu Amazon ECR finden Sie in der *[Dokumentation zu Amazon Elastic Container Registry](https://docs.aws.amazon.com/ecr)*.

**Topics**
+ [Erstellen Sie einen benutzerdefinierten Container](working-with_custom-containers_create.md)
+ [Ändern Sie ein Projekt, um einen benutzerdefinierten Container zu verwenden](working-with_custom-containers_modify-project.md)
+ [Häufig gestellte Fragen zu benutzerdefinierten Containern](working-with_custom-containers_faq.md)
+ [Problembehandlung bei benutzerdefinierten Containern](working-with_custom-containers_troubleshooting.md)

# Erstellen Sie einen benutzerdefinierten Container
<a name="working-with_custom-containers_create"></a>

Bei diesen Anweisungen wird davon ausgegangen, dass Sie wissen, wie Docker und Amazon Elastic Container Registry (Amazon ECR) verwendet werden. Weitere Informationen zur Amazon ECR finden Sie unter Sicherheit im *[Amazon-ECR-Benutzerhandbuch](https://docs.aws.amazon.com/AmazonECR/latest/userguide)*.

**Voraussetzungen**
+ Die IAM-Identität (Verwendung oder Rolle), die Sie für diese Aktionen verwenden, verfügt über die richtigen Berechtigungen zur Verwendung von Amazon ECR
+ Docker ist auf Ihrem lokalen System installiert

**Um einen benutzerdefinierten Container zu erstellen**

1. Erstellen Sie Ihr `Dockerfile`.

   A `Dockerfile` zum Ausführen von AWS SimSpace Weaver Apps beginnt mit dem Amazon Linux 2 Bild in Amazon ECR.

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

1. Baue dein`Dockerfile`.

1. Laden Sie Ihr Container-Image auf Amazon ECR hoch.
   + [Verwenden Sie die AWS-Managementkonsole.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html)
   + [Benutze die AWS Command Line Interface.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
**Anmerkung**  
Wenn Sie beim Versuch, Ihr Container-Image auf Amazon ECR hochzuladen, eine `AccessDeniedException` Fehlermeldung erhalten, verfügt Ihre IAM-Identität (Benutzer oder Rolle) möglicherweise nicht über die erforderlichen Berechtigungen zur Verwendung von Amazon ECR. Sie können die `AmazonEC2ContainerRegistryPowerUser` AWS verwaltete Richtlinie an Ihre IAM-Identität anhängen und es erneut versuchen. Weitere Informationen zum Anhängen einer Richtlinie finden Sie unter [Hinzufügen und Entfernen von IAM-Identitätsberechtigungen](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) im *AWS Identity and Access Management Benutzerhandbuch*.

# Ändern Sie ein Projekt, um einen benutzerdefinierten Container zu verwenden
<a name="working-with_custom-containers_modify-project"></a>

Bei diesen Anweisungen wird davon ausgegangen, dass Sie bereits wissen, wie Sie Ihre App verwenden AWS SimSpace Weaver können, und dass Sie Ihre Workflows für App-Speicher und Entwicklung AWS Cloud effizienter gestalten möchten.

**Voraussetzungen**
+ Sie haben einen benutzerdefinierten Container in Amazon Elastic Container Registry (Amazon ECR). Weitere Informationen zum Erstellen eines benutzerdefinierten Containers finden Sie unter[Erstellen Sie einen benutzerdefinierten Container](working-with_custom-containers_create.md).

**So ändern Sie Ihr Projekt so, dass es einen benutzerdefinierten Container verwendet**

1. Fügen Sie der Simulations-App-Rolle Ihres Projekts Berechtigungen zur Verwendung von Amazon ECR hinzu.

   1. Wenn Sie noch keine IAM-Richtlinie mit den folgenden Berechtigungen haben, erstellen Sie die Richtlinie. Wir empfehlen den Namen `simspaceweaver-ecr` der Richtlinie. Weitere Informationen zum Erstellen einer IAM-Richtlinie finden Sie unter [Erstellen von IAM-Richtlinien](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) im *AWS Identity and Access Management Benutzerhandbuch*.

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

   1. Suchen Sie nach dem Namen der Simulations-App-Rolle Ihres Projekts:

      1. Öffnen Sie die CloudFormation Vorlage in einem Texteditor:

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

      1. Suchen Sie die `RoleName` Immobilie unter`WeaverAppRole`. Der Wert ist der Name der Simulations-App-Rolle Ihres Projekts.  
**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. Ordnen Sie die `simspaceweaver-ecr` Richtlinie der Simulations-App-Rolle des Projekts zu. Weitere Informationen zum Anhängen einer Richtlinie finden Sie unter [Hinzufügen und Entfernen von IAM-Identitätsberechtigungen](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) im *AWS Identity and Access Management Benutzerhandbuch*. 

   1. Navigieren Sie zu dem folgenden Befehl `sdk-folder` und führen Sie ihn aus, um den SimSpace Weaver Beispielstapel zu aktualisieren:

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

1. Geben Sie Ihre Container-Images im Simulationsschema des Projekts an.
   + Sie können die optionale `default_image` Eigenschaft unter hinzufügen`simulation_properties`, um ein benutzerdefiniertes Standard-Container-Image für alle Domänen anzugeben.
   + Fügen Sie die `image` Eigenschaft `app_config` für eine Domain hinzu, für die Sie ein benutzerdefiniertes Container-Image verwenden möchten. Geben Sie die Amazon ECR-Repository-URI als Wert an. Sie können für jede Domain ein anderes Bild angeben.
     + Wenn es `image` nicht für eine Domain angegeben `default_image` ist, aber angegeben ist, verwenden Apps in dieser Domain das Standardbild.
     + Wenn es `image` nicht für eine Domain angegeben und auch `default_image` nicht angegeben ist, werden Apps in dieser Domain in einem SimSpace Weaver Standardcontainer ausgeführt.  
**Example Schemasnippet, das benutzerdefinierte Container-Einstellungen enthält**  

   ```
   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. Erstellen Sie Ihr Projekt und laden Sie es wie gewohnt hoch.

# Häufig gestellte Fragen zu benutzerdefinierten Containern
<a name="working-with_custom-containers_faq"></a>

## F1. Was mache ich, wenn ich den Inhalt meines Containers ändern möchte?
<a name="working-with_custom-containers_faq_q1"></a>
+ **Für eine laufende Simulation** — Sie können den Container nicht für eine laufende Simulation ändern. Sie müssen einen neuen Container erstellen und eine neue Simulation starten, die diesen Container verwendet.
+ **Für eine neue Simulation** — Erstellen Sie einen neuen Container, laden Sie ihn in Amazon Elastic Container Registry (Amazon ECR) hoch und starten Sie eine neue Simulation, die diesen Container verwendet.

## F2. Wie kann ich das Container-Image für meine Simulation ändern?
<a name="working-with_custom-containers_faq_q2"></a>
+ **Für eine laufende Simulation** — Sie können den Container für eine laufende Simulation nicht ändern. Sie müssen eine neue Simulation starten, die den neuen Container verwendet.
+ **Für eine neue Simulation** — Geben Sie das neue Container-Image im Simulationsschema Ihres Projekts an. Weitere Informationen finden Sie unter [Ändern Sie ein Projekt, um einen benutzerdefinierten Container zu verwenden](working-with_custom-containers_modify-project.md).

# Problembehandlung bei benutzerdefinierten Containern
<a name="working-with_custom-containers_troubleshooting"></a>

**Topics**
+ [AccessDeniedException wenn Sie Ihr Bild in Amazon Elastic Container Registry (Amazon ECR) hochladen](working-with_custom-containers_troubleshooting_access-denied.md)
+ [Eine Simulation, die einen benutzerdefinierten Container verwendet, kann nicht gestartet werden](working-with_custom-containers_troubleshooting_no-start.md)

# AccessDeniedException wenn Sie Ihr Bild in Amazon Elastic Container Registry (Amazon ECR) hochladen
<a name="working-with_custom-containers_troubleshooting_access-denied"></a>

Wenn Sie beim Versuch, Ihr Container-Image auf Amazon ECR hochzuladen, eine `AccessDeniedException` Fehlermeldung erhalten, verfügt Ihre IAM-Identität (Benutzer oder Rolle) möglicherweise nicht über die erforderlichen Berechtigungen zur Verwendung von Amazon ECR. Sie können die `AmazonEC2ContainerRegistryPowerUser` AWS verwaltete Richtlinie an Ihre IAM-Identität anhängen und es erneut versuchen. Weitere Informationen zum Anhängen einer Richtlinie finden Sie unter [Hinzufügen und Entfernen von IAM-Identitätsberechtigungen](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) im *AWS Identity and Access Management Benutzerhandbuch*.

# Eine Simulation, die einen benutzerdefinierten Container verwendet, kann nicht gestartet werden
<a name="working-with_custom-containers_troubleshooting_no-start"></a>

**Tipps zur Problembehebung**
+ Wenn die Protokollierung für Ihre Simulation aktiviert ist, überprüfen Sie Ihre Fehlerprotokolle.
+ Testen Sie Ihre Simulation ohne einen benutzerdefinierten Container.
+ Testen Sie Ihre Simulation lokal. Weitere Informationen finden Sie unter [Lokale Entwicklung in SimSpace Weaver](working-with_local-development.md).

# Verwenden von Python
<a name="working-with_python"></a>

Sie können Python für Ihre SimSpace Weaver Apps und Ihren Client verwenden. Das Python Software Development Kit (Python SDK) ist Teil des verteilbaren Standardpakets des SimSpace Weaver App-SDK. Die Entwicklung mit Python funktioniert ähnlich wie die Entwicklung in den anderen unterstützten Sprachen.

**Wichtig**  
SimSpace Weaver unterstützt nur Python-Version 3.9.

**Wichtig**  
SimSpace Weaver Für die Unterstützung von Python ist SimSpace Weaver Version 1.15.0 oder höher erforderlich.

**Topics**
+ [Ein Python-Projekt erstellen](working-with_python_create-project.md)
+ [Eine Python-Simulation starten](working-with_python_start-sim.md)
+ [Der Python-Beispielclient](working-with_python_client.md)
+ [Häufig gestellte Fragen zur Verwendung von Python](working-with_python_faq.md)
+ [Behebung von Problemen im Zusammenhang mit Python](working-with_python_troubleshooting.md)

# Ein Python-Projekt erstellen
<a name="working-with_python_create-project"></a>

## Benutzerdefinierter Python-Container
<a name="working-with_python_create-project_container"></a>

Um Ihre Python-basierte SimSpace Weaver Simulation in der auszuführen AWS Cloud, können Sie einen benutzerdefinierten Container erstellen, der die erforderlichen Abhängigkeiten enthält. Weitere Informationen finden Sie unter [Maßgeschneiderte Behälter](working-with_custom-containers.md). 

Ein benutzerdefinierter Python-Container muss Folgendes enthalten:
+ gcc
+ openssl-devel
+ bzip2-Entwicklung
+ libffi-entwickeln
+ wget
+ tar
+ gzip
+ make
+ Python (Version 3.9)

Wenn Sie die `PythonBubblesSample` Vorlage verwenden, um Ihr Projekt zu erstellen, können Sie das `quick-start.py` Skript (das sich im `tools` Ordner Ihres Projekts befindet) ausführen, um ein Docker-Image mit den erforderlichen Abhängigkeiten zu erstellen. Das Skript lädt das Bild in Amazon Elastic Container Registry (Amazon ECR) hoch.

Das `quick-start.py` Skript verwendet Folgendes: `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
```

Sie können Ihre eigenen Abhängigkeiten hinzufügen zu`Dockerfile`:

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

Die `requirements.txt` Datei enthält eine Liste von Python-Paketen, die für die `PythonBubblesSample` Beispielsimulation benötigt werden:

```
Flask==2.1.1
```

Sie können Ihre eigenen Python-Paketabhängigkeiten hinzufügen zu`requirements.txt`:

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

Die `Dockerfile` und `requirements.txt` befinden sich im `tools` Ordner Ihres Projekts.

**Wichtig**  
Sie müssen technisch gesehen keinen benutzerdefinierten Container für Ihre Python-Simulation verwenden, aber wir empfehlen dringend, einen benutzerdefinierten Container zu verwenden. Der von uns bereitgestellte Standardcontainer für Amazon Linux 2 (AL2) enthält kein Python. Wenn Sie also keinen benutzerdefinierten Container mit Python verwenden, müssen Sie Python und die erforderlichen Abhängigkeiten in jede App-ZIP-Datei aufnehmen, in die Sie hochladen SimSpace Weaver. 

# Eine Python-Simulation starten
<a name="working-with_python_start-sim"></a>

Sie können Ihre Python-basierte Simulation genauso starten wie eine normale SimSpace Weaver Simulation, sowohl in SimSpace Weaver Local und in der SimSpace Weaver . AWS Cloud Weitere Informationen finden Sie in den Tutorials unter[Erste Schritte mit SimSpace Weaver](getting-started.md).

Das `PythonBubblesSample` beinhaltet einen eigenen Python-Beispielclient. Weitere Informationen finden Sie unter [Der Python-Beispielclient](working-with_python_client.md). 

# Der Python-Beispielclient
<a name="working-with_python_client"></a>

Wenn Sie die `PythonBubblesSample` Vorlage verwenden, um ein Projekt zu erstellen, enthält Ihr Projekt einen Python-Beispielclient. Sie können den Beispielclient verwenden, um die `PythonBubblesSample` Simulation anzusehen. Sie können den Beispielclient auch als Ausgangspunkt verwenden, um Ihren eigenen Python-Client zu erstellen.

Beim folgenden Verfahren wird davon ausgegangen, dass Sie ein `PythonBubblesSample` Projekt erstellt und dessen Simulation gestartet haben.

**Um den Python-Client zu starten**

1. Gehen Sie in einem **Befehlszeilenfenster** zum `PyBubbleClient` Beispielprojektordner.

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

1. Führen Sie den Python-Client aus.

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

**Parameter**  
**host**  
Die IP-Adresse Ihrer Simulation. Für eine Simulation AWS Cloud, die in gestartet wurde, können Sie die IP-Adresse Ihrer Simulation in der [SimSpace Weaver Konsole](https://console.aws.amazon.com/simspaceweaver) finden oder das Verfahren im [Rufen Sie die IP-Adresse und die Portnummer einer benutzerdefinierten App abHolen Sie sich die IP-Adresse und die Portnummer](working-with_get-ip.md) Schnellstart-Tutorial verwenden. Verwenden Sie `127.0.0.1` für eine lokale Simulation die IP-Adresse.  
**port**  
Die Portnummer Ihrer Simulation. Für eine Simulation AWS Cloud, die in gestartet wurde, ist dies die `Actual` Portnummer. Sie finden die Portnummer Ihrer Simulation in der [SimSpace Weaver Konsole](https://console.aws.amazon.com/simspaceweaver) oder verwenden Sie das Verfahren im [Rufen Sie die IP-Adresse und die Portnummer einer benutzerdefinierten App abHolen Sie sich die IP-Adresse und die Portnummer](working-with_get-ip.md) Schnellstart-Tutorial. Verwenden Sie für eine lokale Simulation `7000` die Portnummer.  
**simsize**  
Die maximale Anzahl von Entitäten, die im Client angezeigt werden sollen.

# Häufig gestellte Fragen zur Verwendung von Python
<a name="working-with_python_faq"></a>

## F1. Welche Versionen von Python werden unterstützt?
<a name="working-with_python_faq_q1"></a>

SimSpace Weaver unterstützt nur Python-Version 3.9.

# Behebung von Problemen im Zusammenhang mit Python
<a name="working-with_python_troubleshooting"></a>

**Topics**
+ [Fehler bei der Erstellung eines benutzerdefinierten Containers](working-with_python_troubleshooting_create-container-failure.md)
+ [Ihre Python-Simulation kann nicht gestartet werden](working-with_python_troubleshooting_no-start.md)
+ [Ein Python-Simulations- oder View-Client gibt einen ModuleNotFound Fehler aus](working-with_python_troubleshooting_module-not-found.md)

# Fehler bei der Erstellung eines benutzerdefinierten Containers
<a name="working-with_python_troubleshooting_create-container-failure"></a>

Wenn Sie `no basic auth credentials` nach der Ausführung eine Fehlermeldung erhalten, `quick-start.py` liegt möglicherweise ein Problem mit Ihren temporären Anmeldeinformationen für Amazon ECR vor. Führen Sie den folgenden Befehl mit Ihrer AWS-Region ID und AWS Kontonummer aus:

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

**Wichtig**  
Stellen Sie sicher, dass es sich bei dem von AWS-Region Ihnen angegebenen um denselben handelt, den Sie für Ihre Simulation verwenden. Verwenden Sie eine der AWS-Regionen SimSpace Weaver Unterstützungen. Weitere Informationen finden Sie unter [SimSpace Weaver-Endpunkte und Kontingente](service-quotas.md).

Nachdem Sie den `aws ecr` Befehl ausgeführt haben, führen Sie ihn `quick-start.py` erneut aus.

**Weitere Ressourcen zur Fehlerbehebung, die Sie überprüfen sollten**
+ [Problembehandlung bei benutzerdefinierten Containern](working-with_custom-containers_troubleshooting.md)
+ [Amazon ECR-Fehlerbehebung](https://docs.aws.amazon.com/AmazonECR/latest/userguide/troubleshooting.html) im *Amazon ECR-Benutzerhandbuch*
+ [Einrichtung mit Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html) im *Amazon ECR-Benutzerhandbuch*

# Ihre Python-Simulation kann nicht gestartet werden
<a name="working-with_python_troubleshooting_no-start"></a>

Möglicherweise wird im Verwaltungsprotokoll Ihrer Simulation ein `Unable to start app` Fehler angezeigt. Dies kann passieren, wenn die Erstellung Ihres benutzerdefinierten Containers fehlgeschlagen ist. Weitere Informationen finden Sie unter [Fehler bei der Erstellung eines benutzerdefinierten Containers](working-with_python_troubleshooting_create-container-failure.md). Weitere Informationen über Protokolle finden Sie unter [SimSpace Weaver loggt sich in Amazon CloudWatch Logs ein](cloudwatch-logs.md).

Wenn Sie sicher sind, dass an Ihrem Container nichts falsch ist, überprüfen Sie den Python-Quellcode Ihrer App. Sie können Folgendes verwenden … SimSpace Weaver Local um deine App zu testen. Weitere Informationen finden Sie unter [Lokale Entwicklung in SimSpace Weaver](working-with_local-development.md).

# Ein Python-Simulations- oder View-Client gibt einen ModuleNotFound Fehler aus
<a name="working-with_python_troubleshooting_module-not-found"></a>

Python gibt einen `ModuleNotFound` Fehler aus, wenn es ein erforderliches Python-Paket nicht finden kann.

Wenn sich Ihre Simulation in der befindet AWS Cloud, stellen Sie sicher, dass Ihr benutzerdefinierter Container alle erforderlichen Abhängigkeiten enthält, die in Ihrem `requirements.txt` aufgeführt sind. Denken Sie daran, den `quick-start.py` Vorgang bei der Bearbeitung erneut auszuführen`requirements.txt`.

Wenn Sie die Fehlermeldung für den `PythonBubblesSample` Client erhalten, verwenden Sie, `pip` um das angegebene Paket zu installieren:

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

# Support für andere Motoren
<a name="working-with_engines"></a>

Sie können Ihre eigenen benutzerdefinierten verwenden C\$1\$1 Motor mit SimSpace Weaver. Wir entwickeln derzeit Unterstützung für die folgenden Engines. Für jede dieser Engines gibt es eine separate Dokumentation.

**Wichtig**  
Integrationen mit den hier aufgeführten Engines sind experimentell. Sie sind als Vorschau verfügbar.

**Motoren**
+ [Unity](#working-with_engines_unity)(Mindestversion 2022.3.19.F1)
+ [Unreal Engine](#working-with_engines_unreal)(Mindestversion 5.0)

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

Sie müssen die haben Unity Die Entwicklungsumgebung ist bereits installiert, bevor Sie SimSpace Weaver Simulationen mit Unity erstellen. Weitere Informationen finden Sie in den einzelnen Anweisungen:

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

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

Sie müssen eine erstellen Unreal Engine dedizierter Server aus dem Quellcode. Das SimSpaceWeaverAppSdkDistributable beinhaltet eine Version des PathfindingSample für Unreal Engine. Weitere Informationen finden Sie in den einzelnen Anweisungen: 

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

# Verwendung von lizenzierter Software mit AWS SimSpace Weaver
<a name="working-with_byol"></a>

AWS SimSpace Weaver ermöglicht es Ihnen, Simulationen mit der Simulationsengine und den Inhalten Ihrer Wahl zu erstellen. Im Zusammenhang mit Ihrer Nutzung von sind Sie dafür verantwortlich SimSpace Weaver, die Lizenzbedingungen aller Software oder Inhalte, die Sie in Ihren Simulationen verwenden, zu beschaffen, zu pflegen und einzuhalten. Stellen Sie sicher, dass Ihr Lizenzvertrag Ihnen die Bereitstellung Ihrer Software und Inhalte in einer virtuellen, gehosteten Umgebung ermöglicht.

# Verwaltung Ihrer Ressourcen mit AWS CloudFormation
<a name="working-with_cloudformation"></a>

Sie können es verwenden AWS CloudFormation , um Ihre AWS SimSpace Weaver Ressourcen zu verwalten. CloudFormation ist ein separater AWS Dienst, der Sie dabei unterstützt, Ihre AWS Infrastruktur als Code zu spezifizieren, bereitzustellen und zu verwalten. Mit erstellen CloudFormation Sie eine JSON- oder YAML-Datei, die als *[Vorlage](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-templates template)* bezeichnet wird. Ihre Vorlage spezifiziert die Details Ihrer Infrastruktur. CloudFormation verwendet Ihre Vorlage, um Ihre Infrastruktur als eine einzelne Einheit bereitzustellen, die als *[Stack](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#w2ab1b5c15b9)* bezeichnet wird. Wenn Sie Ihren Stack löschen, können Sie CloudFormation festlegen, dass alles im Stack gleichzeitig gelöscht wird. Sie können Ihre Vorlage mithilfe von Standardprozessen zur Quellcodeverwaltung verwalten (z. B. indem Sie sie in einem Versionskontrollsystem wie [Git](https://git-scm.com/) verfolgen). Weitere Informationen zu CloudFormation finden Sie im [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide).

**Ihre Simulationsressource**  
 AWS In ist eine *Ressource* eine Entität, mit der Sie arbeiten können. Beispiele hierfür sind eine EC2 Amazon-Instance, ein Amazon S3-Bucket oder eine IAM-Rolle. Ihre SimSpace Weaver Simulation ist eine Ressource. In Konfigurationen geben Sie normalerweise eine AWS Ressource im Formular an`AWS::service::resource`. Für SimSpace Weaver geben Sie Ihre Simulationsressource als an`AWS::SimSpaceWeaver::Simulation`. Weitere Informationen zu Ihrer Simulationsressource finden Sie im [SimSpace Weaver](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-simspaceweaver-simulation.html)Abschnitt im *AWS CloudFormation Benutzerhandbuch*. CloudFormation

**Wie kann ich CloudFormation mit verwenden SimSpace Weaver?**  
Sie können eine CloudFormation Vorlage erstellen, die die AWS Ressourcen angibt, die Sie bereitstellen möchten. Ihre Vorlage kann eine gesamte Architektur, einen Teil einer Architektur oder eine kleine Lösung angeben. Sie könnten beispielsweise eine Architektur für Ihre SimSpace Weaver Lösung angeben, die Amazon S3 S3-Buckets, IAM-Berechtigungen, eine unterstützende Datenbank in Amazon Relational Database Service oder Amazon DynamoDB und Ihre Ressource umfasst. `Simulation` Anschließend können Sie all diese Ressourcen als Einheit und gleichzeitig bereitstellen. CloudFormation 

**Example Vorlage, die IAM-Ressourcen erstellt und eine Simulation startet**  
Die folgende Beispielvorlage erstellt eine IAM-Rolle und SimSpace Weaver Berechtigungen, die für die Ausführung von Aktionen in Ihrem Konto erforderlich sind. Die SimSpace Weaver App-SDK-Skripts erstellen die Rolle und die Berechtigungen in einem bestimmten Bereich, AWS-Region wenn Sie ein Projekt erstellen. Sie können jedoch eine CloudFormation Vorlage verwenden, um die Simulation für eine andere bereitzustellen, AWS-Region ohne die Skripts erneut ausführen zu müssen. Sie können dies beispielsweise tun, um eine Backup-Simulation für Disaster Recovery-Zwecke einzurichten.  
In diesem Beispiel lautet der ursprüngliche Simulationsname`MySimulation`. In dem Bereich, in dem der Stack erstellt CloudFormation wird, ist bereits ein Bucket für das Schema vorhanden. AWS-Region Der Bucket enthält eine Version des Schemas, die ordnungsgemäß konfiguriert ist, um die Simulation darin auszuführen AWS-Region. Denken Sie daran, dass das Schema den Speicherort Ihrer App-ZIP-Dateien angibt, bei denen es sich genauso AWS-Region wie bei der Simulation um einen Amazon S3 S3-Bucket handelt. Der ZIP-Bucket und die Dateien der App müssen bereits im AWS-Region Zeitpunkt der Erstellung des CloudFormation Stacks vorhanden sein, da Ihre Simulation sonst nicht gestartet wird. Beachten Sie, dass der Bucket-Name in diesem Beispiel den enthält AWS-Region, aber das bestimmt nicht, wo sich der Bucket tatsächlich befindet. Sie müssen sicherstellen, dass sich der Bucket tatsächlich darin befindet AWS-Region (Sie können die Bucket-Eigenschaften in der Amazon S3-Konsole, mit Amazon S3 APIs oder mit den Amazon S3 S3-Befehlen in der überprüfen AWS CLI).  
In diesem Beispiel werden einige integrierte Funktionen und Parameter verwendet CloudFormation , um die Variablenersetzung durchzuführen. *Weitere Informationen finden Sie unter Referenz zu [systeminternen Funktionen und Referenz](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) zu [Pseudo-Parametern im Benutzerhandbuch.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html)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'
```

# Verwenden von Schnappschüssen mit AWS CloudFormation
<a name="working-with_cloudformation_snapshots"></a>

Ein [Snapshot](working-with_snapshots.md) ist eine Sicherungskopie einer Simulation. Im folgenden Beispiel wird eine neue Simulation anhand eines Snapshots statt anhand eines Schemas gestartet. Der Snapshot in diesem Beispiel wurde anhand einer SimSpace Weaver App-SDK-Projektsimulation erstellt. CloudFormation erstellt die neue Simulationsressource und initialisiert sie mit Daten aus dem Snapshot. Die neue Simulation kann sich von der `MaximumDuration` ursprünglichen Simulation unterscheiden.

Wir empfehlen Ihnen, eine Kopie der App-Rolle Ihrer ursprünglichen Simulation zu erstellen und zu verwenden. Die App-Rolle der ursprünglichen Simulation könnte gelöscht werden, wenn Sie den CloudFormation Stack dieser Simulation löschen.

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

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

Sie können jederzeit einen *Snapshot* erstellen, um Ihre Simulationsentitätsdaten zu sichern. SimSpace Weaver erstellt eine .zip-Datei in einem Amazon S3 S3-Bucket. Sie können mit dem Snapshot eine neue Simulation erstellen. SimSpace Weaver initialisiert die State Fabric Ihrer neuen Simulation mit den im Snapshot gespeicherten Entitätsdaten, startet die Spatial- und Service-Apps, die bei der Erstellung des Snapshots ausgeführt wurden, und setzt die Uhr auf das entsprechende Tick. SimSpace Weaver ruft die Konfiguration Ihrer Simulation aus dem Snapshot statt aus einer Schemadatei ab. Ihre ZIP-Dateien der App müssen sich in Amazon S3 am selben Speicherort befinden wie in der ursprünglichen Simulation. Sie müssen alle benutzerdefinierten Apps separat starten.

**Themen**
+ [Anwendungsfälle für Schnappschüsse](#working-with_snapshots_use-cases)
+ [Verwenden Sie die SimSpace Weaver Konsole, um mit Snapshots zu arbeiten](working-with_snapshots_console.md)
+ [Verwenden Sie den AWS CLI , um mit Schnappschüssen zu arbeiten](working-with_snapshots_cli.md)
+ [Verwenden von Schnappschüssen mit AWS CloudFormation](working-with_cloudformation_snapshots.md)
+ [Häufig gestellte Fragen zu Schnappschüssen](working-with_snapshots_faq.md)

## Anwendungsfälle für Schnappschüsse
<a name="working-with_snapshots_use-cases"></a>

### Kehren Sie zu einem früheren Status zurück und erkunden Sie Verzweigungsszenarien
<a name="working-with_snapshots_use-case_branching"></a>

Sie können einen Snapshot Ihrer Simulation erstellen, um sie in einem bestimmten Status zu speichern. Anschließend können Sie anhand dieses Snapshots mehrere neue Simulationen erstellen und verschiedene Szenarien untersuchen, die von diesem Status ausgehen könnten.

### Bewährte Methoden für Notfallwiederherstellung und Sicherheit
<a name="working-with_snapshots_use-cases_best-practice"></a>

Wir empfehlen, dass Sie Ihre Simulation regelmäßig sichern, insbesondere bei Simulationen, die länger als eine Stunde dauern oder mehrere Workers verwenden. Backups können Ihnen bei der Wiederherstellung nach Katastrophen und Sicherheitsvorfällen helfen. Schnappschüsse bieten Ihnen die Möglichkeit, Ihre Simulation zu sichern. Für Snapshots müssen sich Ihre ZIP-Dateien Ihrer App am selben Speicherort in Amazon S3 befinden wie zuvor. Wenn Sie in der Lage sein müssen, Ihre ZIP-Dateien Ihrer App an einen anderen Speicherort zu verschieben, müssen Sie eine benutzerdefinierte Backup-Lösung verwenden. 

Weitere Informationen zu anderen bewährten Methoden finden Sie unter [Bewährte Methoden bei der Arbeit mit SimSpace Weaver](best-practices.md) und[Bewährte Sicherheitsmethoden für SimSpace Weaver](security_best-practices.md).

### Verlängern Sie die Dauer Ihrer Simulation
<a name="working-with_snapshots_use-cases_extend-duration"></a>

Ihre *Simulationsressource* ist die Darstellung Ihrer Simulation in SimSpace Weaver. Alle Simulationsressourcen haben eine `MaximumDuration` Einstellung. Eine Simulationsressource stoppt automatisch, wenn sie ihren Wert erreicht`MaximumDuration`. Der Höchstwert von `MaximumDuration` ist `14D` (14 Tage). 

Wenn Ihre Simulation länger als die `MaximumDuration` zugehörige Simulationsressource bestehen soll, können Sie einen Snapshot erstellen, bevor die Simulationsressource ihren `MaximumDuration` Wert erreicht. Sie können mit Ihrem Snapshot eine neue Simulation starten (eine neue Simulationsressource erstellen). SimSpace Weaver initialisiert Ihre Entitätsdaten aus dem Snapshot, startet dieselben Spatial- und Service-Apps, die zuvor ausgeführt wurden, und stellt die Uhr wieder her. Sie können Ihre benutzerdefinierten Apps starten und jede zusätzliche benutzerdefinierte Initialisierung durchführen. Sie können für die `MaximumDuration` neue Simulationsressource einen anderen Wert festlegen, wenn Sie sie starten.

# Verwenden Sie die SimSpace Weaver Konsole, um mit Snapshots zu arbeiten
<a name="working-with_snapshots_console"></a>

Sie können die SimSpace Weaver Konsole verwenden, um einen Snapshot Ihrer Simulation zu erstellen.

**Topics**
+ [Snapshot erstellen](#working-with_snapshots_console_create)
+ [Starten Sie eine Simulation aus einem Snapshot](#working-with_snapshots_console_start)

## Verwenden Sie die Konsole, um einen Snapshot zu erstellen
<a name="working-with_snapshots_console_create"></a>

**So erstellen Sie einen Snapshot**

1. Melden Sie sich bei der an AWS-Managementkonsole und stellen Sie eine Verbindung zur [SimSpace Weaver Konsole](https://console.aws.amazon.com/simspaceweaver) her.

1. Wählen Sie im Navigationsbereich die Option **Simulationen** aus.

1. Wählen Sie das Optionsfeld neben dem Namen der Simulation aus. Der **Status Ihrer Simulation muss „****Gestartet“ lauten**. 

1. Wählen Sie oben auf der Seite die Option **Snapshot erstellen** aus.

1. Geben Sie unter **Snapshot-Einstellungen** für **Snapshot-Ziel** die Amazon S3 S3-URI eines Buckets oder Buckets und des Ordners ein, in dem Sie Ihren Snapshot erstellen SimSpace Weaver möchten. Sie können „**S3 durchsuchen**“ wählen, wenn Sie lieber Ihre verfügbaren Buckets durchsuchen und einen Standort auswählen möchten.
**Wichtig**  
Der Amazon S3 S3-Bucket muss sich in derselben Konfiguration AWS-Region befinden wie die Simulation.
**Anmerkung**  
SimSpace Weaver erstellt einen `snapshot` Ordner innerhalb des ausgewählten Snapshot-Ziels. SimSpace Weaver erstellt die Snapshot-.zip-Datei in diesem `snapshot` Ordner.

1. Wählen Sie **Snapshot erstellen** aus.

## Verwenden Sie die Konsole, um eine Simulation von einem Snapshot aus zu starten
<a name="working-with_snapshots_console_start"></a>

Um eine Simulation von einem Snapshot aus zu starten, muss Ihre Snapshot-.zip-Datei in einem Amazon S3 S3-Bucket vorhanden sein, auf den Ihre Simulation zugreifen kann. Ihre Simulation verwendet Berechtigungen, die in der App-Rolle definiert sind, die Sie beim Start der Simulation auswählen. Alle ZIP-Dateien der App aus der Originalsimulation müssen sich an denselben Speicherorten befinden wie bei der Erstellung des Snapshots.

**Um eine Simulation von einem Snapshot aus zu starten**

1. Melden Sie sich bei der an AWS-Managementkonsole und stellen Sie eine Verbindung zur [SimSpace Weaver Konsole](https://console.aws.amazon.com/simspaceweaver) her.

1. Wählen Sie im Navigationsbereich die Option **Simulationen** aus.

1. Wählen Sie oben auf der Seite die Option **Simulation starten** aus.

1. Geben Sie unter **Simulationseinstellungen** einen Namen und optional eine Beschreibung für Ihre Simulation ein. Ihr Simulationsname muss in Ihrem Fall eindeutig sein AWS-Konto.

1. Wählen **Sie unter Simulationsstartmethode** die Option **Einen Snapshot in Amazon S3 verwenden** aus.

1. Geben Sie für **Amazon S3 S3-URI für Snapshot** die Amazon S3 S3-URI Ihrer Snapshot-Datei ein, oder wählen Sie **Browse S3**, um die Datei zu durchsuchen und auszuwählen.
**Wichtig**  
Der Amazon S3 S3-Bucket muss sich in derselben Konfiguration AWS-Region befinden wie die Simulation.

1. Wählen Sie für die **IAM-Rolle** die App-Rolle aus, die Ihre Simulation verwenden soll.

1. Geben Sie für **Maximale Dauer** die maximale Dauer ein, für die Ihre Simulationsressource ausgeführt werden soll. Die maximale Wert ist `14D`. Weitere Informationen zur maximalen Dauer finden Sie unter[.](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)

1. Wählen Sie unter **Tags — *optional*** die Option **Neues Tag hinzufügen** aus, wenn Sie ein Tag hinzufügen möchten.

1. Wählen Sie **Simulation starten** aus.

# Verwenden Sie den AWS CLI , um mit Schnappschüssen zu arbeiten
<a name="working-with_snapshots_cli"></a>

Sie können das verwenden AWS CLI , um das SimSpace Weaver APIs von einer Befehlszeile aus aufzurufen. Sie müssen das ordnungsgemäß AWS CLI installiert und konfiguriert haben. Weitere Informationen finden Sie unter [Installation oder Aktualisierung der neuesten Version der AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) im *AWS Command Line Interface Benutzerhandbuch für Version 2.*

**Topics**
+ [Snapshot erstellen](#working-with_snapshots_cli_create)
+ [Starten Sie eine Simulation aus einem Snapshot](#working-with_snapshots_cli_start)

## Verwenden Sie den AWS CLI , um einen Snapshot zu erstellen
<a name="working-with_snapshots_cli_create"></a>

**So erstellen Sie einen Snapshot**
+ Rufen Sie in einer **Befehlszeile** die `CreateSnapshot` API auf.

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

  **Parameter**  
Simulation  
Der Name einer gestarteten Simulation. Sie können ihn verwenden`aws simspaceweaver list-simulations`, um die Namen und den Status Ihrer Simulationen zu sehen.  
Ziel  
Eine Zeichenfolge, die den Amazon S3-Ziel-Bucket und das optionale Objektschlüsselpräfix für Ihre Snapshot-Datei angibt. Ihr Objektschlüsselpräfix ist normalerweise ein Ordner in Ihrem Bucket. SimSpace Weaver erstellt Ihren Snapshot in einem `snapshot` Ordner an diesem Ziel.   
Der Amazon S3 S3-Bucket muss sich in derselben Konfiguration AWS-Region befinden wie die Simulation.

  **Beispiel**

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

Weitere Informationen zur `CreateSnapshot` API finden Sie [CreateSnapshot](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_CreateSnapshot.html)in der *AWS SimSpace Weaver API-Referenz*.

## Verwenden Sie den AWS CLI , um eine Simulation von einem Snapshot aus zu starten
<a name="working-with_snapshots_cli_start"></a>

**Um eine Simulation von einem Snapshot aus zu starten**
+ Rufen Sie in einer **Befehlszeile** die `StartSimulation` API auf.

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

  **Parameter**  
Name  
Der Name der neuen Simulation. Der Simulationsname muss in Ihrem Fall eindeutig sein AWS-Konto. Sie können verwenden`aws simspaceweaver list-simulations`, um die Namen Ihrer vorhandenen Simulationen zu sehen.  
role-arn  
Der Amazon-Ressourcenname (ARN) der App-Rolle, die Ihre Simulation verwenden wird.  
snapshot-s3-Standort  
Eine Zeichenfolge, die den Amazon S3 S3-Bucket und den Objektschlüssel Ihrer Snapshot-Datei angibt.  
Der Amazon S3 S3-Bucket muss sich in derselben Konfiguration AWS-Region befinden wie die Simulation.

  **Beispiel**

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

Weitere Informationen zur `StartSimulation` API finden Sie [StartSimulation](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)in der *AWS SimSpace Weaver API-Referenz*.

# Häufig gestellte Fragen zu Schnappschüssen
<a name="working-with_snapshots_faq"></a>

**Läuft meine Simulation während eines Snapshots weiter?**  
Ihre Simulationsressourcen werden während eines Snapshots weiter ausgeführt, und Sie erhalten für diesen Zeitraum weiterhin Abrechnungsgebühren. Die Zeit wird auf die maximale Dauer Ihrer Simulation angerechnet. Während der Snapshot läuft, erhalten Ihre Apps keine Häkchen. Wenn Ihr Uhrstatus zu dem `STARTED` Zeitpunkt war, an dem die Snapshot-Erstellung gestartet wurde, zeigt Ihre Uhr trotzdem `STARTED` den Status an. Ihre Apps erhalten nach Abschluss des Snapshots wieder Häkchen. Wenn Ihr Uhrstatus war`STOPPED`, bleibt Ihr Uhrstatus bestehen`STOPPED`. Beachten Sie, dass eine Simulation mit einem `STARTED` Status auch dann läuft, wenn ihr Uhrstatus lautet`STOPPED`.

**Was passiert, wenn gerade ein Snapshot läuft und meine Simulation ihre maximale Dauer erreicht?**  
Ihre Simulation beendet den Snapshot und stoppt dann, sobald der Snapshot-Vorgang beendet ist (entweder erfolgreich oder erfolglos). Wir empfehlen Ihnen, den Snapshot-Prozess vorher zu testen, um herauszufinden, wie lange er dauert, mit welcher Größe die Snapshot-Datei zu rechnen ist und ob er erfolgreich abgeschlossen werden sollte.

**Was passiert, wenn ich eine Simulation beende, bei der gerade ein Snapshot läuft?**  
Ein laufender Snapshot wird sofort beendet, wenn Sie die Simulation beenden. Es wird keine Snapshot-Datei erstellt.

**Wie kann ich einen laufenden Snapshot stoppen?**  
Die einzige Möglichkeit, einen laufenden Snapshot zu beenden, besteht darin, die Simulation zu beenden. **Sie können eine Simulation nicht erneut starten, nachdem Sie sie beendet haben.**

**Wie lange dauert es, bis mein Snapshot fertig ist?**  
Die Zeit, die für die Erstellung eines Snapshots benötigt wird, hängt von Ihrer Simulation ab. Wir empfehlen Ihnen, den Snapshot-Prozess vorher zu testen, um herauszufinden, wie lange Ihre Simulation dauern wird.

**Wie groß wird meine Snapshot-Datei sein?**  
Die Größe einer Snapshot-Datei hängt von Ihrer Simulation ab. Wir empfehlen Ihnen, den Snapshot-Prozess vorher zu testen, um herauszufinden, wie groß die Datei für Ihre Simulation sein könnte.

# Messaging
<a name="working-with_messaging"></a>

Die Messaging-API vereinfacht die Kommunikation von Anwendung zu Anwendung innerhalb der Simulation. APIs Das Senden und Empfangen von Nachrichten ist Teil des SimSpace Weaver App-SDK. Messaging verwendet derzeit einen Best-Effort-Ansatz zum Senden und Empfangen von Nachrichten. SimSpace Weaver versucht, send/receive Nachrichten beim nächsten Simulations-Tick zu versenden, aber es gibt keine Garantie für die Lieferung, Bestellung oder Ankunftszeit.

**Topics**
+ [Anwendungsfälle für Messaging](#working-with_messaging_use-cases)
+ [Verwenden der Nachrichtenübermittlung APIs](working-with_messaging_using.md)
+ [Wann sollte Messaging verwendet werden](working-with_messaging_when-to-use.md)
+ [Tipps für die Arbeit mit Nachrichten](working-with_messaging_tips.md)
+ [Fehler bei der Nachrichtenübermittlung und Problembehandlung](working-with_messaging_troubleshooting.md)

## Anwendungsfälle für Messaging
<a name="working-with_messaging_use-cases"></a>

**Kommunizieren Sie zwischen Simulationsanwendungen**  
Verwenden Sie die Messaging-API, um zwischen den Anwendungen in Ihrer Simulation zu kommunizieren. Verwenden Sie sie, um den Status von Objekten in der Ferne zu ändern, das Verhalten von Objekten zu ändern oder Informationen an die gesamte Simulation zu übertragen.

**Bestätigen Sie den Empfang einer Nachricht**  
Gesendete Nachrichten enthalten Informationen über den Absender im Nachrichtenkopf. Verwenden Sie diese Informationen, um nach Erhalt einer Nachricht eine Bestätigungsantwort zurückzusenden.

**Leiten Sie Daten, die von einer benutzerdefinierten App empfangen wurden, an andere Apps innerhalb der Simulation weiter**  
Messaging ist kein Ersatz für die Art und Weise, wie Clients eine Verbindung zu benutzerdefinierten Apps herstellen, die in ausgeführt SimSpace Weaver werden. Mit Messaging können Benutzer jedoch Daten von benutzerdefinierten Apps, die Clientdaten empfangen, an andere Apps weiterleiten, die keine externe Verbindung haben. Der Nachrichtenfluss kann auch umgekehrt funktionieren, sodass Apps ohne externe Verbindung Daten an eine benutzerdefinierte App und dann an einen Client weiterleiten können. 

# Verwenden der Nachrichtenübermittlung APIs
<a name="working-with_messaging_using"></a>

Die Nachrichten APIs sind im SimSpace Weaver App-SDK (Mindestversion 1.16.0) enthalten. Messaging wird in C\$1\$1, Python und unseren Integrationen mit Unreal Engine 5 und Unity unterstützt.

Es gibt zwei Funktionen, die Nachrichtentransaktionen verarbeiten: `SendMessage` und. `ReceiveMessages` Alle gesendeten Nachrichten enthalten ein Ziel und eine Nutzlast. Die `ReceiveMessages` API gibt eine Liste der Nachrichten zurück, die sich derzeit in der Warteschlange für eingehende Nachrichten einer App befinden.

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

**Nachricht senden**

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

**Empfangen Sie Nachrichten**

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

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

**Nachricht senden**

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

**Empfangen Sie Nachrichten**

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

------

**Topics**
+ [Senden von Nachrichten](#working-with_messaging_using_send)
+ [Empfangen von Nachrichten](#working-with_messaging_using_receive)
+ [Dem Absender antworten](#working-with_messaging_using_reply)

## Senden von Nachrichten
<a name="working-with_messaging_using_send"></a>

Nachrichten bestehen aus einer Transaktion (ähnlich wie bei anderen Weaver-API-Aufrufen), einer Nutzlast und einem Ziel.

### Nachrichten-Payload
<a name="working-with_messaging_using_send_payload"></a>

Die Nachrichtennutzlast ist eine flexible Datenstruktur mit bis zu 256 Byte. Wir empfehlen Folgendes als bewährte Methode für die Erstellung Ihrer Nachrichtennutzlasten.

**Um die Nachrichten-Payload zu erstellen**

1. Erstellen Sie eine Datenstruktur (z. B. eine `struct` in C\$1\$1), die den Inhalt der Nachricht definiert.

1. Erstellen Sie die Nachrichtennutzlast, die die Werte enthält, die in Ihrer Nachricht gesendet werden sollen.

1. Erstellen Sie das Objekt `MessagePayload`.

### Ziel der Nachricht
<a name="working-with_messaging_using_send_destination"></a>

Das Ziel einer Nachricht wird durch das `MessageEndpoint` Objekt definiert. Dies beinhaltet sowohl einen Endpunkttyp als auch eine Endpunkt-ID. Derzeit wird nur der Endpunkttyp unterstützt`Partition`, der es Ihnen ermöglicht, Nachrichten an andere Partitionen in der Simulation zu adressieren. Die Endpunkt-ID ist die Partitions-ID Ihres Zielziels.

Sie können in einer Nachricht nur eine Zieladresse angeben. Erstellen und senden Sie mehrere Nachrichten, wenn Sie Nachrichten an mehr als eine Partition gleichzeitig senden möchten.

Hinweise zum Auflösen eines Nachrichtenendpunkts von einer Position aus finden Sie unter[Tipps für die Arbeit mit Nachrichten](working-with_messaging_tips.md).

### Senden Sie die Nachricht
<a name="working-with_messaging_using_send_send"></a>

Sie können die `SendMessage` API verwenden, nachdem Sie die Ziel- und Payload-Objekte erstellt haben.

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

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

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

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

------

**Vollständiges Beispiel für das Senden von Nachrichten**  
Das folgende Beispiel zeigt, wie Sie eine generische Nachricht erstellen und senden können. In diesem Beispiel werden 16 einzelne Nachrichten gesendet. Jede Nachricht enthält eine Nutzlast mit einem Wert zwischen 0 und 15 und den aktuellen Simulationstick.

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

## Empfangen von Nachrichten
<a name="working-with_messaging_using_receive"></a>

SimSpace Weaver übermittelt Nachrichten in die Warteschlange für eingehende Nachrichten einer Partition. Verwenden Sie die `ReceiveMessages` API, um ein `MessageList` Objekt abzurufen, das die Nachrichten aus der Warteschlange enthält. Verarbeiten Sie jede Nachricht mit der `ExtractMessage` API, um die Nachrichtendaten abzurufen.

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

## Dem Absender antworten
<a name="working-with_messaging_using_reply"></a>

Jede empfangene Nachricht enthält einen Nachrichtenkopf mit Informationen über den ursprünglichen Absender der Nachricht. Sie können den message.header.source\$1endpoint verwenden, um eine Antwort zu senden.

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

# Wann sollte Messaging verwendet werden
<a name="working-with_messaging_when-to-use"></a>

Das Einsenden von Nachrichten SimSpace Weaver bietet ein weiteres Muster für den Informationsaustausch zwischen Simulationsanwendungen. Abonnements bieten einen Pull-Mechanismus zum Lesen von Daten aus bestimmten Anwendungen oder Bereichen der Simulation; Nachrichten bieten einen Push-Mechanismus, um Daten an bestimmte Anwendungen oder Bereiche der Simulation zu senden.

Im Folgenden sind zwei Anwendungsfälle aufgeführt, in denen es hilfreicher ist, Daten mithilfe von Nachrichten weiterzuleiten, als Daten über ein Abonnement abzurufen oder zu lesen.

**Example 1: Senden eines Befehls an eine andere App, um die Position einer Entität zu ändern**  

```
// 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);
```
Auf der Empfangsseite aktualisiert die App die Position der Entität und schreibt sie in die 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: Senden einer Nachricht zum Erstellen einer Entität an eine räumliche App**  

```
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);
```
Auf der Empfangsseite erstellt die App eine neue Entität in der State Fabric und aktualisiert deren Position.  

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

# Tipps für die Arbeit mit Nachrichten
<a name="working-with_messaging_tips"></a>

## Löst einen Endpunkt anhand einer Position oder eines Anwendungsnamens auf
<a name="working-with_messaging_tips_resolve-endpoint"></a>

Sie können die `AllPartitions` Funktion verwenden, um die räumlichen Grenzen und eine Domänen-ID abzurufen, die Sie zur Bestimmung der Nachrichtenpartition IDs und der Nachrichtenziele benötigen. Wenn Sie jedoch die Position kennen, an der Sie eine Nachricht senden möchten, aber nicht die Partitions-ID, können Sie die MessageEndpointResolver Funktion verwenden.

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

## Serialisierung und Deserialisierung der Nachrichtennutzdaten
<a name="working-with_messaging_tips_serialize-payload"></a>

Sie können die folgenden Funktionen verwenden, um Nachrichtennutzlasten zu erstellen und zu lesen. Weitere Informationen finden Sie unter MessagingUtils .h in der App-SDK-Bibliothek auf Ihrem lokalen System.

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

# Fehler bei der Nachrichtenübermittlung und Problembehandlung
<a name="working-with_messaging_troubleshooting"></a>

Bei der Verwendung von Messaging können die folgenden Fehler auftreten APIs.

## Fehler bei der Endpunktauflösung
<a name="working-with_messaging_troubleshooting_endpoint-resolution"></a>

Diese Fehler können auftreten, bevor eine App eine Nachricht sendet.

### Überprüfung des Domainnamens
<a name="working-with_messaging_troubleshooting_dns-check"></a>

Das Senden einer Nachricht an einen ungültigen Endpunkt führt zu dem folgenden Fehler:

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

Dies kann passieren, wenn Sie versuchen, eine Nachricht an eine benutzerdefinierte App zu senden und diese benutzerdefinierte App der Simulation noch nicht beigetreten ist. Stellen Sie mithilfe der `DescribeSimulation` API sicher, dass Ihre benutzerdefinierte App gestartet wurde, bevor Sie eine Nachricht an sie senden. Dieses Verhalten ist in SimSpace Weaver Local und beim dasselbe AWS Cloud.

### Position überprüfen
<a name="working-with_messaging_troubleshooting_position-check"></a>

Der Versuch, einen Endpunkt mit einem gültigen Domainnamen, aber einer ungültigen Position aufzulösen, führt zu dem folgenden Fehler.

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

Wir empfehlen, das `MessageEndpointResolver` in der im SimSpace Weaver App-SDK enthaltenen `MessageUtils` Bibliothek zu verwenden.

## Fehler beim Senden von Nachrichten
<a name="working-with_messaging_troubleshooting_message-sending"></a>

Die folgenden Fehler können auftreten, wenn eine App eine Nachricht sendet.

### Das Limit für das Senden von Nachrichten pro App und Tick wurde überschritten
<a name="working-with_messaging_troubleshooting_send-limit"></a>

Das aktuelle Limit für die Anzahl der Nachrichten, die pro App pro Simulationstrick gesendet werden können, liegt bei 128. Nachfolgende Aufrufe mit demselben Tick schlagen mit dem folgenden Fehler fehl: 

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

SimSpace Weaver versucht, beim nächsten Tick noch nicht gesendete Nachrichten zu senden. Senken Sie die Sendefrequenz, um dieses Problem zu beheben. Kombinieren Sie Nachrichtennutzlasten, die unter dem 256-Byte-Limit liegen, um die Anzahl der ausgehenden Nachrichten zu verringern.

Dieses Verhalten ist in SimSpace Weaver Local und in der identisch. AWS Cloud

### Die Größenbeschränkung für die Nachrichtennutzlast wurde überschritten
<a name="working-with_messaging_troubleshooting_size-limit"></a>

Das aktuelle Limit für die Größe der Nachrichtennutzlast beträgt 256 Byte SimSpace Weaver Local sowohl in als auch in der. AWS Cloud Das Senden einer Nachricht mit einer Nutzlast von mehr als 256 Byte führt zu dem folgenden Fehler:

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

SimSpace Weaver überprüft jede Nachricht und lehnt nur diejenigen ab, die das Limit überschreiten. Wenn Ihre App beispielsweise versucht, 10 Nachrichten zu senden, und eine Nachricht die Prüfung nicht besteht, wird nur diese eine Nachricht zurückgewiesen. SimSpace Weaver sendet die anderen 9 Nachrichten.

Dieses Verhalten ist dasselbe in SimSpace Weaver Local und dem AWS Cloud.

### Ziel ist dasselbe wie Quelle
<a name="working-with_messaging_troubleshooting_dst-src-same"></a>

Apps können keine Nachrichten an Partitionen senden, deren Eigentümer sie sind. Sie erhalten die folgende Fehlermeldung, wenn eine App eine Nachricht an eine Partition sendet, deren Eigentümer sie ist.

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

Dieses Verhalten ist in SimSpace Weaver Local und beim dasselbe AWS Cloud.

### Nachrichtenübermittlung nach besten Kräften
<a name="working-with_messaging_troubleshooting_best-effort"></a>

SimSpace Weaver garantiert keine Nachrichtenzustellung. Der Dienst versucht, die Zustellung der Nachrichten beim nächsten Simulations-Tick abzuschließen, aber Nachrichten können verloren gehen oder sich verzögern.