@ignifx/physics-2d 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -82,20 +82,9 @@ export declare function defaultPhysics2DSettings(): Physics2DSettings;
82
82
  //#endregion
83
83
  //#region src/material.d.ts
84
84
  /**
85
- * The `ignifx.physicsmaterial` asset, read by the 2D extension.
86
- *
87
- * ## Why the format is the 3D one
88
- *
89
- * `11-2d-toolkit.md` §8 lists a `PhysicsMaterial2D`, and `09-physics.md` §2.4 already defines
90
- * `{ "format": "ignifx.physicsmaterial", "friction": …, "staticFriction": …, "restitution": … }`.
91
- * Inventing a second document for the same two numbers would give artists two files to keep in
92
- * step, so this package reads **the same format and the same `.physicsmaterial.json` extension**,
93
- * ignoring `staticFriction` (Rapier 2D has one friction coefficient, `geometry/collider.d.ts`).
94
- * `@ignifx/physics` and `@ignifx/physics-2d` never run in one world — `IGX-1101` — so the two
95
- * loaders never collide.
96
- *
97
- * The 2D-only knobs, how two surfaces' friction and restitution are **combined**, are fields on the
98
- * collider rather than on the asset, so the document stays byte-identical to the 3D one.
85
+ * Read the shared `.physicsmaterial.json` format, ignoring `staticFriction` because Rapier has one
86
+ * friction coefficient. Combine rules stay on colliders. Only one physics extension runs per world,
87
+ * so the 2D and 3D loaders do not compete.
99
88
  */
100
89
  /**
101
90
  * The asset type name `.physicsmaterial.json` addresses resolve to.
@@ -184,23 +173,10 @@ export declare function parsePhysicsMaterial2D(address: string, document: JsonVa
184
173
  //#endregion
185
174
  //#region src/lite/rapier/world.d.ts
186
175
  /**
187
- * The Rapier 2D adapter (`docs/architecture/11-2d-toolkit.md` §8, ADR-0006). Everything the runtime
188
- * needs from `@dimforge/rapier2d-compat` is a function here, so the rest of `src/` never imports the
189
- * backend (`ignifx/no-lite-outside-adapter`, coding standards §4).
190
- *
191
- * ## Facts measured against `@dimforge/rapier2d-compat@0.20.0` (spike S6.2)
192
- *
193
- * - **The broadphase is only built by `World.step`.** Before the first step, `castRay` returns
194
- * `null` and `KinematicCharacterController.computeColliderMovement` reports the full requested
195
- * motion with no obstacles; a collider created after the last step is invisible until the next
196
- * one. {@link primeWorld} runs a zero-length step, which builds the broadphase without
197
- * integrating — but it is *not* free of side effects on a running simulation (a settled pile
198
- * hashes differently), so the runtime primes only when the collider set changed.
199
- * - **`InteractionGroups` is one 32-bit number**: membership in the high 16 bits, filter in the low
200
- * 16 (`geometry/interaction_groups.d.ts`). Sixteen layers, not thirty-two.
201
- * - **`ActiveCollisionTypes.DEFAULT` excludes non-dynamic pairs**, so a kinematic character never
202
- * reports entering a static sensor. Colliders that want events are given
203
- * `ActiveCollisionTypes.ALL`.
176
+ * Keep Rapier calls inside the adapter (ADR-0006).
177
+ * Queries need a built broadphase. Prime after collider-set changes only: a zero-length step can
178
+ * still affect a running simulation. Interaction groups support sixteen layers; event-enabled
179
+ * colliders include non-dynamic pairs so characters can enter static sensors.
204
180
  */
