@ggez/three-runtime 0.1.0
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 +134 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +2805 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# @ggez/three-runtime
|
|
2
|
+
|
|
3
|
+
Three.js adapter for Web Hammer runtime content.
|
|
4
|
+
|
|
5
|
+
`@ggez/three-runtime` no longer owns the runtime format or build pipeline.
|
|
6
|
+
|
|
7
|
+
Package split:
|
|
8
|
+
|
|
9
|
+
- `@ggez/runtime-format`: runtime contracts, parsing, validation, migration
|
|
10
|
+
- `@ggez/runtime-build`: `.whmap` compilation, asset externalization, bundle packing
|
|
11
|
+
- `@ggez/three-runtime`: Three object creation and scene instances
|
|
12
|
+
- `@ggez/runtime-streaming`: optional chunk/world orchestration
|
|
13
|
+
- `@ggez/runtime-physics-rapier`: optional Rapier bindings
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bun add @ggez/three-runtime three
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Host Ownership
|
|
22
|
+
|
|
23
|
+
The Three adapter does not own:
|
|
24
|
+
|
|
25
|
+
- renderer creation
|
|
26
|
+
- main loop
|
|
27
|
+
- camera policy
|
|
28
|
+
- input
|
|
29
|
+
- physics stepping
|
|
30
|
+
- chunk streaming policy
|
|
31
|
+
- gameplay systems
|
|
32
|
+
|
|
33
|
+
It gives you Three objects and helpers. Your application decides what to do with them.
|
|
34
|
+
|
|
35
|
+
## Load A Runtime Scene Instance
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { Scene } from "three";
|
|
39
|
+
import {
|
|
40
|
+
createThreeAssetResolver,
|
|
41
|
+
createThreeRuntimeSceneInstance,
|
|
42
|
+
parseWebHammerEngineBundleZip
|
|
43
|
+
} from "@ggez/three-runtime";
|
|
44
|
+
|
|
45
|
+
const response = await fetch("/levels/tutorial.runtime.zip");
|
|
46
|
+
const zipBytes = new Uint8Array(await response.arrayBuffer());
|
|
47
|
+
const bundle = parseWebHammerEngineBundleZip(zipBytes);
|
|
48
|
+
const assetResolver = createThreeAssetResolver(bundle);
|
|
49
|
+
|
|
50
|
+
const threeScene = new Scene();
|
|
51
|
+
const instance = await createThreeRuntimeSceneInstance(bundle.manifest, {
|
|
52
|
+
applyToScene: threeScene,
|
|
53
|
+
lod: {
|
|
54
|
+
lowDistance: 30,
|
|
55
|
+
midDistance: 10
|
|
56
|
+
},
|
|
57
|
+
resolveAssetUrl: ({ path }) => assetResolver.resolve(path)
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
threeScene.add(instance.root);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The instance returns:
|
|
64
|
+
|
|
65
|
+
- `root`
|
|
66
|
+
- `nodesById`
|
|
67
|
+
- `lights`
|
|
68
|
+
- `physicsDescriptors`
|
|
69
|
+
- `entities`
|
|
70
|
+
- `scene`
|
|
71
|
+
- `dispose()`
|
|
72
|
+
|
|
73
|
+
## Compatibility Loader
|
|
74
|
+
|
|
75
|
+
If you still want the old convenience surface, `loadWebHammerEngineScene()` remains available and now wraps `createThreeRuntimeSceneInstance()`.
|
|
76
|
+
|
|
77
|
+
## Lower-Level Object Factory
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { createThreeRuntimeObjectFactory } from "@ggez/three-runtime";
|
|
81
|
+
|
|
82
|
+
const factory = createThreeRuntimeObjectFactory(scene, {
|
|
83
|
+
lod: {
|
|
84
|
+
lowDistance: 30,
|
|
85
|
+
midDistance: 10
|
|
86
|
+
},
|
|
87
|
+
resolveAssetUrl: ({ path }) => `/assets/${path}`
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const nodeObject = await factory.createNodeObject(scene.nodes[0]);
|
|
91
|
+
const instancingObjects = await factory.createInstancingObjects();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## World Settings
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import {
|
|
98
|
+
applyRuntimeWorldSettingsToThreeScene,
|
|
99
|
+
clearRuntimeWorldSettingsFromThreeScene
|
|
100
|
+
} from "@ggez/three-runtime";
|
|
101
|
+
|
|
102
|
+
await applyRuntimeWorldSettingsToThreeScene(threeScene, {
|
|
103
|
+
settings: runtimeScene.settings
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
clearRuntimeWorldSettingsFromThreeScene(threeScene);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Bundles Vs Manifests
|
|
110
|
+
|
|
111
|
+
- `.whmap`: authored editor source
|
|
112
|
+
- `scene.runtime.json`: stable runtime manifest
|
|
113
|
+
- `scene.runtime.zip`: transport bundle for quick validation, handoff, or small levels
|
|
114
|
+
|
|
115
|
+
For production worlds, prefer unpacked manifests plus normal asset hosting and optional chunk streaming.
|
|
116
|
+
|
|
117
|
+
## Vanilla Three Integration
|
|
118
|
+
|
|
119
|
+
Recommended stack:
|
|
120
|
+
|
|
121
|
+
1. Build runtime artifacts with `@ggez/runtime-build`.
|
|
122
|
+
2. Parse or fetch runtime manifests with `@ggez/runtime-format`.
|
|
123
|
+
3. Instantiate Three content with `@ggez/three-runtime`.
|
|
124
|
+
4. Add physics with `@ggez/runtime-physics-rapier` if needed.
|
|
125
|
+
5. Add streaming with `@ggez/runtime-streaming` if your world is chunked.
|
|
126
|
+
|
|
127
|
+
## React Three Fiber Integration
|
|
128
|
+
|
|
129
|
+
The same package split applies in R3F:
|
|
130
|
+
|
|
131
|
+
1. Load manifests or bundles outside the render tree.
|
|
132
|
+
2. Build a Three runtime scene instance.
|
|
133
|
+
3. Mount `instance.root` into your R3F scene graph or mirror its contents into declarative components.
|
|
134
|
+
4. Keep physics, gameplay, and streaming host-owned.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { WebHammerEngineNode, WebHammerExportMaterial, WebHammerEngineScene, RuntimeScene, WebHammerEngineBundle, RuntimeBundle } from '@ggez/runtime-format';
|
|
2
|
+
export { RuntimeBundle, RuntimeBundleFile, RuntimeGeometry, RuntimeGeometryLod, RuntimeGeometryNode, RuntimeInstancingNode, RuntimeLodLevel, RuntimeMaterial, RuntimeModelLod, RuntimeModelNode, RuntimeNode, RuntimePrimitive, RuntimeScene, RuntimeSceneMetadata, RuntimeWorldChunk, RuntimeWorldIndex, WebHammerEngineBundle, WebHammerEngineBundleFile, WebHammerEngineGeometryNode, WebHammerEngineInstancingNode, WebHammerEngineModelNode, WebHammerEngineNode, WebHammerEngineScene, WebHammerEngineSceneMetadata, WebHammerExportGeometry, WebHammerExportGeometryLod, WebHammerExportMaterial, WebHammerExportModelLod, WebHammerExportPrimitive, WebHammerLodLevel } from '@ggez/runtime-format';
|
|
3
|
+
import { Asset, SceneSkyboxSettings, PropPhysics, Transform } from '@ggez/shared';
|
|
4
|
+
import * as three from 'three';
|
|
5
|
+
import { Object3D, Group, Scene } from 'three';
|
|
6
|
+
import { createWebHammerEngineBundleZip as createWebHammerEngineBundleZip$1, externalizeWebHammerEngineScene as externalizeWebHammerEngineScene$1, parseWebHammerEngineBundleZip as parseWebHammerEngineBundleZip$1 } from '@ggez/runtime-build';
|
|
7
|
+
export { buildRuntimeBundle, buildRuntimeScene, buildRuntimeWorldIndex, externalizeRuntimeAssets, packRuntimeBundle, unpackRuntimeBundle } from '@ggez/runtime-build';
|
|
8
|
+
|
|
9
|
+
type TextureSlot = "baseColorTexture" | "metallicRoughnessTexture" | "normalTexture";
|
|
10
|
+
type WebHammerAssetResolverContext = {
|
|
11
|
+
kind: "model";
|
|
12
|
+
node: Extract<WebHammerEngineNode, {
|
|
13
|
+
kind: "model";
|
|
14
|
+
}>;
|
|
15
|
+
asset?: Asset;
|
|
16
|
+
path: string;
|
|
17
|
+
format: "gltf" | "obj";
|
|
18
|
+
} | {
|
|
19
|
+
kind: "texture";
|
|
20
|
+
material: WebHammerExportMaterial;
|
|
21
|
+
path: string;
|
|
22
|
+
slot: TextureSlot;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "skybox";
|
|
25
|
+
path: string;
|
|
26
|
+
skybox: SceneSkyboxSettings;
|
|
27
|
+
};
|
|
28
|
+
type WebHammerSceneLoaderOptions = {
|
|
29
|
+
applyToScene?: Scene;
|
|
30
|
+
castShadow?: boolean;
|
|
31
|
+
lod?: WebHammerSceneLodOptions;
|
|
32
|
+
receiveShadow?: boolean;
|
|
33
|
+
resolveAssetUrl?: (context: WebHammerAssetResolverContext) => Promise<string> | string;
|
|
34
|
+
};
|
|
35
|
+
type WebHammerSceneLodOptions = {
|
|
36
|
+
lowDistance: number;
|
|
37
|
+
midDistance: number;
|
|
38
|
+
};
|
|
39
|
+
type ThreeRuntimeSceneInstance = {
|
|
40
|
+
dispose: () => void;
|
|
41
|
+
entities: WebHammerEngineScene["entities"];
|
|
42
|
+
lights: Object3D[];
|
|
43
|
+
nodesById: Map<string, Object3D>;
|
|
44
|
+
physicsDescriptors: Array<{
|
|
45
|
+
nodeId: string;
|
|
46
|
+
object: Object3D;
|
|
47
|
+
physics: PropPhysics;
|
|
48
|
+
}>;
|
|
49
|
+
root: Group;
|
|
50
|
+
scene: WebHammerEngineScene;
|
|
51
|
+
};
|
|
52
|
+
type WebHammerLoadedScene = ThreeRuntimeSceneInstance & {
|
|
53
|
+
nodes: ThreeRuntimeSceneInstance["nodesById"];
|
|
54
|
+
physicsNodes: ThreeRuntimeSceneInstance["physicsDescriptors"];
|
|
55
|
+
};
|
|
56
|
+
type ThreeRuntimeAssetResolverContext = WebHammerAssetResolverContext;
|
|
57
|
+
type ThreeRuntimeSceneInstanceOptions = WebHammerSceneLoaderOptions;
|
|
58
|
+
type ThreeRuntimeSceneLodOptions = WebHammerSceneLodOptions;
|
|
59
|
+
declare function isWebHammerEngineScene(value: unknown): value is WebHammerEngineScene;
|
|
60
|
+
declare function isWebHammerEngineBundle(value: unknown): value is WebHammerEngineBundle;
|
|
61
|
+
declare function parseWebHammerEngineScene(text: string): WebHammerEngineScene;
|
|
62
|
+
declare function fetchWebHammerEngineScene(url: string, init?: RequestInit): Promise<WebHammerEngineScene>;
|
|
63
|
+
declare function createThreeRuntimeSceneInstance(input: RuntimeScene | string, options?: WebHammerSceneLoaderOptions): Promise<ThreeRuntimeSceneInstance>;
|
|
64
|
+
declare function loadWebHammerEngineScene(input: WebHammerEngineScene | string, options?: WebHammerSceneLoaderOptions): Promise<WebHammerLoadedScene>;
|
|
65
|
+
declare function loadWebHammerEngineSceneFromUrl(url: string, options?: WebHammerSceneLoaderOptions): Promise<WebHammerLoadedScene>;
|
|
66
|
+
declare function loadThreeRuntimeSceneInstanceFromUrl(url: string, options?: WebHammerSceneLoaderOptions): Promise<ThreeRuntimeSceneInstance>;
|
|
67
|
+
declare function applyWebHammerWorldSettings(target: Scene, engineScene: Pick<WebHammerEngineScene, "settings">, options?: Pick<WebHammerSceneLoaderOptions, "resolveAssetUrl">): Promise<void>;
|
|
68
|
+
declare function clearWebHammerWorldSettings(target: Scene): void;
|
|
69
|
+
declare const applyRuntimeWorldSettingsToThreeScene: typeof applyWebHammerWorldSettings;
|
|
70
|
+
declare const clearRuntimeWorldSettingsFromThreeScene: typeof clearWebHammerWorldSettings;
|
|
71
|
+
|
|
72
|
+
declare function createThreeAssetResolver(bundle: RuntimeBundle): {
|
|
73
|
+
dispose(): void;
|
|
74
|
+
resolve(path: string): string;
|
|
75
|
+
};
|
|
76
|
+
declare function createWebHammerBundleAssetResolver(bundle: WebHammerEngineBundle): {
|
|
77
|
+
dispose(): void;
|
|
78
|
+
resolve(path: string): string;
|
|
79
|
+
};
|
|
80
|
+
declare function createWebHammerEngineBundleZip(bundle: WebHammerEngineBundle, options?: Parameters<typeof createWebHammerEngineBundleZip$1>[1]): Uint8Array<ArrayBufferLike>;
|
|
81
|
+
declare function parseWebHammerEngineBundleZip(bundleBytes: Uint8Array, options?: Parameters<typeof parseWebHammerEngineBundleZip$1>[1]): RuntimeBundle;
|
|
82
|
+
declare function externalizeWebHammerEngineScene(scene: WebHammerEngineBundle["manifest"], options?: Parameters<typeof externalizeWebHammerEngineScene$1>[1]): Promise<RuntimeBundle>;
|
|
83
|
+
|
|
84
|
+
type WebHammerSceneObjectFactoryOptions = Pick<WebHammerSceneLoaderOptions, "castShadow" | "lod" | "receiveShadow" | "resolveAssetUrl">;
|
|
85
|
+
type CreateNodeObjectOverrides = {
|
|
86
|
+
transform?: Transform;
|
|
87
|
+
};
|
|
88
|
+
type WebHammerSceneObjectFactory = {
|
|
89
|
+
createInstancingObjects: () => Promise<Object3D[]>;
|
|
90
|
+
createNodeObject: (node: WebHammerEngineNode, overrides?: CreateNodeObjectOverrides) => Promise<Object3D>;
|
|
91
|
+
};
|
|
92
|
+
declare function createWebHammerSceneObjectFactory(engineScene: Pick<WebHammerEngineScene, "assets" | "nodes">, options?: WebHammerSceneObjectFactoryOptions): WebHammerSceneObjectFactory;
|
|
93
|
+
declare const createThreeRuntimeObjectFactory: typeof createWebHammerSceneObjectFactory;
|
|
94
|
+
declare function extractPhysics(node: WebHammerEngineNode): PropPhysics | undefined;
|
|
95
|
+
declare function findPrimaryLight(object: Object3D): Object3D<three.Object3DEventMap> | undefined;
|
|
96
|
+
|
|
97
|
+
export { type ThreeRuntimeAssetResolverContext, type ThreeRuntimeSceneInstance, type ThreeRuntimeSceneInstanceOptions, type ThreeRuntimeSceneLodOptions, type WebHammerAssetResolverContext, type WebHammerLoadedScene, type WebHammerSceneLoaderOptions, type WebHammerSceneLodOptions, type WebHammerSceneObjectFactory, applyRuntimeWorldSettingsToThreeScene, applyWebHammerWorldSettings, clearRuntimeWorldSettingsFromThreeScene, clearWebHammerWorldSettings, createThreeAssetResolver, createThreeRuntimeObjectFactory, createThreeRuntimeSceneInstance, createWebHammerBundleAssetResolver, createWebHammerEngineBundleZip, createWebHammerSceneObjectFactory, externalizeWebHammerEngineScene, extractPhysics, fetchWebHammerEngineScene, findPrimaryLight, isWebHammerEngineBundle, isWebHammerEngineScene, loadThreeRuntimeSceneInstanceFromUrl, loadWebHammerEngineScene, loadWebHammerEngineSceneFromUrl, parseWebHammerEngineBundleZip, parseWebHammerEngineScene };
|