{"id":17100654,"url":"https://github.com/jakobhellermann/bevy_mod_js_scripting","last_synced_at":"2025-04-12T23:54:43.103Z","repository":{"id":50595270,"uuid":"496992077","full_name":"jakobhellermann/bevy_mod_js_scripting","owner":"jakobhellermann","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-01T10:04:54.000Z","size":497,"stargazers_count":86,"open_issues_count":7,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-12T23:54:25.303Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jakobhellermann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-27T12:41:42.000Z","updated_at":"2025-03-28T13:51:23.000Z","dependencies_parsed_at":"2023-01-31T21:45:23.693Z","dependency_job_id":null,"html_url":"https://github.com/jakobhellermann/bevy_mod_js_scripting","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhellermann%2Fbevy_mod_js_scripting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhellermann%2Fbevy_mod_js_scripting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhellermann%2Fbevy_mod_js_scripting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhellermann%2Fbevy_mod_js_scripting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jakobhellermann","download_url":"https://codeload.github.com/jakobhellermann/bevy_mod_js_scripting/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647232,"owners_count":21139083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2024-10-14T15:14:20.493Z","updated_at":"2025-04-12T23:54:43.065Z","avatar_url":"https://github.com/jakobhellermann.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bevy_mod_js_scripting\n\n`bevy_mod_js_scripting` is an experimental scripting integration crate for writing javascript/typescript scripts and running them\nin `bevy` with full access to the ECS values like components and resources.\n\n\n## Example\n\n```ts\n// type safe access to resources and values\ntype Scoreboard = { score: number };\nconst Scoreboard: BevyType\u003cScoreboard\u003e = { typeName: \"breakout::Scoreboard\" };\n\n// script-local variables can be used for easy cross-frame state\nlet i = 0;\n\nfunction run() {\n    // increment score every 60 frames\n    if(i % 60 == 0) {\n        let score = world.resource(Scoreboard)!;\n        score.score += 1;\n        // logging works via `trace`, `debug`, `info`, `warn`, `error`\n        info(score.score);\n    }\n\n    // query components\n    for (const item of world.query(Transform, Aabb)) {\n        let [transform, aabb] = item.components;\n        info(\"Translation:\", transform.translation.toString());\n        info(\"AABB Center:\", aabb.center.toString());\n\n        // call methods on value references (requires app code setup, see headless.rs)\n        let normalized = transform.scale.normalize();\n    }\n}\n\nexport default {\n    // execute the `run` function in the update stage\n    update: run,\n}\n```\n\nMore examples can be found in the [examples](./examples/) folder.\nAlso check out the [punchy wiki page](https://github.com/fishfolks/punchy/wiki/Scripting) on scripting, which uses `bevy_mod_js_scripting`.\n\n## Current Status\n\nCurrently supported operations are \n- resource access (`world.resource(Time)`)\n- world information (`world.components`, `world.resources`, `world.entities`)\n- queries (`world.query(Ball, Velocity).map(({ entity, components }) =\u003e components[1])`)\n- component insertion (`world.insert(value)`)\n- dealing with ecs value references (`Value.create`, `Value.patch`)\n\n## Design decisions\n\n\u003cdetails\u003e\n\u003csummary\u003eTypes\u003c/summary\u003e\n\nIn `bevy_ecs`, the common methods for dealing with ECS values all take a type parameter, like \n```rs\nworld.resource::\u003cT\u003e(); // or\nworld.query\u003c(Entity, \u0026Component)\u003e();\n```\nIdeally we would be able to write\n```ts\nlet time = world.resource\u003cTime\u003e();\n```\nas well in typescript, but since typescript just transpiles to javascript without adding any new runtime capabilities, we cannot associate any runtime values with the `Time` type.\n\n\nInstead, what we need to do is write `type` definition with an associated variable of type `BevyType\u003cT\u003e`, which contains the referenced type's type name.\n\n```ts\ntype Transform = {\n  translation: Vec3,\n  rotation: Quat,\n  scale: Vec3,\n};\nconst Transform: BevyType\u003cTransform\u003e = {\n    typeName: \"bevy_transform::components::global_transform::GlobalTransform\"\n};\n\n// `world.resource` is typed so that typescript can infer `transform` to be of type `Transform | undefined`\nlet transform = world.resource(Transform);\n```\n\nSimilarly, queries list their types like\n```ts\nfor (item of world.query(Ball, Velocity)) {\n    info(item.entity);\n    let [_ball, velocity] = item.components;\n    // velocity is properly typed\n}\n```\n\nCurrently, there is a pregenerated list of bevy types in [./types/bevy_types.ts](./types/bevy_types.ts), and you can also just define your own ones.\n    \nIn the future we may include a utility for automatically generating the typescript definitions for your game in a `build.rs` script, so that you don't need to manually write or re-generate them.\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eJavascript Values \u0026 ECS Value references\u003c/summary\u003e\n\nWhen you call `world.resource` (or any other method returning references to ECS values), what you get is not just a simple javascript object corresponding to the rust value, but instead a `Proxy` which defers all accesses/modifications to the actual value inside the bevy world.\n\nOnly leaf values, like `transform.translation.x`, which can be natively represented as a javascript primitive, are automatically converted to/from the rust representation on gets and sets.\n\nThis means that\n```ts\nlet transform = world.resource(Transform);\nlet translation = transform.translation;\n// typeof translation.x == \"number\"\ntranslation.x = 3.0;\n```\n\nIf you want to create a new value reference, for example for inserting a new resource, the current APIs to do that are `Value.create` and `Value.patch`.\n\n```ts\nlet transform = Value.create(Transform);\nlet vec3 = Value.create(Vec3, { x: 0.0, y: 1.0, z: 2.0 });\ntransform.translation = vec3;\nworld.insertResource(Transform, transform);\n```\n\nExpect to see changes in this area as we figure out the best way to deal with the interaction of javascript objects and value references.\n\u003c/details\u003e\n\n## Web support\n\n`bevy_mod_js_scripting` can run in the browser using its native javascript execution environment.\nTo try it out, download and configure [wasm-server-runner](https://github.com/jakobhellermann/wasm-server-runner) and run\n```sh\ncargo run --example breakout --target wasm32-unknown-unknown\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakobhellermann%2Fbevy_mod_js_scripting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjakobhellermann%2Fbevy_mod_js_scripting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakobhellermann%2Fbevy_mod_js_scripting/lists"}