@kvyverse/world-runtime 0.1.0 → 0.3.2

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.
Files changed (68) hide show
  1. package/README.md +78 -60
  2. package/dist/{BallCollider-8ZrxReEd.js → BallCollider-3L5vOrcL.js} +2 -2
  3. package/dist/{CapsuleCollider-bynyf6Mc.js → CapsuleCollider-CBTsR-Ys.js} +2 -2
  4. package/dist/ChatModule-2tiWS_Yr.js +411 -0
  5. package/dist/{Collider-4_rCTHVA.js → Collider-CPUCG3RA.js} +2 -2
  6. package/dist/{ConeCollider-DtRZmgK8.js → ConeCollider-C3XU3Y9X.js} +2 -2
  7. package/dist/{ConvexMeshCollider-BSmDM4o3.js → ConvexMeshCollider-DzNV4HTO.js} +1 -1
  8. package/dist/{CuboidCollider-CJvq7--s.js → CuboidCollider-Dp1DZoFM.js} +1 -1
  9. package/dist/{CylinderCollider-CQPSh4tu.js → CylinderCollider-C0h_nhB5.js} +2 -2
  10. package/dist/{FpsCameraController-BE2EirRj.js → FpsCameraController-2GNWJM5D.js} +1 -1
  11. package/dist/RapierDebugRenderer-BQy_m-3C.js +73 -0
  12. package/dist/{RapierFpsPlayerController-VsNfQl6v.js → RapierFpsPlayerController-DthD8dw9.js} +5 -22
  13. package/dist/{RapierPhysics-C_3b7QOn.js → RapierPhysics-zLwVZpwF.js} +33 -15
  14. package/dist/{Rigidbody-b7QNF4ev.js → Rigidbody-DLhN8ddv.js} +12 -1
  15. package/dist/World.d.ts +2 -2
  16. package/dist/WorldRuntime.d.ts +13 -4
  17. package/dist/addons/AddonsRuntime.d.ts +35 -0
  18. package/dist/addons/lib-registry.d.ts +34 -0
  19. package/dist/addons/types.d.ts +28 -0
  20. package/dist/behaviours/physics/BallCollider.d.ts +1 -1
  21. package/dist/behaviours/physics/CapsuleCollider.d.ts +1 -1
  22. package/dist/behaviours/physics/ConeCollider.d.ts +1 -1
  23. package/dist/behaviours/physics/ConvexMeshCollider.d.ts +1 -1
  24. package/dist/behaviours/physics/CuboidCollider.d.ts +1 -1
  25. package/dist/behaviours/physics/CylinderCollider.d.ts +1 -1
  26. package/dist/behaviours/physics/HalfspaceCollider.d.ts +1 -1
  27. package/dist/behaviours/physics/_required-patch.d.ts +10 -6
  28. package/dist/chat.module-descriptor-BTsep-Kq.js +107 -0
  29. package/dist/{get-scale-from-obj-QKv3Fig5.js → get-scale-from-obj-B7JlVPni.js} +1 -1
  30. package/dist/index.d.ts +21 -13
  31. package/dist/index.js +441 -155
  32. package/dist/modules/InputSystemModule.d.ts +14 -32
  33. package/dist/modules/chat/ChatDom.d.ts +100 -0
  34. package/dist/modules/chat/ChatModule.d.ts +36 -0
  35. package/dist/modules/chat/chat.module-descriptor.d.ts +43 -0
  36. package/dist/modules/contracts/addons.module-api.d.ts +15 -0
  37. package/dist/modules/contracts/chat.module-api.d.ts +52 -0
  38. package/dist/modules/contracts/controls.module-api.d.ts +58 -0
  39. package/dist/modules/contracts/html.module-api.d.ts +9 -1
  40. package/dist/modules/contracts/input.module-api.d.ts +11 -11
  41. package/dist/modules/contracts/module-events.d.ts +17 -0
  42. package/dist/modules/contracts/rapier.module-api.d.ts +13 -1
  43. package/dist/modules/controls/ControlsModule.d.ts +45 -0
  44. package/dist/modules/controls/KeyboardControlsDriver.d.ts +12 -0
  45. package/dist/modules/index.d.ts +30 -3
  46. package/dist/modules/optional-module-descriptor.d.ts +36 -0
  47. package/dist/modules/optional-modules.d.ts +11 -0
  48. package/dist/modules/physics/RapierDebugRenderer.d.ts +19 -0
  49. package/dist/{behaviours/physics/rapier-addon-core → modules/physics}/RapierPhysics.d.ts +13 -3
  50. package/dist/modules/physics/physics.module-descriptor.d.ts +16 -0
  51. package/dist/modules/registry.d.ts +7 -3
  52. package/dist/rendering/SceneBloom.d.ts +1 -1
  53. package/dist/rendering/renderer-apply.d.ts +1 -1
  54. package/dist/{settings → rendering}/types.d.ts +1 -12
  55. package/dist/types.d.ts +10 -3
  56. package/dist/version.gen.d.ts +1 -1
  57. package/package.json +9 -1
  58. package/dist/RapierDebugRenderer-sURZDLP4.js +0 -55
  59. package/dist/behaviours/physics/rapier-addon-core/RapierDebugRenderer.d.ts +0 -17
  60. package/dist/modules/contracts/rapierDebug.module-api.d.ts +0 -5
  61. package/dist/rolldown-runtime-D7D4PA-g.js +0 -13
  62. package/dist/settings/AddonsRuntime.d.ts +0 -19
  63. package/dist/settings/lib-loaders.d.ts +0 -7
  64. package/dist/settings/lib-registry.d.ts +0 -24
  65. package/dist/settings/module-registry.d.ts +0 -25
  66. /package/dist/{settings → addons}/externals.d.ts +0 -0
  67. /package/dist/behaviours/physics/{rapier-addon-core/Collider.d.ts → Collider.d.ts} +0 -0
  68. /package/dist/behaviours/physics/{rapier-addon-core/get-scale-from-obj.d.ts → get-scale-from-obj.d.ts} +0 -0
