@rydr/game-sdk 1.13.0 → 1.14.1
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.
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const RYDR_PROTOCOL_VERSION: 5;
|
|
10
10
|
/** Semver of this SDK build. Sent in the handshake for telemetry/debugging. */
|
|
11
|
-
export declare const RYDR_SDK_VERSION = "1.
|
|
11
|
+
export declare const RYDR_SDK_VERSION = "1.14.1";
|
|
12
12
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/protocol/version.js
CHANGED
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
// shells omit it, the client falls back to its default).
|
|
11
11
|
export const RYDR_PROTOCOL_VERSION = 5;
|
|
12
12
|
/** Semver of this SDK build. Sent in the handshake for telemetry/debugging. */
|
|
13
|
-
export const RYDR_SDK_VERSION = "1.
|
|
13
|
+
export const RYDR_SDK_VERSION = "1.14.1";
|
|
14
14
|
//# sourceMappingURL=version.js.map
|
|
@@ -7,17 +7,20 @@
|
|
|
7
7
|
* so it lives behind the optional `@rydr/game-sdk/three` entry point (with `three` as a peer
|
|
8
8
|
* dependency) and never burdens games that don't render 3D.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
10
|
+
* ## A world is loaded once and reused
|
|
11
|
+
*
|
|
12
|
+
* A platform world is a static environment, so it is fetched, DRACO-decoded, uploaded to the GPU and
|
|
13
|
+
* shader-compiled **once** ({@link loadWorld}, cached by {@link CoreWorld.id}) and then reused — a game
|
|
14
|
+
* that tears down and rebuilds gameplay on every restart still gets an instant world. Two caches back
|
|
15
|
+
* this: a per-URL GLB dedup inside {@link createGlbLoader} (repeated props clone shared
|
|
16
|
+
* geometry/material instead of re-downloading), and the per-world {@link LoadedWorld} handle cache.
|
|
17
|
+
*
|
|
18
|
+
* ## The handle owns the GPU resources — disposal is safe
|
|
19
|
+
*
|
|
20
|
+
* {@link loadWorld} returns a {@link LoadedWorld} handle, the single owner of the world's GPU
|
|
21
|
+
* resources. Use `attach`/`detach` for the cheap per-restart show/hide, and `dispose` as the *only*
|
|
22
|
+
* way to free memory (it also evicts the cache). This makes the cache impossible to corrupt: there is
|
|
23
|
+
* no "remember to detach, never dispose the shared group" rule to get wrong.
|
|
21
24
|
*/
|
|
22
25
|
import * as THREE from "three";
|
|
23
26
|
import type { CoreWorld } from "../protocol/worlds.js";
|
|
@@ -27,27 +30,66 @@ export interface GlbLoaderOptions {
|
|
|
27
30
|
/** Override the DRACO decoder directory (defaults to {@link DRACO_DECODER_PATH}). */
|
|
28
31
|
dracoDecoderPath?: string;
|
|
29
32
|
}
|
|
33
|
+
/** A transform applied to a loaded world group: translate · Y-rotation · uniform scale. */
|
|
34
|
+
export interface WorldPlacement {
|
|
35
|
+
position?: [number, number, number];
|
|
36
|
+
/** Y-axis rotation, radians. */
|
|
37
|
+
rotationY?: number;
|
|
38
|
+
/** Uniform scale. */
|
|
39
|
+
scale?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface LoadWorldOptions extends GlbLoaderOptions {
|
|
42
|
+
/** Optional transform applied to the world group on every `loadWorld` call (incl. cache hits). */
|
|
43
|
+
placement?: WorldPlacement;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A loaded platform world — the single owner of its GPU resources.
|
|
47
|
+
*
|
|
48
|
+
* Lifecycle: `attach(scene)` to show it, `detach()` to cheaply remove it (the per-restart op — keeps
|
|
49
|
+
* everything on the GPU), and `dispose()` to actually free its geometry/materials and evict it from
|
|
50
|
+
* the cache (real teardown, or switching to a different world). Never call `geometry.dispose()` on
|
|
51
|
+
* `group` yourself — the resources are shared with the cache; use `dispose()`.
|
|
52
|
+
*/
|
|
53
|
+
export interface LoadedWorld {
|
|
54
|
+
/** The {@link CoreWorld.id} this was built from. */
|
|
55
|
+
readonly id: string;
|
|
56
|
+
/** The assembled meshes. Cached/shared — manage its lifetime through this handle, don't dispose it. */
|
|
57
|
+
readonly group: THREE.Group;
|
|
58
|
+
/** Add the world to a scene (or any parent). Idempotent; re-attaching after `detach` is the cheap resume. */
|
|
59
|
+
attach(parent: THREE.Object3D): void;
|
|
60
|
+
/** Remove the world from its parent **without** freeing GPU resources — the cheap per-restart teardown. */
|
|
61
|
+
detach(): void;
|
|
62
|
+
/** Free geometry + materials and evict from the cache. For real teardown or switching worlds. */
|
|
63
|
+
dispose(): void;
|
|
64
|
+
}
|
|
30
65
|
/**
|
|
31
66
|
* A `loadGlb` callback for {@link applyWorld}: fetches a glb by URL and resolves to its root scene.
|
|
32
67
|
*
|
|
33
68
|
* The returned closure shares one `GLTFLoader` + DRACO decoder across all URLs and fetches +
|
|
34
|
-
* DRACO-decodes each
|
|
35
|
-
* geometry/material) rather than re-downloading and re-decoding. Cloning is also
|
|
36
|
-
* correctness: `applyWorld` adds every returned object to the group, and a single
|
|
37
|
-
* parented twice.
|
|
69
|
+
* DRACO-decodes each asset **once** — repeated placements of the same asset resolve to a lightweight
|
|
70
|
+
* `.clone()` (shared geometry/material) rather than re-downloading and re-decoding. Cloning is also
|
|
71
|
+
* required for correctness: `applyWorld` adds every returned object to the group, and a single
|
|
72
|
+
* Object3D can't be parented twice.
|
|
73
|
+
*
|
|
74
|
+
* The cache is keyed by the URL's **path**, not the full URL: platform assets are served as presigned
|
|
75
|
+
* R2 URLs whose signature/expiry query string varies per request, so the same prop placed N times
|
|
76
|
+
* arrives as N distinct full URLs. Keying by path (the R2 object identity) collapses them to one
|
|
77
|
+
* decode; without it every placement re-fetches and re-DRACO-decodes the same glb (slow level loads).
|
|
38
78
|
*/
|
|
39
79
|
export declare function createGlbLoader(opts?: GlbLoaderOptions): (url: string) => Promise<THREE.Object3D>;
|
|
40
80
|
/**
|
|
41
|
-
* Load a platform world's meshes
|
|
42
|
-
*
|
|
43
|
-
*
|
|
81
|
+
* Load (and cache by id) a platform world's meshes. Re-calling for the same `coreWorld.id` resolves to
|
|
82
|
+
* the **same** {@link LoadedWorld} handle instantly — no re-fetch / re-decode / re-upload — so games
|
|
83
|
+
* that rebuild gameplay on restart keep an instant world. `placement`, if given, is applied to the
|
|
84
|
+
* group on every call (cheap). Rejects if any glb fails to load.
|
|
44
85
|
*/
|
|
45
|
-
export declare function
|
|
86
|
+
export declare function loadWorld(coreWorld: CoreWorld, opts?: LoadWorldOptions): Promise<LoadedWorld>;
|
|
87
|
+
/** Apply a {@link WorldPlacement} (translate · Y-rotation · uniform scale) to a group. */
|
|
88
|
+
export declare function applyPlacement(group: THREE.Object3D, placement: WorldPlacement): void;
|
|
46
89
|
/**
|
|
47
|
-
* Release cached
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* memory unbounded. Safe to call while a group is still in a scene, but detach it from the scene first.
|
|
90
|
+
* Release cached worlds and dispose their geometry + materials (textures are left alone — they may be
|
|
91
|
+
* shared elsewhere). Pass an `id` to drop a single world, or omit it to clear everything. Equivalent
|
|
92
|
+
* to calling `dispose()` on the matching handle(s); use it when you don't hold the handle.
|
|
51
93
|
*/
|
|
52
94
|
export declare function clearWorldCache(id?: string): void;
|
|
53
95
|
//# sourceMappingURL=world-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world-loader.d.ts","sourceRoot":"","sources":["../../src/three/world-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"world-loader.d.ts","sourceRoot":"","sources":["../../src/three/world-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,4DAA4D,CAAC;AAE5F,MAAM,WAAW,gBAAgB;IAC/B,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,2FAA2F;AAC3F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,kGAAkG;IAClG,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IAC5B,6GAA6G;IAC7G,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;IACrC,2GAA2G;IAC3G,MAAM,IAAI,IAAI,CAAC;IACf,iGAAiG;IACjG,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,gBAAqB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAgBrG;AAKD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC,CAcjG;AAmBD,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,cAAc,GAAG,IAAI,CAIrF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAWjD"}
|
|
@@ -7,17 +7,20 @@
|
|
|
7
7
|
* so it lives behind the optional `@rydr/game-sdk/three` entry point (with `three` as a peer
|
|
8
8
|
* dependency) and never burdens games that don't render 3D.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
10
|
+
* ## A world is loaded once and reused
|
|
11
|
+
*
|
|
12
|
+
* A platform world is a static environment, so it is fetched, DRACO-decoded, uploaded to the GPU and
|
|
13
|
+
* shader-compiled **once** ({@link loadWorld}, cached by {@link CoreWorld.id}) and then reused — a game
|
|
14
|
+
* that tears down and rebuilds gameplay on every restart still gets an instant world. Two caches back
|
|
15
|
+
* this: a per-URL GLB dedup inside {@link createGlbLoader} (repeated props clone shared
|
|
16
|
+
* geometry/material instead of re-downloading), and the per-world {@link LoadedWorld} handle cache.
|
|
17
|
+
*
|
|
18
|
+
* ## The handle owns the GPU resources — disposal is safe
|
|
19
|
+
*
|
|
20
|
+
* {@link loadWorld} returns a {@link LoadedWorld} handle, the single owner of the world's GPU
|
|
21
|
+
* resources. Use `attach`/`detach` for the cheap per-restart show/hide, and `dispose` as the *only*
|
|
22
|
+
* way to free memory (it also evicts the cache). This makes the cache impossible to corrupt: there is
|
|
23
|
+
* no "remember to detach, never dispose the shared group" rule to get wrong.
|
|
21
24
|
*/
|
|
22
25
|
import * as THREE from "three";
|
|
23
26
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
@@ -29,10 +32,15 @@ export const DRACO_DECODER_PATH = "https://www.gstatic.com/draco/versioned/decod
|
|
|
29
32
|
* A `loadGlb` callback for {@link applyWorld}: fetches a glb by URL and resolves to its root scene.
|
|
30
33
|
*
|
|
31
34
|
* The returned closure shares one `GLTFLoader` + DRACO decoder across all URLs and fetches +
|
|
32
|
-
* DRACO-decodes each
|
|
33
|
-
* geometry/material) rather than re-downloading and re-decoding. Cloning is also
|
|
34
|
-
* correctness: `applyWorld` adds every returned object to the group, and a single
|
|
35
|
-
* parented twice.
|
|
35
|
+
* DRACO-decodes each asset **once** — repeated placements of the same asset resolve to a lightweight
|
|
36
|
+
* `.clone()` (shared geometry/material) rather than re-downloading and re-decoding. Cloning is also
|
|
37
|
+
* required for correctness: `applyWorld` adds every returned object to the group, and a single
|
|
38
|
+
* Object3D can't be parented twice.
|
|
39
|
+
*
|
|
40
|
+
* The cache is keyed by the URL's **path**, not the full URL: platform assets are served as presigned
|
|
41
|
+
* R2 URLs whose signature/expiry query string varies per request, so the same prop placed N times
|
|
42
|
+
* arrives as N distinct full URLs. Keying by path (the R2 object identity) collapses them to one
|
|
43
|
+
* decode; without it every placement re-fetches and re-DRACO-decodes the same glb (slow level loads).
|
|
36
44
|
*/
|
|
37
45
|
export function createGlbLoader(opts = {}) {
|
|
38
46
|
const loader = new GLTFLoader();
|
|
@@ -41,62 +49,89 @@ export function createGlbLoader(opts = {}) {
|
|
|
41
49
|
loader.setDRACOLoader(draco);
|
|
42
50
|
const decoded = new Map();
|
|
43
51
|
return (url) => {
|
|
44
|
-
|
|
52
|
+
const cut = url.search(/[?#]/); // dedup by asset path; presigned query strings vary per placement
|
|
53
|
+
const key = cut === -1 ? url : url.slice(0, cut);
|
|
54
|
+
let p = decoded.get(key);
|
|
45
55
|
if (!p) {
|
|
46
56
|
p = loader.loadAsync(url).then((g) => g.scene);
|
|
47
|
-
decoded.set(
|
|
57
|
+
decoded.set(key, p);
|
|
48
58
|
}
|
|
49
59
|
return p.then((scene) => scene.clone());
|
|
50
60
|
};
|
|
51
61
|
}
|
|
52
|
-
/**
|
|
53
|
-
const
|
|
62
|
+
/** Loaded worlds, keyed by {@link CoreWorld.id}. See the module doc for the lifecycle contract. */
|
|
63
|
+
const worldCache = new Map();
|
|
54
64
|
/**
|
|
55
|
-
* Load a platform world's meshes
|
|
56
|
-
*
|
|
57
|
-
*
|
|
65
|
+
* Load (and cache by id) a platform world's meshes. Re-calling for the same `coreWorld.id` resolves to
|
|
66
|
+
* the **same** {@link LoadedWorld} handle instantly — no re-fetch / re-decode / re-upload — so games
|
|
67
|
+
* that rebuild gameplay on restart keep an instant world. `placement`, if given, is applied to the
|
|
68
|
+
* group on every call (cheap). Rejects if any glb fails to load.
|
|
58
69
|
*/
|
|
59
|
-
export function
|
|
60
|
-
let p =
|
|
70
|
+
export function loadWorld(coreWorld, opts = {}) {
|
|
71
|
+
let p = worldCache.get(coreWorld.id);
|
|
61
72
|
if (!p) {
|
|
62
|
-
p = (
|
|
63
|
-
const group = new THREE.Group();
|
|
64
|
-
group.name = "platform-world";
|
|
65
|
-
await applyWorld(group, coreWorld, { loadGlb: createGlbLoader(opts) });
|
|
66
|
-
return group;
|
|
67
|
-
})();
|
|
73
|
+
p = buildWorld(coreWorld, opts);
|
|
68
74
|
// Don't cache a rejected build — let the next attempt retry the fetch.
|
|
69
75
|
p.catch(() => {
|
|
70
|
-
if (
|
|
71
|
-
|
|
76
|
+
if (worldCache.get(coreWorld.id) === p)
|
|
77
|
+
worldCache.delete(coreWorld.id);
|
|
72
78
|
});
|
|
73
|
-
|
|
79
|
+
worldCache.set(coreWorld.id, p);
|
|
74
80
|
}
|
|
75
|
-
return p
|
|
81
|
+
return p.then((world) => {
|
|
82
|
+
if (opts.placement)
|
|
83
|
+
applyPlacement(world.group, opts.placement);
|
|
84
|
+
return world;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async function buildWorld(coreWorld, opts) {
|
|
88
|
+
const group = new THREE.Group();
|
|
89
|
+
group.name = "platform-world";
|
|
90
|
+
await applyWorld(group, coreWorld, { loadGlb: createGlbLoader(opts) });
|
|
91
|
+
const id = coreWorld.id;
|
|
92
|
+
return {
|
|
93
|
+
id,
|
|
94
|
+
group,
|
|
95
|
+
attach: (parent) => void parent.add(group),
|
|
96
|
+
detach: () => void group.removeFromParent(),
|
|
97
|
+
dispose: () => {
|
|
98
|
+
disposeGroup(group);
|
|
99
|
+
if (worldCache.has(id))
|
|
100
|
+
worldCache.delete(id);
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Apply a {@link WorldPlacement} (translate · Y-rotation · uniform scale) to a group. */
|
|
105
|
+
export function applyPlacement(group, placement) {
|
|
106
|
+
if (placement.position)
|
|
107
|
+
group.position.fromArray(placement.position);
|
|
108
|
+
if (placement.rotationY !== undefined)
|
|
109
|
+
group.rotation.y = placement.rotationY;
|
|
110
|
+
if (placement.scale !== undefined)
|
|
111
|
+
group.scale.setScalar(placement.scale);
|
|
76
112
|
}
|
|
77
113
|
/**
|
|
78
|
-
* Release cached
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* memory unbounded. Safe to call while a group is still in a scene, but detach it from the scene first.
|
|
114
|
+
* Release cached worlds and dispose their geometry + materials (textures are left alone — they may be
|
|
115
|
+
* shared elsewhere). Pass an `id` to drop a single world, or omit it to clear everything. Equivalent
|
|
116
|
+
* to calling `dispose()` on the matching handle(s); use it when you don't hold the handle.
|
|
82
117
|
*/
|
|
83
118
|
export function clearWorldCache(id) {
|
|
84
119
|
const drop = (key, promise) => {
|
|
85
|
-
|
|
86
|
-
void promise.then(disposeGroup).catch(() => { });
|
|
120
|
+
worldCache.delete(key);
|
|
121
|
+
void promise.then((w) => disposeGroup(w.group)).catch(() => { });
|
|
87
122
|
};
|
|
88
123
|
if (id !== undefined) {
|
|
89
|
-
const p =
|
|
124
|
+
const p = worldCache.get(id);
|
|
90
125
|
if (p)
|
|
91
126
|
drop(id, p);
|
|
92
127
|
return;
|
|
93
128
|
}
|
|
94
|
-
for (const [key, p] of
|
|
129
|
+
for (const [key, p] of worldCache)
|
|
95
130
|
drop(key, p);
|
|
96
131
|
}
|
|
97
|
-
/**
|
|
132
|
+
/** Remove a group from its parent and dispose its geometry + materials (not textures). */
|
|
98
133
|
function disposeGroup(group) {
|
|
99
|
-
group.
|
|
134
|
+
group.removeFromParent();
|
|
100
135
|
group.traverse((o) => {
|
|
101
136
|
const mesh = o;
|
|
102
137
|
if (!mesh.isMesh)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world-loader.js","sourceRoot":"","sources":["../../src/three/world-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"world-loader.js","sourceRoot":"","sources":["../../src/three/world-loader.ts"],"names":[],"mappings":"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"}
|