205
181
  /**
206
182
  * Rapier's physics world.
@@ -265,29 +241,9 @@ type RapierShape2D = {
265
241
  //#endregion
266
242
  //#region src/components/collider.d.ts
267
243
  /**
268
- * The 2D collider contract (`docs/architecture/11-2d-toolkit.md` §8). Every collider shares an
269
- * offset, the trigger flag, a surface, a layer override, and the one-way platform flag, and answers
270
- * one question the body builder asks: which Rapier shapes it stands for.
271
- *
272
- * ## Corrections to §8
273
- *
274
- * - **The material is two fields, not a union.** A schema field has exactly one kind (ADR-0004), so
275
- * {@link Collider2D.material} (an asset reference) and {@link Collider2D.inlineMaterial} (a
276
- * record) are separate; the asset wins, the inline record is the fallback, and
277
- * `physics2d.defaultMaterial` is the last resort. This is the same split `@ignifx/physics` makes.
278
- * - **Combine rules are collider fields.** Rapier combines two surfaces' friction and restitution
279
- * with a per-collider rule (`dynamics/coefficient_combine_rule.d.ts`); the 3D
280
- * `ignifx.physicsmaterial` document has no such field, so the knob lives here rather than
281
- * forking the asset format.
282
- * - **A collider may stand for several Rapier colliders.** `TilemapCollider2D` produces one polygon
283
- * per merged tile run, so {@link Collider2D.collectShapes} fills a list rather than returning one
284
- * shape.
285
- *
286
- * ## Sizes and scale
287
- *
288
- * Sizes are authored in local metres and multiplied by the entity's lossy scale when the shapes are
289
- * built. Rapier cannot rescale a built shape, so a later scale change needs
290
- * {@link Collider2D.rebuild}.
244
+ * Build shapes from local metres multiplied by entity scale; call `rebuild` after changing scale.
245
+ * Material assets take precedence over inline values, then project defaults. Friction and restitution
246
+ * combine rules belong to each collider. A tilemap collider can produce several backend shapes.
291
247
  */
292
248
  /**
293
249
  * How two surfaces' coefficients are combined when they touch, mirroring Rapier's
@@ -390,26 +346,8 @@ export declare abstract class Collider2D extends Component implements ComponentH
390
346
  //#endregion
391
347
  //#region src/events.d.ts
392
348
  /**
393
- * The payloads the five physics callbacks receive in 2D (`docs/architecture/11-2d-toolkit.md` §8,
394
- * `09-physics.md` §4).
395
- *
396
- * ## The callbacks are the 3D names
397
- *
398
- * `11-2d-toolkit.md` §8 writes them as `onCollisionEnter2D`/`onTriggerEnter2D`. The kernel's
399
- * `PhysicsCallbackName` union has five members and no `2D` variants
400
- * (`packages/core/src/lifecycle/callbacks.ts`), and a world uses either `physics()` or
401
- * `physics2d()` — never both, which is what `IGX-1101` enforces. So a 2D game implements
402
- * `onCollisionEnter`, `onCollisionStay`, `onCollisionExit`, `onTriggerEnter`, and `onTriggerExit`,
403
- * and receives the 2D payloads below. §8 is corrected accordingly.
404
- *
405
- * ## Identities are native
406
- *
407
- * Rapier reports **both** colliders of every event (`pipeline/event_queue.d.ts`,
408
- * `drainCollisionEvents`), so `other` is never `null` for a live body and the ADR-0013 waiver that
409
- * 3D physics needs has no counterpart here.
410
- *
411
- * Every payload is **pooled**: the same instances are reused for every event of a step, so a script
412
- * that needs a value after its callback returns must copy it out (coding standards §7).
349
+ * 2D physics uses the same five collision and trigger callback names as 3D, without a `2D` suffix.
350
+ * Rapier supplies both collider identities. Payloads are pooled; copy values needed after a callback.
413
351
  */