@@ -0,0 +1,73 @@
1
+ import * as THREE from "three/webgpu";
2
+ //#region packages/world-runtime/src/modules/physics/RapierDebugRenderer.ts
3
+ /**
4
+ * Draws rapier colliders as lines. Not a ctx module: it lives inside
5
+ * `RapierPhysics` (`enableDebug`/`disableDebug`) and is pulled dynamically —
6
+ * worlds without debug never load this code.
7
+ *
8
+ * @see {@link https://github.com/vladkrutenyuk/three-kvy-core/blob/main/src/addons/RapierDebugRenderer.ts | Source}
9
+ */
10
+ var RapierDebugRenderer = class {
11
+ _ctx;
12
+ _rapier;
13
+ _clear = null;
14
+ constructor(ctx, rapier) {
15
+ this._ctx = ctx;
16
+ this._rapier = rapier;
17
+ }
18
+ get enabled() {
19
+ return !!this._clear;
20
+ }
21
+ start() {
22
+ if (this._clear) return;
23
+ const geometry = new THREE.BufferGeometry();
24
+ const lines = new THREE.LineSegments(geometry, new THREE.LineBasicMaterial({
25
+ vertexColors: true,
26
+ toneMapped: false
27
+ }));
28
+ lines.frustumCulled = false;
29
+ lines.renderOrder = Number.MAX_SAFE_INTEGER;
30
+ this._ctx.scene.add(lines);
31
+ let positionAttr = null;
32
+ let colorAttr = null;
33
+ const rapier = this._rapier;
34
+ const draw = () => {
35
+ const { vertices, colors } = rapier.world.debugRender();
36
+ const vertexCount = vertices.length / 3;
37
+ if (!positionAttr || positionAttr.array.length < vertices.length) {
38
+ positionAttr = new THREE.BufferAttribute(new Float32Array(vertices.length), 3);
39
+ positionAttr.setUsage(THREE.DynamicDrawUsage);
40
+ geometry.setAttribute("position", positionAttr);
41
+ colorAttr = new THREE.BufferAttribute(new Float32Array(vertexCount * 3), 3);
42
+ colorAttr.setUsage(THREE.DynamicDrawUsage);
43
+ geometry.setAttribute("color", colorAttr);
44
+ }
45
+ const positions = positionAttr.array;
46
+ const colorValues = colorAttr.array;
47
+ positions.set(vertices);
48
+ for (let i = 0; i < vertexCount; i++) {
49
+ colorValues[i * 3] = colors[i * 4] ?? 1;
50
+ colorValues[i * 3 + 1] = colors[i * 4 + 1] ?? 1;
51
+ colorValues[i * 3 + 2] = colors[i * 4 + 2] ?? 1;
52
+ }
53
+ positionAttr.needsUpdate = true;
54
+ colorAttr.needsUpdate = true;
55
+ geometry.setDrawRange(0, vertexCount);
56
+ };
57
+ rapier.on("stepafter", draw);
58
+ this._clear = () => {
59
+ rapier.off("stepafter", draw);
60
+ lines.removeFromParent();
61
+ geometry.dispose();
62
+ lines.material.dispose();
63
+ positionAttr = null;
64
+ colorAttr = null;
65
+ this._clear = null;
66
+ };
67
+ }
68
+ stop() {
69
+ this._clear?.();
70
+ }
71
+ };
72
+ //#endregion
73
+ export { RapierDebugRenderer, RapierDebugRenderer as default };
@@ -61,29 +61,12 @@ var RapierFpsPlayerController = class extends Object3DBehaviour {
61
61
  const kcc = this.kcc;
62
62
  const col = this.col;
63
63
  const dt = this.getDt();
64
- const input = this.modules.input;
64
+ const controls = this.modules.controls;
65
65
  const dir = this._inputDir;
66
- dir.setScalar(0);
67
- const playerInput = input.player;
68
- let speed = this.walkSpeed;
69
- switch (playerInput.mode) {
70
- case 0: {
71
- const keys = input.isKeyDown;
72
- if (keys("KeyW") || keys("ArrowUp")) dir.z -= 1;
73
- if (keys("KeyS") || keys("ArrowDown")) dir.z += 1;
74
- if (keys("KeyA") || keys("ArrowLeft")) dir.x -= 1;
75
- if (keys("KeyD") || keys("ArrowRight")) dir.x += 1;
76
- if (this.useShiftRun && input.shiftKey) speed = this.runSpeed;
77
- break;
78
- }
79
- case 1: {
80
- const { forward, lateral, force } = input.player;
81
- dir.z -= forward;
82
- dir.x += lateral;
83
- speed = force > 2 ? THREE.MathUtils.lerp(this.walkSpeed, this.runSpeed, THREE.MathUtils.clamp(force - 2, 0, 1.5)) : this.walkSpeed;
84
- break;
85
- }
86
- }
66
+ dir.set(controls.move.x, 0, -controls.move.y);
67
+ const analog = THREE.MathUtils.clamp(controls.force - 2, 0, 1);
68
+ const running = this.useShiftRun && controls.run;
69
+ const speed = THREE.MathUtils.lerp(this.walkSpeed, this.runSpeed, running ? 1 : analog);
87
70
  dir.normalize();
88
71
  const camera = this.ctx.camera;
89
72
  if (dir.lengthSq() > 0) {
@@ -1,10 +1,5 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
1
  import { ContextModule, ThreeContextEvents, defineProps, readOnly } from "three-start";
3
- //#region packages/world-runtime/src/behaviours/physics/rapier-addon-core/RapierPhysics.ts
4
- var RapierPhysics_exports = /* @__PURE__ */ __exportAll({
5
- RapierPhysics: () => RapierPhysics,
6
- default: () => RapierPhysics
7
- });
2
+ //#region packages/world-runtime/src/modules/physics/RapierPhysics.ts
8
3
  var RapierPhysics = class RapierPhysics extends ContextModule {
9
4
  isRapierPhysics;
10
5
  api;
@@ -13,24 +8,33 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
13
8
  /** @default "vary" */
14
9
  timeStep;
15
10
  _steppingState = { accumulator: 0 };
16
- constructor(Rapier, options = {}) {
11
+ _debug = null;
12
+ _debugOnStart;
13
+ _gravity;
14
+ constructor(options = {}) {
17
15
  super();
18
16
  const { timeStep = "vary", gravity = [
19
17
  0,
20
18
  -9.81,
21
19
  0
22
- ] } = options;
23
- const world = new Rapier.World({
24
- x: gravity[0],
25
- y: gravity[1],
26
- z: gravity[2]
27
- });
20
+ ], debug = false } = options;
21
+ this._debugOnStart = debug;
22
+ this._gravity = gravity;
28
23
  this.timeStep = timeStep;
24
+ }
25
+ onAwake() {
26
+ const Rapier = this.modules.addons.rapier;
27
+ if (!Rapier) throw new Error("RapierPhysics: the physics engine is not loaded — `addons` has no rapier");
28
+ const [x, y, z] = this._gravity;
29
29
  console.log(`Rapier version: ${Rapier.version()}`);
30
30
  defineProps(this, {
31
31
  isRapierPhysics: readOnly(true),
32
32
  api: readOnly(Rapier),
33
- world: readOnly(world),
33
+ world: readOnly(new Rapier.World({
34
+ x,
35
+ y,
36
+ z
37
+ })),
34
38
  eventQueue: readOnly(new Rapier.EventQueue(false))
35
39
  });
36
40
  }
@@ -40,10 +44,24 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
40
44
  this.ctx.on(ThreeContextEvents.RenderBefore, this.update);
41
45
  });
