@kvyverse/world-runtime 0.1.0 → 0.4.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.
- package/README.md +84 -59
- package/dist/{BallCollider-8ZrxReEd.js → BallCollider-3L5vOrcL.js} +2 -2
- package/dist/{CapsuleCollider-bynyf6Mc.js → CapsuleCollider-CBTsR-Ys.js} +2 -2
- package/dist/ChatModule-2tiWS_Yr.js +411 -0
- package/dist/{Collider-4_rCTHVA.js → Collider-CPUCG3RA.js} +2 -2
- package/dist/{ConeCollider-DtRZmgK8.js → ConeCollider-C3XU3Y9X.js} +2 -2
- package/dist/{ConvexMeshCollider-BSmDM4o3.js → ConvexMeshCollider-DzNV4HTO.js} +1 -1
- package/dist/{CuboidCollider-CJvq7--s.js → CuboidCollider-Dp1DZoFM.js} +1 -1
- package/dist/{CylinderCollider-CQPSh4tu.js → CylinderCollider-C0h_nhB5.js} +2 -2
- package/dist/{FpsCameraController-BE2EirRj.js → FpsCameraController-2GNWJM5D.js} +1 -1
- package/dist/RapierDebugRenderer-BQy_m-3C.js +73 -0
- package/dist/{RapierFpsPlayerController-VsNfQl6v.js → RapierFpsPlayerController-DthD8dw9.js} +5 -22
- package/dist/{RapierPhysics-C_3b7QOn.js → RapierPhysics-CU6X--c7.js} +34 -15
- package/dist/{Rigidbody-b7QNF4ev.js → Rigidbody-DLhN8ddv.js} +12 -1
- package/dist/World.d.ts +4 -2
- package/dist/WorldRuntime.d.ts +15 -5
- package/dist/addons/AddonsRuntime.d.ts +37 -0
- package/dist/addons/builtin-libs.d.ts +20 -0
- package/dist/addons/lib-registry.d.ts +60 -0
- package/dist/addons/required-libs.d.ts +9 -0
- package/dist/addons/types.d.ts +28 -0
- package/dist/behaviours/physics/BallCollider.d.ts +1 -1
- package/dist/behaviours/physics/CapsuleCollider.d.ts +1 -1
- package/dist/behaviours/physics/ConeCollider.d.ts +1 -1
- package/dist/behaviours/physics/ConvexMeshCollider.d.ts +1 -1
- package/dist/behaviours/physics/CuboidCollider.d.ts +1 -1
- package/dist/behaviours/physics/CylinderCollider.d.ts +1 -1
- package/dist/behaviours/physics/HalfspaceCollider.d.ts +1 -1
- package/dist/behaviours/physics/_required-patch.d.ts +10 -8
- package/dist/behaviours/registry.d.ts +9 -2
- package/dist/chat.module-descriptor-BTsep-Kq.js +107 -0
- package/dist/{get-scale-from-obj-QKv3Fig5.js → get-scale-from-obj-B7JlVPni.js} +1 -1
- package/dist/index.d.ts +26 -14
- package/dist/index.js +594 -202
- package/dist/lib-registry-D1VyVPBg.js +142 -0
- package/dist/modules/HtmlHudModule.d.ts +5 -1
- package/dist/modules/InputSystemModule.d.ts +14 -32
- package/dist/modules/chat/ChatDom.d.ts +100 -0
- package/dist/modules/chat/ChatModule.d.ts +36 -0
- package/dist/modules/chat/chat.module-descriptor.d.ts +43 -0
- package/dist/modules/contracts/addons.module-api.d.ts +15 -0
- package/dist/modules/contracts/chat.module-api.d.ts +52 -0
- package/dist/modules/contracts/controls.module-api.d.ts +58 -0
- package/dist/modules/contracts/html.module-api.d.ts +22 -2
- package/dist/modules/contracts/input.module-api.d.ts +11 -11
- package/dist/modules/contracts/module-events.d.ts +17 -0
- package/dist/modules/contracts/rapier.module-api.d.ts +13 -1
- package/dist/modules/controls/ControlsModule.d.ts +45 -0
- package/dist/modules/controls/KeyboardControlsDriver.d.ts +12 -0
- package/dist/modules/index.d.ts +30 -3
- package/dist/modules/optional-module-descriptor.d.ts +39 -0
- package/dist/modules/optional-modules.d.ts +11 -0
- package/dist/modules/physics/RapierDebugRenderer.d.ts +19 -0
- package/dist/{behaviours/physics/rapier-addon-core → modules/physics}/RapierPhysics.d.ts +13 -3
- package/dist/modules/physics/physics.module-descriptor.d.ts +16 -0
- package/dist/modules/registry.d.ts +7 -3
- package/dist/rendering/SceneBloom.d.ts +1 -1
- package/dist/rendering/renderer-apply.d.ts +1 -1
- package/dist/{settings → rendering}/types.d.ts +1 -12
- package/dist/types.d.ts +10 -3
- package/dist/utils/lazy.d.ts +7 -0
- package/dist/version.gen.d.ts +1 -1
- package/dist/world-stores.d.ts +39 -0
- package/package.json +10 -1
- package/dist/RapierDebugRenderer-sURZDLP4.js +0 -55
- package/dist/behaviours/physics/rapier-addon-core/RapierDebugRenderer.d.ts +0 -17
- package/dist/modules/contracts/rapierDebug.module-api.d.ts +0 -5
- package/dist/rolldown-runtime-D7D4PA-g.js +0 -13
- package/dist/settings/AddonsRuntime.d.ts +0 -19
- package/dist/settings/lib-loaders.d.ts +0 -7
- package/dist/settings/lib-registry.d.ts +0 -24
- package/dist/settings/module-registry.d.ts +0 -25
- /package/dist/{settings → addons}/externals.d.ts +0 -0
- /package/dist/behaviours/physics/{rapier-addon-core/Collider.d.ts → Collider.d.ts} +0 -0
- /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 };
|
package/dist/{RapierFpsPlayerController-VsNfQl6v.js → RapierFpsPlayerController-DthD8dw9.js}
RENAMED
|
@@ -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
|
|
64
|
+
const controls = this.modules.controls;
|
|
65
65
|
const dir = this._inputDir;
|
|
66
|
-
dir.
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
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,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as LibId } from "./lib-registry-D1VyVPBg.js";
|
|
2
2
|
import { ContextModule, ThreeContextEvents, defineProps, readOnly } from "three-start";
|
|
3
|
-
//#region packages/world-runtime/src/
|
|
4
|
-
var RapierPhysics_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
-
RapierPhysics: () => RapierPhysics,
|
|
6
|
-
default: () => RapierPhysics
|
|
7
|
-
});
|
|
3
|
+
//#region packages/world-runtime/src/modules/physics/RapierPhysics.ts
|
|
8
4
|
var RapierPhysics = class RapierPhysics extends ContextModule {
|
|
9
5
|
isRapierPhysics;
|
|
10
6
|
api;
|
|
@@ -13,24 +9,33 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
|
|
|
13
9
|
/** @default "vary" */
|
|
14
10
|
timeStep;
|
|
15
11
|
_steppingState = { accumulator: 0 };
|
|
16
|
-
|
|
12
|
+
_debug = null;
|
|
13
|
+
_debugOnStart;
|
|
14
|
+
_gravity;
|
|
15
|
+
constructor(options = {}) {
|
|
17
16
|
super();
|
|
18
17
|
const { timeStep = "vary", gravity = [
|
|
19
18
|
0,
|
|
20
19
|
-9.81,
|
|
21
20
|
0
|
|
22
|
-
] } = options;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
y: gravity[1],
|
|
26
|
-
z: gravity[2]
|
|
27
|
-
});
|
|
21
|
+
], debug = false } = options;
|
|
22
|
+
this._debugOnStart = debug;
|
|
23
|
+
this._gravity = gravity;
|
|
28
24
|
this.timeStep = timeStep;
|
|
25
|
+
}
|
|
26
|
+
onAwake() {
|
|
27
|
+
const Rapier = this.modules.addons.lib(LibId.Rapier);
|
|
28
|
+
if (!Rapier) throw new Error("RapierPhysics: the physics engine is not loaded — `addons` has no rapier");
|
|
29
|
+
const [x, y, z] = this._gravity;
|
|
29
30
|
console.log(`Rapier version: ${Rapier.version()}`);
|
|
30
31
|
defineProps(this, {
|
|
31
32
|
isRapierPhysics: readOnly(true),
|
|
32
33
|
api: readOnly(Rapier),
|
|
33
|
-
world: readOnly(
|
|
34
|
+
world: readOnly(new Rapier.World({
|
|
35
|
+
x,
|
|
36
|
+
y,
|
|
37
|
+
z
|
|
38
|
+
})),
|
|
34
39
|
eventQueue: readOnly(new Rapier.EventQueue(false))
|
|
35
40
|
});
|
|
36
41
|
}
|
|
@@ -40,10 +45,24 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
|
|
|
40
45
|
this.ctx.on(ThreeContextEvents.RenderBefore, this.update);
|
|
41
46
|
});
|
|
42
47
|
});
|
|
48
|
+
if (this._debugOnStart) this.enableDebug();
|
|
49
|
+
}
|
|
50
|
+
/** Whether collider outlines are being drawn right now. */
|
|
51
|
+
get isDebugEnabled() {
|
|
52
|
+
return !!this._debug?.enabled;
|
|
53
|
+
}
|
|
54
|
+
/** Turn on collider debug drawing; the renderer is fetched on demand. */
|
|
55
|
+
async enableDebug() {
|
|
56
|
+
this._debug ??= new (await (import("./RapierDebugRenderer-BQy_m-3C.js"))).RapierDebugRenderer(this.ctx, this);
|
|
57
|
+
this._debug.start();
|
|
58
|
+
}
|
|
59
|
+
disableDebug() {
|
|
60
|
+
this._debug?.stop();
|
|
43
61
|
}
|
|
44
62
|
/** three-start ContextModule has no onDestroy; teardown is explicit. */
|
|
45
63
|
dispose() {
|
|
46
64
|
this.ctx.off(ThreeContextEvents.RenderBefore, this.update);
|
|
65
|
+
this.disableDebug();
|
|
47
66
|
}
|
|
48
67
|
update = () => {
|
|
49
68
|
const steppingState = this._steppingState;
|
|
@@ -71,4 +90,4 @@ var RapierPhysics = class RapierPhysics extends ContextModule {
|
|
|
71
90
|
}
|
|
72
91
|
};
|
|
73
92
|
//#endregion
|
|
74
|
-
export {
|
|
93
|
+
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,10 +10,12 @@ 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: (
|
|
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
|
+
/** Shared reactive state — the same one as `world.stores` in scripts. */
|
|
18
|
+
get stores(): WorldRuntime["stores"];
|
|
17
19
|
start(): this;
|
|
18
20
|
dispose(): void;
|
|
19
21
|
}
|
package/dist/WorldRuntime.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import EventEmitter from "eventemitter3";
|
|
2
|
-
import
|
|
2
|
+
import { AddonsRuntime } from "./addons/AddonsRuntime";
|
|
3
|
+
import { WorldStores } from "./world-stores";
|
|
4
|
+
import type * as THREE from "three/webgpu";
|
|
3
5
|
import type { Object3DBehaviourConstructor, ThreeContext, ThreeStart } from "three-start";
|
|
4
6
|
import type { SceneBloom } from "./rendering/SceneBloom";
|
|
5
7
|
import type { LoadWorldOptions, RuntimeApi, WorldDefinition } from "./types";
|
|
6
8
|
/** 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">;
|
|
9
|
+
export type RuntimeDefinitionSlice = Pick<WorldDefinition, "assets" | "scripts" | "entryScript" | "styles" | "fontPaths" | "usedBuiltins" | "addons" | "imports">;
|
|
8
10
|
/**
|
|
9
11
|
* Owner of the world's runtime state: assets, script execution, ctx access.
|
|
10
12
|
* The only object the generated code receives.
|
|
@@ -14,27 +16,34 @@ export declare class WorldRuntime implements RuntimeApi {
|
|
|
14
16
|
readonly options: LoadWorldOptions;
|
|
15
17
|
/** World lifecycle event bus (`world.events` in scripts). */
|
|
16
18
|
readonly emitter: EventEmitter<string | symbol, any>;
|
|
19
|
+
/** Shared reactive state of the world (`world.stores` in scripts). */
|
|
20
|
+
readonly stores: WorldStores;
|
|
17
21
|
private readonly _addons;
|
|
18
22
|
private readonly _executedScripts;
|
|
19
23
|
private readonly _builtins;
|
|
20
24
|
private readonly _styleElements;
|
|
21
25
|
private _resources;
|
|
26
|
+
/** Reverse index for `getUrl(resource)` — play mode resolves objects too. */
|
|
27
|
+
private readonly _pathByResource;
|
|
22
28
|
private _ctx;
|
|
23
29
|
private _bloom;
|
|
24
30
|
private _scriptContext;
|
|
25
31
|
constructor(definition: RuntimeDefinitionSlice, options: LoadWorldOptions);
|
|
32
|
+
/** The world's external dependencies; also the `addons` ctx module. */
|
|
33
|
+
get addons(): AddonsRuntime;
|
|
26
34
|
/** ctx appears at the 3d-context creation step; unavailable to scripts before that. */
|
|
27
35
|
get ctx(): ThreeContext;
|
|
28
36
|
/** @internal Set by bootstrap. */
|
|
29
37
|
setContext(ctx: ThreeContext): void;
|
|
30
38
|
/** @internal World bloom, if enabled in the renderer config. */
|
|
31
39
|
setBloom(bloom: SceneBloom): void;
|
|
32
|
-
/** @internal
|
|
40
|
+
/** @internal Libs (config + required by modules/behaviours) and externals. */
|
|
33
41
|
loadAddons(): Promise<void>;
|
|
34
42
|
/** @internal World resources by asset path — result of `loadAssets`. */
|
|
35
43
|
setResources(resources: Record<string, unknown>): void;
|
|
36
44
|
reportProgress(stage: string, details?: string): void;
|
|
37
|
-
|
|
45
|
+
/** Accepts an asset path or a resource returned by `require` — like play mode. */
|
|
46
|
+
getUrl: (source: string | object) => string;
|
|
38
47
|
/**
|
|
39
48
|
* Built-in behaviour class by uuid. Classes are preloaded by bootstrap,
|
|
40
49
|
* so attaching in `buildScene` is synchronous.
|
|
@@ -52,7 +61,8 @@ export declare class WorldRuntime implements RuntimeApi {
|
|
|
52
61
|
require: (key: string) => unknown;
|
|
53
62
|
/**
|
|
54
63
|
* Runtime spawn: a prefab (build-time factory) is assembled anew, a regular
|
|
55
|
-
* object is cloned.
|
|
64
|
+
* object is cloned. The instance is only created and returned — adding it to
|
|
65
|
+
* the scene hierarchy is up to the caller (`ctx.scene.add(obj)`).
|
|
56
66
|
*/
|
|
57
67
|
instantiate: (source: THREE.Object3D | PrefabFactory, options?: InstantiateOptions) => THREE.Object3D;
|
|
58
68
|
/** Runs a script once and caches its `output`. The cache entry is set before
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ContextModule } from "three-start";
|
|
2
|
+
import type { AddonsModuleApi } from "../modules/contracts/addons.module-api";
|
|
3
|
+
import type { LibId } from "./lib-registry";
|
|
4
|
+
import type { AddonsConfig, WorldImports } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* External dependencies of the world: libs and external scripts. Built-in libs
|
|
7
|
+
* are registered right away (the runtime bundles them), optional ones are loaded
|
|
8
|
+
* before the world starts — enabled in `settings.addons.json → libs` or declared
|
|
9
|
+
* by a module/behaviour through `requiredLibs`. Scripts reach all of them by
|
|
10
|
+
* `require("<key>")`.
|
|
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`).
|
|
16
|
+
*/
|
|
17
|
+
export declare class AddonsRuntime extends ContextModule implements AddonsModuleApi {
|
|
18
|
+
private readonly _imports;
|
|
19
|
+
/** libs — by requireKey (`@tweenjs/tween.js`), externals — by accessor (`Tone`). */
|
|
20
|
+
private readonly _byKey;
|
|
21
|
+
private readonly _byLibId;
|
|
22
|
+
private readonly _scriptTags;
|
|
23
|
+
constructor(_imports?: WorldImports);
|
|
24
|
+
/** `usedBuiltinUuids` — built-in behaviours on the scene; they may require libs. */
|
|
25
|
+
load(addons: AddonsConfig, usedBuiltinUuids?: readonly string[]): Promise<void>;
|
|
26
|
+
/** Resolves a require key: a lib or an external accessor; undefined otherwise. */
|
|
27
|
+
resolve(key: string): unknown;
|
|
28
|
+
/** The lib itself, for runtime code that knows what it needs (physics → rapier). */
|
|
29
|
+
lib<T>(id: LibId): T | undefined;
|
|
30
|
+
/** Libs bundled with the runtime: no importer, no config, always available. */
|
|
31
|
+
private _registerBuiltins;
|
|
32
|
+
private _loadLibs;
|
|
33
|
+
private _register;
|
|
34
|
+
private _loadExternals;
|
|
35
|
+
private _mountScript;
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as THREE from "three/webgpu";
|
|
2
|
+
import * as TSL from "three/tsl";
|
|
3
|
+
import { LibId } from "./lib-registry";
|
|
4
|
+
/**
|
|
5
|
+
* Libraries the runtime bundles itself: `require("<key>")` hands these back in
|
|
6
|
+
* every world, no config and no importer involved. Metadata (keys, labels) is
|
|
7
|
+
* in `lib-registry`; the modules live here so the registry stays importable
|
|
8
|
+
* from the editor without dragging three & co along.
|
|
9
|
+
*/
|
|
10
|
+
export declare const BUILTIN_LIB_MODULES: Partial<Record<LibId, unknown>>;
|
|
11
|
+
/**
|
|
12
|
+
* The subset of built-ins that is also a bare global in script scope — same
|
|
13
|
+
* objects as above, so `THREE === require("three")`. Typed literally: the
|
|
14
|
+
* script context contract depends on these exact shapes.
|
|
15
|
+
*/
|
|
16
|
+
export declare const BUILTIN_GLOBALS: {
|
|
17
|
+
readonly THREE: typeof THREE;
|
|
18
|
+
readonly TSL: typeof TSL;
|
|
19
|
+
readonly van: import("vanjs-core").Van;
|
|
20
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry of the libraries scripts can `require`. One entry describes one
|
|
3
|
+
* library; the flags say how it gets into the world:
|
|
4
|
+
*
|
|
5
|
+
* - **built-in** (`builtin: true`) — the runtime already bundles it, so it is
|
|
6
|
+
* available in every world with no config and no importer. Some of them are
|
|
7
|
+
* additionally exposed as a bare global (`globalName`) — that is the only
|
|
8
|
+
* difference between `THREE` and, say, `nanostores`.
|
|
9
|
+
* - **optional** — enabled in `settings.addons.json → libs`, or pulled in by
|
|
10
|
+
* something that declares it in `requiredLibs` (physics → rapier). The
|
|
11
|
+
* importer comes from the runtime owner (`WorldImports`), never from the
|
|
12
|
+
* package itself — see `./optional-imports.ts`.
|
|
13
|
+
*
|
|
14
|
+
* `id` is the config key under `libs`, `requireKey` is what the user writes in
|
|
15
|
+
* `require(...)` (and the import specifier importers are built from). Single
|
|
16
|
+
* source for: the app's importer map, the `imports.libs` block of an exported
|
|
17
|
+
* world, the JSON schema and the editor's require typings.
|
|
18
|
+
*/
|
|
19
|
+
export declare enum LibId {
|
|
20
|
+
Three = "three",
|
|
21
|
+
Tsl = "tsl",
|
|
22
|
+
ThreeStart = "threeStart",
|
|
23
|
+
Van = "van",
|
|
24
|
+
Nanostores = "nanostores",
|
|
25
|
+
EventEmitter = "eventemitter3",
|
|
26
|
+
Howler = "howler",
|
|
27
|
+
Tween = "tween",
|
|
28
|
+
Anime = "anime",
|
|
29
|
+
Nipplejs = "nipplejs",
|
|
30
|
+
Stats = "stats",
|
|
31
|
+
Rapier = "rapier",
|
|
32
|
+
Css2d = "css2d",
|
|
33
|
+
Css3d = "css3d"
|
|
34
|
+
}
|
|
35
|
+
export interface LibDescriptor {
|
|
36
|
+
readonly id: LibId;
|
|
37
|
+
/** Key the user gets the lib by: `require("<requireKey>")`. It is also the
|
|
38
|
+
* import specifier — importers are generated from it. */
|
|
39
|
+
readonly requireKey: string;
|
|
40
|
+
readonly label: string;
|
|
41
|
+
/** npm package to install; defaults to `requireKey` (differs for subpaths). */
|
|
42
|
+
readonly packageName?: string;
|
|
43
|
+
/** Bundled with the runtime: always available, no importer, nothing to install. */
|
|
44
|
+
readonly builtin?: boolean;
|
|
45
|
+
/** Built-in libs that are also bare globals in script scope. */
|
|
46
|
+
readonly globalName?: string;
|
|
47
|
+
/** The package exposes its API as the default export — unwrap it on load. */
|
|
48
|
+
readonly defaultExport?: boolean;
|
|
49
|
+
/** Post-import step, e.g. wasm init. Returns what `require` should hand back. */
|
|
50
|
+
readonly init?: (module: unknown) => Promise<unknown>;
|
|
51
|
+
}
|
|
52
|
+
export declare const LIBS: Readonly<Record<LibId, LibDescriptor>>;
|
|
53
|
+
export declare const LIB_IDS: LibId[];
|
|
54
|
+
export declare const LIB_DESCRIPTORS: LibDescriptor[];
|
|
55
|
+
/** Bundled with the runtime — available in every world. */
|
|
56
|
+
export declare const BUILTIN_LIB_DESCRIPTORS: LibDescriptor[];
|
|
57
|
+
/** Enabled in `settings.addons.json → libs` or required by a module/behaviour. */
|
|
58
|
+
export declare const OPTIONAL_LIB_DESCRIPTORS: LibDescriptor[];
|
|
59
|
+
export declare const OPTIONAL_LIB_IDS: LibId[];
|
|
60
|
+
export declare function libByRequireKey(requireKey: string): LibDescriptor | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LibId } from "./lib-registry";
|
|
2
|
+
import type { AddonsConfig } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Libs the world needs beyond what `libs` lists: an enabled module or a built-in
|
|
5
|
+
* behaviour on the scene declares them itself (`requiredLibs`), so physics keeps
|
|
6
|
+
* working without a line in `settings.addons.json`. Same answer for the game and
|
|
7
|
+
* for the export — the build emits importers from it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function collectRequiredLibs(addons: AddonsConfig | undefined, usedBuiltinUuids?: readonly string[]): LibId[];
|
|
@@ -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
|
+
/** Optional libs by `LibId` — enabled in `settings.addons.json → libs` or
|
|
16
|
+
* required by a module/behaviour (physics → rapier). Built-in libs are
|
|
17
|
+
* bundled with the runtime and need no importer. */
|
|
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,10 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { RequiredPatch } from "../registry";
|
|
2
|
+
import type { RapierPhysics } from "../../modules/physics/RapierPhysics";
|
|
3
|
+
import type { NormalizedPhysics } from "../../modules/physics/physics.module-descriptor";
|
|
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
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* What a physics behaviour needs on top of its class: the rapier lib (loaded
|
|
9
|
+
* with the other addons, before the world starts) and the physics ctx module.
|
|
10
|
+
* A collider on the scene is enough — no line in `settings.addons.json`.
|
|
9
11
|
*/
|
|
10
|
-
export declare
|
|
12
|
+
export declare const rapierPhysicsPatch: RequiredPatch;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Object3DBehaviourConstructor, ThreeStart } from "three-start";
|
|
2
|
+
import type { LibId } from "../addons/lib-registry";
|
|
2
3
|
/**
|
|
3
4
|
* Built-in behaviour: uuid is its identity in user worlds — it must never
|
|
4
5
|
* change. The class loads lazily, so a world without physics doesn't pull rapier.
|
|
@@ -7,8 +8,14 @@ export interface BuiltinBehaviour {
|
|
|
7
8
|
uuid: string;
|
|
8
9
|
name: string;
|
|
9
10
|
load: () => Promise<Object3DBehaviourConstructor>;
|
|
10
|
-
/**
|
|
11
|
-
requiredPatch?:
|
|
11
|
+
/** ctx modules (and their libs) the behaviour cannot work without. */
|
|
12
|
+
requiredPatch?: RequiredPatch;
|
|
13
|
+
}
|
|
14
|
+
/** What a behaviour needs beyond its own class: libs to load before the world
|
|
15
|
+
* starts, and ctx modules to register strictly before `start()`. */
|
|
16
|
+
export interface RequiredPatch {
|
|
17
|
+
requiredLibs?: LibId[];
|
|
18
|
+
apply: (starter: ThreeStart) => Promise<void>;
|
|
12
19
|
}
|
|
13
20
|
/** Registry of built-in behaviours by uuid — source of truth for both game and export. */
|
|
14
21
|
export declare const BUILTIN_BEHAVIOURS: Record<string, BuiltinBehaviour | undefined>;
|
|
@@ -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 };
|