{"_id":"@codexo/exojs-tilemap-physics","_rev":"4-df5344fc9226f6b23633ba10eff63d80","name":"@codexo/exojs-tilemap-physics","dist-tags":{"latest":"0.17.0"},"versions":{"0.16.0":{"name":"@codexo/exojs-tilemap-physics","version":"0.16.0","license":"MIT","_id":"@codexo/exojs-tilemap-physics@0.16.0","maintainers":[{"name":"exoridus","email":"dieter-giesler@gmx.de"}],"homepage":"https://github.com/Exoridus/ExoJS#readme","bugs":{"url":"https://github.com/Exoridus/ExoJS/issues"},"dist":{"shasum":"cc6bf78547a2a043e31004f9ec15310edfa149cb","tarball":"https://registry.npmjs.org/@codexo/exojs-tilemap-physics/-/exojs-tilemap-physics-0.16.0.tgz","fileCount":30,"integrity":"sha512-4l0Q1bi2mgguZPtTULd3E79UcmJMh6bTrM3e0G/Wnz6KyVRi1fZe8lv4JU+3P1WpjuQ6mLLT8ueOSQAO8BDG1A==","signatures":[{"sig":"MEQCIDDF0ug6nPhCoaKRlppHqVfvRkmt1t1RB/s+RAO0vKuBAiBYXKE7CVx44AbTK7UMmUZGW3aOSGrVpVlpO49Z8EC12w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":100465},"main":"./dist/esm/index.js","type":"module","_from":"file:codexo-exojs-tilemap-physics-0.16.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","default":"./dist/esm/index.js"},"./package.json":"./package.json"},"scripts":{"lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --root ../.. --project=exojs-tilemap-physics","build":"tsx ../../scripts/build-extension.ts","build:dev":"tsx ../../scripts/build-extension.ts --dev","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json"},"_npmUser":{"name":"exoridus","email":"dieter-giesler@gmx.de"},"_resolved":"C:\\Users\\User\\Development\\exojs\\packages\\exojs-tilemap-physics\\codexo-exojs-tilemap-physics-0.16.0.tgz","_integrity":"sha512-4l0Q1bi2mgguZPtTULd3E79UcmJMh6bTrM3e0G/Wnz6KyVRi1fZe8lv4JU+3P1WpjuQ6mLLT8ueOSQAO8BDG1A==","repository":{"url":"git+https://github.com/Exoridus/ExoJS.git","type":"git","directory":"packages/exojs-tilemap-physics"},"_npmVersion":"11.11.0","description":"Static physics colliders from ExoJS tilemap collision geometry.","directories":{},"sideEffects":false,"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@codexo/exojs":"workspace:*","@codexo/exojs-ldtk":"workspace:*","@codexo/exojs-tiled":"workspace:*","@codexo/exojs-config":"workspace:*","@codexo/exojs-physics":"workspace:*","@codexo/exojs-tilemap":"workspace:*"},"peerDependencies":{"@codexo/exojs":"0.16.x","@codexo/exojs-physics":"0.16.x","@codexo/exojs-tilemap":"0.16.x"},"_npmOperationalInternal":{"tmp":"tmp/exojs-tilemap-physics_0.16.0_1788308619170_0.8187797879813872","host":"s3://npm-registry-packages-npm-production"}},"0.16.1":{"name":"@codexo/exojs-tilemap-physics","version":"0.16.1","license":"MIT","_id":"@codexo/exojs-tilemap-physics@0.16.1","maintainers":[{"name":"exoridus","email":"dieter-giesler@gmx.de"}],"homepage":"https://github.com/Exoridus/ExoJS#readme","bugs":{"url":"https://github.com/Exoridus/ExoJS/issues"},"dist":{"shasum":"0cb87a445efa1dbb8eb1d21ac177bd6f4a0ba8b4","tarball":"https://registry.npmjs.org/@codexo/exojs-tilemap-physics/-/exojs-tilemap-physics-0.16.1.tgz","fileCount":30,"integrity":"sha512-VLnJNnAbbGrC0vQy6VOWxsOKIk4Ta6X4I8NfgK21jtiXifYBk/Rd4HiTSqXqiVQqRg1nc8y3JW7gXq9szZlWIg==","signatures":[{"sig":"MEQCIG3ZRpluJtW4cVFa7TMyVyhKqLeVJhvgzLpgw4ox04myAiBCR9xVohWqe4wRa7h6O/F8KEBtQRNkqWt24m7xN+HGcg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codexo%2fexojs-tilemap-physics@0.16.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":100433},"main":"./dist/esm/index.js","type":"module","_from":"file:/home/runner/work/ExoJS/ExoJS/.release/artifacts/codexo-exojs-tilemap-physics-0.16.1.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","default":"./dist/esm/index.js"},"./package.json":"./package.json"},"scripts":{"lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --root ../.. --project=exojs-tilemap-physics","build":"tsx ../../scripts/build-extension.ts","build:dev":"tsx ../../scripts/build-extension.ts --dev","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c75b14b6-5b62-4a80-baa9-82d20225cb40"}},"_resolved":"/home/runner/work/ExoJS/ExoJS/.release/artifacts/codexo-exojs-tilemap-physics-0.16.1.tgz","_integrity":"sha512-VLnJNnAbbGrC0vQy6VOWxsOKIk4Ta6X4I8NfgK21jtiXifYBk/Rd4HiTSqXqiVQqRg1nc8y3JW7gXq9szZlWIg==","repository":{"url":"git+https://github.com/Exoridus/ExoJS.git","type":"git","directory":"packages/exojs-tilemap-physics"},"_npmVersion":"11.19.0","description":"Static physics colliders from ExoJS tilemap collision geometry.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@codexo/exojs":"0.16.1","@codexo/exojs-ldtk":"0.16.1","@codexo/exojs-tiled":"0.16.1","@codexo/exojs-config":"0.0.0","@codexo/exojs-physics":"0.16.1","@codexo/exojs-tilemap":"0.16.1"},"peerDependencies":{"@codexo/exojs":"0.16.x","@codexo/exojs-physics":"0.16.x","@codexo/exojs-tilemap":"0.16.x"},"_npmOperationalInternal":{"tmp":"tmp/exojs-tilemap-physics_0.16.1_1788396128912_0.7298795922203676","host":"s3://npm-registry-packages-npm-production"}},"0.16.2":{"name":"@codexo/exojs-tilemap-physics","version":"0.16.2","license":"MIT","_id":"@codexo/exojs-tilemap-physics@0.16.2","maintainers":[{"name":"exoridus","email":"dieter-giesler@gmx.de"}],"homepage":"https://github.com/Exoridus/ExoJS#readme","bugs":{"url":"https://github.com/Exoridus/ExoJS/issues"},"dist":{"shasum":"be47670324395ec7b8611ae0ba2e0b9423160ffd","tarball":"https://registry.npmjs.org/@codexo/exojs-tilemap-physics/-/exojs-tilemap-physics-0.16.2.tgz","fileCount":30,"integrity":"sha512-1D+en0gYpDFPl2f+13/HUXRYSezhuu/MtEVmR+vnry6WEhGbozFTBvSr9UpUqh9nRHADsiETMdbEFaPZGJH0lA==","signatures":[{"sig":"MEYCIQC4h7ErmIbTq4Fupi1W7URerC/vo7MI34+xLT9QA+2+7AIhAPwkiUt8fUjS1Wmfuw740LGUtuPaOid0Ov2MEDTcKbJj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCBoQj4K/VPiXpCyL5EB1/M2UArweyayBMm5cNBSy6GQgIgScDIjTERPtfd+5/Di+hxppC3mX0FWe3ouPlHLLjXtHI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codexo%2fexojs-tilemap-physics@0.16.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":102439},"main":"./dist/esm/index.js","type":"module","_from":"file:/home/runner/work/ExoJS/ExoJS/.release/artifacts/codexo-exojs-tilemap-physics-0.16.2.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","default":"./dist/esm/index.js"},"./package.json":"./package.json"},"scripts":{"lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --root ../.. --project=exojs-tilemap-physics","build":"tsx ../../scripts/build-extension.ts","build:dev":"tsx ../../scripts/build-extension.ts --dev","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c75b14b6-5b62-4a80-baa9-82d20225cb40"}},"_resolved":"/home/runner/work/ExoJS/ExoJS/.release/artifacts/codexo-exojs-tilemap-physics-0.16.2.tgz","_integrity":"sha512-1D+en0gYpDFPl2f+13/HUXRYSezhuu/MtEVmR+vnry6WEhGbozFTBvSr9UpUqh9nRHADsiETMdbEFaPZGJH0lA==","repository":{"url":"git+https://github.com/Exoridus/ExoJS.git","type":"git","directory":"packages/exojs-tilemap-physics"},"_npmVersion":"11.19.0","description":"Static physics colliders from ExoJS tilemap collision geometry.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@codexo/exojs":"0.16.2","@codexo/exojs-ldtk":"0.16.2","@codexo/exojs-tiled":"0.16.2","@codexo/exojs-config":"0.0.0","@codexo/exojs-physics":"0.16.2","@codexo/exojs-tilemap":"0.16.2"},"peerDependencies":{"@codexo/exojs":"0.16.x","@codexo/exojs-physics":"0.16.x","@codexo/exojs-tilemap":"0.16.x"},"_npmOperationalInternal":{"tmp":"tmp/exojs-tilemap-physics_0.16.2_1788464015805_0.5761082822056485","host":"s3://npm-registry-packages-npm-production"}},"0.17.0":{"_id":"@codexo/exojs-tilemap-physics@0.17.0","bugs":{"url":"https://github.com/Exoridus/ExoJS/issues"},"dist":{"shasum":"de5edf94a712a548f17e7673f773dffab062713f","tarball":"https://registry.npmjs.org/@codexo/exojs-tilemap-physics/-/exojs-tilemap-physics-0.17.0.tgz","fileCount":30,"integrity":"sha512-ISlqOfhwLUNYdPL+4UgKK3Z5Ea6mmKJBidA5qCKEcpJs0/mExs0dXE68j8gu0uaBiWkU25on/5xXXKuroIBZYA==","signatures":[{"sig":"MEUCIQDvyS8bsV/8eG/BkpJ9rU9g4nOH7kVtnA6dFJCJpqcuMwIgB0IsqkdcOVEUtnNe7nL/4hXymn64H5+U7J8lISuDmVA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID46UGO7nhuNI3ovaNb+3RZteOHpoQOgcHQZesbdze9NAiEA/vLKfvBDRaGh+4LplWVZ/opkm4MXaseCuRdPAs7i/Qo="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codexo%2fexojs-tilemap-physics@0.17.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":102439},"main":"./dist/esm/index.js","name":"@codexo/exojs-tilemap-physics","type":"module","_from":"file:/home/runner/work/ExoJS/ExoJS/.release/artifacts/codexo-exojs-tilemap-physics-0.17.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","default":"./dist/esm/index.js"},"./package.json":"./package.json"},"license":"MIT","scripts":{"lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --root ../.. --project=exojs-tilemap-physics","build":"tsx ../../scripts/build-extension.ts","build:dev":"tsx ../../scripts/build-extension.ts --dev","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json"},"version":"0.17.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c75b14b6-5b62-4a80-baa9-82d20225cb40"}},"homepage":"https://github.com/Exoridus/ExoJS#readme","_resolved":"/home/runner/work/ExoJS/ExoJS/.release/artifacts/codexo-exojs-tilemap-physics-0.17.0.tgz","_integrity":"sha512-ISlqOfhwLUNYdPL+4UgKK3Z5Ea6mmKJBidA5qCKEcpJs0/mExs0dXE68j8gu0uaBiWkU25on/5xXXKuroIBZYA==","repository":{"url":"git+https://github.com/Exoridus/ExoJS.git","type":"git","directory":"packages/exojs-tilemap-physics"},"_npmVersion":"11.19.0","description":"Static physics colliders from ExoJS tilemap collision geometry.","directories":{},"maintainers":[{"name":"exoridus","email":"dieter-giesler@gmx.de"}],"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@codexo/exojs":"0.17.0","@codexo/exojs-ldtk":"0.17.0","@codexo/exojs-tiled":"0.17.0","@codexo/exojs-config":"0.0.0","@codexo/exojs-physics":"0.17.0","@codexo/exojs-tilemap":"0.17.0"},"peerDependencies":{"@codexo/exojs":"0.17.x","@codexo/exojs-physics":"0.17.x","@codexo/exojs-tilemap":"0.17.x"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/exojs-tilemap-physics_0.17.0_1788626246217_0.7680744402258013"}}},"time":{"created":"2026-09-02T00:23:38.879Z","modified":"2026-09-05T16:37:26.612Z","0.16.0":"2026-09-02T00:23:39.303Z","0.16.1":"2026-09-03T00:42:09.052Z","0.16.2":"2026-09-03T19:33:35.889Z","0.17.0":"2026-09-05T16:37:26.312Z"},"bugs":{"url":"https://github.com/Exoridus/ExoJS/issues"},"license":"MIT","homepage":"https://github.com/Exoridus/ExoJS#readme","repository":{"url":"git+https://github.com/Exoridus/ExoJS.git","type":"git","directory":"packages/exojs-tilemap-physics"},"description":"Static physics colliders from ExoJS tilemap collision geometry.","maintainers":[{"name":"exoridus","email":"dieter-giesler@gmx.de"}],"readme":"# @codexo/exojs-tilemap-physics\n\nStatic physics colliders from ExoJS tilemap collision geometry.\n\n> A peer-dependency library on top of `@codexo/exojs`, `@codexo/exojs-tilemap`\n> and `@codexo/exojs-physics` — construct its API directly. Importing it\n> registers nothing.\n\n`@codexo/exojs-tilemap` never imports physics and `@codexo/exojs-physics` never\nimports tilemap; this package is the seam between them, so both stay usable on\ntheir own.\n\n## Installation\n\n```sh\nnpm install @codexo/exojs @codexo/exojs-tilemap @codexo/exojs-physics @codexo/exojs-tilemap-physics\n```\n\n## Tile layers\n\n`TileColliderStreamer` keeps a physics world's static tile colliders in sync\nwith a `TileLayer`: one static body per chunk-sized partition of the layer,\nrebuilt when that partition is edited, destroyed when its chunk is evicted.\n\n```ts\nimport { PhysicsWorld } from '@codexo/exojs-physics';\nimport { TileColliderStreamer } from '@codexo/exojs-tilemap-physics';\n\nconst world = new PhysicsWorld({ gravity: { x: 0, y: 1600 } });\nconst colliders = new TileColliderStreamer(world, groundLayer);\n\nscene.systems.add({\n  update: delta => {\n    colliders.sync();\n    world.step(delta.seconds);\n  },\n});\n```\n\n`sync()` is cheap to call every frame: with no change since the last call it\nreturns immediately and does no work. It observes the layer through its public\nrevision counters, so it works with `ChunkStreamer`, a hand-rolled loader, or a\nbounded layer that is fully resident.\n\nCall `destroy()` to remove every body the bridge created. Bodies it did not\ncreate are untouched.\n\n## Collision authored per cell\n\nSome editors author collision per grid cell rather than per tile - LDtk's\n`IntGrid` is the common case. Pass a `cells` source and the bridge covers the\nwhole bounded layer, including partitions that hold no tiles at all:\n\n```ts\nimport { createLdtkIntGridCellSource } from '@codexo/exojs-ldtk';\n\nconst colliders = new TileColliderStreamer(world, collisionLayer, {\n  cells: createLdtkIntGridCellSource(collisionLayer),\n  material: ({ type }) => (type === 'Water' ? { isSensor: true } : null),\n});\n```\n\nA cell source is a plain `(tx, ty) => string | null`, so a procedural or\nhand-rolled grid works the same way. The returned string is a classification,\nnever a meaning: it is the merge key for adjacent cells and it is what the\n`material` resolver sees. Nothing in this package knows what `Solid` or `Water`\nare supposed to do.\n\nThe source is sampled while a partition is built and is expected to answer\nidentically for the lifetime of the bridge. Changing what it returns does not\ninvalidate colliders that already exist - rebuild by recreating the bridge.\n\n## Object layers\n\nAn object layer is static data with no residency, so it gets a one-shot build:\n\n```ts\nimport { buildObjectLayerColliders } from '@codexo/exojs-tilemap-physics';\n\nconst built = buildObjectLayerColliders(world, triggersLayer, {\n  isSensor: true,\n});\n\nfor (const { object, body } of built) {\n  // `object` is the source object: name, type, custom properties.\n}\n```\n\n## Geometry mapping\n\n| Source                                             | Collider                                             |\n| -------------------------------------------------- | ---------------------------------------------------- |\n| Merged whole-cell region (`regionMode: 'boxes'`)   | one box per merged rectangle                         |\n| Merged whole-cell region (`regionMode: 'outline'`) | one closed chain per boundary loop                   |\n| Rectangle                                          | box                                                  |\n| Ellipse                                            | capsule along the major axis, or a circle when round |\n| Convex polygon                                     | one polygon                                          |\n| Concave polygon                                    | several convex polygons on the same body             |\n| Polyline                                           | open chain; closed chain when its endpoints coincide |\n| Point                                              | nothing                                              |\n\nAn ellipse maps to the capsule with the minor semi-axis as its radius and the\ndifference of the semi-axes as its spine. That capsule contains the ellipse and\nis contained in the circumscribed circle, so it covers the source without a\ntuning constant, and degenerates to a circle when the ellipse is round.\n\n## Region modes\n\n`regionMode: 'boxes'` (the default) keeps merged rectangles as solid boxes. The\nregion has an interior, so point queries, overlaps and sensors behave, and a\nbody that starts inside solid tiles is pushed out. Where the merge cannot merge\n— neighbouring cells with different collision semantics, staircase profiles,\npartial cells — adjacent boxes share an internal edge that a body sliding across\ncan catch on.\n\n`regionMode: 'outline'` traces the boundary of each solid region into closed\none-sided chains, which have no internal edges at all. It removes intra-chunk\nseams between adjacent cells that resolve to the same collision semantics;\nboundaries between regions with different resolved semantics remain separate, as\ndo chunk boundaries. The trade-off is that a chain is a boundary, not an area:\nqueries inside the region find nothing, and a body spawned inside it falls\nthrough.\n\n## Materials\n\nFriction, restitution, density, the sensor flag and the collision filter are\ncall-level defaults, optionally overridden per object:\n\n```ts\nnew TileColliderStreamer(world, groundLayer, {\n  friction: 0.8,\n  material: ({ type }) => (type === 'ice' ? { friction: 0.02 } : null),\n});\n```\n\nThe resolver is a build-time mapping, not a live rule: it runs only while a\nchunk is being built or rebuilt. Changing what it would return has no effect\nuntil the layer itself changes. An unrecognised `type` is not an error — it\nreaches the resolver like any other and falls back to the defaults.\n\nIn `outline` mode the resolved material also decides what may share a boundary:\ncells whose colliders would be indistinguishable are traced into one chain, and\ncells that resolve differently keep their own.\n\n## Things to know before shipping a level\n\n- **Merging never crosses a chunk boundary.** A solid run spanning two chunks is\n  at least two rectangles. That is what makes the result independent of the\n  order chunks were loaded in.\n- **A dynamic body resting on an evicted chunk falls.** Eviction is the chunk\n  source's decision; widen its unload radius if that matters.\n- **Order is stable, part counts are not.** For a given layer and resident chunk\n  set the colliders are identical regardless of load order, and `bodies()`\n  iterates in `(cy, cx)` chunk order. The number of convex parts a concave\n  polygon decomposes into, and the exact rectangle decomposition of a merged\n  region, are not contractual.\n\n## Core compatibility\n\n| `@codexo/exojs-tilemap-physics` | `@codexo/exojs` |\n| ------------------------------- | --------------- |\n| 0.15.x                          | 0.15.x          |\n\n## License\n\nMIT © Codexo\n","readmeFilename":"README.md"}