42
46
  });
47
+ if (this._debugOnStart) this.enableDebug();
48
+ }
49
+ /** Whether collider outlines are being drawn right now. */
50
+ get isDebugEnabled() {
51
+ return !!this._debug?.enabled;
52
+ }
53
+ /** Turn on collider debug drawing; the renderer is fetched on demand. */
54
+ async enableDebug() {
55
+ this._debug ??= new (await (import("./RapierDebugRenderer-BQy_m-3C.js"))).RapierDebugRenderer(this.ctx, this);
56
+ this._debug.start();
57
+ }
58
+ disableDebug() {
59
+ this._debug?.stop();
43
60
  }
44
61
  /** three-start ContextModule has no onDestroy; teardown is explicit. */
45
62
  dispose() {
46
63
  this.ctx.off(ThreeContextEvents.RenderBefore, this.update);
64
+ this.disableDebug();
47
65
  }
48
66
  update = () => {
49
67
  const steppingState = this._steppingState;
@@ -71,4 +89,4 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
71
89
  }
72
90
  };
73
91
  //#endregion
74
- export { RapierPhysics_exports as n, RapierPhysics as t };
92
+ export { RapierPhysics, RapierPhysics as default };
@@ -1,6 +1,17 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
1
  import * as THREE from "three/webgpu";
