

Pemberitahuan akhir dukungan: Pada 20 Mei 2026, AWS akan mengakhiri dukungan untuk AWS SimSpace Weaver. Setelah 20 Mei 2026, Anda tidak akan lagi dapat mengakses SimSpace Weaver konsol atau SimSpace Weaver sumber daya. Untuk informasi selengkapnya, lihat [AWS SimSpace Weaver akhir dukungan](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html). 

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Bekerja dengan SimSpace Weaver
<a name="working-with"></a>

Bab ini memberikan informasi dan panduan untuk membantu Anda membangun aplikasi Anda sendiri SimSpace Weaver.

**Topics**
+ [Mengkonfigurasi simulasi Anda](working-with_configuring-simulation.md)
+ [Durasi maksimum simulasi](working-with_max-duration.md)
+ [Mengembangkan aplikasi](working-with_developing-apps.md)
+ [Mengembangkan aplikasi klien](working-with_developing-client-applications.md)
+ [Dapatkan alamat IP dan nomor port aplikasi khusus](working-with_get-ip.md)
+ [Meluncurkan klien tampilan Unreal Engine](working-with_unreal-client.md)
+ [Pembangunan lokal di SimSpace Weaver](working-with_local-development.md)
+ [AWS SimSpace Weaver aplikasi SDK](working-with_app-sdk.md)
+ [AWS SimSpace Weaver kerangka demo](working-with_demo-framework.md)
+ [Bekerja dengan kuota layanan](working-with_quotas.md)
+ [Simulasi debugging](working-with_debugging.md)
+ [Wadah khusus](working-with_custom-containers.md)
+ [Bekerja menggunakan Python](working-with_python.md)
+ [Support untuk mesin lain](working-with_engines.md)
+ [Penggunaan perangkat lunak berlisensi dengan AWS SimSpace Weaver](working-with_byol.md)
+ [Mengelola sumber daya Anda dengan AWS CloudFormation](working-with_cloudformation.md)
+ [Snapshot](working-with_snapshots.md)
+ [Perpesanan](working-with_messaging.md)

# Mengkonfigurasi simulasi Anda
<a name="working-with_configuring-simulation"></a>

**Skema simulasi (atau **skema****) adalah YAML-file teks berformat yang menentukan konfigurasi untuk simulasi. Anda dapat menggunakan skema yang sama untuk memulai beberapa simulasi. File skema terletak di folder proyek untuk simulasi Anda. Anda dapat menggunakan editor teks apa pun untuk mengedit file. SimSpace Weaver hanya membaca skema Anda ketika memulai simulasi. Setiap pengeditan yang Anda buat pada file skema hanya memengaruhi simulasi baru yang Anda mulai setelah pengeditan. 

Untuk mengonfigurasi simulasi Anda, edit file skema simulasi Anda (gunakan pemisah jalur yang sesuai untuk sistem operasi Anda):

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

Anda mengunggah skema simulasi saat membuat simulasi baru. Skrip pembantu mulai cepat untuk proyek Anda akan mengunggah skema sebagai bagian dari prosesnya untuk membangun simulasi Anda: 

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

Untuk informasi selengkapnya tentang menjalankan skrip mulai cepat, lihat [Tutorial terperinci](getting-started_detailed.md) di bagian [Memulai](getting-started.md) panduan ini.

## Parameter konfigurasi simulasi
<a name="working-with_configuring-simulation_config-parameters"></a>