414
352
  /**
415
353
  * One contact point of a 2D collision. Pooled with its owning {@link Collision2D}.
@@ -488,24 +426,9 @@ interface CharacterCollision2D {
488
426
  //#endregion
489
427
  //#region src/components/rigidbody.d.ts
490
428
  /**
491
- * The `Rigidbody2D` component (`docs/architecture/11-2d-toolkit.md` §8): what makes an entity's 2D
492
- * colliders a simulated, kinematic, or explicitly static Rapier body.
493
- *
494
- * ## Decisions §8 leaves open
495
- *
496
- * - **`mass` is exact, and `0` means "weigh the colliders".** Rapier derives a body's mass and
497
- * angular inertia from each collider's *density* and area (`geometry/collider.d.ts`,
498
- * `setDensity`), and `setAdditionalMass` adds mass without inertia. So a non-zero `mass` is
499
- * applied by scaling every collider's density until the body weighs exactly that, which keeps the
500
- * inertia distribution the shapes imply; `mass: 0` leaves Rapier's own density of 1 kg/m² alone.
501
- * - **`freezeRotation` is one boolean, not three.** A 2D body has one rotational degree of freedom
502
- * (`dynamics/rigid_body.d.ts`, `lockRotations`).
503
- * - **Damping is per body here, unlike 3D.** Havok has no per-body damping; Rapier does
504
- * (`setLinearDamping`, `setAngularDamping`), so `linearDamping` and `angularDamping` are real
505
- * fields rather than upstream requests.
506
- * - **`collisionEvents` is a three-valued enum**, exactly as in `@ignifx/physics`: a schema field
507
- * has one kind (ADR-0004), and `"auto"` recomputes from `ctx.entityImplements` whenever a
508
- * component joins or leaves the entity.
429
+ * A nonzero mass rescales collider densities while preserving their inertia distribution.
430
+ * Zero keeps the default density of 1 kg/m². Rotation has one freeze flag; damping is per body.
431
+ * Automatic collision events follow callbacks as components join or leave the entity.
509
432
  */
510
433
  /**
511
434
  * How a 2D body moves.
@@ -675,27 +598,9 @@ export declare class Rigidbody2D extends Component implements ComponentHooks {
675
598
  //#endregion
676
599
  //#region src/components/character-controller.d.ts
677
600
  /**
678
- * The `CharacterController2D` component (`docs/architecture/11-2d-toolkit.md` §8): Rapier's
679
- * `KinematicCharacterController` (`control/character_controller.d.ts`) driven from `fixedUpdate`.
680
- *
681
- * ## How it is driven
682
- *
683
- * Call {@link CharacterController2D.move} from `fixedUpdate`. The requested displacements of one
684
- * step are summed and handed to Rapier's `computeColliderMovement` by the step system, so two
685
- * scripts moving the same character compose instead of fighting. Gravity is **not** applied by this
686
- * component: a bare controller is purely kinematic, exactly as the 3D one is, and the toolkit
687
- * controller scripts integrate gravity themselves.
688
- *
689
- * After the step the controller owns the entity's world X and Y. Z and `rotation2D` stay
690
- * user-controlled.
691
- *
692
- * ## The one addition to §8: `shape`
693
- *
694
- * §8 describes the controller as a capsule. Measured against `@dimforge/rapier2d-compat@0.20.0`
695
- * (spike S6.2), Rapier's autostep clears a 0.3 m step with a **box** character and refuses anything
696
- * above about 0.15 m with a capsule of radius 0.2 — so `stepOffset` is only usable with a box.
697
- * {@link CharacterController2D.shape} therefore chooses between the two, defaulting to `"capsule"`
698
- * as §8 says, and the limitation is documented in the skill and in ADR-0006's validation section.
601
+ * Sum `move` displacements during `fixedUpdate`; game scripts supply gravity.
602
+ * After the step the controller owns world X/Y, while Z and rotation remain user-controlled.
603
+ * Box shapes support taller autosteps than capsules; see ADR-0006's validation results.
699
604
  */
700
605
  /**
701
606
  * The collision shape a 2D character controller uses.
@@ -974,25 +879,9 @@ export declare class EdgeCollider2D extends Collider2D {
974
879
  //#endregion
975
880
  //#region src/components/tilemap-collider.d.ts
976
881
  /**
977
- * `TilemapCollider2D` (`docs/architecture/11-2d-toolkit.md` §2.5, §8): the merged collision surface
978
- * of a `Tilemap`, turned into Rapier geometry.
979
- *
980
- * ## How it reaches the data
981
- *
982
- * `@ignifx/2d` is an **optional** peer of `@ignifx/physics-2d` (a physics-only 2D game needs no
983
- * sprite toolkit), so this component never imports the toolkit as a value — only the
984
- * `TilemapCollisionData` type. A game, or `@ignifx/2d`'s own tilemap loader, assigns
985
- * {@link TilemapCollider2D.collisionData}; the runtime compares the data's `version` at the start of
986
- * every fixed step and rebuilds the shapes when it changes, which is the same moment
987
- * `Tilemap.onCollisionChanged` fires and needs no signal subscription across the package boundary.
988
- *
989
- * ## Why closed polylines rather than polygons
990
- *
991
- * A merged run of solid tiles is not convex in general — an L of tiles merges into an L — and
992
- * Rapier's polygon shape is a **convex hull** (`geometry/shape.d.ts`, `ConvexPolygon`), which would
993
- * silently fill the notch. A closed `polyline` reproduces the outline exactly and is the shape
994
- * static level geometry wants; the trade-off is that a polyline is infinitely thin, so a body that
995
- * starts inside the tilemap is not pushed out.
882
+ * Read tile collision data through the optional 2D toolkit's type and rebuild when its version changes.
883
+ * Closed polylines preserve concave tile outlines that convex hulls would fill in. They are thin
884
+ * surfaces, so a body starting inside the map is not pushed out.
996
885
  */