3
2
  import { Object3DBehaviour, assertDefined, defineProps, readOnly } from "three-start";
3
+ //#region \0rolldown/runtime.js
4
+ var __defProp = Object.defineProperty;
5
+ var __exportAll = (all, no_symbols) => {
6
+ let target = {};
7
+ for (var name in all) __defProp(target, name, {
8
+ get: all[name],
9
+ enumerable: true
10
+ });
11
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
12
+ return target;
13
+ };
14
+ //#endregion
4
15
  //#region packages/world-runtime/src/behaviours/physics/Rigidbody.ts
5
16
  var Rigidbody_exports = /* @__PURE__ */ __exportAll({ default: () => Rigidbody });
6
17
  /**
package/dist/World.d.ts CHANGED
@@ -10,8 +10,8 @@ import type { WorldRuntime } from "./WorldRuntime";
10
10
  export declare class World extends ThreeStart {
11
11
  private readonly _runtime;
12
12
  constructor(options: ThreeStartOptions, _runtime: WorldRuntime);
13
- /** Asset URL by project path — same resolving as `getUrl` in scripts. */
14
- getUrl: (path: string) => string;
13
+ /** Asset URL by project path or resource — same resolving as `getUrl` in scripts. */
14
+ getUrl: (source: string | object) => string;
15
15
  /** World lifecycle event bus — the same one as `world.events` in scripts. */
16
16
  get events(): WorldRuntime["emitter"];
17
17
  start(): this;
@@ -1,10 +1,11 @@
1
1
  import EventEmitter from "eventemitter3";
2
2
  import * as THREE from "three/webgpu";
3
+ import { AddonsRuntime } from "./addons/AddonsRuntime";
3
4
  import type { Object3DBehaviourConstructor, ThreeContext, ThreeStart } from "three-start";
4
5
  import type { SceneBloom } from "./rendering/SceneBloom";
5
6
  import type { LoadWorldOptions, RuntimeApi, WorldDefinition } from "./types";
6
7
  /** Slice of the world definition the runtime needs: independent of the asset bag type. */
7
- export type RuntimeDefinitionSlice = Pick<WorldDefinition, "assets" | "scripts" | "entryScript" | "styles" | "fontPaths" | "usedBuiltins" | "addons">;
8
+ export type RuntimeDefinitionSlice = Pick<WorldDefinition, "assets" | "scripts" | "entryScript" | "styles" | "fontPaths" | "usedBuiltins" | "addons" | "imports">;
8
9
  /**
9
10
  * Owner of the world's runtime state: assets, script execution, ctx access.
10
11
  * The only object the generated code receives.
@@ -19,22 +20,29 @@ export declare class WorldRuntime implements RuntimeApi {
19
20
  private readonly _builtins;
20
21
  private readonly _styleElements;
21
22
  private _resources;
23
+ /** Reverse index for `getUrl(resource)` — play mode resolves objects too. */
24
+ private readonly _pathByResource;
22
25
  private _ctx;
23
26
  private _bloom;
24
27
  private _scriptContext;
25
28
  constructor(definition: RuntimeDefinitionSlice, options: LoadWorldOptions);
29
+ /** The world's external dependencies; also the `addons` ctx module. */
30
+ get addons(): AddonsRuntime;
26
31
  /** ctx appears at the 3d-context creation step; unavailable to scripts before that. */
27
32
  get ctx(): ThreeContext;
28
33
  /** @internal Set by bootstrap. */
29
34
  setContext(ctx: ThreeContext): void;
30
35
  /** @internal World bloom, if enabled in the renderer config. */
31
36
  setBloom(bloom: SceneBloom): void;
32
- /** @internal Built-in libs and external scripts from `settings.addons.json`. */
37
+ /** @internal Built-in libs, externals and the physics engine, if the world needs one. */
33
38
  loadAddons(): Promise<void>;
39
+ /** Physics is on in the config, or a built-in behaviour on the scene needs it. */
40
+ private _usesPhysics;
34
41
  /** @internal World resources by asset path — result of `loadAssets`. */
35
42
  setResources(resources: Record<string, unknown>): void;
36
43
  reportProgress(stage: string, details?: string): void;
