@nodetool-ai/game-renderer 0.8.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.
Files changed (62) hide show
  1. package/dist/.nodetool-build-stamp +1 -0
  2. package/dist/audio.d.ts +39 -0
  3. package/dist/audio.d.ts.map +1 -0
  4. package/dist/audio.js +227 -0
  5. package/dist/audio.js.map +1 -0
  6. package/dist/browser-fonts.d.ts +8 -0
  7. package/dist/browser-fonts.d.ts.map +1 -0
  8. package/dist/browser-fonts.js +39 -0
  9. package/dist/browser-fonts.js.map +1 -0
  10. package/dist/browser.d.ts +31 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +106 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/build.d.ts +19 -0
  15. package/dist/build.d.ts.map +1 -0
  16. package/dist/build.js +236 -0
  17. package/dist/build.js.map +1 -0
  18. package/dist/canvas2d.d.ts +34 -0
  19. package/dist/canvas2d.d.ts.map +1 -0
  20. package/dist/canvas2d.js +208 -0
  21. package/dist/canvas2d.js.map +1 -0
  22. package/dist/fonts.d.ts +5 -0
  23. package/dist/fonts.d.ts.map +1 -0
  24. package/dist/fonts.js +10 -0
  25. package/dist/fonts.js.map +1 -0
  26. package/dist/frame.d.ts +55 -0
  27. package/dist/frame.d.ts.map +1 -0
  28. package/dist/frame.js +123 -0
  29. package/dist/frame.js.map +1 -0
  30. package/dist/gpu-capture.d.ts +4 -0
  31. package/dist/gpu-capture.d.ts.map +1 -0
  32. package/dist/gpu-capture.js +192 -0
  33. package/dist/gpu-capture.js.map +1 -0
  34. package/dist/index.d.ts +43 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +3 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/input.d.ts +3 -0
  39. package/dist/input.d.ts.map +1 -0
  40. package/dist/input.js +16 -0
  41. package/dist/input.js.map +1 -0
  42. package/dist/lighting.d.ts +17 -0
  43. package/dist/lighting.d.ts.map +1 -0
  44. package/dist/lighting.js +79 -0
  45. package/dist/lighting.js.map +1 -0
  46. package/dist/node.d.ts +14 -0
  47. package/dist/node.d.ts.map +1 -0
  48. package/dist/node.js +177 -0
  49. package/dist/node.js.map +1 -0
  50. package/dist/standalone-player.d.ts +2 -0
  51. package/dist/standalone-player.d.ts.map +1 -0
  52. package/dist/standalone-player.js +286 -0
  53. package/dist/standalone-player.js.map +1 -0
  54. package/dist/touch-controls.d.ts +18 -0
  55. package/dist/touch-controls.d.ts.map +1 -0
  56. package/dist/touch-controls.js +136 -0
  57. package/dist/touch-controls.js.map +1 -0
  58. package/dist/webgpu.d.ts +75 -0
  59. package/dist/webgpu.d.ts.map +1 -0
  60. package/dist/webgpu.js +807 -0
  61. package/dist/webgpu.js.map +1 -0
  62. package/package.json +64 -0