Skema simulasi berisi informasi bootstrap, termasuk:
+ **Properti simulasi** [— Versi SDK dan konfigurasi komputasi (jenis dan jumlah pekerja)](w2aac51.md#glossary_worker)
+ **Jam** - tingkat centang dan toleransi
+ **Strategi partisi spasial** — topologi spasial (seperti grid), batas, dan kelompok penempatan (pengelompokan partisi spasial pada pekerja)
+ **Domain dan aplikasinya** — bucket aplikasi, jalur, dan perintah peluncuran

SimSpace Weaver menggunakan konfigurasi skema Anda untuk mengonfigurasi dan mengatur partisi spasial, meluncurkan aplikasi, dan memajukan simulasi pada tingkat centang yang Anda tentukan. 

**catatan**  
Skrip create-project di SDK SimSpace Weaver aplikasi akan secara otomatis menghasilkan skema simulasi untuk Anda, berdasarkan contoh aplikasi.

Topik berikut menjelaskan parameter dalam skema simulasi. Untuk deskripsi lengkap tentang skema simulasi, lihat. [SimSpace Weaver referensi skema simulasi](schema-reference.md) 

**Topics**
+ [Parameter konfigurasi simulasi](#working-with_configuring-simulation_config-parameters)
+ [Versi SDK](working-with_configuring-simulation_sdk-version.md)
+ [Sifat simulasi](working-with_configuring-simulation_simulation-properties.md)
+ [Pekerja](working-with_configuring-simulation_workers.md)
+ [Jam](working-with_configuring-simulation_clock.md)
+ [Strategi partisi](working-with_configuring-simulation_partitioning-strategies.md)
+ [Domain](working-with_configuring-simulation_domains.md)

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

`sdk_version`Bidang menentukan versi skema SimSpace Weaver yang diformat untuk. Nilai valid: `1.17`, `1.16`, `1.15`, `1.14`, `1.13`, `1.12`

**penting**  
Nilai `sdk_version` hanya mencakup nomor versi utama dan nomor versi minor pertama. Misalnya, nilai `1.12` menentukan semua versi`1.12.x`, seperti, `1.12.0``1.12.1`, dan`1.12.2`.

# Sifat simulasi
<a name="working-with_configuring-simulation_simulation-properties"></a>

`simulation_properties`Bagian skema Anda menentukan konfigurasi logging dan tipe data untuk bidang indeks (biasanya lokasi spasial) entitas.

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

Nilai `log_destination_service` menentukan interpretasi nilai`log_destination_resource_name`. Saat ini, satu-satunya nilai yang didukung adalah `logs`. Ini berarti bahwa nilai `log_destination_resource_name` adalah nama grup log di Amazon CloudWatch Logs

**catatan**  
Logging adalah opsional. Jika Anda tidak mengonfigurasi properti tujuan log maka simulasi Anda tidak akan menghasilkan log.

Properti `default_entity_index_key_type` diperlukan. Satu-satunya nilai yang valid adalah `Vector3<f32>`.

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

`workers`Bagian ini menentukan jenis dan jumlah pekerja yang Anda inginkan untuk simulasi Anda. SimSpace Weaver menggunakan tipe pekerjanya sendiri yang memetakan ke jenis EC2 instans Amazon. 

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

## Mengaktifkan simulasi multi-pekerja
<a name="working-with_configuring-simulation_workers_multi-worker"></a>

Anda dapat membuat simulasi yang menggunakan lebih dari 1 pekerja. Secara default, simulasi menggunakan 1 pekerja. Anda harus memodifikasi skema simulasi Anda sebelum memulai simulasi. 

**catatan**  
Anda tidak dapat mengubah simulasi yang sudah dimulai. Jika Anda ingin mengaktifkan multi-pekerja untuk simulasi yang sedang berjalan, Anda harus menghentikan dan menghapus simulasi terlebih dahulu.

Untuk menggunakan lebih dari satu pekerja, atur `desired` jumlah instance komputasi ke nilai yang lebih besar dari 1. Ada jumlah maksimum aplikasi untuk setiap pekerja. Untuk informasi lebih lanjut, lihat[SimSpace Titik akhir dan kuota Weaver](service-quotas.md). SimSpace Weaver hanya akan menggunakan lebih dari 1 pekerja ketika jumlah aplikasi pada pekerja melebihi batas ini. SimSpace Weaver dapat menempatkan aplikasi pada salah satu pekerja yang tersedia. Penempatan aplikasi pada pekerja tertentu tidak dijamin. 

Cuplikan skema berikut menunjukkan konfigurasi untuk simulasi yang meminta 2 pekerja. SimSpace Weaver akan mencoba mengalokasikan pekerja kedua jika jumlah aplikasi melebihi jumlah maksimum aplikasi untuk 1 pekerja.

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

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

`clock`Bagian ini menentukan properti dari jam simulasi. Saat ini, Anda hanya dapat mengonfigurasi **tingkat centang** (jumlah kutu per detik yang dikirim jam ke aplikasi). Tingkat centang adalah tingkat maksimum. Tingkat tick efektif bisa lebih rendah karena semua operasi (seperti pembaruan entitas) untuk centang harus selesai sebelum centang berikutnya dapat dimulai. Tick rate juga disebut **clock rate**.

Nilai yang valid untuk `tick_rate` bergantung pada yang `sdk_version` ditentukan dalam skema Anda.

**Nilai yang valid untuk tingkat centang**
+ Versi lebih awal dari`"1.14"`:
  + `10`
  + `15`
  + `30`
+ Versi `"1.14"` atau yang lebih baru:
  + `"10"`
  + `"15"`
  + `"30"`
  + `"unlimited"`

    Untuk informasi selengkapnya, lihat [Tingkat centang tak terbatas](#working-with_configuring-simulation_clock_unlimited).

**penting**  
Untuk skema dengan `sdk_version` lebih awal `"1.14"` dari nilai `tick_rate` adalah bilangan **bulat**, seperti. `30`
Untuk skema dengan `sdk_version` of `"1.14"` atau yang lebih baru, nilai `tick_rate` adalah **string**, seperti`"30"`. Nilai **harus menyertakan tanda kutip ganda**.  
Jika Anda mengonversi versi `"1.12"` atau `"1.13"` skema ke versi `"1.14"` atau yang lebih baru, Anda harus menyertakan nilai `tick_rate` dalam tanda kutip ganda.

## Tingkat centang tak terbatas
<a name="working-with_configuring-simulation_clock_unlimited"></a>

Anda dapat mengatur `tick_rate` to `"unlimited"` untuk mengaktifkan simulasi Anda berjalan secepat kode Anda dapat mengeksekusi. Dengan tingkat centang tak terbatas, SimSpace Weaver kirimkan centang berikutnya segera setelah semua aplikasi menyelesaikan komit untuk centang saat ini.

**penting**  
Tingkat centang tak terbatas tidak didukung dalam SimSpace Weaver versi sebelum 1.14.0. Nilai minimum `sdk_version` dalam skema adalah`"1.14"`.

**Tingkat centang tak terbatas di SimSpace Weaver Local**  
SimSpace Weaver Localmengimplementasikan `"unlimited"` seolah-olah skema menentukan tingkat centang 10 kHz (10000). Efeknya sama dengan tingkat centang tak terbatas di AWS Cloud. Anda masih menentukan `tick_rate: "unlimited"` dalam skema Anda. Untuk informasi selengkapnya tentang SimSpace Weaver Local, lihat [Pembangunan lokal di SimSpace Weaver](working-with_local-development.md).

## Pertanyaan yang sering diajukan tentang jam
<a name="working-with_configuring-simulation_clock_faq"></a>

### T1. Dapatkah saya mengubah simulasi STARTED untuk menggunakan tick rate yang berbeda?
<a name="working-with_configuring-simulation_clock_faq_q1"></a>

Anda tidak dapat mengubah tingkat centang simulasi yang sudah ada AWS Cloud di setiap tahap siklus hidupnya. Anda juga tidak dapat mengubah tingkat centang simulasi yang berjalan. SimSpace Weaver Local Anda dapat mengatur `tick_rate` dalam skema dan memulai simulasi baru dari skema itu.

### T2. Dapatkah saya menjalankan simulasi saya dengan tingkat centang tak terbatas dalam versi yang lebih awal dari 1,14?
<a name="working-with_configuring-simulation_clock_faq_q2"></a>

Tidak, tingkat centang tak terbatas tidak didukung dalam versi sebelum 1.14.0.

## Memecahkan masalah kesalahan jam
<a name="working-with_configuring-simulation_clock_troubleshooting"></a>

Jika simulasi Anda gagal untuk memulai, Anda dapat memeriksa nilai `"StartError"` dalam output **DescribeSimulation**API. `tick_rate`Nilai yang tidak valid dalam skema Anda akan menghasilkan kesalahan berikut.

**catatan**  
Output kesalahan yang ditampilkan di sini ditampilkan pada beberapa baris untuk meningkatkan keterbacaan. Output kesalahan sebenarnya adalah satu baris.
+ `sdk_version`Itu lebih awal dari `"1.14"` dan nilai `tick_rate` adalah bilangan bulat yang tidak valid. Nilai valid: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"}]"
  ```
+ `sdk_version`Itu lebih awal dari `"1.14"` dan nilainya `tick_rate` adalah string. Nilai valid: `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\"}]"
  ```
+ `sdk_version`Is `"1.14"` atau yang lebih baru dan nilai `tick_rate` adalah string yang tidak valid. Nilai valid: `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"}]"
  ```
+ `sdk_version`Adalah `"1.14"` atau lebih baru dan nilai dari `tick_rate` adalah bilangan bulat. Nilai valid: `"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\"}]"
  ```

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

`partitioning_strategies`Bagian ini menentukan properti konfigurasi untuk partisi aplikasi spasial. Anda memberikan nama Anda sendiri untuk strategi partisi (sekumpulan properti di bagian ini) dan menggunakannya dalam konfigurasi aplikasi spasial Anda.

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

`topology`Properti menentukan jenis sistem koordinat yang digunakan simulasi Anda. Nilai `Grid` menentukan grid 2 dimensi (2D).

Untuk `Grid` topologi, ruang simulasi dimodelkan sebagai kotak pembatas sejajar sumbu (AABB). Anda menentukan batas koordinat untuk setiap sumbu AABB Anda di properti. `aabb_bounds` Semua entitas yang ada secara spasial dalam simulasi Anda harus memiliki posisi di dalam AABB.

## Grup penempatan grid
<a name="working-with_configuring-simulation_partitioning-strategies_placement-groups"></a>

**Grup penempatan adalah kumpulan** partisi aplikasi spasial yang SimSpace Weaver ingin Anda tempatkan pada pekerja yang sama. Anda menentukan jumlah dan susunan grup penempatan (dalam kotak) di `grid_placement_groups` properti. SimSpace Weaver akan mencoba untuk mendistribusikan partisi secara merata di seluruh grup penempatan. Area kepemilikan aplikasi spasial dengan partisi dalam grup penempatan yang sama akan berdekatan secara spasial.

Kami merekomendasikan bahwa x\$1 y sama dengan jumlah pekerja yang Anda inginkan. Jika tidak sama, SimSpace Weaver akan mencoba menyeimbangkan grup penempatan Anda di seluruh pekerja yang tersedia.

Jika Anda tidak menentukan konfigurasi grup penempatan, SimSpace Weaver akan menghitung satu untuk Anda.

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

Anda memberikan nama untuk satu set properti konfigurasi untuk domain. Setelan peluncuran untuk aplikasi dalam domain menentukan jenis domain:
+ **`launch_apps_via_start_app_call`**— domain kustom
+ **`launch_apps_by_partitioning_strategy`**— domain spasial
+ **`launch_apps_per_worker`**(tidak termasuk dalam aplikasi sampel) — domain layanan

**penting**  
SimSpace Weaver mendukung hingga 5 domain untuk setiap simulasi. Ini mencakup semua domain spasial, kustom, dan layanan.

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

**catatan**  
SimSpace Weaver proyek SDK aplikasi versi 1.12.x menggunakan bucket terpisah untuk file aplikasi.zip dan skema:  
penenun- - *lowercase-project-name* -app-ritsleting *account-number* - *region*
penenun- - -skema *lowercase-project-name* - *account-number* *region*

**Topics**
+ [Konfigurasi aplikasi](working-with_configuring-simulation_domains_app-config.md)
+ [Mengkonfigurasi domain spasial](working-with_configuring-simulation_domains_spatial.md)
+ [Titik akhir jaringan](working-with_configuring-simulation_domains_endpoints.md)
+ [Mengkonfigurasi domain layanan](working-with_configuring-simulation_domains_service-domains.md)

# Konfigurasi aplikasi
<a name="working-with_configuring-simulation_domains_app-config"></a>

Anda menentukan konfigurasi app (`app_config`) sebagai bagian dari konfigurasi domainnya. Semua jenis domain menggunakan properti konfigurasi aplikasi yang sama ini.

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

**catatan**  
SimSpace Weaver proyek SDK aplikasi versi 1.12.x menggunakan bucket terpisah untuk file aplikasi.zip dan skema:  
penenun- - *lowercase-project-name* -app-ritsleting *account-number* - *region*
penenun- - -skema *lowercase-project-name* - *account-number* *region*

`package`Properti menentukan URI S3 dari file zip dalam bucket S3. File zip berisi aplikasi yang dapat dieksekusi (juga disebut *biner*) dan sumber daya lain yang dibutuhkan (seperti pustaka). Setiap instance aplikasi yang dapat dieksekusi berjalan dalam Docker wadah pada pekerja. 

`launch_command`Properti menentukan nama opsi executable dan baris perintah apa pun untuk menjalankan aplikasi. Nilai dari `launch_command` adalah array. Setiap token dari seluruh string perintah peluncuran adalah elemen dalam array.

**Contoh**
+ Untuk perintah peluncuran: `MyTestApp --option1 value1`
+ Tentukan: `launch_command: ["MyTestApp", "-option1", "value1"]`

`required_resource_units`Properti menentukan jumlah unit sumber daya komputasi yang SimSpace Weaver harus dialokasikan ke aplikasi ini. Unit sumber daya komputasi adalah jumlah kapasitas pemrosesan (vCPU) dan memori yang tetap (RAM) pada pekerja. Anda dapat meningkatkan nilai ini untuk meningkatkan jumlah daya komputasi yang tersedia untuk aplikasi saat dijalankan pada pekerja. Ada sejumlah unit sumber daya komputasi terbatas pada setiap pekerja. Untuk informasi selengkapnya, lihat [SimSpace Titik akhir dan kuota Weaver](service-quotas.md).

# Mengkonfigurasi domain spasial
<a name="working-with_configuring-simulation_domains_spatial"></a>

Untuk domain spasial, Anda harus menentukan. `partitioning_strategy` Nilai properti ini adalah nama yang Anda berikan untuk strategi partisi yang Anda definisikan di bagian lain dari skema. 

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

**catatan**  
SimSpace Weaver proyek SDK aplikasi versi 1.12.x menggunakan bucket terpisah untuk file aplikasi.zip dan skema:  
penenun- - *lowercase-project-name* -app-ritsleting *account-number* - *region*
penenun- - -skema *lowercase-project-name* - *account-number* *region*

Strategi partisi dengan `Grid` topologi (satu-satunya topologi yang didukung dalam rilis ini) mengarahkan SimSpace Weaver untuk mengatur partisi aplikasi spasial domain ini dalam kisi. `grid_partition`Properti menentukan jumlah baris dan kolom dari grid partisi. 

SimSpace Weaver akan memulai 1 instance aplikasi spasial untuk setiap sel di kisi partisi. Misalnya, jika domain spasial memiliki `grid_partition` nilai `x: 2` dan`y: 2`, ada 2 \$1 2 = 4 partisi dalam domain spasial. SimSpace Weaver akan memulai 4 instance aplikasi yang dikonfigurasi dalam domain spasial dan menetapkan 1 partisi ke setiap instance aplikasi.

**Topik**
+ [Persyaratan sumber daya untuk domain spasial](#working-with_configuring-simulation_domains_spatial_resources)
+ [Beberapa domain spasial](#working-with_configuring-simulation_domains_spatial_multiple)
+ [Pertanyaan yang sering diajukan tentang domain spasial](#working-with_configuring-simulation_domains_spatial_faq)
+ [Memecahkan masalah domain spasial](#working-with_configuring-simulation_domains_spatial_troubleshooting)

## Persyaratan sumber daya untuk domain spasial
<a name="working-with_configuring-simulation_domains_spatial_resources"></a>

Anda dapat menetapkan hingga 17 unit sumber daya komputasi untuk setiap pekerja. Anda menentukan jumlah unit sumber daya komputasi yang digunakan setiap aplikasi spasial di `app_config` bagian domain spasial Anda.

**Example cuplikan skema yang menampilkan unit sumber daya komputasi untuk aplikasi spasial**  

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

Untuk menghitung jumlah unit sumber daya komputasi yang dibutuhkan domain, kalikan jumlah sel di kisi Anda (dalam`grid_partition`, `x` \$1`y`) dengan jumlah unit sumber daya komputasi yang ditetapkan ke aplikasi spasial.

Untuk contoh sebelumnya, domain `MySpatialDomain` menentukan:
+ `x`: `2`
+ `y`: `2`
+ `compute`: `1`

Grid untuk `MySpatialDomain` memiliki 2 \$1 2 = 4 sel. Domain spasial membutuhkan 4 \$1 1 = 4 unit sumber daya komputasi.

Jumlah total unit sumber daya komputasi untuk semua domain yang ditentukan dalam skema Anda harus kurang dari atau sama dengan jumlah pekerja dikalikan dengan `desired` jumlah maksimum unit sumber daya komputasi untuk setiap pekerja (17).

## Beberapa domain spasial
<a name="working-with_configuring-simulation_domains_spatial_multiple"></a>

Anda dapat mengonfigurasi simulasi Anda untuk menggunakan lebih dari 1 domain spasial. Misalnya, Anda dapat menggunakan 1 domain spasial untuk mengontrol aktor utama dalam simulasi (seperti orang dan mobil) dan domain spasial yang berbeda untuk mengontrol lingkungan.

Anda juga dapat menggunakan beberapa domain spasial untuk menetapkan sumber daya yang berbeda ke berbagai bagian simulasi Anda. Misalnya, jika simulasi Anda memiliki tipe entitas yang memiliki 10x lebih banyak instance entitas daripada tipe lain, Anda dapat membuat domain yang berbeda untuk menangani setiap jenis entitas dan mengalokasikan lebih banyak sumber daya untuk domain dengan lebih banyak entitas.

**penting**  
SimSpace Weaver versi sebelum 1.14.0 tidak mendukung beberapa domain spasial.

**penting**  
AWS SimSpace Weaver Localsaat ini tidak mendukung beberapa domain spasial. Untuk informasi selengkapnya tentang SimSpace Weaver Local, lihat [Pembangunan lokal di SimSpace Weaver](working-with_local-development.md).

**penting**  
SimSpace Weaver mendukung hingga 5 domain untuk setiap simulasi. Ini mencakup semua domain spasial, kustom, dan layanan.

### Konfigurasikan beberapa domain spasial
<a name="working-with_configuring-simulation_domains_spatial_multiple_configure"></a>

Untuk mengonfigurasi lebih dari 1 domain spasial, tambahkan definisi domain spasial lainnya sebagai bagian bernama terpisah dalam skema Anda. Setiap domain harus menentukan `launch_apps_by_partitioning_strategy` kuncinya. Lihat contoh skema berikut.

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

### Menempatkan domain spasial bersama-sama
<a name="working-with_configuring-simulation_domains_spatial_multiple_placement"></a>

Dalam beberapa skenario, Anda mungkin ingin menempatkan partisi untuk domain spasial pada pekerja di samping partisi dari domain lain. Ini dapat meningkatkan karakteristik kinerja jika partisi tersebut membuat langganan lintas domain satu sama lain.

Tambahkan kunci tingkat atas `placement_constraints` ke skema Anda untuk menentukan domain mana yang SimSpace Weaver harus ditempatkan bersama. `on_workers`Kunci yang diperlukan harus mengacu pada `workers` konfigurasi bernama dalam skema.

**Example cuplikan skema yang menunjukkan domain spasial yang ditempatkan bersama**  

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

**penting**  
Jika Anda menggunakan grup penempatan:  
Pastikan bahwa x\$1 y adalah kelipatan dari jumlah pekerja.
Pastikan bahwa nilai grup penempatan adalah pembagi umum untuk dimensi kisi domain yang Anda tempatkan bersama.
Jika Anda **tidak menggunakan** grup penempatan:  
Pastikan bahwa 1 sumbu grid domain spasial Anda memiliki pembagi umum yang sama dengan jumlah pekerja.
Untuk informasi selengkapnya tentang grup penempatan, lihat[Strategi partisi](working-with_configuring-simulation_partitioning-strategies.md#working-with_configuring-simulation_partitioning-strategies_placement-groups).

## Pertanyaan yang sering diajukan tentang domain spasial
<a name="working-with_configuring-simulation_domains_spatial_faq"></a>

### T1. Bagaimana saya bisa menambahkan domain spasial lain ke simulasi yang ada?
<a name="working-with_configuring-simulation_domains_spatial_faq_q1"></a>
+ **Untuk simulasi yang sedang berjalan** — Anda tidak dapat mengubah konfigurasi untuk simulasi yang sedang berjalan. Ubah konfigurasi domain dalam skema, unggah skema dan ritsleting aplikasi, dan mulai simulasi baru.
+ **Untuk simulasi baru** — Tambahkan konfigurasi domain ke skema, unggah skema dan ritsleting aplikasi, dan mulai simulasi baru.

## Memecahkan masalah domain spasial
<a name="working-with_configuring-simulation_domains_spatial_troubleshooting"></a>

Mungkin mendapatkan kesalahan berikut ketika Anda mencoba memulai simulasi Anda tetapi konfigurasi domain Anda tidak valid.

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

**Potensi penyebab**
+ Skema mengalokasikan lebih banyak unit sumber daya komputasi untuk aplikasi daripada yang tersedia pada pekerja.
+ SimSpace Weaver tidak dapat menentukan pengaturan untuk menempatkan domain bersama pada pekerja. Ini terjadi ketika Anda menentukan beberapa domain spasial tetapi tidak ada pembagi umum atau kelipatan antara kisi domain, seperti antara kisi 2x4 dan kisi 3x5).

# Titik akhir jaringan
<a name="working-with_configuring-simulation_domains_endpoints"></a>

Aplikasi kustom dan layanan dapat memiliki titik akhir jaringan yang dapat dihubungkan oleh klien eksternal. Anda menentukan daftar nomor port sebagai nilai untuk `ingress_ports` dalam`endpoint_config`. Nomor port ini adalah TCP dan UDP. Aplikasi kustom atau layanan harus mengikat ke nomor port yang Anda tentukan. `ingress_ports` SimSpace Weaver secara dinamis mengalokasikan nomor port saat runtime dan memetakan port ini ke port dinamis. Anda dapat memanggil **describe-app** API setelah aplikasi Anda mulai menemukan nomor port dinamis (aktual). Untuk informasi lebih lanjut, lihat [Dapatkan alamat IP dan nomor port aplikasi khususDapatkan alamat IP dan nomor port](working-with_get-ip.md) dari tutorial mulai cepat.

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

**catatan**  
SimSpace Weaver proyek SDK aplikasi versi 1.12.x menggunakan bucket terpisah untuk file aplikasi.zip dan skema:  
penenun- - *lowercase-project-name* -app-ritsleting *account-number* - *region*
penenun- - -skema *lowercase-project-name* - *account-number* *region*

**catatan**  
`endpoint_config`adalah properti opsional untuk aplikasi khusus dan aplikasi layanan. Jika Anda tidak menentukan, `endpoint_config` maka aplikasi tidak akan memiliki titik akhir jaringan.

# Mengkonfigurasi domain layanan
<a name="working-with_configuring-simulation_domains_service-domains"></a>

Kehadiran `launch_apps_per_worker:` dalam konfigurasi domain menunjukkan bahwa itu adalah domain layanan yang memiliki aplikasi layanan. SimSpace Weaver memulai dan menghentikan aplikasi layanan untuk Anda. Saat SimSpace Weaver memulai dan menghentikan aplikasi, aplikasi dianggap memiliki *siklus hidup terkelola*. SimSpace Weaver saat ini mendukung memulai 1 atau 2 aplikasi layanan pada setiap pekerja. 

**Example Contoh domain yang dikonfigurasi untuk meluncurkan 1 aplikasi layanan pada setiap pekerja**  

```
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 Contoh domain yang dikonfigurasi untuk meluncurkan 2 aplikasi layanan pada setiap pekerja**  

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

# Durasi maksimum simulasi
<a name="working-with_max-duration"></a>

Setiap simulasi AWS SimSpace Weaver memiliki pengaturan *durasi maksimum* yang menentukan waktu maksimum simulasi dapat dijalankan. Anda memberikan durasi maksimum sebagai parameter ketika Anda memulai simulasi. [Antarmuka pemrograman `StartSimulation` aplikasi (API)](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html) memiliki parameter opsional`MaximumDuration`. Nilai parameter adalah sejumlah menit (m atau M), jam (h atau H), atau hari (d atau D). Misalnya, `1h` atau `1H` berarti 1 jam. SimSpace Weaver menghentikan simulasi Anda ketika mencapai batas ini.

## Nilai maksimum
<a name="working-with_max-duration_max-value"></a>

Nilai valid tertinggi untuk `MaximumDuration` adalah`14D`, atau setara dalam jam (`336H`) atau menit (`20160M`).

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

Parameter `MaximumDuration` bersifat opsional. Jika Anda tidak memberikan nilai, SimSpace Weaver gunakan nilai`14D`.

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

Nilai valid terendah untuk `MaximumDuration` adalah nilai yang secara numerik setara `0` dengan. Misalnya, nilai,`0M`, dan `0H``0D`, semuanya setara secara numerik dengan`0`.

Jika Anda memberikan nilai minimum untuk durasi maksimum, simulasi Anda segera beralih ke `STOPPING` status segera setelah mencapai status. `STARTED`

## Memulai simulasi menggunakan konsol
<a name="working-with_max-duration_console"></a>

Anda dapat memberikan nilai untuk **Durasi maksimum** saat memulai simulasi di [SimSpace Weaver konsol](https://console.aws.amazon.com/simspaceweaver). Masukkan nilai di bidang **Durasi maksimum** formulir **Pengaturan simulasi** saat Anda memilih **Mulai simulasi**.

**penting**  
Jika Anda tidak memberikan nilai untuk **Durasi maksimum**, SimSpace Weaver gunakan [nilai default](#working-with_max-duration_default-value) (`14D`).

## Status simulasi yang mencapai durasi maksimumnya
<a name="working-with_max-duration_sim-state"></a>

Ketika SimSpace Weaver secara otomatis menghentikan simulasi yang mencapai durasi maksimumnya, **status** simulasi adalah `STOPPING` (jika sedang berlangsung) atau. `STOPPED` Di [SimSpace Weaver konsol](https://console.aws.amazon.com/simspaceweaver), **status target** simulasi masih`STARTED`, karena itu adalah status terakhir yang diminta oleh pengguna.

# Mengembangkan aplikasi
<a name="working-with_developing-apps"></a>

SimSpace Weaver Pengembangan membutuhkan Amazon Linux 2 (AL2) lingkungan untuk membangun aplikasi karena simulasi Anda berjalan Amazon Linux di AWS Cloud. Jika Anda menggunakan Windows, Anda dapat menggunakan skrip di SDK SimSpace Weaver aplikasi untuk membuat dan meluncurkan Docker kontainer yang berjalan AL2 dengan dependensi yang Anda butuhkan untuk membangun SimSpace Weaver aplikasi. Anda juga dapat meluncurkan AL2 lingkungan menggunakan Windows Subsystem for Linux (WSL), atau gunakan asli AL2 sistem. Untuk informasi selengkapnya, lihat [Siapkan lingkungan lokal Anda untuk SimSpace Weaver](setting-up_local.md).

**catatan**  
Terlepas dari bagaimana Anda mengonfigurasi lingkungan pengembangan lokal Anda, aplikasi Anda berjalan di Docker wadah saat Anda mengunggahnya untuk dijalankan di AWS Cloud. **Aplikasi Anda tidak memiliki akses langsung ke sistem operasi host**.

**Alur umum SimSpace Weaver aplikasi**

1. Buat aplikasi.

1. Lingkaran:

   1. Mulai pembaruan dengan membuat file`Transaction`.

      1. Keluar dari loop jika simulasi dimatikan.

   1. Memproses acara entitas berlangganan dan kepemilikan.

   1. Perbarui simulasi.

   1. Komit `Transaction` untuk mengakhiri pembaruan.

1. Hancurkan aplikasi.

## Aplikasi spasial
<a name="working-with_developing-apps_spatial-apps"></a>

Setiap aplikasi spasial memiliki area kepemilikan yang merupakan wilayah spasial dunia simulasi. Entitas yang terletak di area kepemilikan aplikasi spasial disimpan di partisi yang ditetapkan aplikasi. Aplikasi spasial tunggal memiliki kepemilikan penuh (izin baca dan tulis) atas semua entitas dalam partisi yang ditetapkan. Tidak ada aplikasi lain yang dapat menulis ke entitas tersebut. Aplikasi spasial memajukan keadaan entitasnya. Setiap aplikasi spasial hanya memiliki 1 partisi. SimSpace Weaver menggunakan lokasi spasial entitas untuk mengindeks dan menetapkannya ke partisi aplikasi spasial.

 SimSpace Weaver Aplikasi SDK menyediakan contoh aplikasi. Anda dapat menemukan kode sumber untuk aplikasi spasial aplikasi sampel di folder berikut (gunakan pemisah jalur yang benar untuk sistem operasi Anda): 

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

## Aplikasi kustom
<a name="working-with_developing-apps_custom-apps"></a>

Anda membuat dan menggunakan aplikasi khusus untuk berinteraksi dengan simulasi. 

**Aplikasi kustom bisa**
+ Buat entitas
+ Berlangganan partisi lain
+ Komit perubahan

**Alur umum aplikasi kustom**

1. Buat aplikasi.

1. Berlangganan ke wilayah tertentu dalam simulasi:

   1. Buat a `Transaction` untuk memulai pembaruan pertama.

   1. Buat langganan untuk wilayah tertentu.

   1. Komit `Transaction` untuk mengakhiri pembaruan pertama.

1. Lingkaran:

   1. Buat a `Transaction` untuk memulai pembaruan.

      1. Keluar dari loop jika simulasi dimatikan.

   1. Perubahan status proses.

   1. Komit `Transaction` untuk mengakhiri pembaruan.

1. Hancurkan aplikasi.

Setelah aplikasi kustom membuat entitas, aplikasi harus mentransfer entitas ke domain spasial agar entitas ada secara spasial dalam simulasi. SimSpace Weaver menggunakan lokasi spasial entitas untuk menempatkan entitas di partisi aplikasi spasial yang sesuai. Aplikasi kustom yang membuat entitas tidak dapat memperbarui atau menghapus entitas setelah mentransfernya ke domain spasial. 

 SimSpace Weaver Aplikasi SDK menyediakan contoh aplikasi. Anda dapat menggunakan aplikasi khusus yang disertakan dalam aplikasi sampel sebagai model untuk aplikasi kustom Anda sendiri. Anda dapat menemukan kode sumber untuk aplikasi tampilan (aplikasi khusus) dari aplikasi sampel di folder berikut (gunakan pemisah jalur yang benar untuk sistem operasi Anda):

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

# Mengembangkan aplikasi klien
<a name="working-with_developing-client-applications"></a>

Beberapa alasan Anda mungkin ingin menghubungkan klien ke simulasi meliputi:
+ Menyuntikkan informasi lalu lintas real-time ke dalam simulasi skala kota.
+ Buat *human-in-the-loop*simulasi, di mana operator manusia mengontrol beberapa aspek simulasi.
+ Memungkinkan pengguna untuk berinteraksi dengan simulasi, seperti untuk simulasi pelatihan.

Aplikasi khusus dalam contoh ini bertindak sebagai antarmuka antara status simulasi dan dunia luar. Klien terhubung ke aplikasi khusus untuk berinteraksi dengan simulasi. 

SimSpace Weaver tidak menangani aplikasi klien dan komunikasinya dengan aplikasi khusus Anda. Anda bertanggung jawab atas desain, pembuatan, pengoperasian, dan keamanan aplikasi klien Anda dan komunikasinya dengan aplikasi khusus Anda. SimSpace Weaver hanya mengekspos alamat IP dan nomor port untuk setiap aplikasi kustom Anda sehingga klien dapat terhubung ke mereka. 

 SimSpace Weaver Aplikasi SDK menyediakan klien untuk aplikasi sampelnya. Anda dapat menggunakan klien ini sebagai model untuk aplikasi klien Anda sendiri. Anda dapat menemukan kode sumber untuk klien aplikasi sampel di folder berikut: 

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

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

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

**penting**  
Kami memberikan instruksi ini untuk kenyamanan Anda. Mereka untuk digunakan dengan Windows Subsystem for Linux (WSL), dan tidak didukung. Untuk informasi selengkapnya, lihat [Siapkan lingkungan lokal Anda untuk SimSpace Weaver](setting-up_local.md).

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

------

Untuk informasi lebih lanjut tentang membangun dan menggunakan klien aplikasi sampel, lihat tutorial di[Memulai dengan SimSpace Weaver](getting-started.md). 

# Dapatkan alamat IP dan nomor port aplikasi khusus
<a name="working-with_get-ip"></a>

Untuk melihat simulasi, Anda membuat aplikasi khusus dan menghubungkannya dengan klien. Untuk informasi lebih lanjut, lihat tutorial di[Memulai dengan SimSpace Weaver](getting-started.md). Anda dapat menggunakan prosedur berikut untuk mendapatkan alamat IP dan nomor port aplikasi khusus Anda. Gunakan pemisah jalur yang sesuai untuk sistem operasi Anda (misalnya, `\` di Windows dan `/` Linux).

**Untuk mendapatkan alamat IP dan nomor port**

1. Gunakan ** ListSimulations**API untuk mendapatkan nama simulasi Anda.

   ```
   aws simspaceweaver list-simulations
   ```

   Contoh output:

   ```
   {
       "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. Gunakan ** DescribeSimulation**API untuk mendapatkan daftar domain dalam simulasi Anda.

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

   Cari `Domains` bagian di `LiveSimulationState` bagian output.

   Contoh output:

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

1. Gunakan ** ListApps**API untuk mendapatkan daftar aplikasi kustom di domain. Misalnya, nama domain untuk aplikasi tampilan (kustom) dalam proyek sampel adalah`MyViewDomain`. Cari nama aplikasi di output.

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

   Contoh output:

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

1. Gunakan ** DescribeApp**API untuk mendapatkan alamat IP dan nomor port. Untuk proyek sampel, nama domain adalah `MyViewDomain` dan nama aplikasinya`ViewApp`. 

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

   Alamat IP dan nomor port ada di `EndpointInfo` blok di output. Alamat IP adalah nilai `Address` dan nomor port adalah nilai`Actual`.

   Contoh output:

   ```
   {
       "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"
   }
   ```
**catatan**  
Nilai `Declared` adalah nomor port yang harus diikat oleh kode aplikasi Anda. Nilai `Actual` adalah nomor port yang SimSpace Weaver mengekspos klien untuk terhubung ke aplikasi Anda. SimSpace Weaver memetakan `Declared` port ke `Actual` port.

# Meluncurkan klien tampilan Unreal Engine
<a name="working-with_unreal-client"></a>

 Arahkan ke: 

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

1. Jalankan salah satu perintah berikut ini:
   + buruh pelabuhan: `python quick-start.py`
   + WSL: `python quick-start.py --al2`

1. Dapatkan alamat IP dan nomor port “Aktual”. Ini akan berada di output konsol dari menjalankan quick-start.py, atau mendapatkannya dengan mengikuti prosedur di[Dapatkan alamat IP dan nomor port aplikasi khususDapatkan alamat IP dan nomor port](working-with_get-ip.md).

1.  Arahkan ke: 

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

1.  Jalankan perintah berikut untuk membangun perpustakaan NNG: 

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

1.  Dalam **editor teks**, buka`view_app_url.txt`. 

1.  Perbarui URL dengan alamat IP dan nomor port untuk aplikasi tampilan Anda: `tcp://ip-address:actual-port-number` (seharusnya terlihat seperti`tcp://198.51.100.135:1234`). 

1.  Di **editor Unreal**, pilih **mainkan**. 

## Pemecahan Masalah
<a name="working-with_unreal-client_troubleshooting"></a>
+  **Langkah CMake instalasi NNG gagal dengan “Mungkin perlu hak administratif “:** 

  ```
  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)
  ```
  +  **Resolusi:** Jika `nng.lib` atau `nng.so` ada di UnrealClient direktori/lib, kesalahan ini dapat diabaikan dengan aman. Jika tidak, coba jalankan perintah cmake build di terminal dengan hak administrator. 
+  **“CMake untuk menemukan file konfigurasi paket yang disediakan oleh nng”:** 

  ```
  CMake Error at CMakeLists.txt:23 (find_package):
  By not providing "Findnng.cmake" in CMAKE_MODULE_PATH this project has
   asked CMake to find a package configuration file provided by "nng", but
   CMake did not find one.
  ```
  +  **Resolusi:** CMake mengalami kesulitan menemukan `Findnng.cmake` file. Saat membangun dengan CMake, tambahkan argumen`-DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty`. Pastikan `Findnng.cmake` file masih dalam `ThirdParty` direktori sebelum menjalankan ulang build. CMake 

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

# Pembangunan lokal di SimSpace Weaver
<a name="working-with_local-development"></a>

Anda dapat menerapkan SimSpace Weaver aplikasi Anda secara lokal untuk pengujian cepat dan debugging.

**Persyaratan**
+ Selesaikan langkah-langkah dalam [Menyiapkan untuk SimSpace Weaver](setting-up.md).

**Topics**
+ [Langkah 1: Luncurkan simulasi lokal Anda](working-with_local_launch.md)
+ [Langkah 2: Lihat simulasi lokal Anda](working-with_local-development_view.md)
+ [Langkah 3: Hentikan simulasi lokal Anda (opsional pada Windows)](working-with_local-development_stop-sim.md)
+ [Memecahkan masalah pembangunan lokal di SimSpace Weaver](working-with_local-development_troubleshooting.md)

# Langkah 1: Luncurkan simulasi lokal Anda
<a name="working-with_local_launch"></a>

1. Arahkan ke

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

1. Jalankan perintah berikut untuk membangun dan meluncurkan simulasi Anda secara lokal.

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

   Script ini akan melakukan hal berikut:

   1. Bangun proyek.
      +  `quick-start.py`memanggil `build_project` fungsi yang didefinisikan dalam build.py. Langkah ini akan bervariasi tergantung pada proyek. Untuk PathfindingSample, CMake digunakan. Perintah CMake and Docker yang dapat ditemukan di build.py. 

   1. Luncurkan simulasi lokal Anda
      + Skrip akan meluncurkan satu proses lokal untuk setiap partisi spasial yang ditentukan dalam skema.
      + Skrip akan meluncurkan satu proses untuk setiap aplikasi kustom yang ditentukan dalam skema.
      + Aplikasi spasial akan diluncurkan terlebih dahulu, diikuti oleh aplikasi khusus — masing-masing dalam urutan mereka muncul dalam skema.

**penting**  
Saat meluncurkan di lingkungan yang tidak mendukung GUI, seperti sesi SSH konsol, gunakan `--noappwindow` opsi untuk mengarahkan semua output ke terminal saat ini.

**penting**  
Untuk pengguna Linux, skrip mengasumsikan sistem Anda memiliki `xterm` perintah. Jika distribusi Linux Anda tidak memiliki `xterm` perintah, gunakan `--noappwindow` opsi untuk mengarahkan semua output ke terminal saat ini.
+  -h, --membantu 
  +  Buat daftar parameter ini. 
+  --bersih 
  +  Hapus konten direktori build sebelum membangun. 
+  --nobuild 
  +  Lewati pembangunan kembali proyek. 
+  --noappwindow 
  +  Jangan membuka jendela baru untuk setiap aplikasi. Sebagai gantinya, arahkan stdout ke terminal saat ini. 
+  --berkas log 
  +  Tulis output konsol ke file log. 
+  --konolelien 
  +  Secara otomatis menghubungkan klien konsol yang tercantum dalam konfigurasi. 
+  --skema SKEMA
  + Skema apa yang akan digunakan doa ini. Default ke 'SCHEMA' di config.py. 

# Langkah 2: Lihat simulasi lokal Anda
<a name="working-with_local-development_view"></a>

Untuk melihat simulasi lokal Anda, Anda dapat menggunakan salah satu klien yang disertakan dengan. SimSpaceWeaverAppSdkDistributable Untuk informasi lebih lanjut tentang membangun dan menggunakan klien sampel, lihat tutorial di[Memulai dengan SimSpace Weaver](getting-started.md).

Anda harus memperbarui alamat IP dan nomor port di klien untuk terhubung ke aplikasi tampilan untuk simulasi lokal Anda. Selalu gunakan nilai berikut dengan SimSpace Weaver Local:

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

Tergantung pada klien yang Anda pilih, Anda dapat memperbarui alamat IP dan nomor port sebagai berikut:
+ **Unreal** — Ubah URL pada baris 1 `view_app_url.txt`
+ **Konsol** — Luncurkan klien dengan alamat IP dan URL nomor port sebagai parameter

# Langkah 3: Hentikan simulasi lokal Anda (opsional pada Windows)
<a name="working-with_local-development_stop-sim"></a>

**catatan**  
Langkah ini diperlukan di Linux tetapi opsional pada Windows.

1.  Arahkan ke: 

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

1.  Jalankan perintah berikut untuk menghentikan simulasi lokal Anda dan menghapus sumber daya memori bersama. 

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

    Script ini akan melakukan hal berikut: 
   +  Hentikan proses lokal. 
   +  Hapus objek memori bersama (hanya diperlukan di Linux). 

**stop-and-deleteparameter .py**
+  -h, --membantu 
  +  Buat daftar parameter ini. 
+  --berhenti 
  +  Hanya mencoba untuk menghentikan proses. 
+  --hapus 
  +  Hanya mencoba untuk menghapus sumber daya memori bersama. 
+  --proses 
  +  Nama proses untuk berhenti. Gunakan ini jika nama proses Anda tidak cocok dengan nama paket dalam skema. 
+  --skema SKEMA 
  +  Skema apa yang akan digunakan doa ini. Default ke nilai 'SCHEMA' di config.py. 

# Memecahkan masalah pembangunan lokal di SimSpace Weaver
<a name="working-with_local-development_troubleshooting"></a>
+  **Linux: perintah xterm tidak ditemukan/tidak dapat dibuka** 
  + Skrip lokal mengasumsikan perintah xterm ada saat berjalan di Linux. Jika Anda tidak memiliki perintah xterm atau berjalan di lingkungan yang tidak mendukung GUI, gunakan `--noappwindow` opsi saat menjalankan skrip mulai cepat.
+  **Tidak ada jendela aplikasi yang terbuka\$1** 
  +  Ini terjadi ketika simulasi lokal langsung mogok. Untuk melihat keluaran konsol setelah crash, gunakan `--logfile` opsi `--noappwindow` or saat menjalankan skrip mulai cepat. 
+  **Simulasi tidak berdetak setelah aplikasi tampilan dimulai atau melihat klien terhubung\$1** 
  +  Berjalan dengan `—noappwindow` opsi biasanya menyelesaikan masalah semacam ini. Jika tidak, memulai ulang beberapa kali juga berhasil (walaupun pada tingkat yang jauh lebih rendah). 

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

SDK SimSpace Weaver aplikasi menyediakan APIs yang dapat Anda gunakan untuk mengontrol entitas dalam simulasi dan SimSpace Weaver merespons peristiwa. Ini termasuk namespace berikut: 
+ **API** — definisi inti dari API dan penggunaannya

Tautkan dengan perpustakaan berikut:
+ `libweaver_app_sdk_cxx_v1_full.so`

**penting**  
Pustaka tersedia untuk penautan dinamis saat Anda menjalankan aplikasi di file. AWS Cloud Anda tidak perlu mengunggahnya dengan aplikasi Anda.

**catatan**  
SDK SimSpace Weaver aplikasi APIs mengontrol data dalam simulasi Anda. Ini APIs terpisah dari SimSpace Weaver layanan APIs, yang mengontrol sumber daya SimSpace Weaver layanan Anda (seperti simulasi, aplikasi, dan jam) di. AWS Untuk informasi selengkapnya, lihat [SimSpace Weaver Referensi API](api-reference.md).

**Topics**
+ [Metode API mengembalikan a Result](working-with_app-sdk_return-result.md)
+ [Berinteraksi dengan SDK aplikasi di tingkat atas](working-with_app-sdk_top-level.md)
+ [Manajemen simulasi](working-with_app-sdk_sim.md)
+ [Langganan](working-with_app-sdk_sub.md)
+ [Entitas](working-with_app-sdk_ent.md)
+ [Peristiwa entitas](working-with_app-sdk_events.md)
+ [Result dan penanganan kesalahan](working-with_app-sdk_result.md)
+ [Generik dan jenis domain](working-with_app-sdk_generics.md)
+ [Operasi SDK aplikasi lain-lain](working-with_app-sdk_misc.md)

# Metode API mengembalikan a Result
<a name="working-with_app-sdk_return-result"></a>

Sebagian besar fungsi SimSpace Weaver API memiliki tipe pengembalian`Aws::WeaverRuntime::Result<T>`. Jika fungsi telah berhasil dijalankan, `Result` berisi`T`. Jika tidak, `Result` berisi `Aws::WeaverRuntime::ErrorCode` yang mewakili kode kesalahan dari Rust App SDK.

**Example Contoh**  

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

Metode ini:
+ Mengembalikan `Transaction` jika `BeginUpdate()` mengeksekusi berhasil.
+ Pengembalian `Aws::WeaverRuntime::ErrorCode` jika `BeginUpdate()` gagal.

# Berinteraksi dengan SDK aplikasi di tingkat atas
<a name="working-with_app-sdk_top-level"></a>

**Siklus hidup**
+ SDK SimSpace Weaver aplikasi mengelola siklus hidup aplikasi. Anda tidak perlu membaca atau menulis status siklus hidup aplikasi.

**Partisi**
+ Gunakan `Result <PartitionSet> AssignedPartitions(Transaction& txn);` untuk mendapatkan partisi yang dimiliki.
+ Gunakan `Result <PartitionSet> AllPartitions(Transaction& txn);` untuk mendapatkan semua partisi dalam simulasi.

# Manajemen simulasi
<a name="working-with_app-sdk_sim"></a>

Bagian ini menjelaskan solusi untuk tugas-tugas manajemen simulasi umum.

**Topics**
+ [Mulai simulasi](working-with_app-sdk_sim_start.md)
+ [Perbarui simulasi](working-with_app-sdk_sim_update.md)
+ [Mengakhiri simulasi](working-with_app-sdk_sim_terminate.md)

# Mulai simulasi
<a name="working-with_app-sdk_sim_start"></a>

Gunakan `CreateApplication()` untuk membuat aplikasi.

**Example Contoh**  

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

# Perbarui simulasi
<a name="working-with_app-sdk_sim_update"></a>

Gunakan `BeginUpdate` fungsi berikut untuk memperbarui aplikasi:
+ `Result<Transaction> BeginUpdate(Application& app)`
+ `Result<bool> BeginUpdateWillBlock(Application& app)`— memberi tahu Anda apakah `BeginUpdate()` akan memblokir atau tidak memblokir.

Gunakan `Result<void> Commit(Transaction& txn)` untuk melakukan perubahan.

**Example Contoh**  

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

# Mengakhiri simulasi
<a name="working-with_app-sdk_sim_terminate"></a>

Gunakan `Result<void> DestroyApplication(Application&& app)` untuk menghentikan aplikasi dan simulasi.

Aplikasi lain mengetahui bahwa simulasi dimatikan ketika mereka menerima `ErrorCode::ShuttingDown` dari panggilan mereka ke `BeginUpdateWillBlock()` atau. `BeginUpdate()` Ketika sebuah aplikasi menerima`ErrorCode::ShuttingDown`, ia dapat memanggil `Result<void> DestroyApplication(Application&& app)` untuk mengakhiri dirinya sendiri.

**Example Contoh**  

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

**penting**  
Hanya menelepon `Result<void> DestroyApplication(Application&& app)` setelahnya`Api::Commit()`. Menghancurkan aplikasi selama pembaruan dapat menyebabkan perilaku tidak terdefinisi.

**penting**  
Anda harus menelepon `DestroyApplication()` sebelum program keluar untuk memastikan bahwa laporan aplikasi berhasil dihentikan.  
Kegagalan untuk menelepon `DestroyApplication()` ketika program keluar akan menyebabkan status dianggap sebagai`FATAL`.

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

Anda membuat langganan dengan area berlangganan dan ID domain. ID domain mewakili domain yang memiliki area langganan tersebut. A `BoundingBox2F32` menjelaskan area berlangganan. Gunakan fungsi berikut untuk membuat langganan:

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

**Example Contoh**  

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

Anda dapat menggunakan yang `Api::SubscriptionHandle` dikembalikan oleh `CreateSubscriptionBoundingBox2F32()` untuk memodifikasi langganan. Anda meneruskannya sebagai argumen ke fungsi-fungsi berikut:

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

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

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

Anda memanggil `Store` dan `Load` APIs menggunakan peristiwa perubahan `Api:Entity` kepemilikan yang `Result<Api::Entity>` dikembalikan dari`CreateEntity()`, atau dari saat entitas memasuki area langganan aplikasi (untuk informasi selengkapnya, lihat[Peristiwa entitas](working-with_app-sdk_events.md)). Kami menyarankan Anda melacak `Api::Entity` objek Anda sehingga Anda dapat menggunakannya dengan ini APIs.

**Topics**
+ [Buat entitas](working-with_app-sdk_ent_create.md)
+ [Transfer entitas ke domain spasial](working-with_app-sdk_ent_transfer.md)
+ [Menulis dan membaca data bidang entitas](working-with_app-sdk_ent_readwrite.md)
+ [Menyimpan posisi entitas](working-with_app-sdk_ent_store-position.md)
+ [Memuat posisi entitas](working-with_app-sdk_ent_load-position.md)

# Buat entitas
<a name="working-with_app-sdk_ent_create"></a>

Gunakan `CreateEntity()` untuk membuat entitas. Anda mendefinisikan arti dari `Api::TypeId` yang Anda berikan ke fungsi ini.

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

**catatan**  
Nilai 0-511 untuk dicadangkan`Api::BuiltinTypeId`. Entitas Anda TypeID (`k_entityTypeId`dalam contoh ini) harus memiliki nilai 512 atau lebih tinggi.

# Transfer entitas ke domain spasial
<a name="working-with_app-sdk_ent_transfer"></a>

Setelah aplikasi kustom atau aplikasi layanan membuat entitas, aplikasi harus mentransfer entitas ke domain spasial agar entitas ada secara spasial dalam simulasi. Entitas dalam domain spasial dapat dibaca oleh aplikasi lain dan diperbarui oleh aplikasi spasial. Gunakan `ModifyEntityDomain()` API untuk mentransfer entitas ke domain spasial.

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

Jika `DomainId` tidak cocok dengan yang ditetapkan `Partition` dari aplikasi panggilan, maka `DomainId` harus untuk a `DomainType::Spatial``Domain`. Transfer kepemilikan ke yang baru `Domain` terjadi selama`Commit(Transaction&&)`.Parameter

`txn`  
Saat ini`Transaction`.

`entity`  
Target `Entity` untuk perubahan`Domain`.

`domainId`  
`DomainId`Tujuan `Domain` untuk`Entity`.

API ini kembali `Success` jika domain entitas berhasil diubah.

# Menulis dan membaca data bidang entitas
<a name="working-with_app-sdk_ent_readwrite"></a>

Semua bidang data entitas adalah tipe gumpalan. Anda dapat menulis hingga 1.024 byte data ke entitas. Kami menyarankan Anda menyimpan gumpalan sekecil mungkin karena ukuran yang lebih besar akan mengurangi kinerja. Ketika Anda menulis ke gumpalan, Anda meneruskan SimSpace Weaver pointer ke data dan panjangnya. Ketika Anda membaca dari gumpalan, SimSpace Weaver memberi Anda penunjuk dan panjang untuk dibaca. Semua pembacaan harus lengkap sebelum panggilan aplikasi`Commit()`. Pointer yang dikembalikan dari panggilan baca tidak valid saat aplikasi memanggil. `Commit()`

**penting**  
Membaca dari pointer blob cache setelah a tidak `Commit()` didukung dan dapat menyebabkan simulasi gagal.
Menulis ke penunjuk gumpalan yang dikembalikan dari panggilan baca tidak didukung dan dapat menyebabkan simulasi gagal.

**Topics**
+ [Menyimpan data bidang suatu entitas](working-with_app-sdk_ent_readwrite_store.md)
+ [Memuat data bidang suatu entitas](working-with_app-sdk_ent_readwrite_load.md)
+ [Memuat data bidang entitas yang dihapus](working-with_app-sdk_ent_readwrite_load-removed.md)

# Menyimpan data bidang suatu entitas
<a name="working-with_app-sdk_ent_readwrite_store"></a>

Contoh berikut menunjukkan bagaimana Anda dapat menyimpan (menulis ke struktur status) data bidang entitas yang dimiliki aplikasi. Contoh-contoh ini menggunakan fungsi berikut:

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

`Api::TypeId keyTypeId`Parameter mewakili tipe data dari data yang diteruskan.

`Api::TypeId keyTypeId`Parameter harus menerima yang sesuai `Api::TypeId` dari`Api::BuiltinTypeId`. Jika tidak ada konversi yang sesuai, Anda dapat menggunakannya`Api::BuiltinTypeId::Dynamic`.

Untuk tipe data yang kompleks, gunakan`Api::BuiltInTypeId::Dynamic`.

**catatan**  
Nilai `FieldIndex index` harus lebih besar dari 0. Nilai 0 dicadangkan untuk kunci indeks (lihat`StoreEntityIndexKey()`).

**Example Contoh menggunakan tipe data primitif**  

```
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 Contoh menggunakan struct untuk menyimpan data**  

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

# Memuat data bidang suatu entitas
<a name="working-with_app-sdk_ent_readwrite_load"></a>

Contoh berikut menunjukkan bagaimana Anda dapat memuat (membaca dari struktur status) data bidang suatu entitas. Contoh-contoh ini menggunakan fungsi berikut:

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

`Api::TypeId keyTypeId`Parameter harus menerima yang sesuai `Api::TypeId` dari`Api::BuiltinTypeId`. Jika tidak ada konversi yang sesuai, Anda dapat menggunakannya`Api::BuiltinTypeId::Dynamic`.

**catatan**  
Nilai `FieldIndex` indeks harus lebih besar dari 0. Nilai 0 dicadangkan untuk kunci indeks (lihat`StoreEntityIndexKey()`).

**Example Contoh menggunakan tipe data primitif**  

```
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 Contoh menggunakan struct untuk menyimpan data**  

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

# Memuat data bidang entitas yang dihapus
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

Anda tidak dapat memuat (membaca dari struktur status) data bidang entitas untuk entitas yang telah dihapus dari area kepemilikan dan langganan aplikasi. Contoh berikut menghasilkan kesalahan karena memanggil `Api::LoadIndexKey()` entitas sebagai akibat dari`Api::ChangeListAction::Remove`. Contoh kedua menunjukkan cara yang benar untuk menyimpan dan memuat data entitas secara langsung di aplikasi.

**Example Contoh kode yang salah**  

```
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 Contoh cara yang benar untuk menyimpan dan memuat data entitas di aplikasi**  

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

# Menyimpan posisi entitas
<a name="working-with_app-sdk_ent_store-position"></a>

Anda dapat menyimpan (menulis ke kain negara) posisi entitas menggunakan struktur data integer. Contoh-contoh ini menggunakan fungsi berikut:

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

**catatan**  
Anda `Api::BuiltinTypeId::Vector3F32` harus memberikan`Api::StoreEntityIndexKey()`, seperti yang ditunjukkan dalam contoh berikut.

**Example Contoh menggunakan array untuk mewakili posisi**  

```
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 Contoh menggunakan struct untuk mewakili posisi**  

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

# Memuat posisi entitas
<a name="working-with_app-sdk_ent_load-position"></a>

Anda dapat memuat (membaca dari struktur status) posisi entitas menggunakan struktur data integer. Contoh-contoh ini menggunakan fungsi berikut:

**catatan**  
Anda `Api::BuiltinTypeId::Vector3F32` harus memberikan`Api::LoadEntityIndexKey()`, seperti yang ditunjukkan dalam contoh berikut.

**Example Contoh menggunakan array untuk mewakili posisi**  

```
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 Contoh menggunakan struct untuk mewakili posisi**  

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

# Peristiwa entitas
<a name="working-with_app-sdk_events"></a>

Anda dapat menggunakan fungsi berikut di SDK SimSpace Weaver aplikasi untuk mendapatkan semua peristiwa kepemilikan dan langganan:
+ `Result<OwnershipChangeList> OwnershipChanges(Transaction& txn) `
+ `Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn) `

Anda dapat menggunakan kerangka kerja SimSpace Weaver demo jika Anda memerlukan pemrosesan peristiwa entitas yang digerakkan oleh panggilan balik. Untuk informasi selengkapnya, lihat file header berikut:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/DemoFramework/EntityEventProcessor.h`

Anda juga dapat membuat pemrosesan peristiwa entitas Anda sendiri.

**Topics**
+ [Iterasi melalui peristiwa untuk entitas yang dimiliki](working-with_app-sdk_events_own.md)
+ [Iterasi melalui peristiwa untuk entitas berlangganan](working-with_app-sdk_events_sub.md)
+ [Iterasi melalui peristiwa perubahan kepemilikan untuk entitas](working-with_app-sdk_events_change.md)

# Iterasi melalui peristiwa untuk entitas yang dimiliki
<a name="working-with_app-sdk_events_own"></a>

Gunakan `OwnershipChanges()` untuk mendapatkan daftar peristiwa untuk entitas yang dimiliki (entitas di area kepemilikan aplikasi). Fungsi ini memiliki tanda tangan berikut:

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

Kemudian iterasi melalui entitas dengan loop, seperti yang ditunjukkan dalam contoh berikut.

**Example Contoh**  

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

**Jenis peristiwa**
+ `None`Entitas berada di area dan posisi serta data bidangnya tidak dimodifikasi.
+ `Remove`Entitas telah dihapus dari area tersebut.
+ `Add`Entitas ditambahkan ke area tersebut.
+ `Update`Entitas berada di area tersebut dan telah dimodifikasi.
+ `Reject`— Aplikasi gagal menghapus entitas dari area tersebut.

**catatan**  
Jika terjadi `Reject` peristiwa, aplikasi akan mencoba transfer lagi pada centang berikutnya.

# Iterasi melalui peristiwa untuk entitas berlangganan
<a name="working-with_app-sdk_events_sub"></a>

Gunakan `AllSubscriptionEvents()` untuk mendapatkan daftar peristiwa untuk entitas berlangganan (entitas di area langganan aplikasi). Fungsi ini memiliki tanda tangan berikut:

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

Kemudian iterasi melalui entitas dengan loop, seperti yang ditunjukkan dalam contoh berikut.

**Example Contoh**  

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

**Jenis peristiwa**
+ `None`Entitas berada di area dan posisi serta data bidangnya tidak dimodifikasi.
+ `Remove`Entitas telah dihapus dari area tersebut.
+ `Add`Entitas ditambahkan ke area tersebut.
+ `Update`Entitas berada di area tersebut dan telah dimodifikasi.
+ `Reject`— Aplikasi gagal menghapus entitas dari area tersebut.

**catatan**  
Jika terjadi `Reject` peristiwa, aplikasi akan mencoba transfer lagi pada centang berikutnya.

# Iterasi melalui peristiwa perubahan kepemilikan untuk entitas
<a name="working-with_app-sdk_events_change"></a>

Untuk mendapatkan peristiwa di mana entitas berpindah antara area kepemilikan dan area langganan, bandingkan perubahan antara kepemilikan entitas saat ini dan sebelumnya dan peristiwa berlangganan.

Anda dapat menangani acara ini dengan membaca:
+ `Api::SubscriptionChangeList`
+ `Api::OwnershipEvents`

Anda kemudian dapat membandingkan perubahan dengan data yang disimpan sebelumnya.

Contoh berikut menunjukkan bagaimana Anda dapat menangani peristiwa perubahan kepemilikan entitas. Contoh ini mengasumsikan bahwa untuk entitas yang bertransisi antara entitas berlangganan dan entitas yang dimiliki (di kedua arah), remove/add event occurs first followed by the subscription remove/add peristiwa kepemilikan di centang berikutnya. 

**Example Contoh**  

```
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 dan penanganan kesalahan
<a name="working-with_app-sdk_result"></a>

`Aws::WeaverRuntime::Result<T>`Kelas menggunakan `Outcome` pustaka pihak ketiga. Anda dapat menggunakan pola berikut untuk memeriksa kesalahan `Result` dan catch yang dikembalikan oleh panggilan API.

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

## Result pernyataan kontrol makro
<a name="working-with_app-sdk_result_macro"></a>

Di dalam fungsi dengan tipe pengembalian`Aws::WeaverRuntime::Result<T>`, Anda dapat menggunakan `WEAVERRUNTIME_TRY` makro alih-alih pola kode sebelumnya. Makro akan menjalankan fungsi yang diteruskan ke sana. Jika fungsi yang dilewatkan gagal, makro akan membuat fungsi terlampir mengembalikan kesalahan. Jika fungsi yang dilewatkan berhasil, eksekusi berlanjut ke baris berikutnya. Contoh berikut menunjukkan penulisan ulang dari `DoBeginUpdate()` fungsi sebelumnya. Versi ini menggunakan `WEAVERRUNTIME_TRY` makro, bukan if-else struktur kontrol. Perhatikan bahwa tipe pengembalian fungsi adalah`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();
}
```

Jika `BeginUpdate()` gagal, makro membuat `DoBeginUpdate()` pengembalian lebih awal dengan kegagalan. Anda dapat menggunakan `WEAVERRUNTIME_EXPECT_ERROR` makro untuk mendapatkan `Aws::WeaverRuntime::ErrorCode` dari`BeginUpdate()`. Contoh berikut menunjukkan bagaimana `Update()` fungsi memanggil `DoBeginUpdate()` dan mendapatkan kode kesalahan pada kegagalan.

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

    }
}
```

Anda dapat membuat kode kesalahan dari `BeginUpdate()` tersedia ke fungsi yang memanggil `Update()` dengan mengubah jenis pengembalian `Update()` ke`Aws::WeaverRuntime::Result<void>`. Anda dapat mengulangi proses ini untuk terus mengirim kode kesalahan lebih jauh ke tumpukan panggilan.

# Generik dan jenis domain
<a name="working-with_app-sdk_generics"></a>

SDK SimSpace Weaver aplikasi menyediakan tipe data presisi tunggal `Api::Vector2F32` dan`Api::BoundingBox2F32`, dan presisi ganda `Api::Vector2F64` dan. `Api::BoundingBox2F64` Tipe data ini adalah struktur data pasif tanpa metode kenyamanan. Perhatikan bahwa API hanya menggunakan `Api::Vector2F32` dan`Api::BoundingBox2F32`. Anda dapat menggunakan tipe data ini untuk membuat dan memodifikasi langganan.

Kerangka SimSpace Weaver demo menyediakan versi minimal AzCore perpustakaan matematika, yang berisi `Vector3` dan`Aabb`. Untuk informasi selengkapnya, lihat file header di:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/AzCore/Math`

# Operasi SDK aplikasi lain-lain
<a name="working-with_app-sdk_misc"></a>

**Topics**
+ [AllSubscriptionEvents and OwnershipChanges berisi peristiwa dari panggilan terakhir](working-with_app-sdk_misc_events-from-last-call.md)
+ [Lepaskan kunci baca setelah diproses SubscriptionChangeList](working-with_app-sdk_misc_release-locks.md)
+ [Membuat instance aplikasi mandiri untuk pengujian](working-with_app-sdk_misc_testing-app.md)

# AllSubscriptionEvents and OwnershipChanges berisi peristiwa dari panggilan terakhir
<a name="working-with_app-sdk_misc_events-from-last-call"></a>

Nilai pengembalian panggilan ke `Api::AllSubscriptionEvents()` dan `Api::OwnershipChanges()` berisi peristiwa dari panggilan terakhir, **bukan centang terakhir**. Dalam contoh berikut, `secondSubscriptionEvents` dan `secondOwnershipChangeList` kosong karena fungsinya dipanggil segera setelah panggilan pertama.

Jika Anda menunggu 10 kutu dan kemudian menelepon `Api::AllSubscriptionEvents()` dan`Api::OwnershipChanges()`, hasilnya akan berisi peristiwa dan perubahan dari 10 kutu terakhir (bukan centang terakhir).

**Example Contoh**  

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

**catatan**  
Fungsi `AllSubscriptionEvents()` diimplementasikan tetapi fungsinya **tidak `SubscriptionEvents()` diimplementasikan**.

# Lepaskan kunci baca setelah diproses SubscriptionChangeList
<a name="working-with_app-sdk_misc_release-locks"></a>

Saat Anda memulai pembaruan, ada segmen memori bersama untuk data yang dikomit di partisi lain untuk centang sebelumnya. Segmen memori bersama ini mungkin dikunci oleh pembaca. Aplikasi tidak dapat sepenuhnya berkomitmen sampai semua pembaca merilis kunci. Sebagai pengoptimalan, aplikasi harus menelepon `Api::ReleaseReadLeases()` untuk melepaskan kunci setelah memproses `Api::SubscriptionChangelist` item. Ini mengurangi pertengkaran pada waktu komit. `Api::Commit()`merilis sewa baca secara default, tetapi merupakan praktik terbaik untuk merilisnya secara manual setelah memproses pembaruan langganan.

**Example Contoh**  

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

# Membuat instance aplikasi mandiri untuk pengujian
<a name="working-with_app-sdk_misc_testing-app"></a>

Anda dapat menggunakan `Api::CreateStandaloneApplication()` untuk membuat aplikasi mandiri untuk menguji logika aplikasi sebelum menjalankan kode dalam simulasi aktual.

**Example Contoh**  

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

Kerangka AWS SimSpace Weaver demo (demo framework) adalah perpustakaan utilitas yang dapat Anda gunakan untuk mengembangkan SimSpace Weaver aplikasi.

**Kerangka demo menyediakan**
+ Contoh kode dan pola pemrograman untuk Anda gunakan dan periksa
+ Abstraksi dan fungsi utilitas yang merampingkan pengembangan untuk aplikasi sederhana
+ Cara sederhana untuk menguji fitur eksperimental SDK SimSpace Weaver aplikasi

Kami merancang SDK SimSpace Weaver aplikasi dengan akses tingkat rendah untuk memberikan SimSpace Weaver APIs kinerja yang lebih tinggi. Sebaliknya, kami merancang kerangka demo untuk memberikan abstraksi tingkat yang lebih tinggi dan akses ke APIs yang membuatnya SimSpace Weaver lebih mudah digunakan. Biaya kemudahan penggunaan adalah tingkat kinerja yang lebih rendah dibandingkan dengan langsung menggunakan SDK SimSpace Weaver aplikasi. Simulasi yang dapat mentolerir kinerja yang lebih rendah (seperti yang tanpa persyaratan kinerja waktu nyata) mungkin merupakan kandidat yang baik untuk menggunakan kerangka kerja demo. Sebaiknya gunakan fungsionalitas asli di SDK SimSpace Weaver aplikasi untuk aplikasi yang kompleks karena kerangka kerja demo bukanlah toolkit yang lengkap.

**Kerangka demo termasuk**
+ Contoh kode kerja yang mendukung dan menunjukkan:
  + Manajemen aliran aplikasi
  + Pemrosesan peristiwa entitas yang digerakkan oleh panggilan balik
+ Satu set perpustakaan utilitas pihak ketiga:
  + spdlog (perpustakaan logging)
  + Versi minimal AZCore (perpustakaan matematika) yang hanya berisi:
    + Vector3
    + Aabb
  + cxxopts (pustaka parser opsi baris perintah)
+ Fungsi utilitas khusus untuk SimSpace Weaver

Kerangka demo terdiri dari perpustakaan, file sumber, dan CMakeLists. File-file tersebut disertakan dalam paket SimSpace Weaver aplikasi SDK yang dapat didistribusikan.

# Bekerja dengan kuota layanan
<a name="working-with_quotas"></a>

Bagian ini menjelaskan cara bekerja dengan kuota layanan untuk SimSpace Weaver. **Kuota** juga disebut **batas**. Untuk daftar kuota layanan, lihat[SimSpace Titik akhir dan kuota Weaver](service-quotas.md). APIsDi bagian ini berasal dari kumpulan **aplikasi APIs**. Aplikasi APIs berbeda dari layanan APIs. Aplikasi ini APIs merupakan bagian dari SDK SimSpace Weaver aplikasi. Anda dapat menemukan dokumentasi untuk aplikasi APIs di folder SDK aplikasi di sistem lokal Anda:

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

**Topics**
+ [Dapatkan batasan untuk sebuah aplikasi](#working-with_quotas_get-app-limits)
+ [Dapatkan jumlah sumber daya yang digunakan oleh aplikasi](#working-with_quotas_get-app-resources)
+ [Setel ulang metrik](#working-with_quotas_reset-metrics)
+ [Melebihi batas](#working-with_quotas_exceed-limit)
+ [Kehabisan memori](#working-with_quotas_out-of-memory)
+ [Praktik terbaik](#working-with_quotas_best-practices)

## Dapatkan batasan untuk sebuah aplikasi
<a name="working-with_quotas_get-app-limits"></a>

Anda dapat menggunakan API **RuntimeLimits** aplikasi untuk menanyakan batasan aplikasi.

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

**Application& aplikasi**  
Referensi ke aplikasi.

**LimitTypejenis**  
Enum dengan jenis batas berikut:  

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

Contoh berikut menanyakan batas jumlah entitas.

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

## Dapatkan jumlah sumber daya yang digunakan oleh aplikasi
<a name="working-with_quotas_get-app-resources"></a>

Anda dapat memanggil API **RuntimeMetrics** aplikasi untuk mendapatkan jumlah sumber daya yang digunakan oleh aplikasi:

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

**Application& aplikasi**  
Referensi ke aplikasi.

API mengembalikan referensi ke struct yang berisi metrik. Metrik penghitung memiliki nilai total yang berjalan dan hanya meningkat. Metrik pengukur memiliki nilai yang dapat meningkat atau menurun. Runtime aplikasi memperbarui penghitung setiap kali acara meningkatkan nilainya. Runtime hanya memperbarui pengukur saat Anda memanggil API. SimSpace Weaver menjamin bahwa referensi berlaku untuk masa pakai aplikasi. Ulangi panggilan ke API tidak akan mengubah referensi.

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

## Setel ulang metrik
<a name="working-with_quotas_reset-metrics"></a>

API **ResetRuntimeMetrics** aplikasi menyetel ulang nilai dalam file. `AppRuntimeMetrics` struct

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

Contoh berikut menunjukkan bagaimana Anda dapat menelepon **ResetRuntimeMetrics** di aplikasi Anda.

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

## Melebihi batas
<a name="working-with_quotas_exceed-limit"></a>

Panggilan API aplikasi yang melebihi batas akan menampilkan`ErrorCode::CapacityExceeded`, kecuali transfer entitas. SimSpace Weaver menangani transfer entitas secara asinkron sebagai bagian dari operasi **Komit** dan API **BeginUpdate** aplikasi, jadi tidak ada operasi spesifik yang mengembalikan kesalahan jika transfer gagal karena batas transfer entitas. Untuk mendeteksi kegagalan transfer, Anda dapat membandingkan nilai saat ini `rejected_incoming_transfer_counter` dan `rejected_outgoing_transfer_counter` (dalam `AppRuntimeMetrics`struct) dengan nilai sebelumnya. Entitas yang ditolak tidak akan berada di partisi, tetapi aplikasi masih dapat mensimulasikannya.

## Kehabisan memori
<a name="working-with_quotas_out-of-memory"></a>

SimSpace Weaver menggunakan proses pengumpul sampah untuk membersihkan dan melepaskan memori yang dibebaskan. Dimungkinkan untuk menulis data lebih cepat daripada pengumpul sampah dapat melepaskan memori. Jika ini terjadi, operasi tulis mungkin melebihi batas memori cadangan aplikasi. SimSpace Weaver akan mengembalikan kesalahan internal dengan pesan yang berisi `OutOfMemory` (dan detail tambahan). Untuk informasi selengkapnya, lihat [Spread menulis sepanjang waktu](#working-with_quotas_best-practices_spread-writes).

## Praktik terbaik
<a name="working-with_quotas_best-practices"></a>

Praktik terbaik berikut adalah pedoman umum untuk merancang aplikasi Anda agar tidak melebihi batas. Mereka mungkin tidak berlaku untuk desain aplikasi spesifik Anda.

### Pantau sering dan perlambat
<a name="working-with_quotas_best-practices_monitor"></a>

Anda harus sering memantau metrik Anda dan memperlambat operasi yang hampir mencapai batas.

### Hindari melebihi batas langganan dan batas transfer
<a name="working-with_quotas_best-practices_subscription-and-xfer"></a>

Jika memungkinkan, rancang simulasi Anda untuk mengurangi jumlah langganan jarak jauh dan transfer entitas. Anda dapat menggunakan grup penempatan untuk menempatkan beberapa partisi pada pekerja yang sama dan mengurangi kebutuhan transfer entitas jarak jauh antar pekerja. 

### Spread menulis sepanjang waktu
<a name="working-with_quotas_best-practices_spread-writes"></a>

Jumlah dan ukuran pembaruan dalam tanda centang dapat berdampak signifikan pada waktu dan memori yang diperlukan untuk melakukan transaksi. Persyaratan memori yang besar dapat menyebabkan runtime aplikasi kehabisan memori. Anda dapat menyebarkan penulisan sepanjang waktu untuk menurunkan ukuran total rata-rata pembaruan per centang. Ini dapat membantu meningkatkan kinerja dan menghindari melebihi batas. Kami menyarankan agar Anda tidak menulis lebih dari rata-rata 12 MB pada setiap centang atau 1,5 KB untuk setiap entitas. 

# Simulasi debugging
<a name="working-with_debugging"></a>

Anda dapat menggunakan metode berikut untuk mendapatkan informasi tentang simulasi Anda.

**Topik**
+ [Gunakan SimSpace Weaver Local dan lihat output konsol](#working-with_debugging_use-local)
+ [Lihat log Anda di Amazon CloudWatch Logs](#working-with_debugging_logs)
+ [Gunakan **describe** Panggilan API](#working-with_debugging_api)
+ [Connect klien](#working-with_debugging_client)

## Gunakan SimSpace Weaver Local dan lihat output konsol
<a name="working-with_debugging_use-local"></a>

Kami menyarankan Anda mengembangkan simulasi Anda secara lokal terlebih dahulu dan kemudian menjalankannya di. AWS Cloud Anda dapat melihat output konsol secara langsung saat Anda menjalankannya SimSpace Weaver LocalUntuk informasi selengkapnya, lihat [Pembangunan lokal di SimSpace Weaver](working-with_local-development.md).

## Lihat log Anda di Amazon CloudWatch Logs
<a name="working-with_debugging_logs"></a>

Saat Anda menjalankan simulasi di AWS Cloud output konsol aplikasi Anda dikirim ke aliran log di Amazon CloudWatch Logs. Simulasi Anda juga menulis data log lainnya. Anda harus mengaktifkan login dalam skema simulasi Anda jika Anda ingin simulasi Anda untuk menulis data log. Untuk informasi selengkapnya, lihat [SimSpace Weaver log di Amazon CloudWatch Log](cloudwatch-logs.md).

**Awas**  
Simulasi Anda dapat menghasilkan data log dalam jumlah besar. Data log dapat tumbuh dengan sangat cepat. Anda harus memperhatikan log Anda dengan cermat dan menghentikan simulasi Anda ketika Anda tidak membutuhkannya berjalan lagi. Penebangan dapat menghasilkan biaya besar.

## Gunakan **describe** Panggilan API
<a name="working-with_debugging_api"></a>

Anda dapat menggunakan layanan berikut APIs untuk mendapatkan informasi tentang simulasi Anda di. AWS Cloud
+ **ListSimulations**— dapatkan daftar semua simulasi Anda di. AWS Cloud  
**Example Contoh**  

  ```
  aws simspaceweaver list-simulations
  ```
+ **DescribeSimulation**— dapatkan detail tentang simulasi.  
**Example Contoh**  

  ```
  aws simspaceweaver describe-simulation --simulation MySimulation
  ```
+ **DescribeApp**— dapatkan detail tentang aplikasi.  
**Example Contoh**  

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

Untuk informasi lebih lanjut tentang SimSpace Weaver APIs, lihat[SimSpace Weaver Referensi API](api-reference.md).

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

Anda dapat menghubungkan klien ke aplikasi kustom atau layanan yang sedang berjalan yang Anda tentukan dengan `endpoint_config` skema simulasi Anda. SDK SimSpace Weaver aplikasi menyertakan klien sampel yang dapat Anda gunakan untuk melihat contoh aplikasi. Anda dapat melihat kode sumber untuk klien sampel ini dan aplikasi sampel untuk melihat bagaimana Anda dapat membuat klien Anda sendiri. Untuk informasi selengkapnya tentang cara membangun dan menjalankan klien sampel, lihat tutorial di[Memulai dengan SimSpace Weaver](getting-started.md).

Anda dapat menemukan kode sumber untuk klien sampel di folder berikut:
+ `sdk-folder\packaging-tools\clients\PathfindingSampleClients\`

# Debugging simulasi lokal
<a name="working-with_debugging_local"></a>

Anda dapat men-debug SimSpace Weaver Local aplikasi Anda denganMicrosoft Visual Studio. [Untuk informasi selengkapnya tentang cara men-debugVisual Studio, lihat. Microsoft Visual Studio documentation](https://learn.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour) 

**Untuk men-debug simulasi lokal Anda**

1. Pastikan Anda `schema.yaml` ada di direktori kerja Anda.

1. Di **Visual Studio**, buka menu konteks untuk setiap aplikasi yang ingin Anda debug (seperti `PathfindingSampleLocalSpatial` atau`PathfindingSampleLocalView`) dan atur direktori kerja di bagian debugging.

1. Buka menu konteks untuk aplikasi yang ingin Anda debug dan pilih **Set as Startup project**.

1. Pilih F5 untuk mulai men-debug aplikasi.

Persyaratan untuk men-debug simulasi sama dengan persyaratan untuk menjalankan simulasi secara normal. Anda harus memulai jumlah aplikasi spasial yang ditentukan dalam skema. Misalnya, jika skema menentukan kisi 2x2 dan Anda memulai aplikasi spasial dalam mode debug, simulasi tidak akan berjalan hingga Anda memulai 3 aplikasi spasial lainnya (dalam mode debug atau tidak dalam mode debug).

Untuk men-debug aplikasi kustom, Anda harus terlebih dahulu memulai aplikasi spasial Anda dan kemudian memulai aplikasi kustom di debugger.

Perhatikan bahwa simulasi Anda berjalan dalam langkah kunci. Segera setelah aplikasi mencapai breakpoint, semua aplikasi lain akan berhenti sejenak. Setelah Anda melanjutkan dari breakpoint itu, aplikasi lain akan berlanjut.

# Wadah khusus
<a name="working-with_custom-containers"></a>

AWS SimSpace Weaver aplikasi berjalan di lingkungan containerized Amazon Linux 2 (AL2). Di AWS Cloud, SimSpace Weaver jalankan simulasi Anda dalam wadah Docker yang dibuat dari `amazonlinux:2` gambar yang disajikan dari Amazon Elastic Container Registry (Amazon ECR) Registry (Amazon ECR). Anda dapat membuat gambar Docker kustom, menyimpannya di Amazon ECR, dan menggunakan gambar itu untuk simulasi Anda alih-alih gambar Docker default yang kami sediakan.

Anda dapat menggunakan wadah khusus untuk mengelola dependensi perangkat lunak Anda dan menyertakan komponen perangkat lunak tambahan yang tidak ada dalam gambar Docker standar. Misalnya, Anda dapat menambahkan pustaka perangkat lunak yang tersedia untuk umum yang digunakan aplikasi ke penampung dan hanya memasukkan kode kustom Anda di file zip aplikasi.

**penting**  
Kami hanya mendukung gambar AL2 Docker yang dihosting di repositori Amazon ECR, baik di Galeri Publik Amazon ECR atau registri ECR Amazon pribadi Anda. Kami tidak mendukung gambar Docker yang dihosting di luar Amazon ECR. Untuk informasi selengkapnya tentang Amazon ECR, lihat *[Dokumentasi Registri Amazon Elastic Container](https://docs.aws.amazon.com/ecr)*.

**Topics**
+ [Buat wadah khusus](working-with_custom-containers_create.md)
+ [Ubah proyek untuk menggunakan wadah khusus](working-with_custom-containers_modify-project.md)
+ [Pertanyaan yang sering diajukan tentang wadah khusus](working-with_custom-containers_faq.md)
+ [Memecahkan masalah wadah khusus](working-with_custom-containers_troubleshooting.md)

# Buat wadah khusus
<a name="working-with_custom-containers_create"></a>

Instruksi ini mengasumsikan bahwa Anda tahu cara menggunakan Docker dan Amazon Elastic Container Registry (Amazon ECR). Untuk informasi selengkapnya tentang Amazon ECR, lihat *[Panduan Pengguna Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide)*.

**Prasyarat**
+ Identitas IAM (penggunaan atau peran) yang Anda gunakan untuk melakukan tindakan ini memiliki izin yang benar untuk menggunakan Amazon ECR
+ Docker diinstal pada sistem lokal Anda

**Untuk membuat wadah khusus**

1. Buat `Dockerfile` Anda.

   A `Dockerfile` untuk menjalankan AWS SimSpace Weaver aplikasi dimulai dengan Amazon Linux 2 gambar di Amazon ECR.

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

1. Bangun Anda`Dockerfile`.

1. Unggah gambar kontainer Anda ke Amazon ECR.
   + [Gunakan Konsol Manajemen AWS.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html)
   + [Gunakan AWS Command Line Interface.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
**catatan**  
Jika Anda mendapatkan `AccessDeniedException` kesalahan saat mencoba mengunggah gambar penampung Anda ke Amazon ECR, identitas IAM Anda (pengguna atau peran) mungkin tidak memiliki izin yang diperlukan untuk menggunakan Amazon ECR. Anda dapat melampirkan kebijakan `AmazonEC2ContainerRegistryPowerUser` AWS terkelola ke identitas IAM Anda dan coba lagi. Untuk informasi selengkapnya tentang cara melampirkan kebijakan, lihat [Menambahkan dan menghapus izin identitas IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) di *AWS Identity and Access Management Panduan Pengguna*.

# Ubah proyek untuk menggunakan wadah khusus
<a name="working-with_custom-containers_modify-project"></a>

Petunjuk ini mengasumsikan bahwa Anda sudah tahu cara menggunakan AWS SimSpace Weaver dan ingin membuat alur kerja penyimpanan dan pengembangan aplikasi Anda menjadi AWS Cloud lebih efisien.

**Prasyarat**
+ Anda memiliki wadah khusus di Amazon Elastic Container Registry (Amazon ECR). Untuk informasi selengkapnya tentang membuat wadah kustom, lihat[Buat wadah khusus](working-with_custom-containers_create.md).

**Untuk memodifikasi proyek Anda untuk menggunakan wadah kustom**

1. Tambahkan izin ke peran aplikasi simulasi proyek Anda untuk menggunakan Amazon ECR.

   1. Jika Anda belum memiliki kebijakan IAM dengan izin berikut, buat kebijakan tersebut. Kami menyarankan nama kebijakan`simspaceweaver-ecr`. Untuk informasi selengkapnya tentang cara membuat kebijakan IAM, lihat [Membuat kebijakan IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) di *AWS Identity and Access Management Panduan Pengguna*.

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

   1. Temukan nama peran aplikasi simulasi proyek Anda:

      1. Dalam editor teks, buka CloudFormation template:

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

      1. Temukan `RoleName` properti di bawah`WeaverAppRole`. Nilainya adalah nama peran aplikasi simulasi proyek Anda.  
**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. Lampirkan `simspaceweaver-ecr` kebijakan ke peran aplikasi simulasi proyek. Untuk informasi selengkapnya tentang cara melampirkan kebijakan, lihat [Menambahkan dan menghapus izin identitas IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) di *AWS Identity and Access Management Panduan Pengguna*. 

   1. Arahkan ke `sdk-folder` dan jalankan perintah berikut untuk memperbarui SimSpace Weaver tumpukan sampel:

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

1. Tentukan gambar kontainer Anda dalam skema simulasi proyek.
   + Anda dapat menambahkan `default_image` properti opsional di bawah `simulation_properties` untuk menentukan gambar kontainer kustom default untuk semua domain.
   + Tambahkan `image` properti di `app_config` untuk domain yang ingin Anda gunakan gambar kontainer kustom. Tentukan URI repositori Amazon ECR sebagai nilainya. Anda dapat menentukan gambar yang berbeda untuk setiap domain.
     + Jika `image` tidak ditentukan untuk domain dan `default_image` ditentukan, aplikasi di domain tersebut menggunakan gambar default.
     + Jika `image` tidak ditentukan untuk domain dan `default_image` tidak ditentukan, aplikasi di domain tersebut berjalan dalam SimSpace Weaver wadah standar.  
**Example Cuplikan skema yang mencakup pengaturan wadah khusus**  

   ```
   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. Bangun dan unggah proyek Anda seperti biasa.

# Pertanyaan yang sering diajukan tentang wadah khusus
<a name="working-with_custom-containers_faq"></a>

## T1. Apa yang harus saya lakukan jika saya ingin mengubah isi wadah saya?
<a name="working-with_custom-containers_faq_q1"></a>
+ **Untuk simulasi yang sedang berjalan** — Anda tidak dapat mengubah wadah untuk simulasi yang sedang berjalan. Anda harus membangun wadah baru dan memulai simulasi baru yang menggunakan wadah itu.
+ **Untuk simulasi baru** — Buat wadah baru, unggah ke Amazon Elastic Container Registry (Amazon ECR) Registry ECR), dan mulai simulasi baru yang menggunakan wadah itu.

## T2. Bagaimana saya bisa mengubah gambar kontainer untuk simulasi saya?
<a name="working-with_custom-containers_faq_q2"></a>
+ **Untuk simulasi yang sedang berjalan** — Anda tidak dapat mengubah wadah untuk simulasi yang sedang berjalan. Anda harus memulai simulasi baru yang menggunakan wadah baru.
+ **Untuk simulasi baru** — Tentukan gambar kontainer baru dalam skema simulasi proyek Anda. Untuk informasi selengkapnya, lihat [Ubah proyek untuk menggunakan wadah khusus](working-with_custom-containers_modify-project.md).

# Memecahkan masalah wadah khusus
<a name="working-with_custom-containers_troubleshooting"></a>

**Topics**
+ [AccessDeniedException saat mengunggah gambar Anda ke Amazon Elastic Container Registry (Amazon ECR)](working-with_custom-containers_troubleshooting_access-denied.md)
+ [Simulasi yang menggunakan wadah khusus gagal dimulai](working-with_custom-containers_troubleshooting_no-start.md)

# AccessDeniedException saat mengunggah gambar Anda ke Amazon Elastic Container Registry (Amazon ECR)
<a name="working-with_custom-containers_troubleshooting_access-denied"></a>

Jika Anda mendapatkan `AccessDeniedException` kesalahan saat mencoba mengunggah gambar penampung Anda ke Amazon ECR, identitas IAM Anda (pengguna atau peran) mungkin tidak memiliki izin yang diperlukan untuk menggunakan Amazon ECR. Anda dapat melampirkan kebijakan `AmazonEC2ContainerRegistryPowerUser` AWS terkelola ke identitas IAM Anda dan coba lagi. Untuk informasi selengkapnya tentang cara melampirkan kebijakan, lihat [Menambahkan dan menghapus izin identitas IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) di *AWS Identity and Access Management Panduan Pengguna*.

# Simulasi yang menggunakan wadah khusus gagal dimulai
<a name="working-with_custom-containers_troubleshooting_no-start"></a>

**Tip pemecahan masalah**
+ Jika logging diaktifkan untuk simulasi Anda, periksa log kesalahan Anda.
+ Uji simulasi Anda tanpa wadah khusus.
+ Uji simulasi Anda secara lokal. Lihat informasi yang lebih lengkap di [Pembangunan lokal di SimSpace Weaver](working-with_local-development.md).

# Bekerja menggunakan Python
<a name="working-with_python"></a>

Anda dapat menggunakan Python untuk SimSpace Weaver aplikasi dan klien Anda. Kit pengembangan perangkat lunak Python (Python SDK) disertakan sebagai bagian dari paket yang dapat didistribusikan SDK aplikasi standar SimSpace Weaver . Pengembangan dengan Python bekerja dengan cara yang sama seperti pengembangan dalam bahasa lain yang didukung.

**penting**  
SimSpace Weaver hanya mendukung Python versi 3.9.

**penting**  
SimSpace Weaver dukungan untuk Python membutuhkan SimSpace Weaver versi 1.15.0 atau yang lebih baru.

**Topics**
+ [Membuat proyek Python](working-with_python_create-project.md)
+ [Memulai simulasi Python](working-with_python_start-sim.md)
+ [Contoh klien Python](working-with_python_client.md)
+ [Pertanyaan yang sering diajukan tentang penggunaan Python](working-with_python_faq.md)
+ [Memecahkan masalah yang terkait dengan Python](working-with_python_troubleshooting.md)

# Membuat proyek Python
<a name="working-with_python_create-project"></a>

## Wadah kustom Python
<a name="working-with_python_create-project_container"></a>

Untuk menjalankan SimSpace Weaver simulasi berbasis Python di AWS Cloud, Anda dapat membuat wadah khusus yang menyertakan dependensi yang diperlukan. Untuk informasi selengkapnya, lihat [Wadah khusus](working-with_custom-containers.md). 

Wadah kustom Python harus menyertakan yang berikut:
+ gcc
+ openssl-devel
+ bzip2-devel
+ libffi-devel
+ wget
+ tar
+ gzip
+ membuat
+ Python (versi 3.9)

Jika Anda menggunakan `PythonBubblesSample` template untuk membuat proyek Anda, Anda dapat menjalankan `quick-start.py` skrip (terletak di `tools` folder proyek Anda) untuk membuat gambar Docker dengan dependensi yang diperlukan. Skrip mengunggah gambar ke Amazon Elastic Container Registry (Amazon ECR).

`quick-start.py`Skrip menggunakan yang berikut ini`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
```

Anda dapat menambahkan dependensi Anda sendiri ke: `Dockerfile`

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

`requirements.txt`File tersebut berisi daftar paket Python yang diperlukan untuk simulasi `PythonBubblesSample` sampel:

```
Flask==2.1.1
```

Anda dapat menambahkan dependensi paket Python Anda sendiri ke: `requirements.txt`

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

Itu `Dockerfile` dan `requirements.txt` ada di `tools` folder proyek Anda.

**penting**  
Anda secara teknis tidak harus menggunakan wadah khusus dengan simulasi Python Anda, tetapi kami sangat menyarankan Anda menggunakan wadah khusus. Wadah Amazon Linux 2 (AL2) standar yang kami sediakan tidak memiliki Python. Oleh karena itu, jika Anda tidak menggunakan wadah khusus yang memiliki Python, Anda harus menyertakan Python dan dependensi yang diperlukan di setiap file zip aplikasi yang Anda unggah. SimSpace Weaver

# Memulai simulasi Python
<a name="working-with_python_start-sim"></a>

Anda dapat memulai simulasi berbasis Python dengan cara yang sama seperti simulasi biasa SimSpace Weaver , baik di SimSpace Weaver Local dan SimSpace Weaver di dalam AWS Cloud. Untuk informasi lebih lanjut, lihat tutorial di[Memulai dengan SimSpace Weaver](getting-started.md).

`PythonBubblesSample`Ini termasuk klien sampel Python sendiri. Untuk informasi selengkapnya, lihat [Contoh klien Python](working-with_python_client.md). 

# Contoh klien Python
<a name="working-with_python_client"></a>

Jika Anda menggunakan `PythonBubblesSample` template untuk membuat proyek maka proyek Anda berisi contoh klien Python. Anda dapat menggunakan klien sampel untuk melihat `PythonBubblesSample` simulasi. Anda juga dapat menggunakan klien sampel sebagai titik awal untuk membuat klien Python Anda sendiri.

Prosedur berikut mengasumsikan bahwa Anda membuat `PythonBubblesSample` proyek dan memulai simulasinya.

**Untuk memulai klien Python**

1. Di **jendela prompt perintah**, buka folder proyek `PyBubbleClient` sampel.

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

1. Jalankan klien Python.

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

**Parameter**  
**host**  
Alamat IP simulasi Anda. Untuk simulasi yang dimulai di AWS Cloud, Anda dapat menemukan alamat IP simulasi Anda di [SimSpace Weaver konsol](https://console.aws.amazon.com/simspaceweaver) atau menggunakan prosedur di [Dapatkan alamat IP dan nomor port aplikasi khususDapatkan alamat IP dan nomor port](working-with_get-ip.md) tutorial mulai cepat. Untuk simulasi lokal, gunakan `127.0.0.1` sebagai alamat IP.  
**port**  
Nomor port simulasi Anda. Untuk simulasi yang dimulai pada AWS Cloud, ini adalah nomor `Actual` port. Anda dapat menemukan nomor port simulasi Anda di [SimSpace Weaver konsol](https://console.aws.amazon.com/simspaceweaver) atau menggunakan prosedur di [Dapatkan alamat IP dan nomor port aplikasi khususDapatkan alamat IP dan nomor port](working-with_get-ip.md) tutorial mulai cepat. Untuk simulasi lokal, gunakan `7000` sebagai nomor port.  
**simsize**  
Jumlah maksimum entitas untuk ditampilkan di klien.

# Pertanyaan yang sering diajukan tentang penggunaan Python
<a name="working-with_python_faq"></a>

## T1. Versi Python apa yang didukung?
<a name="working-with_python_faq_q1"></a>

SimSpace Weaver hanya mendukung Python versi 3.9.

# Memecahkan masalah yang terkait dengan Python
<a name="working-with_python_troubleshooting"></a>

**Topics**
+ [Kegagalan selama pembuatan wadah khusus](working-with_python_troubleshooting_create-container-failure.md)
+ [Simulasi Python Anda gagal dimulai](working-with_python_troubleshooting_no-start.md)
+ [Sebuah simulasi Python atau tampilan klien melempar kesalahan ModuleNotFound](working-with_python_troubleshooting_module-not-found.md)

# Kegagalan selama pembuatan wadah khusus
<a name="working-with_python_troubleshooting_create-container-failure"></a>

Jika Anda mendapatkan kesalahan `no basic auth credentials` setelah menjalankan `quick-start.py` maka mungkin ada masalah dengan kredensi sementara Anda untuk Amazon ECR. Jalankan perintah berikut dengan Wilayah AWS ID dan nomor AWS akun Anda:

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

**penting**  
Pastikan bahwa yang Wilayah AWS Anda tentukan sama dengan yang Anda gunakan untuk simulasi Anda. Gunakan salah satu Wilayah AWS yang SimSpace Weaver mendukung. Untuk informasi selengkapnya, lihat [SimSpace Titik akhir dan kuota Weaver](service-quotas.md).

Setelah Anda menjalankan `aws ecr` perintah, jalankan `quick-start.py` lagi.

**Sumber pemecahan masalah lainnya untuk diperiksa**
+ [Memecahkan masalah wadah khusus](working-with_custom-containers_troubleshooting.md)
+ [Pemecahan masalah Amazon ECR di Panduan](https://docs.aws.amazon.com/AmazonECR/latest/userguide/troubleshooting.html) Pengguna *Amazon* ECR
+ [Menyiapkan dengan Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html) di Panduan Pengguna *Amazon ECR*

# Simulasi Python Anda gagal dimulai
<a name="working-with_python_troubleshooting_no-start"></a>

Anda mungkin melihat `Unable to start app` kesalahan dalam log manajemen simulasi Anda. Ini bisa terjadi jika pembuatan penampung kustom Anda gagal. Untuk informasi selengkapnya, lihat [Kegagalan selama pembuatan wadah khusus](working-with_python_troubleshooting_create-container-failure.md). Untuk informasi lebih lanjut tentang log, lihat [SimSpace Weaver log di Amazon CloudWatch Log](cloudwatch-logs.md).

Jika Anda yakin tidak ada yang salah dengan container Anda, periksa kode sumber Python aplikasi Anda. Anda dapat menggunakan SimSpace Weaver Local untuk menguji aplikasi Anda. Untuk informasi selengkapnya, lihat [Pembangunan lokal di SimSpace Weaver](working-with_local-development.md).

# Sebuah simulasi Python atau tampilan klien melempar kesalahan ModuleNotFound
<a name="working-with_python_troubleshooting_module-not-found"></a>

Python melempar `ModuleNotFound` kesalahan ketika tidak dapat menemukan paket Python yang diperlukan.

Jika simulasi Anda ada di dalam AWS Cloud, pastikan bahwa penampung kustom Anda memiliki semua dependensi yang diperlukan yang tercantum dalam file Anda. `requirements.txt` Ingatlah untuk menjalankan `quick-start.py` lagi jika Anda mengedit`requirements.txt`.

Jika Anda mendapatkan kesalahan untuk `PythonBubblesSample` klien, gunakan `pip` untuk menginstal paket yang ditunjukkan:

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

# Support untuk mesin lain
<a name="working-with_engines"></a>

Anda dapat menggunakan kustom Anda sendiri C\$1\$1 mesin dengan SimSpace Weaver. Saat ini kami sedang mengembangkan dukungan untuk mesin berikut. Ada dokumentasi terpisah untuk masing-masing mesin ini.

**penting**  
Integrasi dengan mesin yang tercantum di sini bersifat eksperimental. Mereka tersedia untuk pratinjau.

**Mesin**
+ [Unity](#working-with_engines_unity)(versi minimum 2022.3.19.F1)
+ [Unreal Engine](#working-with_engines_unreal)(versi minimum 5.0)

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

Anda harus memiliki Unity lingkungan pengembangan sudah diinstal sebelum Anda membangun SimSpace Weaver simulasi dengan Unity. Untuk informasi selengkapnya, lihat petunjuk terpisah:

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

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

Anda harus membangun sebuah Unreal Engine server khusus dari kode sumber. SimSpaceWeaverAppSdkDistributable Termasuk versi PathfindingSample untuk Unreal Engine. Untuk informasi selengkapnya, lihat petunjuk terpisah: 

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

# Penggunaan perangkat lunak berlisensi dengan AWS SimSpace Weaver
<a name="working-with_byol"></a>

AWS SimSpace Weaver memungkinkan Anda membangun simulasi dengan mesin dan konten simulasi pilihan Anda. Sehubungan dengan penggunaan Anda SimSpace Weaver, Anda bertanggung jawab untuk memperoleh, memelihara, dan mematuhi ketentuan lisensi perangkat lunak atau konten apa pun yang Anda gunakan dalam simulasi Anda. Verifikasi perjanjian lisensi Anda memungkinkan Anda untuk menyebarkan perangkat lunak dan konten Anda di lingkungan yang dihosting virtual.

# Mengelola sumber daya Anda dengan AWS CloudFormation
<a name="working-with_cloudformation"></a>

Anda dapat menggunakan AWS CloudFormation untuk mengelola AWS SimSpace Weaver sumber daya Anda. CloudFormation adalah AWS layanan terpisah yang membantu Anda menentukan, menyediakan, dan mengelola AWS infrastruktur Anda sebagai kode. *[Dengan CloudFormation Anda membuat file JSON atau YAMB, yang disebut template.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-templates template)* Template Anda menentukan rincian infrastruktur Anda. CloudFormation menggunakan template Anda untuk menyediakan infrastruktur Anda sebagai satu unit, yang disebut *[tumpukan](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#w2ab1b5c15b9)*. Ketika Anda menghapus tumpukan Anda, Anda dapat CloudFormation menghapus semua yang ada di tumpukan secara bersamaan. Anda dapat mengelola template Anda menggunakan proses manajemen kode sumber standar (misalnya, melacaknya dalam sistem kontrol versi seperti [Git](https://git-scm.com/)). Untuk informasi selengkapnya CloudFormation, lihat [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide).

**Sumber daya simulasi Anda**  
Di AWS, *sumber daya* adalah entitas yang dapat Anda gunakan. Contohnya termasuk EC2 instans Amazon, bucket Amazon S3, atau peran IAM. SimSpace Weaver Simulasi Anda adalah sumber daya. Dalam konfigurasi, Anda biasanya menentukan AWS sumber daya dalam formulir`AWS::service::resource`. Untuk SimSpace Weaver, Anda menentukan sumber daya simulasi Anda sebagai`AWS::SimSpaceWeaver::Simulation`. Untuk informasi selengkapnya tentang sumber daya simulasi Anda CloudFormation, lihat [SimSpace Weaver](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-simspaceweaver-simulation.html)bagian di *Panduan AWS CloudFormation Pengguna*.

**Bagaimana saya bisa menggunakan CloudFormation dengan SimSpace Weaver?**  
Anda dapat membuat CloudFormation template yang menentukan AWS sumber daya yang ingin Anda sediakan. Template Anda dapat menentukan seluruh arsitektur, bagian dari arsitektur, atau solusi kecil. Misalnya, Anda dapat menentukan arsitektur untuk SimSpace Weaver solusi yang menyertakan bucket Amazon S3, izin IAM, database pendukung di Amazon Relational Database Service atau Amazon DynamoDB, dan sumber daya Anda. `Simulation` Anda kemudian dapat menggunakan CloudFormation untuk menyediakan semua sumber daya tersebut sebagai satu unit, dan pada saat yang sama.

**Example template yang membuat sumber daya IAM dan memulai simulasi**  
Contoh template berikut membuat peran IAM dan izin yang SimSpace Weaver perlu melakukan tindakan di akun Anda. Skrip SDK SimSpace Weaver aplikasi membuat peran dan izin secara spesifik Wilayah AWS saat Anda membuat proyek, tetapi Anda dapat menggunakan CloudFormation templat untuk menerapkan simulasi ke yang lain Wilayah AWS tanpa menjalankan skrip lagi. Misalnya, Anda dapat melakukan ini untuk menyiapkan simulasi cadangan untuk tujuan pemulihan bencana.  
Dalam contoh ini, nama simulasi aslinya adalah`MySimulation`. Sebuah ember untuk skema sudah ada di Wilayah AWS mana CloudFormation akan membangun tumpukan. Bucket berisi versi skema yang dikonfigurasi dengan benar untuk menjalankan simulasi di dalamnya. Wilayah AWS Ingat bahwa skema menentukan lokasi file zip aplikasi Anda, yang merupakan bucket Amazon S3 yang Wilayah AWS sama dengan simulasi. Bucket ritsleting aplikasi dan file harus sudah ada di Wilayah AWS saat CloudFormation membangun tumpukan, jika tidak simulasi Anda tidak akan dimulai. Perhatikan bahwa nama bucket dalam contoh ini menyertakan Wilayah AWS, tetapi itu tidak menentukan di mana sebenarnya bucket berada. Anda harus memastikan bahwa bucket benar-benar ada di dalamnya Wilayah AWS (Anda dapat memeriksa properti bucket di konsol Amazon S3, dengan Amazon S3, atau dengan APIs perintah Amazon S3 di). AWS CLI  
Contoh ini menggunakan beberapa fungsi dan parameter bawaan CloudFormation untuk melakukan substitusi variabel. *Untuk informasi selengkapnya, lihat [Referensi fungsi intrinsik dan referensi](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) [parameter semu](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) di Panduan Pengguna.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'
```

# Menggunakan snapshot dengan AWS CloudFormation
<a name="working-with_cloudformation_snapshots"></a>

[Snapshot](working-with_snapshots.md) adalah cadangan dari simulasi. Contoh berikut memulai simulasi baru dari snapshot bukan dari skema. Snapshot dalam contoh ini dibuat dari simulasi proyek SDK SimSpace Weaver aplikasi. CloudFormation membuat sumber daya simulasi baru dan menginisialisasi dengan data dari snapshot. Simulasi baru dapat berbeda `MaximumDuration` dari simulasi aslinya.

Kami menyarankan Anda membuat dan menggunakan salinan peran aplikasi simulasi asli Anda. Peran aplikasi simulasi asli dapat dihapus jika Anda menghapus tumpukan simulasi itu. CloudFormation 

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

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

Anda dapat membuat *snapshot* untuk mencadangkan data entitas simulasi Anda kapan saja. SimSpace Weaver membuat file.zip di bucket Amazon S3. Anda dapat membuat simulasi baru dengan snapshot. SimSpace Weaver menginisialisasi State Fabric simulasi baru Anda dengan data entitas yang disimpan dalam snapshot, memulai aplikasi spasial dan layanan yang berjalan saat snapshot dibuat, dan menyetel jam ke centang yang sesuai. SimSpace Weaver mendapatkan konfigurasi simulasi Anda dari snapshot alih-alih dari file skema. File zip aplikasi Anda harus berada di lokasi yang sama di Amazon S3 seperti di simulasi asli. Anda harus memulai aplikasi khusus apa pun secara terpisah.

**Topik**
+ [Gunakan kasus untuk snapshot](#working-with_snapshots_use-cases)
+ [Gunakan SimSpace Weaver konsol untuk bekerja dengan snapshot](working-with_snapshots_console.md)
+ [Gunakan AWS CLI untuk bekerja dengan snapshot](working-with_snapshots_cli.md)
+ [Menggunakan snapshot dengan AWS CloudFormation](working-with_cloudformation_snapshots.md)
+ [Pertanyaan yang sering diajukan tentang snapshot](working-with_snapshots_faq.md)

## Gunakan kasus untuk snapshot
<a name="working-with_snapshots_use-cases"></a>

### Kembali ke keadaan sebelumnya dan jelajahi skenario percabangan
<a name="working-with_snapshots_use-case_branching"></a>

Anda dapat membuat snapshot simulasi Anda untuk menyimpannya pada status tertentu. Anda kemudian dapat membuat beberapa simulasi baru dari snapshot itu dan menjelajahi berbagai skenario yang dapat bercabang dari status itu.

### Praktik terbaik pemulihan bencana dan keamanan
<a name="working-with_snapshots_use-cases_best-practice"></a>

Kami menyarankan Anda secara teratur mencadangkan simulasi Anda, terutama untuk simulasi yang berjalan selama lebih dari 1 jam atau menggunakan banyak pekerja. Cadangan dapat membantu Anda pulih dari bencana dan insiden keamanan. Snapshots menyediakan cara bagi Anda untuk membuat cadangan simulasi Anda. Snapshot mengharuskan file.zip aplikasi Anda ada di lokasi yang sama di Amazon S3 seperti sebelumnya. Jika Anda harus dapat memindahkan file.zip aplikasi Anda ke lokasi lain, Anda harus menggunakan solusi cadangan khusus. 

Untuk informasi lebih lanjut tentang praktik terbaik lainnya, lihat [Praktik terbaik saat bekerja dengan SimSpace Weaver](best-practices.md) dan[Praktik terbaik keamanan untuk SimSpace Weaver](security_best-practices.md).

### Perpanjang durasi simulasi Anda
<a name="working-with_snapshots_use-cases_extend-duration"></a>

*Sumber daya simulasi* Anda adalah representasi dari simulasi Anda. SimSpace Weaver Semua sumber daya simulasi memiliki `MaximumDuration` pengaturan. Sumber daya simulasi secara otomatis berhenti ketika mencapainya`MaximumDuration`. Nilai maksimum `MaximumDuration` adalah `14D` (14 hari). 

Jika Anda membutuhkan simulasi untuk bertahan lebih lama dari sumber daya simulasi, Anda dapat membuat snapshot sebelum sumber daya simulasi mencapai sumber daya simulasi. `MaximumDuration` `MaximumDuration` Anda dapat memulai simulasi baru (membuat sumber daya simulasi baru) dengan snapshot Anda. SimSpace Weaver menginisialisasi data entitas Anda dari snapshot, memulai aplikasi spasial dan layanan yang sama yang berjalan sebelumnya, dan memulihkan jam. Anda dapat memulai aplikasi kustom dan melakukan inisialisasi kustom tambahan. Anda dapat mengatur sumber daya simulasi baru ke nilai yang berbeda saat Anda memulainya. `MaximumDuration`

# Gunakan SimSpace Weaver konsol untuk bekerja dengan snapshot
<a name="working-with_snapshots_console"></a>

Anda dapat menggunakan SimSpace Weaver konsol untuk membuat snapshot simulasi Anda.

**Topics**
+ [Buat snapshot](#working-with_snapshots_console_create)
+ [Mulai simulasi dari snapshot](#working-with_snapshots_console_start)

## Gunakan konsol untuk membuat snapshot
<a name="working-with_snapshots_console_create"></a>

**Untuk membuat snapshot**

1. Masuk ke Konsol Manajemen AWS dan sambungkan ke [SimSpace Weaver konsol](https://console.aws.amazon.com/simspaceweaver).

1. Pilih **Simulasi** dari panel navigasi.

1. Pilih tombol radio di sebelah nama simulasi. **Status** simulasi Anda harus **Dimulai**. 

1. Di bagian atas halaman, pilih **Buat snapshot**.

1. Di bawah **pengaturan Snapshot**, untuk **tujuan Snapshot**, masukkan URI Amazon S3 dari bucket atau bucket dan folder tempat Anda SimSpace Weaver ingin membuat snapshot. Anda dapat memilih **Browse S3** jika Anda lebih suka menelusuri bucket yang tersedia dan memilih lokasi.
**penting**  
Bucket Amazon S3 harus Wilayah AWS sama dengan simulasi.
**catatan**  
SimSpace Weaver membuat `snapshot` folder di dalam tujuan snapshot yang Anda pilih. SimSpace Weaver membuat file snapshot .zip di folder itu`snapshot`.

1. Pilih **Buat snapshot**.

## Gunakan konsol untuk memulai simulasi dari snapshot
<a name="working-with_snapshots_console_start"></a>

Untuk memulai simulasi dari snapshot, file snapshot .zip Anda harus ada di bucket Amazon S3 yang dapat diakses simulasi Anda. Simulasi Anda menggunakan izin yang ditentukan dalam peran aplikasi yang Anda pilih saat memulai simulasi. Semua file aplikasi.zip dari simulasi asli harus ada di lokasi yang sama seperti saat snapshot dibuat.

**Untuk memulai simulasi dari snapshot**

1. Masuk ke Konsol Manajemen AWS dan sambungkan ke [SimSpace Weaver konsol](https://console.aws.amazon.com/simspaceweaver).

1. Pilih **Simulasi** dari panel navigasi.

1. Di bagian atas halaman, pilih **Mulai simulasi.**

1. Di bawah **Pengaturan simulasi**, masukkan nama dan deskripsi opsional untuk simulasi Anda. Nama simulasi Anda harus unik di Anda Akun AWS.

1. Untuk **metode mulai simulasi**, pilih **Gunakan snapshot di Amazon S3**.

1. Untuk URI **Amazon S3 untuk snapshot, masukkan URI** Amazon S3 dari file snapshot Anda, atau pilih **Browse S3 untuk menelusuri** dan memilih file.
**penting**  
Bucket Amazon S3 harus Wilayah AWS sama dengan simulasi.

1. Untuk **peran IAM**, pilih peran aplikasi yang akan digunakan simulasi Anda.

1. Untuk **Durasi maksimum**, masukkan jumlah waktu maksimum yang harus dijalankan oleh sumber daya simulasi Anda. Nilai maksimumnya adalah `14D`. Untuk informasi selengkapnya tentang durasi maksimum, lihat[.](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)

1. Di bawah **Tag - *opsional***, pilih **Tambahkan tag baru** jika Anda ingin menambahkan tag.

1. Pilih **Mulai simulasi.**

# Gunakan AWS CLI untuk bekerja dengan snapshot
<a name="working-with_snapshots_cli"></a>

Anda dapat menggunakan AWS CLI untuk memanggil SimSpace Weaver APIs dari command prompt. Anda harus AWS CLI menginstal dan mengkonfigurasi dengan benar. Untuk informasi selengkapnya, lihat [Menginstal atau memperbarui AWS CLI versi terbaru](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) di *Panduan AWS Command Line Interface Pengguna untuk Versi 2*.

**Topics**
+ [Buat snapshot](#working-with_snapshots_cli_create)
+ [Mulai simulasi dari snapshot](#working-with_snapshots_cli_start)

## Gunakan AWS CLI untuk membuat snapshot
<a name="working-with_snapshots_cli_create"></a>

**Untuk membuat snapshot**
+ Pada **prompt perintah**, panggil `CreateSnapshot` API.

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

  **Parameter**  
simulasi  
Nama simulasi yang dimulai. Anda dapat menggunakan `aws simspaceweaver list-simulations` untuk melihat nama dan status simulasi Anda.  
tujuan  
String yang menentukan bucket Amazon S3 tujuan dan awalan key objek opsional untuk file snapshot Anda. Object key prefix Anda biasanya berupa folder di bucket Anda. SimSpace Weaver membuat snapshot Anda di dalam `snapshot` folder di tujuan ini.   
Bucket Amazon S3 harus Wilayah AWS sama dengan simulasi.

  **Contoh**

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

Untuk informasi selengkapnya tentang `CreateSnapshot` API, lihat [CreateSnapshot](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_CreateSnapshot.html)di *Referensi AWS SimSpace Weaver API*.

## Gunakan AWS CLI untuk memulai simulasi dari snapshot
<a name="working-with_snapshots_cli_start"></a>

**Untuk memulai simulasi dari snapshot**
+ Pada **prompt perintah**, panggil `StartSimulation` API.

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

  **Parameter**  
name  
Nama simulasi baru. Nama simulasi harus unik di Anda Akun AWS. Anda dapat menggunakan `aws simspaceweaver list-simulations` untuk melihat nama-nama simulasi yang ada.  
peran-arn  
Nama Sumber Daya Amazon (ARN) dari peran aplikasi yang akan digunakan simulasi Anda.  
snapshot-s3-lokasi  
String yang menentukan bucket Amazon S3 dan kunci objek file snapshot Anda.  
Bucket Amazon S3 harus Wilayah AWS sama dengan simulasi.

  **Contoh**

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

Untuk informasi selengkapnya tentang `StartSimulation` API, lihat [StartSimulation](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)di *Referensi AWS SimSpace Weaver API*.

# Pertanyaan yang sering diajukan tentang snapshot
<a name="working-with_snapshots_faq"></a>

**Apakah simulasi saya terus berjalan selama snapshot?**  
Sumber daya simulasi Anda terus berjalan selama snapshot dan Anda terus menerima biaya penagihan untuk waktu itu. Waktu dihitung untuk durasi maksimum simulasi Anda. Aplikasi Anda tidak menerima kutu saat snapshot sedang berlangsung. Jika status jam Anda `STARTED` saat pembuatan snapshot dimulai, jam Anda akan tetap menunjukkan `STARTED` status. Aplikasi Anda menerima kutu lagi setelah snapshot selesai. Jika status jam Anda adalah `STOPPED` maka status jam Anda akan tetap ada`STOPPED`. Perhatikan bahwa simulasi dengan `STARTED` status berjalan meskipun status jamnya. `STOPPED`

**Apa yang terjadi jika snapshot sedang berlangsung dan simulasi saya mencapai durasi maksimumnya?**  
Simulasi Anda akan menyelesaikan snapshot dan kemudian berhenti segera setelah proses snapshot berakhir (baik berhasil atau tidak berhasil). Kami menyarankan Anda menguji proses snapshot sebelumnya untuk mengetahui berapa lama waktu yang dibutuhkan, ukuran file snapshot yang dapat Anda harapkan, dan apakah itu harus berhasil diselesaikan.

**Apa yang terjadi jika saya menghentikan simulasi yang memiliki snapshot sedang berlangsung?**  
Cuplikan yang sedang berlangsung segera berhenti saat Anda menghentikan simulasi. Itu tidak akan membuat file snapshot.

**Bagaimana saya bisa menghentikan snapshot yang sedang berlangsung?**  
Satu-satunya cara untuk menghentikan snapshot yang sedang berlangsung adalah dengan menghentikan simulasi. **Anda tidak dapat memulai ulang simulasi setelah Anda menghentikannya.**

**Berapa lama waktu yang dibutuhkan untuk menyelesaikan snapshot saya?**  
Waktu yang dibutuhkan untuk membuat snapshot tergantung pada simulasi Anda. Kami menyarankan Anda menguji proses snapshot sebelumnya untuk mengetahui berapa lama waktu yang dibutuhkan untuk simulasi Anda.

**Seberapa besar file snapshot saya?**  
Ukuran file snapshot tergantung pada simulasi Anda. Kami menyarankan Anda menguji proses snapshot terlebih dahulu untuk mengetahui seberapa besar file tersebut untuk simulasi Anda.

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

API perpesanan menyederhanakan aplikasi untuk komunikasi aplikasi dalam simulasi. APIs untuk mengirim dan menerima pesan adalah bagian dari SDK SimSpace Weaver aplikasi. Pesan saat ini menggunakan pendekatan upaya terbaik untuk mengirim dan menerima pesan. SimSpace Weaver mencoba send/receive mengirim pesan pada centang simulasi berikutnya, tetapi tidak ada jaminan waktu pengiriman, pemesanan, atau kedatangan.

**Topik**
+ [Kasus penggunaan untuk pengiriman pesan](#working-with_messaging_use-cases)
+ [Menggunakan pesan APIs](working-with_messaging_using.md)
+ [Kapan menggunakan pesan](working-with_messaging_when-to-use.md)
+ [Kiat saat bekerja dengan perpesanan](working-with_messaging_tips.md)
+ [Kesalahan pesan dan pemecahan masalah](working-with_messaging_troubleshooting.md)

## Kasus penggunaan untuk pengiriman pesan
<a name="working-with_messaging_use-cases"></a>

**Berkomunikasi antara aplikasi simulasi**  
Gunakan API perpesanan untuk berkomunikasi antar aplikasi dalam simulasi Anda. Gunakan untuk mengubah status entitas di kejauhan, mengubah perilaku entitas, atau menyiarkan informasi ke seluruh simulasi.

**Akui tanda terima pesan**  
Pesan terkirim berisi informasi tentang pengirim di header pesan. Gunakan informasi ini untuk mengirim kembali balasan pengakuan pada saat menerima pesan.

**Meneruskan data yang diterima oleh aplikasi khusus ke aplikasi lain dalam simulasi**  
Perpesanan bukanlah pengganti cara klien terhubung ke aplikasi khusus yang berjalan SimSpace Weaver. Namun, perpesanan memungkinkan pengguna metode penerusan data dari aplikasi khusus yang menerima data klien ke aplikasi lain yang tidak memiliki koneksi eksternal. Alur pesan juga dapat bekerja secara terbalik, memungkinkan aplikasi tanpa koneksi eksternal untuk meneruskan data ke aplikasi khusus kemudian ke klien. 

# Menggunakan pesan APIs
<a name="working-with_messaging_using"></a>

Pesan APIs terkandung dalam SDK SimSpace Weaver aplikasi (versi minimum 1.16.0). Pesan didukung dalam C \$1\$1, Python, dan integrasi kami dengan Unreal Engine 5 dan Unity.

Ada dua fungsi yang menangani transaksi pesan: `SendMessage` dan`ReceiveMessages`. Semua pesan terkirim berisi tujuan dan muatan. `ReceiveMessages`API menampilkan daftar pesan yang saat ini berada dalam antrean pesan masuk aplikasi.

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

**Kirim pesan**

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

**Menerima pesan**

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

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

**Kirim pesan**

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

**Menerima pesan**

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

------

**Topik**
+ [Mengirim pesan](#working-with_messaging_using_send)
+ [Menerima pesan](#working-with_messaging_using_receive)
+ [Membalas pengirim](#working-with_messaging_using_reply)

## Mengirim pesan
<a name="working-with_messaging_using_send"></a>

Pesan terdiri dari transaksi (mirip dengan panggilan Weaver API lainnya), payload, dan tujuan.

### Muatan pesan
<a name="working-with_messaging_using_send_payload"></a>

Payload pesan adalah struktur data fleksibel hingga 256 byte. Kami merekomendasikan hal berikut sebagai praktik terbaik untuk membuat muatan pesan Anda.

**Untuk membuat payload pesan**

1. Buat struktur data (seperti `struct` dalam C \$1\$1) yang mendefinisikan isi pesan.

1. Buat payload pesan yang berisi nilai yang akan dikirim dalam pesan Anda.

1. Buat `MessagePayload` objek.

### Tujuan pesan
<a name="working-with_messaging_using_send_destination"></a>

Tujuan pesan ditentukan oleh `MessageEndpoint` objek. Ini termasuk tipe endpoint dan endpoint ID. Satu-satunya jenis endpoint yang saat ini didukung adalah`Partition`, yang memungkinkan Anda untuk menangani pesan ke partisi lain dalam simulasi. Endpoint ID adalah ID partisi tujuan target Anda.

Anda hanya dapat memberikan 1 alamat tujuan dalam satu pesan. Buat dan kirim beberapa pesan jika Anda ingin mengirim pesan ke lebih dari 1 partisi secara bersamaan.

Untuk panduan tentang cara menyelesaikan titik akhir pesan dari suatu posisi, lihat[Kiat saat bekerja dengan perpesanan](working-with_messaging_tips.md).

### Kirim pesan
<a name="working-with_messaging_using_send_send"></a>

Anda dapat menggunakan `SendMessage` API setelah membuat objek tujuan dan payload.

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

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

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

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

------

**Contoh lengkap pengiriman pesan**  
Contoh berikut menunjukkan bagaimana Anda dapat membangun dan mengirim pesan generik. Contoh ini mengirimkan 16 pesan individual. Setiap pesan berisi muatan dengan nilai antara 0 dan 15, dan centang simulasi saat ini.

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

## Menerima pesan
<a name="working-with_messaging_using_receive"></a>

SimSpace Weaver mengirimkan pesan ke antrian pesan masuk partisi. Gunakan `ReceiveMessages` API untuk mendapatkan `MessageList` objek yang berisi pesan dari antrian. Proses setiap pesan dengan `ExtractMessage` API untuk mendapatkan data pesan.

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

## Membalas pengirim
<a name="working-with_messaging_using_reply"></a>

Setiap pesan yang diterima berisi header pesan dengan informasi tentang pengirim asli pesan. Anda dapat menggunakan message.header.source\$1endpoint untuk mengirim balasan.

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

# Kapan menggunakan pesan
<a name="working-with_messaging_when-to-use"></a>

Messaging in SimSpace Weaver menawarkan pola lain untuk bertukar informasi antara aplikasi simulasi. Langganan menyediakan mekanisme tarik untuk membaca data dari aplikasi atau area simulasi tertentu; pesan menyediakan mekanisme push untuk mengirim data ke aplikasi atau area simulasi tertentu.

Di bawah ini adalah dua kasus penggunaan di mana lebih membantu untuk mendorong data menggunakan pesan daripada menarik atau membaca data melalui langganan.

**Example 1: Mengirim perintah ke aplikasi lain untuk mengubah posisi entitas**  

```
// 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);
```
Di sisi penerima, aplikasi memperbarui posisi entitas dan menuliskannya ke 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: Mengirim pesan entitas buat ke aplikasi spasial**  

```
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);
```
Di sisi penerima, aplikasi membuat entitas baru di State Fabric dan memperbarui posisinya.  

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

# Kiat saat bekerja dengan perpesanan
<a name="working-with_messaging_tips"></a>

## Menyelesaikan titik akhir dari posisi atau nama aplikasi
<a name="working-with_messaging_tips_resolve-endpoint"></a>

Anda dapat menggunakan `AllPartitions` fungsi untuk mendapatkan batas spasial dan ID domain yang Anda butuhkan untuk menentukan partisi pesan IDs dan tujuan pesan. Namun, jika Anda tahu posisi yang ingin Anda pesan, tetapi bukan ID partisi, Anda dapat menggunakan MessageEndpointResolver fungsi tersebut.

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

## Serialisasi dan deserialisasi payload pesan
<a name="working-with_messaging_tips_serialize-payload"></a>

Anda dapat menggunakan fungsi berikut untuk membuat dan membaca muatan pesan. Untuk informasi selengkapnya, lihat MessagingUtils .h di pustaka SDK aplikasi di sistem lokal Anda.

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

# Kesalahan pesan dan pemecahan masalah
<a name="working-with_messaging_troubleshooting"></a>

Anda mungkin mengalami kesalahan berikut saat menggunakan pesan APIs.

## Kesalahan resolusi titik akhir
<a name="working-with_messaging_troubleshooting_endpoint-resolution"></a>

Kesalahan ini dapat terjadi sebelum aplikasi mengirim pesan.

### Pemeriksaan nama domain
<a name="working-with_messaging_troubleshooting_dns-check"></a>

Mengirim pesan ke titik akhir yang tidak valid menghasilkan kesalahan berikut:

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

Ini dapat terjadi ketika Anda mencoba mengirim pesan ke aplikasi khusus dan aplikasi khusus itu belum bergabung dengan simulasi. Gunakan `DescribeSimulation` API untuk memastikan aplikasi kustom Anda telah diluncurkan sebelum Anda mengirim pesan ke sana. Perilaku ini sama di dalam SimSpace Weaver Local dan AWS Cloud.

### Pemeriksaan posisi
<a name="working-with_messaging_troubleshooting_position-check"></a>

Mencoba menyelesaikan titik akhir dengan nama domain yang valid tetapi posisi yang tidak valid menghasilkan kesalahan berikut.

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

Sebaiknya gunakan `MessageUtils` pustaka `MessageEndpointResolver` di dalam aplikasi yang terdapat dalam SDK SimSpace Weaver aplikasi.

## Kesalahan pengiriman pesan
<a name="working-with_messaging_troubleshooting_message-sending"></a>

Kesalahan berikut dapat terjadi saat aplikasi mengirim pesan.

### Batas pengiriman pesan per aplikasi, per centang, terlampaui
<a name="working-with_messaging_troubleshooting_send-limit"></a>

Batas saat ini untuk jumlah pesan yang dapat dikirim per aplikasi per tick simulasi adalah 128. Panggilan berikutnya pada centang yang sama akan gagal dengan kesalahan berikut: 

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

SimSpace Weaver mencoba mengirim pesan yang tidak terkirim pada centang berikutnya. Turunkan frekuensi kirim untuk mengatasi masalah ini. Gabungkan muatan pesan yang lebih kecil dari batas 256 byte untuk menurunkan jumlah pesan keluar.

Perilaku ini sama di dalam SimSpace Weaver Local dan di AWS Cloud. 

### Batas ukuran muatan pesan terlampaui
<a name="working-with_messaging_troubleshooting_size-limit"></a>

Batas saat ini untuk ukuran payload pesan adalah 256 byte di keduanya SimSpace Weaver Local dan di. AWS Cloud Mengirim pesan dengan muatan yang lebih besar dari 256 byte menghasilkan kesalahan berikut:

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

SimSpace Weaver memeriksa setiap pesan dan hanya menolak pesan yang melebihi batas. Misalnya, jika aplikasi Anda mencoba mengirim 10 pesan dan 1 gagal dicentang, hanya 1 pesan yang ditolak. SimSpace Weaver mengirim 9 pesan lainnya.

Perilaku ini sama di dalam SimSpace Weaver Local dan AWS Cloud.

### Tujuan adalah sama dengan sumber
<a name="working-with_messaging_troubleshooting_dst-src-same"></a>

Aplikasi tidak dapat mengirim pesan ke partisi yang mereka miliki. Anda mendapatkan kesalahan berikut jika aplikasi mengirim pesan ke partisi yang dimilikinya.

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

Perilaku ini sama di dalam SimSpace Weaver Local dan AWS Cloud.

### Pesan upaya terbaik
<a name="working-with_messaging_troubleshooting_best-effort"></a>

SimSpace Weaver tidak menjamin pengiriman pesan. Layanan akan mencoba menyelesaikan pengiriman pesan pada centang simulasi berikutnya, tetapi pesan mungkin hilang atau tertunda.