37
- getUrl: (path: string) => string;
44
+ /** Accepts an asset path or a resource returned by `require` — like play mode. */
45
+ getUrl: (source: string | object) => string;
38
46
  /**
39
47
  * Built-in behaviour class by uuid. Classes are preloaded by bootstrap,
40
48
  * so attaching in `buildScene` is synchronous.
@@ -52,7 +60,8 @@ export declare class WorldRuntime implements RuntimeApi {
52
60
  require: (key: string) => unknown;
53
61
  /**
54
62
  * Runtime spawn: a prefab (build-time factory) is assembled anew, a regular
55
- * object is cloned. Returns a detached object — the caller adds it.
63
+ * object is cloned. The instance is only created and returned — adding it to
64
+ * the scene hierarchy is up to the caller (`ctx.scene.add(obj)`).
56
65
  */
57
66
  instantiate: (source: THREE.Object3D | PrefabFactory, options?: InstantiateOptions) => THREE.Object3D;
58
67
  /** Runs a script once and caches its `output`. The cache entry is set before
@@ -0,0 +1,35 @@
1
+ import { ContextModule } from "three-start";
2
+ import type { AddonsModuleApi } from "../modules/contracts/addons.module-api";
3
+ import type { AddonsConfig, WorldImports } from "./types";
4
+ import type RAPIER from "@dimforge/rapier3d-compat";
5
+ /**
6
+ * External dependencies of the world: built-in libs, externals and the physics
7
+ * engine. Loaded before the world starts; scripts reach them through
8
+ * `resolve(key)` (`require`), the physics module through `rapier`.
9
+ *
10
+ * This is the `addons` ctx module, but it also works without a ctx: launcher
11
+ * worlds have no 3d context while `require` still has to work, so there the
12
+ * instance is used directly. How to import packages is up to the runtime owner
13
+ * (see `WorldImports`).
14
+ */
15
+ export declare class AddonsRuntime extends ContextModule implements AddonsModuleApi {
16
+ private readonly _imports;
17
+ /** libs — by requireKey (`@tweenjs/tween.js`), externals — by accessor (`Tone`). */
18
+ private readonly _byKey;
19
+ private readonly _scriptTags;
20
+ private _rapier;
21
+ constructor(_imports?: WorldImports);
22
+ /** `physics` — whether the world needs rapier (config or a physics behaviour). */
23
+ load(addons: AddonsConfig, options?: {
24
+ physics?: boolean;
25
+ }): Promise<void>;
26
+ /** Resolves a require key: enabled lib or external accessor; undefined otherwise. */
27
+ resolve(key: string): unknown;
28
+ /** The physics engine, loaded and initialized; `null` in worlds without physics. */
29
+ get rapier(): typeof RAPIER | null;
30
+ private _loadLibs;
31
+ private _loadRapier;
32
+ private _loadExternals;
33
+ private _mountScript;
34
+ dispose(): void;
35
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Registry of built-in libraries enabled via `settings.addons.json → libs`.
3
+ *
4
+ * Separates two keys: `id` (short config key under `libs`) and `requireKey`
5
+ * (what the user writes in `require(...)` in scripts — and the import specifier
6
+ * importers are built from). Single source for:
7
+ * - game: the app's importer map (`core/game/settings/optional-imports`),
8
+ * - export: the `imports.libs` block the build emits into the world module,
9
+ * - editor: JSON schema (`libs` props) + require typings (`AddonsRequireTypings`).
10
+ *
11
+ * Adding a lib = add an entry here (+ importer in the app, + d.ts loader in editor).
12
+ * The package itself never imports these — see `./optional-imports.ts`.
13
+ */
14
+ export declare enum LibId {
15
+ Tween = "tween",
16
+ Anime = "anime",
17
+ Nipplejs = "nipplejs",
18
+ Stats = "stats"
19
+ }
20
+ export interface LibDescriptor {
21
+ readonly id: LibId;
22
+ /** Key the user gets the lib by: `require("<requireKey>")`. It is also the
23
+ * import specifier — importers are generated from it. */
24
+ readonly requireKey: string;
25
+ readonly label: string;
26
+ /** npm package to install; defaults to `requireKey` (differs for subpaths). */
27
+ readonly packageName?: string;
28
+ /** The package exposes its API as the default export — unwrap it on load. */
29
+ readonly defaultExport?: boolean;
30
+ }
31
+ export declare const LIBS: Readonly<Record<LibId, LibDescriptor>>;
32
+ export declare const LIB_IDS: LibId[];
33
+ export declare const LIB_DESCRIPTORS: LibDescriptor[];
34
+ export declare function libByRequireKey(requireKey: string): LibDescriptor | undefined;
@@ -0,0 +1,28 @@
1
+ import type { ExternalDescriptor } from "./externals";
2
+ import type { LibId } from "./lib-registry";
3
+ import type { ChatConfig } from "../modules/chat/chat.module-descriptor";
4
+ import type { PhysicsConfig } from "../modules/physics/physics.module-descriptor";
5
+ /** How to import an optional npm package. */
6
+ export type PackageImport = () => Promise<unknown>;
7
+ /**
8
+ * Importers of the world's optional packages. The runtime never spells them out
9
+ * itself: a literal `import("nipplejs")` in its dist would force the host
10
+ * project's bundler to resolve a package that may not be installed. The runtime
11
+ * owner supplies them — the platform on game start, an exported world through
12
+ * `imports` in `defineWorld`.
13
+ */
14
+ export interface WorldImports {
15
+ /** `@dimforge/rapier3d-compat` — worlds with physics. */
16
+ rapier?: PackageImport;
17
+ /** Built-in libs by `LibId` (`settings.addons.json → libs`). */
18
+ libs?: Partial<Record<LibId, PackageImport>>;
19
+ }
20
+ /** `settings.addons.json` — pluggable modules, built-in libs, external scripts. */
21
+ export interface AddonsConfig {
22
+ modules?: {
23
+ physics?: PhysicsConfig;
24
+ chat?: ChatConfig;
25
+ };
26
+ libs?: Partial<Record<LibId, boolean>>;
27
+ externals?: ExternalDescriptor[];
28
+ }
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class BallCollider extends Collider {
4
4
  readonly type = "Ball";
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class CapsuleCollider extends Collider {
4
4
  readonly type = "Capsule";
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class ConeCollider extends Collider {
4
4
  readonly type = "Cone";
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class ConvexMeshCollider extends Collider {
4
4
  readonly type = "Convex";
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class CuboidCollider extends Collider {
4
4
  readonly type = "Cuboid";
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class CylinderCollider extends Collider {
4
4
  readonly type = "Cylinder";
@@ -1,4 +1,4 @@
1
- import { Collider } from "./rapier-addon-core/Collider";
1
+ import { Collider } from "./Collider";
2
2
  import type * as RAPIER from "@dimforge/rapier3d-compat";
3
3
  export default class HalfspaceCollider extends Collider {
4
4
  readonly type = "Halfspace";
@@ -1,10 +1,14 @@
1
+ import type { RapierPhysics } from "../../modules/physics/RapierPhysics";
2
+ import type { NormalizedPhysics } from "../../modules/physics/physics.module-descriptor";
1
3
  import type { ThreeStart } from "three-start";
2
- /** rapier loads lazily: the wasm is pulled only in worlds with physics. */
3
- export declare const lazyRapier: {
4
- get: () => Promise<typeof import("@dimforge/rapier3d-compat")>;
5
- };
4
+ /** The only place the physics module is created — called by the registry
5
+ * descriptor. The module itself takes rapier from `ctx.modules.addons` on awake. */
6
+ export declare function createRapierPhysicsModule(config: NormalizedPhysics): Promise<RapierPhysics>;
6
7
  /**
7
- * Registers rapier modules before bootstrap: three-start forbids `addModules`
8
- * after `start()`. Idempotent — a repeated call sees the module in ctx and exits.
8
+ * Registers physics on demand: a built-in physics behaviour declares it via
9
+ * `meta.requiredPatch`, so a world with a collider on the scene gets
10
+ * `ctx.modules.rapier` even without a line in `settings.addons.json`.
11
+ * Idempotent, and strictly before `start()` — three-start forbids `addModules`
12
+ * afterwards.
9
13
  */
10
14
  export declare function applyRapierPhysicsPatch(starter: ThreeStart): Promise<void>;
@@ -0,0 +1,107 @@
1
+ //#region packages/world-runtime/src/modules/optional-module-descriptor.ts
2
+ /**
3
+ * Keys of the pluggable modules — the same keys as in
4
+ * `settings.addons.json → modules`. Core modules (`addons`/`env`/`html`/`input`/
5
+ * `controls`/`sounds`/`utils`) are not here: every world has them, with no toggle.
6
+ */
7
+ var OptionalModuleId = /* @__PURE__ */ function(OptionalModuleId) {
8
+ OptionalModuleId["Physics"] = "physics";
9
+ OptionalModuleId["Chat"] = "chat";
10
+ return OptionalModuleId;
11
+ }({});
12
+ var OPTIONAL_MODULE_IDS = Object.values(OptionalModuleId);
13
+ //#endregion
14
+ //#region packages/world-runtime/src/modules/chat/chat.module-descriptor.ts
15
+ /** `Slash` opens the chat with a "/" already typed — the Minecraft command gesture. */
16
+ var CHAT_COMMAND_KEY = "Slash";
17
+ var CHAT_INPUT_MODES = ["always", "toggle"];
18
+ var DEFAULTS = {
19
+ input: "always",
20
+ maxLength: 80,
21
+ placeholder: "Chat",
22
+ maxMessages: 150,
23
+ openKeys: ["Enter", "KeyT"],
24
+ visibleLines: 10,
25
+ openedLines: 20,
26
+ fadeAfter: 1e4
27
+ };
28
+ /** Chat defaults live here: `true` = an always visible input with a limit of 80. */
29
+ function normalizeChat(value) {
30
+ if (!value) return null;
31
+ if (value === true) return { ...DEFAULTS };
32
+ if (typeof value === "string") return {
33
+ ...DEFAULTS,
34
+ input: value
35
+ };
36
+ return {
37
+ input: value.input ?? DEFAULTS.input,
38
+ maxLength: value.maxLength ?? DEFAULTS.maxLength,
39
+ placeholder: value.placeholder ?? DEFAULTS.placeholder,
40
+ maxMessages: value.maxMessages ?? DEFAULTS.maxMessages,
41
+ openKeys: value.openKeys ?? DEFAULTS.openKeys,
42
+ visibleLines: value.visibleLines ?? DEFAULTS.visibleLines,
43
+ openedLines: value.openedLines ?? DEFAULTS.openedLines,
44
+ fadeAfter: value.fadeAfter ?? DEFAULTS.fadeAfter
45
+ };
46
+ }
47
+ var chatModuleDescriptor = {
48
+ id: OptionalModuleId.Chat,
49
+ normalize: (raw) => normalizeChat(raw),
50
+ defaultConfig: () => ({ ...DEFAULTS }),
51
+ create: async (config) => {
52
+ const { ChatModule } = await import("./ChatModule-2tiWS_Yr.js");
53
+ return new ChatModule(config);
54
+ },
55
+ schema: {
56
+ description: "World chat. false | \"always\" | \"toggle\" | { input, maxLength, placeholder, maxMessages }.",
57
+ oneOf: [
58
+ { type: "boolean" },
59
+ {
60
+ type: "string",
61
+ enum: [...CHAT_INPUT_MODES]
62
+ },
63
+ {
64
+ type: "object",
65
+ additionalProperties: false,
66
+ properties: {
67
+ input: {
68
+ type: "string",
69
+ enum: [...CHAT_INPUT_MODES],
70
+ description: "always — the input is always visible; toggle — hidden until Enter, hides again on Escape or after sending."
71
+ },
72
+ maxLength: {
73
+ type: "number",
74
+ description: "Max message length (default 80)."
75
+ },
76
+ placeholder: {
77
+ type: "string",
78
+ description: "Input placeholder."
79
+ },
80
+ maxMessages: {
81
+ type: "number",
82
+ description: "How many messages to keep in history (default 150)."
83
+ },
84
+ openKeys: {
85
+ type: "array",
86
+ items: { type: "string" },
87
+ description: "Keys that open the chat — KeyboardEvent.code, layout-independent (default [\"Enter\", \"KeyT\"]). \"Slash\" always opens it with a \"/\" typed in."
88
+ },
89
+ visibleLines: {
90
+ type: "number",
91
+ description: "Lines shown while the chat is closed (default 10)."
92
+ },
93
+ openedLines: {
94
+ type: "number",
95
+ description: "Lines shown while the input is focused (default 20)."
96
+ },
97
+ fadeAfter: {
98
+ type: "number",
99
+ description: "Ms before a line fades out; 0 keeps lines until they are pushed out (default 10000)."
100
+ }
101
+ }
102
+ }
103
+ ]
104
+ }
105
+ };
106
+ //#endregion
107
+ export { OPTIONAL_MODULE_IDS as a, normalizeChat as i, CHAT_INPUT_MODES as n, OptionalModuleId as o, chatModuleDescriptor as r, CHAT_COMMAND_KEY as t };
@@ -1,5 +1,5 @@
1
1
  import * as THREE from "three/webgpu";
2
- //#region packages/world-runtime/src/behaviours/physics/rapier-addon-core/get-scale-from-obj.ts
2
+ //#region packages/world-runtime/src/behaviours/physics/get-scale-from-obj.ts
3
3
  var _hrScale = {
4
4
  radius: 1,
5
5
  halfHeight: 1
package/dist/index.d.ts CHANGED
@@ -20,29 +20,37 @@ export { createVideo, VideoSource } from "./resources/video";
20
20
  export { createFont, FontSource, fontFormatFromMime } from "./resources/font";
21
21
  export { BUILTIN_BEHAVIOUR_LIST, BUILTIN_BEHAVIOURS, getBuiltinBehaviour, } from "./behaviours/registry";
22
22
  export type { BuiltinBehaviour } from "./behaviours/registry";
23
- export { applyRapierPhysicsPatch, lazyRapier, } from "./behaviours/physics/_required-patch";
24
- export { AddonsRuntime } from "./settings/AddonsRuntime";
23
+ export { applyRapierPhysicsPatch } from "./behaviours/physics/_required-patch";
24
+ export { AddonsRuntime } from "./addons/AddonsRuntime";
25
25
  export { applyRendererConfig } from "./rendering/renderer-apply";
26
26
  export { enableSceneEmissiveMrt, SceneBloom } from "./rendering/SceneBloom";
27
27
  export { createTslNode, TslNode } from "./rendering/tsl-node";
28
28
  export type { TslNodeBuilder } from "./rendering/tsl-node";
29
29
  export { createUniformNode, isUniformType, UNIFORM_DEFAULTS, UNIFORM_TYPES, uniformType, } from "./rendering/tsl-uniforms";
30
30
  export type { UniformType } from "./rendering/tsl-uniforms";
31
- export { LIB_DESCRIPTORS, LIB_IDS, LIBS, LibId, libByRequireKey } from "./settings/lib-registry";
32
- export type { LibDescriptor } from "./settings/lib-registry";
33
- export { MODULE_IDS, ModuleId, normalizePhysics, PHYSICS_ENGINES } from "./settings/module-registry";
34
- export { EXTERNAL_TYPES } from "./settings/externals";
31
+ export { LIB_DESCRIPTORS, LIB_IDS, LIBS, LibId, libByRequireKey } from "./addons/lib-registry";
32
+ export type { LibDescriptor } from "./addons/lib-registry";
33
+ export { OPTIONAL_MODULE_IDS, OptionalModuleId } from "./modules/optional-module-descriptor";
34
+ export { OPTIONAL_MODULES, getOptionalModuleDescriptor } from "./modules/optional-modules";
35
+ export { normalizePhysics, PHYSICS_ENGINES, } from "./modules/physics/physics.module-descriptor";
36
+ export { CHAT_INPUT_MODES, normalizeChat } from "./modules/chat/chat.module-descriptor";
37
+ export { EXTERNAL_TYPES } from "./addons/externals";
35
38
  export { BLOOM_MODES, SHADOW_MAP_TYPES, TONE_MAPPING_NAMES, } from "./rendering/renderer-options";
36
39
  export type { BloomModeName, ShadowMapTypeName, ToneMappingName, } from "./rendering/renderer-options";
37
- export type { ExternalDescriptor, ExternalType } from "./settings/externals";
38
- export type { PhysicsConfig, PhysicsEngine } from "./settings/module-registry";
39
- export type { AddonsConfig, BloomConfig, RendererConfig, RendererParams, } from "./settings/types";
40
- export { getHalfheightRadiusScale, getRadiusScale } from "./behaviours/physics/rapier-addon-core/get-scale-from-obj";
40
+ export type { ExternalDescriptor, ExternalType } from "./addons/externals";
41
+ export type { ModuleJsonSchema, OptionalModuleDescriptor, } from "./modules/optional-module-descriptor";
42
+ export type { NormalizedPhysics, PhysicsConfig, PhysicsEngine, } from "./modules/physics/physics.module-descriptor";
43
+ export type { ChatConfig, ChatInputMode, NormalizedChat, } from "./modules/chat/chat.module-descriptor";
44
+ export type { AddonsConfig, PackageImport, WorldImports } from "./addons/types";
45
+ export type { BloomConfig, RendererConfig, RendererParams, } from "./rendering/types";
46
+ export { getHalfheightRadiusScale, getRadiusScale } from "./behaviours/physics/get-scale-from-obj";
47
+ export type { AddonsModuleApi } from "./modules/contracts/addons.module-api";
41
48
  export type { EnvModuleApi } from "./modules/contracts/env.module-api";
42
49
  export type { HtmlModuleApi } from "./modules/contracts/html.module-api";
43
- export type { InputModuleApi, PlayerInputApi } from "./modules/contracts/input.module-api";
44
- export type { RapierJsModule, RapierModuleApi } from "./modules/contracts/rapier.module-api";
45
- export type { RapierDebugModuleApi } from "./modules/contracts/rapierDebug.module-api";
50
+ export type { InputEvents, InputModuleApi } from "./modules/contracts/input.module-api";
51
+ export type { ControlsDriver, ControlsEvents, ControlsModuleApi, ControlsSource, ControlsState, } from "./modules/contracts/controls.module-api";
52
+ export type { ModuleEvents } from "./modules/contracts/module-events";
53
+ export type { RapierEvents, RapierJsModule, RapierModuleApi, } from "./modules/contracts/rapier.module-api";
46
54
  export type { SoundsModuleApi } from "./modules/contracts/sounds.module-api";
47
55
  export type { UtilsModuleApi } from "./modules/contracts/utils.module-api";
48
56
  export type { AssetUrlTable, LoadWorldOptions, RuntimeApi, SceneBuildResult, ScriptModule, ScriptTable, WorldDefinition, WorldLoadProgress, } from "./types";