@kvyverse/world-runtime 0.6.2 → 0.6.8

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 (39) hide show
  1. package/LICENSE.md +2 -2
  2. package/README.md +2 -2
  3. package/dist/{BallCollider-DdxrnexK.js → BallCollider-3L5vOrcL.js} +3 -3
  4. package/dist/{CapsuleCollider-XlGZqg_O.js → CapsuleCollider-CBTsR-Ys.js} +3 -3
  5. package/dist/{ChatModule-DzNY_v-3.js → ChatModule-BFNVVLA8.js} +65 -40
  6. package/dist/{Collider-ElnvKET2.js → Collider-CPUCG3RA.js} +2 -2
  7. package/dist/{ConeCollider-CQfGphDa.js → ConeCollider-C3XU3Y9X.js} +3 -3
  8. package/dist/{ConvexMeshCollider-0Q2u7QAL.js → ConvexMeshCollider-DzNV4HTO.js} +2 -2
  9. package/dist/{CuboidCollider-Cm7kKRMA.js → CuboidCollider-Dp1DZoFM.js} +2 -2
  10. package/dist/{CylinderCollider-P2oZeEyb.js → CylinderCollider-C0h_nhB5.js} +3 -3
  11. package/dist/{FpsCameraController-CuYDbMHJ.js → FpsCameraController-2GNWJM5D.js} +1 -1
  12. package/dist/{MeshInstansing-CSd1gjpu.js → MeshInstansing-Bxij0Yc9.js} +1 -1
  13. package/dist/{PointerLockCameraControls-Cq0m2NLS.js → PointerLockCameraControls-DIK3cVmo.js} +1 -1
  14. package/dist/{RapierDebugRenderer-BSsFENi2.js → RapierDebugRenderer-BQy_m-3C.js} +1 -1
  15. package/dist/{RapierFpsPlayerController-By_mnB5m.js → RapierFpsPlayerController-DthD8dw9.js} +1 -1
  16. package/dist/{RapierPhysics-C22OXUaE.js → RapierPhysics-yrsRPFS3.js} +3 -3
  17. package/dist/{Rigidbody-BHRxJKXd.js → Rigidbody-DLhN8ddv.js} +1 -1
  18. package/dist/{ScalingToFro-CmXQHfR5.js → ScalingToFro-BD-E5-uR.js} +1 -1
  19. package/dist/{SightInteractableArea-C7xBqoQo.js → SightInteractableArea-BK8IXNIl.js} +7 -7
  20. package/dist/{SimpleWASDMovement-BYu0AFeG.js → SimpleWASDMovement-C2m53YYH.js} +1 -1
  21. package/dist/{Spinning-DDhlLF3g.js → Spinning-sgUhHld8.js} +1 -1
  22. package/dist/{StartAnimation-BbY1HgSj.js → StartAnimation-B9eomOS2.js} +1 -1
  23. package/dist/{TrimeshCollider-CGirnNOf.js → TrimeshCollider-7dIs_xtZ.js} +1 -1
  24. package/dist/addons/AddonsRuntime.d.ts +3 -4
  25. package/dist/addons/lib-registry.d.ts +2 -1
  26. package/dist/behaviours/player/SightInteractableArea.d.ts +2 -2
  27. package/dist/{chat.module-descriptor-BMy5jpOU.js → chat.module-descriptor-CGeOaq16.js} +3 -3
  28. package/dist/{get-scale-from-obj-bFMquHMV.js → get-scale-from-obj-B7JlVPni.js} +1 -1
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.js +100 -69
  31. package/dist/{lib-registry-B-NnzKUx.js → lib-registry-CPwXvdYs.js} +8 -1
  32. package/dist/modules/chat/ChatDom.d.ts +16 -10
  33. package/dist/modules/contracts/platform.module-api.d.ts +60 -0
  34. package/dist/modules/index.d.ts +6 -0
  35. package/dist/modules/optional-module-descriptor.d.ts +7 -0
  36. package/dist/modules/platform/NullPlatformModule.d.ts +16 -0
  37. package/dist/modules/registry.d.ts +4 -0
  38. package/dist/version.gen.d.ts +1 -1
  39. package/package.json +2 -2
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Kvyverse World Runtime License
2
2
 
3
- Copyright (c) 2026 Vladislav Kruteniuk (Kvyverse). All rights reserved.
3
+ Copyright (c) 2026 Kvyverse, Inc. All rights reserved.
4
4
 
5
5
  This package (`@kvyverse/world-runtime`, the "Software") is proprietary