997
886
  /**
998
887
  * The collision surface of a tilemap, as one static body's worth of Rapier shapes.
@@ -1600,31 +1489,9 @@ export declare class Physics2DService {
1600
1489
  //#endregion
1601
1490
  //#region src/extension.d.ts
1602
1491
  /**
1603
- * The `@ignifx/physics-2d` extension (`docs/architecture/11-2d-toolkit.md` §8,
1604
- * `04-extensions.md` §1).
1605
- *
1606
- * ## Why `@ignifx/2d` is optional rather than required
1607
- *
1608
- * `00-overview.md` §2 draws `@ignifx/physics-2d` above `@ignifx/2d`, and the layering rule allows
1609
- * the dependency. At runtime the only thing this package needs from the toolkit is the
1610
- * `TilemapCollisionData` **type**, which is erased at build time, so a platformer that draws its own
1611
- * graphics can register `physics2d()` on its own. The manifest therefore declares
1612
- * `requires: []` and `optional: ["@ignifx/2d"]`, and `package.json` makes `@ignifx/2d` an optional
1613
- * peer dependency.
1614
- *
1615
- * ## Why the world is built in `onStart`
1616
- *
1617
- * `register` runs before `createApp` builds the `World` (`packages/core/src/app/app.ts`,
1618
- * `initialize`), and the Rapier world needs the world's layer table; Rapier's WebAssembly module
1619
- * also has to be instantiated, which is asynchronous. So `register` declares everything against a
1620
- * {@link Physics2DHost} holder and `onStart` fills the holder in.
1621
- *
1622
- * ## One physics extension per world
1623
- *
1624
- * `11-2d-toolkit.md` §8: "A world uses either `physics()` or `physics2d()`; registering both throws
1625
- * `IGX-1101`". `@ignifx/physics` publishes its Havok simulation scene through
1626
- * `ExtensionContext.setSimulationScene`, so `app.world.lite.simulationScene !== null` at `onStart`
1627
- * is the test — and it needs no dependency on `@ignifx/physics`, which this package must not have.
1492
+ * The 2D toolkit is optional; physics only needs its tile-collision data type.
1493
+ * Create the Rapier world in `onStart`, once the world's layer table exists and WASM is ready.
1494
+ * Reject a world already using 3D physics with `IGX-1101`.
1628
1495
  */
