{"id":48680724,"url":"https://github.com/arktwin/arktwin","last_synced_at":"2026-04-26T20:00:42.797Z","repository":{"id":245813904,"uuid":"817140139","full_name":"arktwin/arktwin","owner":"arktwin","description":"Distributed Multi-Agent Messaging Framework","archived":false,"fork":false,"pushed_at":"2026-04-20T01:45:07.000Z","size":7013,"stargazers_count":61,"open_issues_count":8,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-20T03:37:01.606Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arktwin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":"CLA.md"}},"created_at":"2024-06-19T05:33:15.000Z","updated_at":"2026-04-20T01:45:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"db3f9f3d-306d-4499-bd0e-6c337ed36656","html_url":"https://github.com/arktwin/arktwin","commit_stats":null,"previous_names":["arktwin/arktwin"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/arktwin/arktwin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arktwin%2Farktwin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arktwin%2Farktwin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arktwin%2Farktwin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arktwin%2Farktwin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arktwin","download_url":"https://codeload.github.com/arktwin/arktwin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arktwin%2Farktwin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32310804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T19:15:34.056Z","status":"ssl_error","status_checked_at":"2026-04-26T19:15:15.467Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-11T01:00:36.059Z","updated_at":"2026-04-26T20:00:42.790Z","avatar_url":"https://github.com/arktwin.png","language":"Scala","funding_links":[],"categories":["进程间通信"],"sub_categories":["Spring Cloud框架"],"readme":"# ArkTwin: Distributed Multi-Agent Messaging Framework\n\n[![Scala CI](https://github.com/arktwin/arktwin/actions/workflows/scala-ci.yaml/badge.svg?branch=main)](https://github.com/arktwin/arktwin/actions/workflows/scala-ci.yaml)\n[![Scala Steward badge](https://img.shields.io/badge/Scala_Steward-helping-blue.svg?style=flat\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAMAAAARSr4IAAAAVFBMVEUAAACHjojlOy5NWlrKzcYRKjGFjIbp293YycuLa3pYY2LSqql4f3pCUFTgSjNodYRmcXUsPD/NTTbjRS+2jomhgnzNc223cGvZS0HaSD0XLjbaSjElhIr+AAAAAXRSTlMAQObYZgAAAHlJREFUCNdNyosOwyAIhWHAQS1Vt7a77/3fcxxdmv0xwmckutAR1nkm4ggbyEcg/wWmlGLDAA3oL50xi6fk5ffZ3E2E3QfZDCcCN2YtbEWZt+Drc6u6rlqv7Uk0LdKqqr5rk2UCRXOk0vmQKGfc94nOJyQjouF9H/wCc9gECEYfONoAAAAASUVORK5CYII=)](https://scala-steward.org)\n\n![ArkTwin logo](logo/ArkTwin_logo_Rectangle_WH_M.png)\n\nArkTwin is a distributed messaging framework designed to connect various agent-based software, such as traffic simulators, pedestrian simulators, virtual camera video generators, virtual reality devices, etc.\nIts primary applications are city-scale co-simulations and digital twins.\n\nArkTwin consists of two modules: Center and Edge.\n\n- ArkTwin Center is a message broker equipped with network culling for handling a large number of agent transform messages.\n- ArkTwin Edge is deployed as a sidecar for each agent-based software. It handles coordinate transformation and time correction, normalizing the spatiotemporal definitions across each simulator.\n\nThe communication protocol between ArkTwin Center and Edge is gRPC.\nHowever, each agent-based software can connect to ArkTwin via local REST API provided by ArkTwin Edge, without managing stream control directly.\n\n## Demo\n\n![](docs/demo.png)\n\n## Building\n\n### Docker\n\n1. `git checkout \u003crelease tag\u003e`\n1. `docker build -t arktwin-center -f docker/center.dockerfile .`\n1. `docker build -t arktwin-edge -f docker/edge.dockerfile .`\n\n### JAR\n\n1. install Java Development Kit (recommended: [Eclipse Temurin 25 LTS](https://adoptium.net/temurin/releases/?variant=openjdk25\u0026jvmVariant=hotspot))\n1. install [sbt](https://www.scala-sbt.org/download)\n1. install [Node.js](https://nodejs.org/en/download/package-manager) (recommended: v24)\n1. `git checkout \u003crelease tag\u003e`\n1. `cd arktwin`\n1. `sbt center/assembly`\n1. pick up `arktwin-center.jar` from `center/target/scala-*.*.*/`\n1. `sbt viewer/package edge/assembly`\n1. pick up `arktwin-edge.jar` from `edge/target/scala-*.*.*/`\n\n## Running\n\n### Docker\n\n- `docker run [--network host | -p 2236:2236] [-v $(pwd)/center.conf:/etc/opt/arktwin/center.conf] arktwin-center  [arg]...`\n- `docker run [--network host | -p 2237:2237] [-v $(pwd)/edge.conf:/etc/opt/arktwin/edge.conf] -e ARKTWIN_CENTER_STATIC_HOST=\u003cCENTER_HOST\u003e arktwin-edge`\n\n### JAR\n\n- `java [-Dconfig.file=center.conf] -XX:+UseZGC -jar arktwin-center.jar`\n- `ARKTWIN_CENTER_STATIC_HOST=\u003cCENTER_HOST\u003e java [-Dconfig.file=edge.conf] -XX:+UseZGC -jar arktwin-edge.jar [arg]...`\n\n### Edge Optional Command Arguments\n\nArkTwin Edge runs with auxiliary functions when the following optional command arguments are specified.\n\n- `docs`: serve only `/docs/`\n- `generate-openapi-center`: generate the OpenAPI yaml for `/api/center/` to stdout\n- `generate-openapi-center \u003cfile\u003e`: generate the OpenAPI yaml file for `/api/center/`\n- `generate-openapi-edge`: generate the OpenAPI yaml for `/api/edge/` to stdout\n- `generate-openapi-edge \u003cfile\u003e`: generate the OpenAPI yaml file for `/api/edge/`\n\n### Endpoints\n\nThe default endpoints for ArkTwin is as follows:\n\n| Module | Role | Endpoint |\n| --- | --- | --- |\n| ArkTwin Center | gRPC Server | localhost:2236 |\n| ArkTwin Center | Health Check | [localhost:2236/health](http://localhost:2236/health) |\n| ArkTwin Center | Prometheus Exporter | [localhost:2236/metrics](http://localhost:2236/metrics) |\n| ArkTwin Edge | REST API Server | localhost:2237/api/ |\n| ArkTwin Edge | REST Docs | [localhost:2237/docs/](http://localhost:2237/docs/) |\n| ArkTwin Edge | Health Check | [localhost:2237/health](http://localhost:2237/health) |\n| ArkTwin Edge | Prometheus Exporter | [localhost:2237/metrics](http://localhost:2237/metrics) |\n| ArkTwin Edge | Neighbors Viewer | [localhost:2237/viewer/](http://localhost:2237/viewer/) |\n\nIf you want to change the host and port settings, see [# Environment Variables](#environment-variables).\n\n## Integrating\n\n- Synchronize the clocks of all machines via the same reliable NTP (Network Time Protocol) server\n    - time.windows.com may cause clock drift of several hundred milliseconds\n- Run an ArkTwin Center\n- Run your agent-based software\n- Run an ArkTwin Edge as a sidecar of your agent-based software\n- Configure your coordinate system and others in the ArkTwin Edge\n```python\nrequests.post(\"http://localhost:2237/api/edge/config/coordinate\", json=[\n    \"vector3\": {\"x\": \"East\", \"y\": \"North\", \"z\": \"Up\", …},\n    \"rotation\": {\"EulerAnglesConfig\": {\"order\": \"XYZ\", …}}\n])\n```\n- Spawn your agents\n- Register your agents in the ArkTwin Edge\n```python\nrequests.post(\"http://localhost:2237/api/edge/agents\", json=[\n    {\"agentIdPrefix\": \"alice\", \"kind\": \"human\", …},\n    {\"agentIdPrefix\": \"bob\",   \"kind\": \"human\", …}, \n…])\n```\n- Advance the clock of your agent-based software\n- Update environment informations\n- Simulate movement per agent\n  - Recognize neighbors\n  - Make decision\n  - Move the agent\n- Update transforms and statuses of your agents\n- Send transforms and statuses and others of your agents to the ArkTwin Edge\n```python\nrequests.put(\"http://localhost:2237/api/edge/agents\", json={\n  \"timestamp\": {\"seconds\": 1645536142, \"nanos\": 0},\n  \"transforms\": {\n    \"alice-1\": {\"transform\": {\"localTranslation\": {\"x\": 10, \"y\":20, \"z\":0.3}, …}, ...},\n    \"bob-a\":   {\"transform\": {\"localTranslation\": {\"x\": 40, \"y\":50, \"z\":0.6}, …}, ...},\n…}})\n```\n- Receive transforms and statuses of neighbors from the ArkTwin Edge \n```python\nrequests.post(\"http://localhost:2237/api/edge/nighbors/_query\", json={\n  \"timestamp\": {\"seconds\": 1645536142, \"nanos\": 0},\n  \"neighborsNumber\": 100,\n…})\n```\n- Update transforms and statuses of neighbors \n- Stop the ArkTwin Edge\n- Stop your agent-based software\n\n## Configuration\n\n### Configuration Files\n\nThe default configuration files of ArkTwin are as follows.\n\n- Center\n  - [arktwin/center/src/main/resources/reference.conf](arktwin/center/src/main/resources/reference.conf)\n  - [arktwin/center/src/main/resources/pekko.conf](arktwin/center/src/main/resources/pekko.conf)\n  - [arktwin/center/src/main/resources/kamon.conf](arktwin/center/src/main/resources/kamon.conf)\n- Edge\n  - [arktwin/edge/src/main/resources/reference.conf](arktwin/edge/src/main/resources/reference.conf)\n  - [arktwin/edge/src/main/resources/pekko.conf](arktwin/edge/src/main/resources/pekko.conf)\n  - [arktwin/edge/src/main/resources/kamon.conf](arktwin/edge/src/main/resources/kamon.conf)\n\nAny configuration can be overridden by specifying a file using the Java startup option `-Dconfig.file=path/to/config-file`.\nThe syntax of configuration files is [HOCON](https://github.com/lightbend/config/blob/main/HOCON.md) used in [Typesafe Config](https://github.com/lightbend/config).\n\n### Coordinate Properties\n\nThe coordinate system for ArkTwin Edge can be configured under the path `arktwin.edge.dynamic.coordinate`. According to this configuration, agent-based software can send and receive transform data to and from ArkTwin Edge.\n\n| Configuration Path | Type | Default | Description |\n| --- | --- | --- | --- |\n| arktwin.edge.dynamic.coordinate.axis.xDirection | East \\| West \\| North \\| South \\| Up \\| Down | East | X-axis direction |\n| arktwin.edge.dynamic.coordinate.axis.yDirection | East \\| West \\| North \\| South \\| Up \\| Down | North | Y-axis direction |\n| arktwin.edge.dynamic.coordinate.axis.zDirection | East \\| West \\| North \\| South \\| Up \\| Down | Up | Z-axis direction |\n| arktwin.edge.dynamic.coordinate.centerOrigin.x | floating-point number | 0.0 | X-coordinate value of center's origin in the edge's coordinate system |\n| arktwin.edge.dynamic.coordinate.centerOrigin.y | floating-point number | 0.0 | Y-coordinate value of center's origin in the edge's coordinate system |\n| arktwin.edge.dynamic.coordinate.centerOrigin.z | floating-point number | 0.0 | Z-coordinate value of center's origin in the edge's coordinate system |\n| arktwin.edge.dynamic.coordinate.rotation.type | EulerAnglesConfig \\| QuaternionConfig | EulerAnglesConfig | Rotation type: euler angles or quaternion |\n| arktwin.edge.dynamic.coordinate.rotation.angleUnit | Degree \\| Radian | Degree | Applicable only if type is EulerAnglesConfig\u003cbr\u003eangle unit |\n| arktwin.edge.dynamic.coordinate.rotation.rotationMode | Extrinsic \\| Intrinsic | Extrinsic | Applicable only if type is EulerAnglesConfig\u003cbr\u003erotation mode: extrinsic rotation (edge's world space rotation) or intrinsic rotation (agent's local space rotation) |\n| arktwin.edge.dynamic.coordinate.rotation.rotationOrder | XYZ \\| XZY \\| YXZ \\| YZX \\| ZXY \\| ZYX | XYZ | Applicable only if type is EulerAnglesConfig\u003cbr\u003eRotation order: For example, XYZ means rotate around X axis first, then Y axis, and finally Z axis |\n| arktwin.edge.dynamic.coordinate.lengthUnit | Millimeter \\| Centimeter \\| Meter \\| Kilometer | Meter | Length unit |\n| arktwin.edge.dynamic.coordinate.speedUnit | MillimeterPerSecond \\| CentimeterPerSecond \\| MeterPerSecond \\| KilometerPerSecond \\| MillimeterPerMinute \\| CentimeterPerMinute \\| MeterPerMinute \\| KilometerPerMinute \\| MillimeterPerHour \\| CentimeterPerHour \\| MeterPerHour \\| KilometerPerHour | MeterPerSecond | Speed unit |\n\nRefer to the following links for the coordinate systems of typical game engines.\n\n- [Rotation and orientation in Unity](https://docs.unity3d.com/Manual/QuaternionAndEulerRotationsInUnity.html)\n- [Units of Measurement in Unreal Engine](https://dev.epicgames.com/documentation/en-us/unreal-engine/units-of-measurement-in-unreal-engine)\n\n### Environment Variables\n\nSome configuration can be overridden using environment variables.\n\n#### Center\n\n| Environment Variable | Configuration Path | Type | Default |\n| --- | --- | --- | --- |\n| ARKTWIN_CENTER_PROMETHEUS_PUSHGATEWAY | kamon.modules.pushgateway-reporter.enabled | boolean | false |\n| ARKTWIN_CENTER_PROMETHEUS_PUSHGATEWAY_API_URL | kamon.prometheus.pushgateway.api-url | string | http://localhost:9091/metrics/job/arktwin-center |\n| ARKTWIN_CENTER_STATIC_HOST | arktwin.center.static.host | string | 0.0.0.0 |\n| ARKTWIN_CENTER_STATIC_LOG_LEVEL | arktwin.center.static.logLevel | Error \\| Warn \\| Info \\| Debug \\| Trace | Info |\n| ARKTWIN_CENTER_STATIC_LOG_LEVEL_COLOR | arktwin.center.static.logLevelColor | boolean | true |\n| ARKTWIN_CENTER_STATIC_PORT | arktwin.center.static.port | integer | 2236 |\n| ARKTWIN_CENTER_STATIC_PORT_AUTO_INCREMENT | arktwin.center.static.portAutoIncrement | boolean | false |\n| ARKTWIN_CENTER_STATIC_PORT_AUTO_INCREMENT_MAX | arktwin.center.static.portAutoIncrementMax | integer | 100 |\n| ARKTWIN_CENTER_STATIC_RUN_ID_PREFIX | arktwin.center.static.runIdPrefix | string | run |\n\n#### Edge\n\n| Environment Variable | Configuration Path | Type | Default Value |\n| --- | --- | --- | --- |\n| ARKTWIN_CENTER_STATIC_HOST | pekko.grpc.client.arktwin.host | string | 127.0.0.1 |\n| ARKTWIN_CENTER_STATIC_PORT | pekko.grpc.client.arktwin.port  | integer | 2236 |\n| ARKTWIN_EDGE_GRPC_CLIENT_TLS | pekko.grpc.client.arktwin.use-tls | boolean | false |\n| ARKTWIN_EDGE_PROMETHEUS_PUSHGATEWAY | kamon.modules.pushgateway-reporter.enabled | boolean | false |\n| ARKTWIN_EDGE_PROMETHEUS_PUSHGATEWAY_API_URL | kamon.prometheus.pushgateway.api-url | string | http://localhost:9091/metrics/job/arktwin-edge |\n| ARKTWIN_EDGE_STATIC_EDGE_ID_PREFIX | arktwin.edge.static.edgeIdPrefix | string | edge |\n| ARKTWIN_EDGE_STATIC_HOST | arktwin.edge.static.host | string | 0.0.0.0 |\n| ARKTWIN_EDGE_STATIC_LOG_LEVEL | arktwin.edge.static.logLevel | Error \\| Warn \\| Info \\| Debug \\| Trace | Info |\n| ARKTWIN_EDGE_STATIC_LOG_LEVEL_COLOR | arktwin.edge.static.logLevelColor | boolean | true |\n| ARKTWIN_EDGE_STATIC_PORT | arktwin.edge.static.port | integer | 2237 |\n| ARKTWIN_EDGE_STATIC_PORT_AUTO_INCREMENT | arktwin.edge.static.portAutoIncrement | boolean | true |\n| ARKTWIN_EDGE_STATIC_PORT_AUTO_INCREMENT_MAX | arktwin.edge.static.portAutoIncrementMax | integer | 100 |\n\n## REST API\n\n- https://arktwin.github.io/arktwin/swagger-ui/center/\n- https://arktwin.github.io/arktwin/swagger-ui/edge/\n\n## Metrics for Prometheus\n\n- Chart metrics\n  - arktwin_edge_chart_1_publish_agent_num {edge_id, run_id}\n  - arktwin_edge_chart_1_publish_batch_num {edge_id, run_id}\n  - arktwin_edge_chart_1_publish_from_put_machine_latency {edge_id, run_id}\n  - arktwin_center_chart_2_publish_agent_num {edge_id, run_id}\n  - arktwin_center_chart_2_publish_batch_num {edge_id, run_id}\n  - arktwin_center_chart_2_publish_from_edge_machine_latency {edge_id, run_id}\n  - arktwin_center_chart_3_route_agent_num {edge_id, run_id}\n  - arktwin_center_chart_3_route_batch_num {edge_id, run_id}\n  - arktwin_center_chart_3_route_from_publish_machine_latency {edge_id, run_id}\n  - arktwin_center_chart_4_subscribe_agent_num {edge_id, run_id}\n  - arktwin_center_chart_4_subscribe_batch_num {edge_id, run_id}\n  - arktwin_center_chart_4_subscribe_from_route_machine_latency {edge_id, run_id}\n  - arktwin_edge_chart_5_subscribe_agent_num {edge_id, run_id}\n  - arktwin_edge_chart_5_subscribe_from_center_machine_latency {edge_id, run_id}\n- REST API metrics\n  - arktwin_edge_rest_agent_num {endpoint, edge_id, run_id}\n  - arktwin_edge_rest_request_num {endpoint, edge_id, run_id}\n  - arktwin_edge_rest_process_machine_time {endpoint, edge_id, run_id}\n  - arktwin_edge_rest_latency {endpoint, edge_id, run_id}\n- Other metrics\n  - arktwin_center_dead_letter_num {recipient, edge_id, run_id}\n  - arktwin_edge_dead_letter_num {recipient, edge_id, run_id}\n\n## Messaging\n\n### Messaging Architecture\n\n![](docs/diagrams/messaging.png)\n\nGray elements are not implemented.\n\n### Messaging Control\n\nTo control messaging, there are following configurations:\n\n- Buffer size of Pekko Streams (e.g., `arktwin.center.static.subscribe-buffer-size`).\n- Mailbox of Pekko Typed Actors (e.g., `pekko.actor.typed.mailbox.arktwin.center.actors.Atlas`).\n\nThe default settings for mailboxes are defined by the following rules:\n\n- Actors exchanging transform data use bounded mailboxes. They have strong at-most-once delivery property because transform data is exchanged in large volumes at high frequency.\n- Actors in `arktwin.edge.actors.sinks` use control-aware mailboxes.\n- Others use `org.apache.pekko.dispatch.SingleConsumerOnlyUnboundedMailbox` as the default mailbox for Pekko Typed Actors.\n\nFor more details on mailboxes, see [Pekko Mailboxes documentation](https://pekko.apache.org/docs/pekko/current/typed/mailboxes.html).\n\n### Center Culling\n\n![](docs/center-culling.png)\n\nCenter provides two culling strategies to optimize message routing between edges:\n\n- **Broadcast**: Sends all agent transforms to all connected edges without filtering\n- **GridCulling**: Partitions the 3D space into grid cells and sends transforms only to edges with agents in neighboring cells\n\n#### GridCulling Dynamic Selection\n\nGridCulling features dynamic grid cell size selection based on agent density. You can specify multiple grid cell size candidates and an upper limit for the number of agents per cell. The system automatically selects the grid cell size, optimizing performance while maintaining appropriate message granularity.\n\n**Selection Algorithm**:\n\n1. Filter candidates where all grid cells have agent counts ≤ `cellAgentNumUpperLimit`\n2. Select the largest grid size (by volume, then x, y, z) from filtered candidates\n3. If no candidate satisfies the limit (high-density scenario), fall back to the smallest grid size to minimize messaging overhead\n\nConfiguration path: `arktwin.center.dynamic.atlas.culling`\n\n### Edge Culling\n\nThis Edge feature sorts neighbors by distance from first agents and enables prioritized neighbor selection.\nWhen enabled, the Chart actor maintains neighbors ordered by their nearest distance to any first agent, allowing efficient retrieval of the closest neighbors.\n\nConfiguration path: `arktwin.edge.dynamic.chart.culling`\n\n### Neighbor Expiration\n\nThis Edge feature automatically removes neighbors whose last transform data is older than the specified timeout.\nThis feature prevents deleted or culled neighbors from being endlessly extrapolated in position calculations.\n\nConfiguration path: `arktwin.edge.dynamic.chart.expiration`\n\n## Presentations\n\n- Takatomo Torigoe. [The Future of Distributed Simulation with the Typed Actor Model (Japanese)](https://speakerdeck.com/piyo7/the-future-of-distributed-simulation-with-the-typed-actor-model). FP Matsuri 2025.\n- Akira Yoshioka, Takatomo Torigoe, Naoki Akiyama, Hideki Fujii, Takashi Machida, Satoru Nakanishi, Takayoshi Yoshimura. [ArkTwin: Distributed Heterogeneous Multi-Agent Simulation Platform (Japanese)](https://tsys.jp/dicomo/2024/program/program_abst.html#DS-2). Multimedia, Distributed, Cooperative, and Mobile Symposium 2024. (awarded first prize at the Noguchi Awards)\n\n## Contributing\n\nPull requests for bug fixes and feature development are very welcome.\nYour contributions are more acceptable if you start a conversation in [Discussions](https://github.com/arktwin/arktwin/discussions) or [Issues](https://github.com/arktwin/arktwin/issues).\n\nWe are especially interested in your ideas and examples for using ArkTwin.\nPlease feel free to share them in [Show and tell](https://github.com/arktwin/arktwin/discussions/categories/show-and-tell).\n\n## License\n\nArkTwin source code is licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0), Copyright 2024-2026 TOYOTA MOTOR CORPORATION.\n\nIf you need license lists for libraries that ArkTwin Center or Edge depends on, follow these steps:\n\n- ArkTwin Center\n  1. `cd arktwin`\n  1. `sbt center/dumpLicenseReport`\n  1. Check generated files in `center/target/license-reports`\n- ArkTwin Edge\n  1. `cd arktwin`\n  1. `sbt edge/dumpLicenseReport`\n  1. Check generated files in `edge/target/license-reports`\n- ArkTwin Edge Neighbors viewer\n  1. `cd arktwin/viewer`\n  1. `npm run license-check`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farktwin%2Farktwin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farktwin%2Farktwin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farktwin%2Farktwin/lists"}