6
6
  software. It is **not** open source.
@@ -54,4 +54,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
54
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55
55
  SOFTWARE.
56
56
 
57
- For other licensing needs, contact: vladislove2402@gmail.com
57
+ For other licensing needs, contact: legal@kvyverse.com
package/README.md CHANGED
@@ -102,8 +102,8 @@ world.stores.set("difficulty", "hard");
102
102
  and the world format version, and refuses to load on an incompatible runtime.
103
103
  Re-export the world after a major runtime update.
104
104
  - **Not everything crosses over.** Platform features (multiplayer server, user
105
- state, launcher worlds, the editor's debug overlay) stay in Kvyverse; the
106
- export report lists whatever your particular world loses.
105
+ state, switching the page to another world, the editor's debug overlay) stay in
106
+ Kvyverse; the export report lists whatever your particular world loses.
107
107
 
108
108
  ## License
109
109
 
@@ -1,6 +1,6 @@
1
- import { n as getRadiusScale } from "./get-scale-from-obj-bFMquHMV.js";
2
- import { t as Collider } from "./Collider-ElnvKET2.js";
3
- //#region src/behaviours/physics/BallCollider.ts
1
+ import { n as getRadiusScale } from "./get-scale-from-obj-B7JlVPni.js";
2
+ import { t as Collider } from "./Collider-CPUCG3RA.js";
3
+ //#region packages/world-runtime/src/behaviours/physics/BallCollider.ts
4
4
  var BallCollider = class extends Collider {
5
5
  type = "Ball";
6
6
  /**
@@ -1,6 +1,6 @@
1
- import { t as getHalfheightRadiusScale } from "./get-scale-from-obj-bFMquHMV.js";
2
- import { t as Collider } from "./Collider-ElnvKET2.js";
3
- //#region src/behaviours/physics/CapsuleCollider.ts
1
+ import { t as getHalfheightRadiusScale } from "./get-scale-from-obj-B7JlVPni.js";
2
+ import { t as Collider } from "./Collider-CPUCG3RA.js";
3
+ //#region packages/world-runtime/src/behaviours/physics/CapsuleCollider.ts
4
4
  var CapsuleCollider = class extends Collider {
5
5
  type = "Capsule";
6
6
  /**
@@ -1,28 +1,29 @@
1
- import { t as CHAT_COMMAND_KEY } from "./chat.module-descriptor-BMy5jpOU.js";
1
+ import { t as CHAT_COMMAND_KEY } from "./chat.module-descriptor-CGeOaq16.js";
2
2
  import { ContextModule, ThreeContextEvents } from "three-start";
3
3
  import van from "vanjs-core";
4
- //#region src/modules/chat/chat.css?inline
5
- var chat_default = "/* Neutral base for the chat input: only what it breaks without on real devices.\n Looks are left to the world. */\n\n.kvy-chat {\n position: absolute;\n left: 0;\n bottom: 0;\n width: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n /* On-screen keyboard: ChatDom writes the overlap height here. */\n padding-bottom: var(--kvy-chat-keyboard-inset, 0px);\n /* Click-through like the HUD around it: the root stretches over the whole feed,\n so catching events here would kill clicks on the world behind the messages.\n Only the input takes events back. */\n pointer-events: none;\n}\n\n.kvy-chat__form {\n display: flex;\n margin: 0;\n}\n\n.kvy-chat__input {\n flex: 1 1 auto;\n min-width: 0;\n /* 16px — below that iOS Safari zooms the page on focus. */\n font: inherit;\n font-size: 16px;\n line-height: 1.25;\n color: inherit;\n background: transparent;\n border: 0;\n outline: none;\n padding: 4px 6px;\n -webkit-appearance: none;\n appearance: none;\n border-radius: 0;\n /* The one interactive part of the chat. */\n pointer-events: auto;\n /* No 300ms delay and no double-tap zoom on the input. */\n touch-action: manipulation;\n}\n\n/* The message feed is a TTL queue, not a scroll container. It sticks to the\n bottom and extra lines are cut from the top — no scrollbar here by design. */\n.kvy-chat__feed {\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n max-height: 40vh;\n overflow: hidden;\n /* Belt and braces: the root is already click-through, but a world restyling it\n must not accidentally make messages catch clicks. */\n pointer-events: none;\n}\n\n.kvy-chat__line {\n opacity: 1;\n transition: opacity 300ms ease;\n overflow-wrap: anywhere;\n}\n\n/* The line has outlived its time: it fades but stays in the DOM — opening the\n chat shows it again instead of rebuilding the feed. */\n.kvy-chat__line--faded {\n opacity: 0;\n}\n\n/* Hidden submit button: backs up implicit submission in old webviews. */\n.kvy-chat__submit {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n/* Toggle mode: the input is hidden until entered (Enter on the canvas).\n Opacity, not visibility/display: an element hidden by those cannot be focused\n programmatically, leaving nothing to open the chat with. */\n.kvy-chat--idle-hidden .kvy-chat__input {\n opacity: 0;\n pointer-events: none;\n}\n";
4
+ //#region packages/world-runtime/src/modules/chat/chat.css?inline
5
+ var chat_default = "/* Neutral base for the chat input: only what it breaks without on real devices.\n Looks are left to the world. */\n\n.kvy-chat {\n position: absolute;\n left: 0;\n bottom: 0;\n width: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n /* On-screen keyboard: ChatDom writes the overlap height here. */\n padding-bottom: var(--kvy-chat-keyboard-inset, 0px);\n /* Click-through like the HUD around it: the root stretches over the whole feed,\n so catching events here would kill clicks on the world behind the messages.\n Only the input takes events back. */\n pointer-events: none;\n}\n\n.kvy-chat__form {\n display: flex;\n}\n\n.kvy-chat__input {\n flex: 1 1 auto;\n min-width: 0;\n /* 16px — below that iOS Safari zooms the page on focus. */\n font: inherit;\n font-size: 16px;\n line-height: 1.25;\n color: inherit;\n background: transparent;\n border: 0;\n outline: none;\n padding: 4px 6px;\n -webkit-appearance: none;\n appearance: none;\n border-radius: 0;\n /* The one interactive part of the chat. */\n pointer-events: auto;\n /* No 300ms delay and no double-tap zoom on the input. */\n touch-action: manipulation;\n}\n\n/* The message feed is a TTL queue, not a scroll container. It sticks to the\n bottom and extra lines are cut from the top — no scrollbar here by design. */\n.kvy-chat__feed {\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n max-height: 40vh;\n overflow: hidden;\n /* Belt and braces: the root is already click-through, but a world restyling it\n must not accidentally make messages catch clicks. */\n pointer-events: none;\n}\n\n.kvy-chat__line {\n opacity: 1;\n transition: opacity 300ms ease;\n overflow-wrap: anywhere;\n}\n\n/* The line has outlived its time: it fades but stays in the DOM — opening the\n chat shows it again instead of rebuilding the feed. */\n.kvy-chat__line--faded {\n opacity: 0;\n}\n\n/* Toggle mode: the input is hidden until entered (Enter on the canvas).\n Opacity, not visibility/display: an element hidden by those cannot be focused\n programmatically, leaving nothing to open the chat with. */\n.kvy-chat--idle-hidden .kvy-chat__input {\n opacity: 0;\n pointer-events: none;\n}\n";
6
6
  //#endregion
7
- //#region src/modules/chat/ChatDom.ts
8
- var { button, div, form, input } = van.tags;
7
+ //#region packages/world-runtime/src/modules/chat/ChatDom.ts
8
+ var { div, input } = van.tags;
9
9
  var STYLE_ID = "kvyverse-chat-styles";
10
+ /** How long a send waits for the keyboard to commit the typed word (ms). */
11
+ var COMPOSITION_COMMIT_TIMEOUT = 150;
10
12
  /**
11
13
  * Chat DOM: the message feed plus the input field.
12
14
  *
13
- * Built to survive real devices: submit through a `<form>` (Enter/Go/Send on any
14
- * mobile keyboard), an IME composition guard, and lifting above the on-screen
15
- * keyboard via `visualViewport`. Details —
16
- * `./README.md`.
15
+ * Built to survive real devices: sending on the Enter keydown (no `<form>`: a
16
+ * sandboxed host may block form submission), an IME composition guard, and
17
+ * lifting above the on-screen keyboard via `visualViewport`. Details — `./README.md`.
17
18
  */
18
19
  var ChatDom = class ChatDom {
19
20
  root;
20
21
  feed;
21
- form;
22
22
  input;
23
23
  _options;
24
24
  _lines = [];
25
- _isComposing = false;
25
+ /** Timer of a send waiting for the keyboard to commit its composition. */
26
+ _pendingSubmit = 0;
26
27
  _viewportRaf = 0;
27
28
  _mounted = false;
28
29
  constructor(options = {}) {
@@ -40,16 +41,8 @@ var ChatDom = class ChatDom {
40
41
  this.input.spellcheck = false;
41
42
  this.input.setAttribute("autocorrect", "off");
42
43
  this.input.setAttribute("autocapitalize", "sentences");
43
- this.form = form({
44
- class: "kvy-chat__form",
45
- novalidate: true
46
- }, this.input, button({
47
- class: "kvy-chat__submit",
48
- type: "submit",
49
- tabindex: "-1"
50
- }, "Send"));
51
44
  this.feed = div({ class: "kvy-chat__feed" });
52
- this.root = div({ class: "kvy-chat" }, this.feed, this.form);
45
+ this.root = div({ class: "kvy-chat" }, this.feed, div({ class: "kvy-chat__form" }, this.input));
53
46
  }
54
47
  /** The focus policy is only known at runtime (mobile/desktop, canvas). */
55
48
  setFocusPolicy(policy) {
@@ -185,10 +178,8 @@ var ChatDom = class ChatDom {
185
178
  line.el.classList.toggle("kvy-chat__line--faded", faded);
186
179
  }
187
180
  _bind() {
188
- this.form.addEventListener("submit", this._onSubmit);
189
- this.input.addEventListener("compositionstart", this._onCompositionStart);
190
- this.input.addEventListener("compositionend", this._onCompositionEnd);
191
181
  this.input.addEventListener("beforeinput", this._onBeforeInput);
182
+ this.input.addEventListener("compositionend", this._onCompositionEnd);
192
183
  this.input.addEventListener("keydown", this._onKeyDown);
193
184
  this.input.addEventListener("keyup", this._stopPropagation);
194
185
  this.input.addEventListener("focus", this._onFocus);
@@ -200,10 +191,9 @@ var ChatDom = class ChatDom {
200
191
  }
201
192
  }
202
193
  _unbind() {
203
- this.form.removeEventListener("submit", this._onSubmit);
204
- this.input.removeEventListener("compositionstart", this._onCompositionStart);
205
- this.input.removeEventListener("compositionend", this._onCompositionEnd);
194
+ this._cancelPendingSubmit();
206
195
  this.input.removeEventListener("beforeinput", this._onBeforeInput);
196
+ this.input.removeEventListener("compositionend", this._onCompositionEnd);
207
197
  this.input.removeEventListener("keydown", this._onKeyDown);
208
198
  this.input.removeEventListener("keyup", this._stopPropagation);
209
199
  this.input.removeEventListener("focus", this._onFocus);
@@ -218,9 +208,7 @@ var ChatDom = class ChatDom {
218
208
  this._viewportRaf = 0;
219
209
  }
220
210
  }
221
- _onSubmit = (e) => {
222
- e.preventDefault();
223
- if (this._isComposing) return;
211
+ _submit() {
224
212
  const text = this.input.value.trim();
225
213
  this.clear();
226
214
  if (!text) return;
@@ -231,25 +219,54 @@ var ChatDom = class ChatDom {
231
219
  }
232
220
  this.blur();
233
221
  this._options.returnFocusTo?.focus({ preventScroll: true });
234
- };
235
- _onCompositionStart = () => {
236
- this._isComposing = true;
222
+ }
223
+ /**
224
+ * Sends now or, while the keyboard still holds the typed word as a composition
225
+ * (Android), once it commits the word: clearing the field under a live
226
+ * composition can bring the word back into it.
227
+ */
228
+ _requestSubmit(isComposing) {
229
+ if (!isComposing) {
230
+ this._cancelPendingSubmit();
231
+ this._submit();
232
+ return;
233
+ }
234
+ if (this._pendingSubmit) return;
235
+ this._pendingSubmit = window.setTimeout(this._flushSubmit, COMPOSITION_COMMIT_TIMEOUT);
236
+ }
237
+ _cancelPendingSubmit() {
238
+ if (!this._pendingSubmit) return;
239
+ clearTimeout(this._pendingSubmit);
240
+ this._pendingSubmit = 0;
241
+ }
242
+ _flushSubmit = () => {
243
+ this._pendingSubmit = 0;
244
+ this._submit();
237
245
  };
238
246
  _onCompositionEnd = () => {
239
- this._isComposing = false;
240
- };
241
- /** Some Android keyboards send no Enter keydown, only `insertLineBreak`. */
242
- _onBeforeInput = (e) => {
243
- if (e.inputType !== "insertLineBreak") return;
244
- e.preventDefault();
245
- this.form.requestSubmit();
247
+ if (!this._pendingSubmit) return;
248
+ clearTimeout(this._pendingSubmit);
249
+ this._pendingSubmit = window.setTimeout(this._flushSubmit, 0);
246
250
  };
247
251
  _onKeyDown = (e) => {
248
252
  e.stopPropagation();
253
+ if (isImeProcessedKey(e)) return;
254
+ if (e.key === "Enter") {
255
+ e.preventDefault();
256
+ this._requestSubmit(e.isComposing);
257
+ return;
258
+ }
249
259
  if (e.key !== "Escape") return;
250
260
  this.blur();
251
261
  this._options.returnFocusTo?.focus({ preventScroll: true });
252
262
  };
263
+ /** Fallback for keyboards that insert a line break instead of sending Enter. */
264
+ _onBeforeInput = (e) => {
265
+ const { inputType, data, isComposing } = e;
266
+ if (!(inputType === "insertLineBreak" || inputType === "insertParagraph" || inputType === "insertText" && data === "\n")) return;
267
+ e.preventDefault();
268
+ this._requestSubmit(isComposing);
269
+ };
253
270
  _stopPropagation = (e) => {
254
271
  e.stopPropagation();
255
272
  };
@@ -298,8 +315,16 @@ var ChatDom = class ChatDom {
298
315
  document.head.append(style);
299
316
  }
300
317
  };
318
+ /**
319
+ * The key went to the IME, not the page: every engine marks it with `keyCode 229`
320
+ * (Safari even after `compositionend`). Not `isComposing`: on Android the typed word
321
+ * is always a composition, and an Enter that reaches the page there means "send".
322
+ */
323
+ function isImeProcessedKey(e) {
324
+ return e.keyCode === 229;
325
+ }
301
326
  //#endregion
302
- //#region src/modules/chat/ChatModule.ts
327
+ //#region packages/world-runtime/src/modules/chat/ChatModule.ts
303
328
  /**
304
329
  * The world chat as a pluggable ctx module: message history plus its own DOM
305
330
  * input (`dom`), no React. Enabled from `settings.addons.json → modules`; it
@@ -1,7 +1,7 @@
1
- import { t as Rigidbody } from "./Rigidbody-BHRxJKXd.js";
1
+ import { t as Rigidbody } from "./Rigidbody-DLhN8ddv.js";
2
2
  import * as THREE from "three/webgpu";
3
3
  import { Object3DBehaviour, assertDefined, getComponents } from "three-start";
4
- //#region src/behaviours/physics/Collider.ts
4
+ //#region packages/world-runtime/src/behaviours/physics/Collider.ts
5
5
  /** Walk the parent chain (ancestors only); stop when `cb` returns `false`. */
6
6
  function traverseUp(obj, cb) {
7
7
  let cur = obj.parent;
@@ -1,6 +1,6 @@
1
- import { t as getHalfheightRadiusScale } from "./get-scale-from-obj-bFMquHMV.js";
2
- import { t as Collider } from "./Collider-ElnvKET2.js";
3
- //#region src/behaviours/physics/ConeCollider.ts
1
+ import { t as getHalfheightRadiusScale } from "./get-scale-from-obj-B7JlVPni.js";
2
+ import { t as Collider } from "./Collider-CPUCG3RA.js";
3
+ //#region packages/world-runtime/src/behaviours/physics/ConeCollider.ts
4
4
  var ConeCollider = class extends Collider {
5
5
  type = "Cone";
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { t as Collider } from "./Collider-ElnvKET2.js";
2
- //#region src/behaviours/physics/ConvexMeshCollider.ts
1
+ import { t as Collider } from "./Collider-CPUCG3RA.js";
2
+ //#region packages/world-runtime/src/behaviours/physics/ConvexMeshCollider.ts
3
3
  var ConvexMeshCollider = class extends Collider {
4
4
  type = "Convex";
5
5
  getDesc(rapier) {
@@ -1,5 +1,5 @@
1
- import { t as Collider } from "./Collider-ElnvKET2.js";
2
- //#region src/behaviours/physics/CuboidCollider.ts
1
+ import { t as Collider } from "./Collider-CPUCG3RA.js";
2
+ //#region packages/world-runtime/src/behaviours/physics/CuboidCollider.ts
3
3
  var CuboidCollider = class extends Collider {
4
4
  type = "Cuboid";
5
5
  /**
@@ -1,6 +1,6 @@
1
- import { t as getHalfheightRadiusScale } from "./get-scale-from-obj-bFMquHMV.js";
2
- import { t as Collider } from "./Collider-ElnvKET2.js";
3
- //#region src/behaviours/physics/CylinderCollider.ts
1
+ import { t as getHalfheightRadiusScale } from "./get-scale-from-obj-B7JlVPni.js";
2
+ import { t as Collider } from "./Collider-CPUCG3RA.js";
3
+ //#region packages/world-runtime/src/behaviours/physics/CylinderCollider.ts
4
4
  var CylinderCollider = class extends Collider {
5
5
  type = "Cylinder";
6
6
  /**
@@ -1,5 +1,5 @@
1
1
  import { Object3DBehaviour } from "three-start";
2
- //#region src/behaviours/controls/FpsCameraController.ts
2
+ //#region packages/world-runtime/src/behaviours/controls/FpsCameraController.ts
3
3
  var FpsCameraController = class extends Object3DBehaviour {
4
4
  sensitivity = .002;
5
5
  mobileSensitivity = .006;
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three/webgpu";
2
2
  import { Object3DBehaviour } from "three-start";
3
- //#region src/behaviours/utils/MeshInstansing.ts
3
+ //#region packages/world-runtime/src/behaviours/utils/MeshInstansing.ts
4
4
  var MeshInstansing = class MeshInstansing extends Object3DBehaviour {
5
5
  static _totalInstance = 0;
6
6
  geometry = null;
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three/webgpu";
2
2
  import { Object3DBehaviour } from "three-start";
3
- //#region src/behaviours/controls/PointerLockCameraControls.ts
3
+ //#region packages/world-runtime/src/behaviours/controls/PointerLockCameraControls.ts
4
4
  var _euler = new THREE.Euler(0, 0, 0, "YXZ");
5
5
  var _vector = new THREE.Vector3();
6
6
  var _MOUSE_SENSITIVITY = .002;
@@ -1,5 +1,5 @@
1
1
  import * as THREE from "three/webgpu";
2
- //#region src/modules/physics/RapierDebugRenderer.ts
2
+ //#region packages/world-runtime/src/modules/physics/RapierDebugRenderer.ts
3
3
  /**
4
4
  * Draws rapier colliders as lines. Not a ctx module: it lives inside
5
5
  * `RapierPhysics` (`enableDebug`/`disableDebug`) and is pulled dynamically —
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three/webgpu";
2
2
  import { Object3DBehaviour } from "three-start";
3
- //#region src/behaviours/physics/RapierFpsPlayerController.ts
3
+ //#region packages/world-runtime/src/behaviours/physics/RapierFpsPlayerController.ts
4
4
  var RapierFpsPlayerController = class extends Object3DBehaviour {
5
5
  halfHeight = .85;
6
6
  radius = .5;
@@ -1,6 +1,6 @@
1
- import { a as LibId } from "./lib-registry-B-NnzKUx.js";
1
+ import { a as LibId } from "./lib-registry-CPwXvdYs.js";
2
2
  import { ContextModule, ThreeContextEvents, defineProps, readOnly } from "three-start";
3
- //#region src/modules/physics/RapierPhysics.ts
3
+ //#region packages/world-runtime/src/modules/physics/RapierPhysics.ts
4
4
  var RapierPhysics = class RapierPhysics extends ContextModule {
5
5
  isRapierPhysics;
6
6
  api;
@@ -53,7 +53,7 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
53
53
  }
54
54
  /** Turn on collider debug drawing; the renderer is fetched on demand. */
55
55
  async enableDebug() {
56
- this._debug ??= new (await (import("./RapierDebugRenderer-BSsFENi2.js"))).RapierDebugRenderer(this.ctx, this);
56
+ this._debug ??= new (await (import("./RapierDebugRenderer-BQy_m-3C.js"))).RapierDebugRenderer(this.ctx, this);
57
57
  this._debug.start();
58
58
  }
59
59
  disableDebug() {
@@ -12,7 +12,7 @@ var __exportAll = (all, no_symbols) => {
12
12
  return target;
13
13
  };
14
14
  //#endregion
15
- //#region src/behaviours/physics/Rigidbody.ts
15
+ //#region packages/world-runtime/src/behaviours/physics/Rigidbody.ts
16
16
  var Rigidbody_exports = /* @__PURE__ */ __exportAll({ default: () => Rigidbody });
17
17
  /**
18
18
  * @see {@link https://github.com/vladkrutenyuk/three-kvy-core/blob/main/src/addons/Rigidbody.ts | Source}
@@ -1,5 +1,5 @@
1
1
  import { Object3DBehaviour } from "three-start";
2
- //#region src/behaviours/animation/ScalingToFro.ts
2
+ //#region packages/world-runtime/src/behaviours/animation/ScalingToFro.ts
3
3
  var ScalingToFro = class extends Object3DBehaviour {
4
4
  scale = 1;
5
5
  max = 2;
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three/webgpu";
2
2
  import { Object3DBehaviour } from "three-start";
3
- //#region src/behaviours/player/SightInteractableArea.ts
3
+ //#region packages/world-runtime/src/behaviours/player/SightInteractableArea.ts
4
4
  var raycaster = new THREE.Raycaster();
5
5
  var SightInteractableArea = class SightInteractableArea extends Object3DBehaviour {
6
6
  static _CURRENT = null;
@@ -18,7 +18,7 @@ var SightInteractableArea = class SightInteractableArea extends Object3DBehaviou
18
18
  this.object.getWorldPosition(this._initWorldPos);
19
19
  }
20
20
  onDisable() {
21
- this._deactivate();
21
+ this._hidePrompt();
22
22
  }
23
23
  setRadius(r) {
24
24
  this.radius = r;
@@ -38,10 +38,10 @@ var SightInteractableArea = class SightInteractableArea extends Object3DBehaviou
38
38
  if (this._active === active) return;
39
39
  this._active = active;
40
40
  this.emit("activechanged", active);
41
- if (active) this._activate();
42
- else this._deactivate();
41
+ if (active) this._showPrompt();
42
+ else this._hidePrompt();
43
43
  }
44
- _activate() {
44
+ _showPrompt() {
45
45
  const modules = this.modules;
46
46
  SightInteractableArea._CURRENT = this.object.id;
47
47
  modules.html.setCrosshair(this.hint);
@@ -50,7 +50,7 @@ var SightInteractableArea = class SightInteractableArea extends Object3DBehaviou
50
50
  modules.html.crosshair.addEventListener("pointerdown", this._interact);
51
51
  } else this.ctx.renderer.domElement.addEventListener("mousedown", this._interact);
52
52
  }
53
- _deactivate() {
53
+ _hidePrompt() {
54
54
  const modules = this.modules;
55
55
  if (SightInteractableArea._CURRENT === this.object.id) {
56
56
  SightInteractableArea._CURRENT = null;
@@ -66,7 +66,7 @@ var SightInteractableArea = class SightInteractableArea extends Object3DBehaviou
66
66
  const current = SightInteractableArea._CURRENT;
67
67
  if (!(current === this.object.id || current === null)) return;
68
68
  this.interactEnabled = false;
69
- this._deactivate();
69
+ this._hidePrompt();
70
70
  this._active = false;
71
71
  this.emit("interaction");
72
72
  console.log("interaction with ", this.object.name);
@@ -1,5 +1,5 @@
1
1
  import { Object3DBehaviour } from "three-start";
2
- //#region src/behaviours/controls/SimpleWASDMovement.ts
2
+ //#region packages/world-runtime/src/behaviours/controls/SimpleWASDMovement.ts
3
3
  var SimpleWASDMovement = class extends Object3DBehaviour {
4
4
  speed = 4;
5
5
  onBeforeRender() {
@@ -1,5 +1,5 @@
1
1
  import { Object3DBehaviour } from "three-start";
2
- //#region src/behaviours/animation/Spinning.ts
2
+ //#region packages/world-runtime/src/behaviours/animation/Spinning.ts
3
3
  var Spinning = class extends Object3DBehaviour {
4
4
  speed = 5;
5
5
  onBeforeRender() {
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three/webgpu";
2
2
  import { Object3DBehaviour } from "three-start";
3
- //#region src/behaviours/animation/StartAnimation.ts
3
+ //#region packages/world-runtime/src/behaviours/animation/StartAnimation.ts
4
4
  var StartAnimation = class extends Object3DBehaviour {
5
5
  mixer;
6
6
  _action;
@@ -1,5 +1,5 @@
1
1
  import { Object3DBehaviour } from "three-start";
2
- //#region src/behaviours/physics/TrimeshCollider.ts
2
+ //#region packages/world-runtime/src/behaviours/physics/TrimeshCollider.ts
3
3
  var TrimeshCollider = class extends Object3DBehaviour {
4
4
  recursive = false;
5
5
  _detach;
@@ -9,10 +9,9 @@ import type { AddonsConfig, WorldImports } from "./types";
9
9
  * by a module/behaviour through `requiredLibs`. Scripts reach all of them by
10
10
  * `require("<key>")`.
11
11
  *
12
- * This is the `addons` ctx module, but it also works without a ctx: launcher
13
- * worlds have no 3d context while `require` still has to work, so there the
14
- * instance is used directly. How to import optional packages is up to the
15
- * runtime owner (see `WorldImports`).
12
+ * This is the `addons` ctx module, but it is loaded before the ctx exists: a
13
+ * module may need its lib (physics needs rapier) the moment the ctx is built.
14
+ * How to import optional packages is up to the runtime owner (see `WorldImports`).
16
15
  */
17
16
  export declare class AddonsRuntime extends ContextModule implements AddonsModuleApi {
18
17
  private readonly _imports;
@@ -30,7 +30,8 @@ export declare enum LibId {
30
30
  Stats = "stats",
31
31
  Rapier = "rapier",
32
32
  Css2d = "css2d",
33
- Css3d = "css3d"
33
+ Css3d = "css3d",
34
+ OrbitControls = "orbitControls"
34
35
  }
35
36
  export interface LibDescriptor {
36
37
  readonly id: LibId;
@@ -17,7 +17,7 @@ export default class SightInteractableArea extends Object3DBehaviour<{
17
17
  onDisable(): void;
18
18
  setRadius(r: number): void;
19
19
  onBeforeRender(): void;
20
- private _activate;
21
- private _deactivate;
20
+ private _showPrompt;
21
+ private _hidePrompt;
22
22
  private _interact;
23
23
  }
@@ -1,4 +1,4 @@
1
- //#region src/modules/optional-module-descriptor.ts
1
+ //#region packages/world-runtime/src/modules/optional-module-descriptor.ts
2
2
  /**
3
3
  * Keys of the pluggable modules — the same keys as in
4
4
  * `settings.addons.json → modules`. Core modules (`addons`/`env`/`html`/`input`/
@@ -11,7 +11,7 @@ var OptionalModuleId = /* @__PURE__ */ function(OptionalModuleId) {
11
11
  }({});
12
12
  var OPTIONAL_MODULE_IDS = Object.values(OptionalModuleId);
13
13
  //#endregion
14
- //#region src/modules/chat/chat.module-descriptor.ts
14
+ //#region packages/world-runtime/src/modules/chat/chat.module-descriptor.ts
15
15
  /** `Slash` opens the chat with a "/" already typed — the Minecraft command gesture. */
16
16
  var CHAT_COMMAND_KEY = "Slash";
17
17
  var CHAT_INPUT_MODES = ["always", "toggle"];
@@ -49,7 +49,7 @@ var chatModuleDescriptor = {
49
49
  normalize: (raw) => normalizeChat(raw),
50
50
  defaultConfig: () => ({ ...DEFAULTS }),
51
51
  create: async (config) => {
52
- const { ChatModule } = await import("./ChatModule-DzNY_v-3.js");
52
+ const { ChatModule } = await import("./ChatModule-BFNVVLA8.js");
53
53
  return new ChatModule(config);
54
54
  },
55
55
  schema: {
@@ -1,5 +1,5 @@
1
1
  import * as THREE from "three/webgpu";
2
- //#region src/behaviours/physics/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
@@ -7,8 +7,9 @@ export { WorldEvent } from "./world-events";
7
7
  export { lazyProxy } from "./utils/lazy";
8
8
  export { WorldStores } from "./world-stores";
9
9
  export type { WorldStore } from "./world-stores";
10
- export { createWorldModules, EnvModule, HtmlHudModule, InputSystemModule, isMobileDevice, SoundsModule, UtilsModule, } from "./modules";
10
+ export { createWorldModules, EnvModule, HtmlHudModule, InputSystemModule, isMobileDevice, NullPlatformModule, SoundsModule, UtilsModule, } from "./modules";
11
11
  export type { EnvMode, WorldModules } from "./modules";
12
+ export type { PlatformModuleApi, PlatformPlayerApi, PlatformPlayerStorageApi, WorldName, WorldNamesRegister, WorldOpenParams, } from "./modules/contracts/platform.module-api";
12
13
  export { DEFAULT_RESOURCE_IDS, DefaultResourceId, getDefaultResource, isDefaultResourceId, } from "./resources/default-resources";
13
14
  export type { DefaultResourceIdValue, DefaultResourceTypes, } from "./resources/default-resources";
14
15
  export { AssetLoaders, configureAssetLoaders, LOADING_MANAGER } from "./resources/loaders";