@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 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.
@@ -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 };