1629
1496
  /**
1630
1497
  * What `physics2d()` accepts.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/settings.ts","../src/material.ts","../src/lite/rapier/world.ts","../src/components/collider.ts","../src/events.ts","../src/components/rigidbody.ts","../src/components/character-controller.ts","../src/components/colliders.ts","../src/components/tilemap-collider.ts","../src/errors.ts","../src/queries.ts","../src/runtime/body-record.ts","../src/runtime/runtime.ts","../src/runtime/host.ts","../src/service.ts","../src/extension.ts","../src/schemas.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/settings.ts","../src/material.ts","../src/lite/rapier/world.ts","../src/components/collider.ts","../src/events.ts","../src/components/rigidbody.ts","../src/components/character-controller.ts","../src/components/colliders.ts","../src/components/tilemap-collider.ts","../src/errors.ts","../src/queries.ts","../src/runtime/body-record.ts","../src/runtime/runtime.ts","../src/runtime/host.ts","../src/service.ts","../src/extension.ts","../src/schemas.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -16,24 +16,9 @@ const Physics2DHostKey = createServiceKey("@ignifx/physics-2d:host");
16
16
  //#endregion
17
17
  //#region src/components/rigidbody.ts
18
18
  /**
19
- * The `Rigidbody2D` component (`docs/architecture/11-2d-toolkit.md` §8): what makes an entity's 2D
20
- * colliders a simulated, kinematic, or explicitly static Rapier body.
21
- *
22
- * ## Decisions §8 leaves open
23
- *
24
- * - **`mass` is exact, and `0` means "weigh the colliders".** Rapier derives a body's mass and
25
- * angular inertia from each collider's *density* and area (`geometry/collider.d.ts`,
26
- * `setDensity`), and `setAdditionalMass` adds mass without inertia. So a non-zero `mass` is
27
- * applied by scaling every collider's density until the body weighs exactly that, which keeps the
28
- * inertia distribution the shapes imply; `mass: 0` leaves Rapier's own density of 1 kg/m² alone.
29
- * - **`freezeRotation` is one boolean, not three.** A 2D body has one rotational degree of freedom
30
- * (`dynamics/rigid_body.d.ts`, `lockRotations`).
31
- * - **Damping is per body here, unlike 3D.** Havok has no per-body damping; Rapier does
32
- * (`setLinearDamping`, `setAngularDamping`), so `linearDamping` and `angularDamping` are real
33
- * fields rather than upstream requests.
34
- * - **`collisionEvents` is a three-valued enum**, exactly as in `@ignifx/physics`: a schema field
35
- * has one kind (ADR-0004), and `"auto"` recomputes from `ctx.entityImplements` whenever a
36
- * component joins or leaves the entity.
19
+ * A nonzero mass rescales collider densities while preserving their inertia distribution.
20
+ * Zero keeps the default density of 1 kg/m². Rotation has one freeze flag; damping is per body.
21
+ * Automatic collision events follow callbacks as components join or leave the entity.
37
22
  */
38
23
  /**
39
24
  * How a 2D body moves.
@@ -233,27 +218,9 @@ function rigidbody2DSchema() {
233
218
  //#endregion
234
219
  //#region src/components/character-controller.ts
235
220
  /**
236
- * The `CharacterController2D` component (`docs/architecture/11-2d-toolkit.md` §8): Rapier's
237
- * `KinematicCharacterController` (`control/character_controller.d.ts`) driven from `fixedUpdate`.
238
- *
239
- * ## How it is driven
240
- *
241
- * Call {@link CharacterController2D.move} from `fixedUpdate`. The requested displacements of one
242
- * step are summed and handed to Rapier's `computeColliderMovement` by the step system, so two
243
- * scripts moving the same character compose instead of fighting. Gravity is **not** applied by this
244
- * component: a bare controller is purely kinematic, exactly as the 3D one is, and the toolkit
245
- * controller scripts integrate gravity themselves.
246
- *
247
- * After the step the controller owns the entity's world X and Y. Z and `rotation2D` stay
248
- * user-controlled.
249
- *
250
- * ## The one addition to §8: `shape`
251
- *
252
- * §8 describes the controller as a capsule. Measured against `@dimforge/rapier2d-compat@0.20.0`
253
- * (spike S6.2), Rapier's autostep clears a 0.3 m step with a **box** character and refuses anything
254
- * above about 0.15 m with a capsule of radius 0.2 — so `stepOffset` is only usable with a box.
255
- * {@link CharacterController2D.shape} therefore chooses between the two, defaulting to `"capsule"`
256
- * as §8 says, and the limitation is documented in the skill and in ADR-0006's validation section.
221
+ * Sum `move` displacements during `fixedUpdate`; game scripts supply gravity.
222
+ * After the step the controller owns world X/Y, while Z and rotation remain user-controlled.
223
+ * Box shapes support taller autosteps than capsules; see ADR-0006's validation results.
257
224
  */