package/dist/frame.js ADDED
@@ -0,0 +1,123 @@
1
+ import { gameFontFamily } from "./fonts.js";
2
+ /** A drawing rectangle by pixel center and size, snapped to whole pixels when the item asks for it. */
3
+ export function pixelRect(item, x, y, width, height) {
4
+ if (!item.snap)
5
+ return { x, y, width, height };
6
+ const left = Math.round(x - width / 2);
7
+ const top = Math.round(y - height / 2);
8
+ const snappedWidth = Math.round(x + width / 2) - left;
9
+ const snappedHeight = Math.round(y + height / 2) - top;
10
+ return { x: left + snappedWidth / 2, y: top + snappedHeight / 2, width: snappedWidth, height: snappedHeight };
11
+ }
12
+ /** Camera projection for the sample between the previous and current tick. */
13
+ export function projectedCamera(frame, interpolation) {
14
+ const alpha = Math.max(0, Math.min(1, interpolation));
15
+ return { x: (frame.camera.previousX ?? frame.camera.x) * (1 - alpha) + frame.camera.x * alpha,
16
+ y: (frame.camera.previousY ?? frame.camera.y) * (1 - alpha) + frame.camera.y * alpha, zoom: frame.camera.zoom };
17
+ }
18
+ export function interpolateTint(previous, current, alpha) {
19
+ if (!previous || !current || !/^#[0-9a-fA-F]{6}$/.test(previous) || !/^#[0-9a-fA-F]{6}$/.test(current))
20
+ return current;
21
+ return `#${[1, 3, 5].map((index) => Math.round(Number.parseInt(previous.slice(index, index + 2), 16) * (1 - alpha) +
22
+ Number.parseInt(current.slice(index, index + 2), 16) * alpha).toString(16).padStart(2, "0")).join("")}`;
23
+ }
24
+ export function visibleItems(frame, interpolation, overscanWorld = 0) {
25
+ const alpha = Math.max(0, Math.min(1, interpolation));
26
+ const camera = projectedCamera(frame, alpha);
27
+ const scale = camera.zoom;
28
+ if (!Number.isFinite(scale) || scale <= 0) {
29
+ return [];
30
+ }
31
+ const halfWidth = frame.width / (2 * scale) + overscanWorld;
32
+ const halfHeight = frame.height / (2 * scale) + overscanWorld;
33
+ const items = [];
34
+ function add(item, x, y, width, height, rotation, opacity = item.opacity ?? 1, tint = item.tint, flipX = false, flipY = false, snap = false) {
35
+ const radius = Math.hypot(width, height) / 2;
36
+ if (x + radius < camera.x - halfWidth || x - radius > camera.x + halfWidth ||
37
+ y + radius < camera.y - halfHeight || y - radius > camera.y + halfHeight) {
38
+ return;
39
+ }
40
+ items.push({
41
+ item,
42
+ x,
43
+ y,
44
+ width,
45
+ height,
46
+ rotation,
47
+ assetId: item.assetId,
48
+ frame: item.frame,
49
+ tint: tint && /^#[0-9a-fA-F]{6}$/.test(tint) ? tint : undefined,
50
+ opacity,
51
+ blend: "blend" in item && item.blend === "additive" ? "additive" : "normal",
52
+ sampling: item.sampling ?? "nearest",
53
+ flipX,
54
+ flipY,
55
+ unlit: "unlit" in item && item.unlit === true,
56
+ snap,
57
+ });
58
+ }
59
+ for (const layer of frame.backgrounds ?? []) {
60
+ const time = Math.max(0, frame.tick - 1 + alpha) / 60;
61
+ const period = layer.mode === "mirror" ? 2 : 1;
62
+ const scrollX = layer.scrollRate.x * time;
63
+ const scrollY = layer.scrollRate.y * time;
64
+ const baseX = layer.origin.x + (layer.mode === "none" ? scrollX : scrollX % (layer.width * period)) + camera.x * (1 - layer.parallax.x);
65
+ const baseY = layer.origin.y + (layer.mode === "none" || layer.mode === "repeatX" ? scrollY : scrollY % (layer.height * period)) + camera.y * (1 - layer.parallax.y);
66
+ const minX = layer.mode === "none" ? 0 : Math.floor((camera.x - halfWidth - baseX) / layer.width);
67
+ const maxX = layer.mode === "none" ? 0 : Math.ceil((camera.x + halfWidth - baseX) / layer.width);
68
+ // A repeatX layer tiles sideways only, so a strip of scenery never stacks above itself.
69
+ const tilesY = layer.mode === "repeat" || layer.mode === "mirror";
70
+ const minY = tilesY ? Math.floor((camera.y - halfHeight - baseY) / layer.height) : 0;
71
+ const maxY = tilesY ? Math.ceil((camera.y + halfHeight - baseY) / layer.height) : 0;
72
+ if ((maxX - minX + 1) * (maxY - minY + 1) > 4096)
73
+ throw new Error(`Background ${layer.id} exceeds 4096 visible tiles`);
74
+ for (let iy = minY; iy <= maxY; iy += 1) {
75
+ for (let ix = minX; ix <= maxX; ix += 1) {
76
+ const item = { entityId: layer.id, assetId: layer.assetId,
77
+ x: baseX + ix * layer.width, y: baseY + iy * layer.height, previousX: baseX + ix * layer.width,
78
+ previousY: baseY + iy * layer.height, rotation: 0, scaleX: 1, scaleY: 1,
79
+ width: layer.width, height: layer.height, layer: layer.layer };
80
+ if (layer.frame)
81
+ item.frame = layer.frame;
82
+ if (layer.sampling)
83
+ item.sampling = layer.sampling;
84
+ add(item, item.x, item.y, item.width, item.height, 0, 1, undefined, layer.mode === "mirror" && Math.abs(ix % 2) === 1, layer.mode === "mirror" && Math.abs(iy % 2) === 1, true);
85
+ }
86
+ }
87
+ }
88
+ for (const item of frame.tiles) {
89
+ add(item, item.x, item.y, item.width, item.height, 0, item.opacity ?? 1, item.tint, false, false, true);
90
+ }
91
+ for (const item of frame.sprites) {
92
+ add(item, item.previousX + (item.x - item.previousX) * alpha, item.previousY + (item.y - item.previousY) * alpha, item.width * ((item.previousScaleX ?? item.scaleX) * (1 - alpha) + item.scaleX * alpha), item.height * ((item.previousScaleY ?? item.scaleY) * (1 - alpha) + item.scaleY * alpha), (item.previousRotation ?? item.rotation) * (1 - alpha) + item.rotation * alpha, (item.previousOpacity ?? item.opacity ?? 1) * (1 - alpha) + (item.opacity ?? 1) * alpha, interpolateTint(item.previousTint, item.tint, alpha), item.flipX === true);
93
+ }
94
+ items.sort((a, b) => a.item.layer - b.item.layer);
95
+ return items;
96
+ }
97
+ export function parseTint(tint) {
98
+ if (!tint || !/^#[0-9a-fA-F]{6}$/.test(tint)) {
99
+ return [1, 1, 1];
100
+ }
101
+ return [
102
+ Number.parseInt(tint.slice(1, 3), 16) / 255,
103
+ Number.parseInt(tint.slice(3, 5), 16) / 255,
104
+ Number.parseInt(tint.slice(5, 7), 16) / 255,
105
+ ];
106
+ }
107
+ /** Paint HUD labels in canvas pixels. Coordinates and sizes scale with the output. */
108
+ export function paintHud(context, hud, scale = 1, gameId = "") {
109
+ context.textBaseline = "top";
110
+ context.shadowColor = "rgba(0, 0, 0, 0.6)";
111
+ for (const label of hud) {
112
+ const size = (label.size ?? 16) * scale;
113
+ const family = label.fontId && gameId ? `"${gameFontFamily(gameId, label.fontId)}", ` : "";
114
+ context.font = `600 ${Math.round(size)}px ${family}system-ui, -apple-system, "Segoe UI", sans-serif`;
115
+ context.textAlign = label.align ?? "left";
116
+ context.fillStyle = label.color ?? "#ffffff";
117
+ context.shadowBlur = size / 4;
118
+ context.fillText(label.text, label.x * scale, label.y * scale);
119
+ }
120
+ context.shadowBlur = 0;
121
+ context.textAlign = "left";
122
+ }
123
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { GameRendererEffect } from "./index.js";
2
+ /** Runs browser GPU effect modules on a straight-alpha sRGB Canvas2D capture. */
3
+ export declare function applyGpuEffects(rgba: Uint8ClampedArray, width: number, height: number, effects: readonly GameRendererEffect[], resolveAsset?: (assetId: string) => Promise<Uint8Array | null>, onDiagnostic?: (message: string) => void): Promise<Uint8ClampedArray>;
4
+ //# sourceMappingURL=gpu-capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu-capture.d.ts","sourceRoot":"","sources":["../src/gpu-capture.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAiCrD,iFAAiF;AACjF,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC1F,OAAO,EAAE,SAAS,kBAAkB,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EACtG,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkJtE"}
@@ -0,0 +1,192 @@
1
+ import { colorBrightnessContrastV1, colorCubeLutV1, createDefaultRegistry, createExecutor, createGPUContextFromDevice, createLabeledTexture, createRecipeRunner, filtersGlowV1 } from "@nodetool-ai/gpu/pool";
2
+ import { createNodeGPUDevice } from "@nodetool-ai/gpu/node";
3
+ import { createCanvas, loadImage } from "@napi-rs/canvas";
4
+ import * as d from "typegpu/data";
5
+ const CONVERSION_SHADER = `
6
+ override encodeOutput: bool = true;
7
+ @group(0) @binding(0) var sourceSampler: sampler;
8
+ @group(0) @binding(1) var sourceTexture: texture_2d<f32>;
9
+ struct VertexOutput { @builtin(position) position: vec4f, @location(0) uv: vec2f };
10
+ @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> VertexOutput {
11
+ let positions = array<vec2f, 3>(vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));
12
+ var output: VertexOutput;
13
+ output.position = vec4f(positions[index], 0.0, 1.0);
14
+ output.uv = positions[index] * vec2f(0.5, -0.5) + vec2f(0.5, 0.5);
15
+ return output;
16
+ }
17
+ @fragment fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
18
+ let premul = textureSample(sourceTexture, sourceSampler, input.uv);
19
+ let straight = premul.rgb / max(premul.a, 1.0 / 255.0);
20
+ let linear = select(straight / 12.92, pow((straight + 0.055) / 1.055, vec3f(2.4)),
21
+ straight > vec3f(0.04045));
22
+ let encoded = select(straight * 12.92, 1.055 * pow(straight, vec3f(1.0 / 2.4)) - 0.055,
23
+ straight > vec3f(0.0031308));
24
+ let converted = select(linear, encoded, encodeOutput);
25
+ return vec4f(clamp(converted, vec3f(0.0), vec3f(1.0)) * premul.a, premul.a);
26
+ }`;
27
+ function toLinear(value) {
28
+ return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
29
+ }
30
+ function toSrgb(value) {
31
+ return value <= 0.0031308 ? value * 12.92 : 1.055 * value ** (1 / 2.4) - 0.055;
32
+ }
33
+ /** Runs browser GPU effect modules on a straight-alpha sRGB Canvas2D capture. */
34
+ export async function applyGpuEffects(rgba, width, height, effects, resolveAsset, onDiagnostic) {
35
+ const device = await createNodeGPUDevice();
36
+ device.pushErrorScope("validation");
37
+ let validationScopeOpen = true;
38
+ const ctx = createGPUContextFromDevice(device);
39
+ const executor = createExecutor();
40
+ const runner = createRecipeRunner();
41
+ const registry = createDefaultRegistry();
42
+ const usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
43
+ const source = createLabeledTexture(device, { width, height, format: "rgba8unorm", usage, label: "game-capture-source" });
44
+ const target = createLabeledTexture(device, { width, height, format: "rgba8unorm", usage, label: "game-capture-target" });
45
+ const srgbSource = effects.some((effect) => effect.kind === "lut") ? createLabeledTexture(device, {
46
+ width, height, format: "rgba8unorm", usage, label: "game-capture-srgb-source", meta: { colorSpace: "srgb" }
47
+ }) : undefined;
48
+ const srgbTarget = effects.some((effect) => effect.kind === "lut") ? createLabeledTexture(device, {
49
+ width, height, format: "rgba8unorm", usage, label: "game-capture-srgb-target", meta: { colorSpace: "srgb" }
50
+ }) : undefined;
51
+ const lutTextures = [];
52
+ const module = device.createShaderModule({ code: CONVERSION_SHADER });
53
+ const layout = device.createBindGroupLayout({ entries: [
54
+ { binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
55
+ { binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float" } }
56
+ ] });
57
+ const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [layout] });
58
+ const pipeline = (encodeOutput) => device.createRenderPipeline({
59
+ layout: pipelineLayout,
60
+ vertex: { module, entryPoint: "vertexMain" },
61
+ fragment: { module, entryPoint: "fragmentMain", constants: { encodeOutput: encodeOutput ? 1 : 0 }, targets: [{ format: "rgba8unorm" }] },
62
+ primitive: { topology: "triangle-list" }
63
+ });
64
+ const toSrgbPipeline = pipeline(true);
65
+ const toLinearPipeline = pipeline(false);
66
+ const sampler = device.createSampler({ magFilter: "nearest", minFilter: "nearest" });
67
+ const convert = (encoder, input, output, conversion) => {
68
+ const group = device.createBindGroup({ layout, entries: [
69
+ { binding: 0, resource: sampler }, { binding: 1, resource: input.createView() }
70
+ ] });
71
+ const pass = encoder.beginRenderPass({ colorAttachments: [{ view: output.createView(), loadOp: "clear", storeOp: "store",
72
+ clearValue: { r: 0, g: 0, b: 0, a: 0 } }] });
73
+ pass.setPipeline(conversion);
74
+ pass.setBindGroup(0, group);
75
+ pass.draw(3);
76
+ pass.end();
77
+ };
78
+ const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
79
+ const readback = device.createBuffer({ size: bytesPerRow * height, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ });
80
+ try {
81
+ const linear = new Uint8Array(width * height * 4);
82
+ for (let index = 0; index < rgba.length; index += 4) {
83
+ const alpha = (rgba[index + 3] ?? 0) / 255;
84
+ linear[index] = Math.round(toLinear((rgba[index] ?? 0) / 255) * alpha * 255);
85
+ linear[index + 1] = Math.round(toLinear((rgba[index + 1] ?? 0) / 255) * alpha * 255);
86
+ linear[index + 2] = Math.round(toLinear((rgba[index + 2] ?? 0) / 255) * alpha * 255);
87
+ linear[index + 3] = rgba[index + 3] ?? 0;
88
+ }
89
+ device.queue.writeTexture({ texture: source.texture }, linear, { bytesPerRow: width * 4 }, [width, height]);
90
+ const encoder = device.createCommandEncoder();
91
+ let input = source;
92
+ let output = target;
93
+ ctx.uniformRing.beginSubmission();
94
+ for (const effect of effects) {
95
+ if (effect.kind === "brightnessContrast") {
96
+ executor.encode({ ctx, module: colorBrightnessContrastV1, encoder, inputs: { source: input }, output,
97
+ params: { brightness: effect.brightness, contrast: effect.contrast }, dispatch: { kind: "fragment" } });
98
+ }
99
+ else if (effect.kind === "bloom") {
100
+ runner.encode({ ctx, module: filtersGlowV1, registry, executor, encoder, inputs: { source: input }, output,
101
+ params: { threshold: effect.threshold, softness: effect.softness, radius: effect.radius, intensity: effect.intensity } });
102
+ }
103
+ else {
104
+ if (!srgbSource || !srgbTarget)
105
+ throw new Error("LUT capture targets are missing");
106
+ let lutPixels;
107
+ let lutWidth;
108
+ let lutHeight;
109
+ try {
110
+ const bytes = await resolveAsset?.(effect.assetId);
111
+ if (!bytes)
112
+ throw new Error(`LUT ${effect.assetId} is missing`);
113
+ const image = await loadImage(Buffer.from(bytes));
114
+ if (image.width !== effect.size * effect.size || image.height !== effect.size) {
115
+ throw new Error(`LUT ${effect.assetId} has invalid dimensions`);
116
+ }
117
+ const canvas = createCanvas(image.width, image.height);
118
+ const context = canvas.getContext("2d");
119
+ context.drawImage(image, 0, 0);
120
+ lutPixels = context.getImageData(0, 0, image.width, image.height).data;
121
+ for (let index = 3; index < lutPixels.length; index += 4) {
122
+ if (lutPixels[index] !== 255)
123
+ throw new Error(`LUT ${effect.assetId} must be opaque`);
124
+ }
125
+ lutWidth = image.width;
126
+ lutHeight = image.height;
127
+ }
128
+ catch (error) {
129
+ if (effect.required)
130
+ throw error;
131
+ onDiagnostic?.(`Optional LUT ${effect.assetId} omitted: ${error instanceof Error ? error.message : String(error)}`);
132
+ continue;
133
+ }
134
+ const lut = createLabeledTexture(device, { width: lutWidth, height: lutHeight, format: "rgba8unorm",
135
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST, label: `game-capture-lut-${effect.assetId}`,
136
+ meta: { colorSpace: "srgb" } });
137
+ lutTextures.push(lut.texture);
138
+ device.queue.writeTexture({ texture: lut.texture }, lutPixels, { bytesPerRow: lutWidth * 4 }, [lutWidth, lutHeight]);
139
+ convert(encoder, input.texture, srgbSource.texture, toSrgbPipeline);
140
+ srgbSource.markWritten();
141
+ executor.encode({ ctx, module: colorCubeLutV1, encoder, inputs: { source: srgbSource, lut }, output: srgbTarget,
142
+ params: { size: effect.size, intensity: effect.intensity,
143
+ domainMin: d.vec4f(...effect.domainMin, 0), domainMax: d.vec4f(...effect.domainMax, 0) },
144
+ dispatch: { kind: "fragment" } });
145
+ convert(encoder, srgbTarget.texture, output.texture, toLinearPipeline);
146
+ output.markWritten();
147
+ }
148
+ [input, output] = [output, input];
149
+ }
150
+ encoder.copyTextureToBuffer({ texture: input.texture }, { buffer: readback, bytesPerRow }, [width, height]);
151
+ device.queue.submit([encoder.finish()]);
152
+ await readback.mapAsync(GPUMapMode.READ);
153
+ const validationError = await device.popErrorScope();
154
+ validationScopeOpen = false;
155
+ if (validationError) {
156
+ throw new Error(`GPU capture failed: ${validationError.message}`);
157
+ }
158
+ const mapped = new Uint8Array(readback.getMappedRange());
159
+ const result = new Uint8ClampedArray(width * height * 4);
160
+ for (let y = 0; y < height; y += 1) {
161
+ for (let x = 0; x < width; x += 1) {
162
+ const index = (y * width + x) * 4;
163
+ const offset = y * bytesPerRow + x * 4;
164
+ const alpha = (mapped[offset + 3] ?? 0) / 255;
165
+ for (let channel = 0; channel < 3; channel += 1) {
166
+ const straight = alpha > 0 ? (mapped[offset + channel] ?? 0) / 255 / alpha : 0;
167
+ result[index + channel] = Math.round(Math.max(0, Math.min(1, toSrgb(straight))) * 255);
168
+ }
169
+ result[index + 3] = mapped[offset + 3] ?? 0;
170
+ }
171
+ }
172
+ return result;
173
+ }
174
+ finally {
175
+ if (validationScopeOpen) {
176
+ await device.popErrorScope();
177
+ }
178
+ readback.unmap();
179
+ readback.destroy();
180
+ source.destroy();
181
+ target.destroy();
182
+ srgbSource?.destroy();
183
+ srgbTarget?.destroy();
184
+ for (const texture of lutTextures)
185
+ texture.destroy();
186
+ ctx.scratch.dispose();
187
+ ctx.uniformRing.dispose();
188
+ ctx.root.destroy();
189
+ device.destroy();
190
+ }
191
+ }
192
+ //# sourceMappingURL=gpu-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu-capture.js","sourceRoot":"","sources":["../src/gpu-capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { GameRenderEffect, GameRenderFrame } from "@nodetool-ai/protocol";
2
+ export { gameKeyAction } from "./input.js";
3
+ export { projectedCamera } from "./frame.js";
4
+ export type GameRendererBackend = "webgpu" | "canvas2d";
5
+ export type GameRendererEffect = GameRenderEffect;
6
+ export type GameHudEffectOrder = "beforeEffects" | "afterEffects";
7
+ export interface GameRendererCapabilities {
8
+ readonly backend: GameRendererBackend;
9
+ readonly core2D: true;
10
+ readonly gpuEffects: boolean;
11
+ readonly lighting: boolean;
12
+ readonly adapterType: "hardware" | "software" | "unknown";
13
+ readonly deviceStatus: "ready" | "lost" | "disposed";
14
+ readonly enabledFeatures: readonly string[];
15
+ readonly requestedFeatures: readonly string[];
16
+ readonly limits: {
17
+ readonly maxTextureDimension2D: number;
18
+ readonly maxBufferSize: number;
19
+ } | null;
20
+ readonly minimalRenderSucceeded: boolean;
21
+ readonly deviceLossCount: number;
22
+ readonly fallbackReason: string | null;
23
+ }
24
+ export interface GameRendererStats {
25
+ readonly backend: GameRendererBackend;
26
+ readonly visibleSprites: number;
27
+ readonly drawCalls: number;
28
+ readonly uploadedBytes: number;
29
+ readonly textureBytes: number;
30
+ readonly targetBytes: number;
31
+ readonly instanceBufferBytes: number;
32
+ }
33
+ export interface GameRenderer {
34
+ readonly backend: GameRendererBackend;
35
+ readonly canvas: HTMLCanvasElement;
36
+ readonly capabilities: GameRendererCapabilities;
37
+ render(frame: GameRenderFrame, interpolation: number): Promise<GameRendererStats>;
38
+ setEffects(effects: readonly GameRendererEffect[], hudOrder?: GameHudEffectOrder): void;
39
+ resize(width: number, height: number): void;
40
+ invalidateAsset(assetId: string): void;
41
+ dispose(): void;
42
+ }
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAClD,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,cAAc,CAAC;AAElE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;IACrD,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnG,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,wBAAwB,CAAC;IAChD,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClF,UAAU,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EAAE,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACxF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,OAAO,IAAI,IAAI,CAAC;CACjB"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { gameKeyAction } from "./input.js";
2
+ export { projectedCamera } from "./frame.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Map a physical key to the action name used by native game documents. */
2
+ export declare function gameKeyAction(code: string, key: string): string;
3
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAS/D"}
package/dist/input.js ADDED
@@ -0,0 +1,16 @@
1
+ /** Map a physical key to the action name used by native game documents. */
2
+ export function gameKeyAction(code, key) {
3
+ switch (code) {
4
+ case "ArrowLeft":
5
+ case "KeyA": return "left";
6
+ case "ArrowRight":
7
+ case "KeyD": return "right";
8
+ case "ArrowUp":
9
+ case "KeyW": return "up";
10
+ case "ArrowDown":
11
+ case "KeyS": return "down";
12
+ case "Space": return "space";
13
+ default: return key.toLowerCase();
14
+ }
15
+ }
16
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,GAAW;IACrD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,MAAM,CAAC;QAC7C,KAAK,YAAY,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,OAAO,CAAC;QAC/C,KAAK,SAAS,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,IAAI,CAAC;QACzC,KAAK,WAAW,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,MAAM,CAAC;QAC7C,KAAK,OAAO,EAAE,OAAO,OAAO,CAAC;QAC7B,SAAS,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { GameRenderFrame } from "@nodetool-ai/protocol";
2
+ export interface PixelBounds {
3
+ readonly x: number;
4
+ readonly y: number;
5
+ readonly width: number;
6
+ readonly height: number;
7
+ }
8
+ /** Conservative raster bounds for one rotated sprite, clipped to the viewport. */
9
+ export declare function spritePixelBounds(x: number, y: number, width: number, height: number, rotation: number, viewportWidth: number, viewportHeight: number): PixelBounds | null;
10
+ /** Multiplies world pixels by ambient and point-light irradiance without changing alpha. */
11
+ export declare function applyLighting(pixels: Uint8ClampedArray, width: number, height: number, frame: GameRenderFrame, interpolation: number, region?: {
12
+ readonly viewportWidth: number;
13
+ readonly viewportHeight: number;
14
+ readonly x: number;
15
+ readonly y: number;
16
+ }): void;
17
+ //# sourceMappingURL=lighting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighting.d.ts","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,MAAM,WAAW,WAAW;IAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAExH,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EACrG,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAUnE;AAkBD,4FAA4F;AAC5F,wBAAgB,aAAa,CAC3B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GACnH,IAAI,CA8CN"}
@@ -0,0 +1,79 @@
1
+ import { parseTint, projectedCamera } from "./frame.js";
2
+ /** Conservative raster bounds for one rotated sprite, clipped to the viewport. */
3
+ export function spritePixelBounds(x, y, width, height, rotation, viewportWidth, viewportHeight) {
4
+ const cosine = Math.abs(Math.cos(rotation));
5
+ const sine = Math.abs(Math.sin(rotation));
6
+ const halfWidth = (cosine * width + sine * height) / 2;
7
+ const halfHeight = (sine * width + cosine * height) / 2;
8
+ const left = Math.max(0, Math.floor(x - halfWidth - 1));
9
+ const top = Math.max(0, Math.floor(y - halfHeight - 1));
10
+ const right = Math.min(viewportWidth, Math.ceil(x + halfWidth + 1));
11
+ const bottom = Math.min(viewportHeight, Math.ceil(y + halfHeight + 1));
12
+ return right > left && bottom > top ? { x: left, y: top, width: right - left, height: bottom - top } : null;
13
+ }
14
+ const LINEAR_FROM_BYTE = Float32Array.from({ length: 256 }, (_, value) => {
15
+ const color = value / 255;
16
+ return color <= 0.04045 ? color / 12.92 : ((color + 0.055) / 1.055) ** 2.4;
17
+ });
18
+ const BYTE_FROM_LINEAR = Uint8Array.from({ length: 4097 }, (_, index) => {
19
+ const color = index / 4096;
20
+ return Math.round((color <= 0.0031308 ? color * 12.92 : 1.055 * color ** (1 / 2.4) - 0.055) * 255);
21
+ });
22
+ function linearColor(color) {
23
+ const channels = parseTint(color);
24
+ return [LINEAR_FROM_BYTE[Math.round(channels[0] * 255)],
25
+ LINEAR_FROM_BYTE[Math.round(channels[1] * 255)],
26
+ LINEAR_FROM_BYTE[Math.round(channels[2] * 255)]];
27
+ }
28
+ /** Multiplies world pixels by ambient and point-light irradiance without changing alpha. */
29
+ export function applyLighting(pixels, width, height, frame, interpolation, region) {
30
+ const lighting = frame.lighting;
31
+ if (!lighting)
32
+ return;
33
+ const camera = projectedCamera(frame, interpolation);
34
+ const viewportWidth = region?.viewportWidth ?? width;
35
+ const viewportHeight = region?.viewportHeight ?? height;
36
+ const originX = region?.x ?? 0;
37
+ const originY = region?.y ?? 0;
38
+ const scaleX = viewportWidth / frame.width * camera.zoom;
39
+ const scaleY = viewportHeight / frame.height * camera.zoom;
40
+ const ambient = linearColor(lighting.ambient.color);
41
+ const irradiance = new Float32Array(width * height * 3);
42
+ for (let index = 0; index < irradiance.length; index += 3) {
43
+ irradiance[index] = ambient[0] * lighting.ambient.intensity;
44
+ irradiance[index + 1] = ambient[1] * lighting.ambient.intensity;
45
+ irradiance[index + 2] = ambient[2] * lighting.ambient.intensity;
46
+ }
47
+ for (const point of lighting.points) {
48
+ const centerX = viewportWidth / 2 + (point.x - camera.x) * scaleX;
49
+ const centerY = viewportHeight / 2 - (point.y - camera.y) * scaleY;
50
+ const firstX = Math.max(0, Math.ceil(centerX - point.radius * scaleX - 0.5) - originX);
51
+ const lastX = Math.min(width - 1, Math.floor(centerX + point.radius * scaleX - 0.5) - originX);
52
+ const firstY = Math.max(0, Math.ceil(centerY - point.radius * scaleY - 0.5) - originY);
53
+ const lastY = Math.min(height - 1, Math.floor(centerY + point.radius * scaleY - 0.5) - originY);
54
+ const color = linearColor(point.color);
55
+ for (let y = firstY; y <= lastY; y += 1) {
56
+ const dy = (y + originY + 0.5 - centerY) / scaleY;
57
+ for (let x = firstX; x <= lastX; x += 1) {
58
+ const dx = (x + originX + 0.5 - centerX) / scaleX;
59
+ const distance = Math.hypot(dx, dy);
60
+ if (distance >= point.radius)
61
+ continue;
62
+ const amount = point.intensity * (1 - distance / point.radius) ** point.falloff;
63
+ const index = (y * width + x) * 3;
64
+ irradiance[index] += color[0] * amount;
65
+ irradiance[index + 1] += color[1] * amount;
66
+ irradiance[index + 2] += color[2] * amount;
67
+ }
68
+ }
69
+ }
70
+ for (let index = 0, lightIndex = 0; index < pixels.length; index += 4, lightIndex += 3) {
71
+ if (pixels[index + 3] === 0)
72
+ continue;
73
+ for (let channel = 0; channel < 3; channel += 1) {
74
+ const linear = Math.min(1, LINEAR_FROM_BYTE[pixels[index + channel]] * irradiance[lightIndex + channel]);
75
+ pixels[index + channel] = BYTE_FROM_LINEAR[Math.round(linear * 4096)];
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=lighting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighting.js","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIxD,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,CAAS,EAAE,KAAa,EAAE,MAAc,EAAE,QAAgB,EACrG,aAAqB,EAAE,cAAsB;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,OAAO,KAAK,GAAG,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9G,CAAC;AAED,MAAM,gBAAgB,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;IAC1B,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC;AAC7E,CAAC,CAAC,CAAC;AACH,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;IACtE,MAAM,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;IAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;AACrG,CAAC,CAAC,CAAC;AAEH,SAAS,WAAW,CAAC,KAAa;IAChC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QACrD,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAC/C,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,aAAa,CAC3B,MAAyB,EACzB,KAAa,EACb,MAAc,EACd,KAAsB,EACtB,aAAqB,EACrB,MAAoH;IAEpH,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,KAAK,CAAC;IACrD,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,MAAM,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;IACzD,MAAM,MAAM,GAAG,cAAc,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;IAC3D,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;IACxD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1D,UAAU,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QAC5D,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QAChE,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;IAClE,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,aAAa,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QAClE,MAAM,OAAO,GAAG,cAAc,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QACvF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QACvF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAChG,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,MAAM,CAAC;YAClD,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,MAAM,CAAC;gBAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACpC,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM;oBAAE,SAAS;gBACvC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC;gBAChF,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;gBACvC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;gBAC3C,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,UAAU,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;QACvF,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;YAAE,SAAS;QACtC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,UAAU,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;YACzG,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;AACH,CAAC"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { GameRenderFrame } from "@nodetool-ai/protocol";
2
+ import type { GameHudEffectOrder, GameRendererEffect } from "./index.js";
3
+ export interface CaptureGameFrameOptions {
4
+ readonly resolveAsset?: (assetId: string) => Promise<Uint8Array | null>;
5
+ readonly interpolation?: number;
6
+ readonly scale?: number;
7
+ readonly onDiagnostic?: (message: string) => void;
8
+ readonly backend?: "canvas2d" | "webgpu";
9
+ readonly effects?: readonly GameRendererEffect[];
10
+ readonly hudEffectOrder?: GameHudEffectOrder;
11
+ }
12
+ /** Renders one frame to PNG with an explicit Canvas2D or GPU effect path. */
13
+ export declare function captureGameFrame(frame: GameRenderFrame, options?: CaptureGameFrameOptions): Promise<Uint8Array>;
14
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACjD,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAC;CAC9C;AAED,6EAA6E;AAC7E,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,UAAU,CAAC,CA8JzH"}