258
225
  /**
259
226
  * The collision shape a 2D character controller uses.
@@ -525,20 +492,9 @@ function physics2DError(code, message, options) {
525
492
  //#endregion
526
493
  //#region src/material.ts
527
494
  /**
528
- * The `ignifx.physicsmaterial` asset, read by the 2D extension.
529
- *
530
- * ## Why the format is the 3D one
531
- *
532
- * `11-2d-toolkit.md` §8 lists a `PhysicsMaterial2D`, and `09-physics.md` §2.4 already defines
533
- * `{ "format": "ignifx.physicsmaterial", "friction": …, "staticFriction": …, "restitution": … }`.
534
- * Inventing a second document for the same two numbers would give artists two files to keep in
535
- * step, so this package reads **the same format and the same `.physicsmaterial.json` extension**,
536
- * ignoring `staticFriction` (Rapier 2D has one friction coefficient, `geometry/collider.d.ts`).
537
- * `@ignifx/physics` and `@ignifx/physics-2d` never run in one world — `IGX-1101` — so the two
538
- * loaders never collide.
539
- *
540
- * The 2D-only knobs, how two surfaces' friction and restitution are **combined**, are fields on the
541
- * collider rather than on the asset, so the document stays byte-identical to the 3D one.
495
+ * Read the shared `.physicsmaterial.json` format, ignoring `staticFriction` because Rapier has one
496
+ * friction coefficient. Combine rules stay on colliders. Only one physics extension runs per world,
497
+ * so the 2D and 3D loaders do not compete.
542
498
  */
543
499
  /**
544
500
  * The asset type name `.physicsmaterial.json` addresses resolve to.
@@ -685,29 +641,9 @@ function numberAt(object, key, fallback) {
685
641
  //#endregion
686
642
  //#region src/components/collider.ts
687
643
  /**
688
- * The 2D collider contract (`docs/architecture/11-2d-toolkit.md` §8). Every collider shares an
689
- * offset, the trigger flag, a surface, a layer override, and the one-way platform flag, and answers
690
- * one question the body builder asks: which Rapier shapes it stands for.
691
- *
692
- * ## Corrections to §8
693
- *
694
- * - **The material is two fields, not a union.** A schema field has exactly one kind (ADR-0004), so
695
- * {@link Collider2D.material} (an asset reference) and {@link Collider2D.inlineMaterial} (a
696
- * record) are separate; the asset wins, the inline record is the fallback, and
697
- * `physics2d.defaultMaterial` is the last resort. This is the same split `@ignifx/physics` makes.
698
- * - **Combine rules are collider fields.** Rapier combines two surfaces' friction and restitution
699
- * with a per-collider rule (`dynamics/coefficient_combine_rule.d.ts`); the 3D
700
- * `ignifx.physicsmaterial` document has no such field, so the knob lives here rather than
701
- * forking the asset format.
702
- * - **A collider may stand for several Rapier colliders.** `TilemapCollider2D` produces one polygon
703
- * per merged tile run, so {@link Collider2D.collectShapes} fills a list rather than returning one
704
- * shape.
705
- *
706
- * ## Sizes and scale
707
- *
708
- * Sizes are authored in local metres and multiplied by the entity's lossy scale when the shapes are
709
- * built. Rapier cannot rescale a built shape, so a later scale change needs
710
- * {@link Collider2D.rebuild}.
644
+ * Build shapes from local metres multiplied by entity scale; call `rebuild` after changing scale.
645
+ * Material assets take precedence over inline values, then project defaults. Friction and restitution
646
+ * combine rules belong to each collider. A tilemap collider can produce several backend shapes.
711
647
  */
712
648
  /**
713
649
  * How two surfaces' coefficients are combined when they touch, mirroring Rapier's
@@ -793,19 +729,9 @@ var Collider2D = class extends Component {
793
729
  //#endregion
794
730
  //#region src/components/colliders.ts
795
731
  /**
796
- * The concrete 2D colliders (`docs/architecture/11-2d-toolkit.md` §8). Each maps to one Rapier
797
- * shape (`geometry/shape.d.ts`), sized in local metres and multiplied by the entity's lossy scale.
798
- *
799
- * ## The two point-list colliders
800
- *
801
- * - `PolygonCollider2D` builds a **convex** shape (`ColliderDesc.convexHull`). Rapier 2D also ships
802
- * `convexDecomposition`, which needs a triangle mesh with an index buffer and runs V-HACD — far
803
- * too heavy for a component field. Concave outlines are expressed as several
804
- * `PolygonCollider2D`s on one entity, which is what a compound body is for, or as an
805
- * `EdgeCollider2D` when the outline is open.
806
- * - `EdgeCollider2D` builds a `polyline`, the open chain a platformer's ground contour wants. A
807
- * polyline is infinitely thin: a fast body can tunnel through it, and a character controller that
808
- * starts *inside* one is not pushed out. Static level geometry is what it is for.
732
+ * Polygon colliders use convex hulls; represent concave geometry with multiple colliders.
733
+ * Edge colliders are thin, open polylines for static contours: fast bodies can tunnel through them,
734
+ * and bodies starting inside are not pushed out.
809
735
  */
810
736
  /** A quarter turn in radians, which is how a horizontal capsule is expressed. */
811
737
  const QUARTER_TURN = Math.PI / 2;
@@ -1128,25 +1054,9 @@ function degenerate(entity, component, requirement) {
1128
1054
  //#endregion
1129
1055
  //#region src/components/tilemap-collider.ts
1130
1056
  /**
1131
- * `TilemapCollider2D` (`docs/architecture/11-2d-toolkit.md` §2.5, §8): the merged collision surface
1132
- * of a `Tilemap`, turned into Rapier geometry.
1133
- *
1134
- * ## How it reaches the data
1135
- *
1136
- * `@ignifx/2d` is an **optional** peer of `@ignifx/physics-2d` (a physics-only 2D game needs no
1137
- * sprite toolkit), so this component never imports the toolkit as a value — only the
1138
- * `TilemapCollisionData` type. A game, or `@ignifx/2d`'s own tilemap loader, assigns
1139
- * {@link TilemapCollider2D.collisionData}; the runtime compares the data's `version` at the start of
1140
- * every fixed step and rebuilds the shapes when it changes, which is the same moment
1141
- * `Tilemap.onCollisionChanged` fires and needs no signal subscription across the package boundary.
1142
- *
1143
- * ## Why closed polylines rather than polygons
1144
- *
1145
- * A merged run of solid tiles is not convex in general — an L of tiles merges into an L — and
1146
- * Rapier's polygon shape is a **convex hull** (`geometry/shape.d.ts`, `ConvexPolygon`), which would
1147
- * silently fill the notch. A closed `polyline` reproduces the outline exactly and is the shape
1148
- * static level geometry wants; the trade-off is that a polyline is infinitely thin, so a body that
1149
- * starts inside the tilemap is not pushed out.
1057
+ * Read tile collision data through the optional 2D toolkit's type and rebuild when its version changes.
1058
+ * Closed polylines preserve concave tile outlines that convex hulls would fill in. They are thin
1059
+ * surfaces, so a body starting inside the map is not pushed out.
1150
1060
  */
1151
1061
  /**
1152
1062
  * The collision surface of a tilemap, as one static body's worth of Rapier shapes.
@@ -1290,21 +1200,9 @@ function segment(from, to, scale) {
1290
1200
  //#endregion
1291
1201
  //#region src/lite/rapier/module.ts
1292
1202
  /**
1293
- * The one place `@dimforge/rapier2d-compat`'s WebAssembly is instantiated
1294
- * (`docs/standards/coding-standards.md` §4, `CONSTITUTION.md` §3.4). Rapier is not Babylon Lite,
1295
- * but it is a native/WASM backend under the same adapter rule, and the rule's allowed directory is
1296
- * `src/lite/**` — hence `src/lite/rapier/`.
1297
- *
1298
- * ## Why `-compat`
1299
- *
1300
- * The `-compat` build inlines the WebAssembly module as base64 inside `rapier.mjs`, so it needs no
1301
- * asset serving and works unchanged in Node and in the browser (spike S6.2, ADR-0006 Validation).
1302
- * `init()` is what decodes and instantiates it; every other Rapier call before that throws.
1303
- *
1304
- * The import is static: `world.ts` and `service.ts` also import Rapier's classes statically, so a
1305
- * dynamic import here alone would not move the 2 MB module out of an app's entry chunk (measured in
1306
- * Phase 6). Splitting it needs the adapter to read every class off the loaded module instead, which
1307
- * is the Phase 12 bundle work.
1203
+ * Initialise Rapier's embedded WebAssembly before making backend calls.
1204
+ * The compat build includes the binary, so both Node and browser apps need no separate asset.
1205
+ * Rapier classes are imported statically by the adapters; delaying `init` does not split that bundle.
1308
1206
  *
1309
1207
  * @internal
1310
1208
  */