Live GPU inputs, measurements and ropes — engine version 12 Use getGPUCapabilities(): liveBufferTools, gpuQueries and gpuTubes must be true. These functions are available in editor code and through the team relay. Refresh the Game view after deployment; pressing Run alone does not reload its scripts. All functions return Promises. Await when later work depends on their results. Change settings or a small part of a simulation without recreating its state. updateGPUBuffer("experiment", "settings", [0.4, 9.81]); updateGPUBuffer("experiment", "positions", [2, 5, 0], 12); Offsets are scalar entries, so xyz point 4 starts at offset 12. Up to 4096 scalars per write. Values must match the buffer's f32/u32 type. This is for small inputs, not a JavaScript loop copying a million particles every frame. Keep an initial GPU state and restore it without a CPU download. await copyGPUBuffer("experiment", "positions", "initialPositions"); await pauseGPUProgram("experiment"); await copyGPUBuffer("experiment", "initialPositions", "positions"); Optional {offset, destinationOffset, count} selects scalar ranges. Default copies the source remainder. Source/destination are distinct buffers of the same scalar type in one program. This is an in-memory copy, not a saved project checkpoint. Copy every solver state buffer needed for reset; clock/RNG state are separate. Clear or initialize a buffer on the GPU. await fillGPUBuffer("experiment", "velocities", 0); await fillGPUBuffer("experiment", "temperature", 300, {offset: 20, count: 10}); Default fills the buffer remainder from offset 0. u32 needs an unsigned integer. Measure a large f32 buffer without downloading it. var result = await summarizeGPUBuffer("experiment", "energy"); result.sum; result.minimum; result.maximum; result.validCount; result.invalidCount; Optional {offset, count} selects a scalar range. NaN/Infinity values are excluded and counted. All-invalid range returns sum/min/max 0. Float32 summation is not exact arithmetic; use convergence/tolerance checks for scientific claims. GPU reduction returns only 64 partial aggregates, not the original population. Find a point near a cursor target or count points in a detector volume. var hit = await findNearestGPUPoint("experiment", "positions", {x: 0, y: 3, z: 0}); hit.index; hit.distance; var detector = await countGPUPointsInSphere("experiment", "positions", {x: 0, y: 3, z: 0}, 2); detector.matches; Positions must be f32 with components:3, in world coordinates. Nearest ties use the lowest index. No valid point gives index/distance -1. A sphere includes its boundary. Nonfinite positions/distances are ignored. These are point queries, not triangle raycasts or mesh picking; they do not create collision events. Draw a rope, cable or pipe along an ordered xyz path on the GPU. await showGPUTube("cable", "positions", {radius: 0.08, sides: 8, extent: 40}); await styleGPUTube("cable", {tint: {x: 0.5, y: 0.3, z: 0.12}}); await styleGPUTube("cable", {radius: 0.12}); 2..256 path points, 3..16 sides, radius in world units. tint is linear RGB 0..1. One tube per typed program. Open ends, transported frames, simple woven shading, main directional light/ambient and received shadows; no shadow casting yet. extent is a world-space box half-size about the origin; include the whole path. The renderer adds no joints, colliders or Rigidbody and applies no forces. Skin an existing physical joint chain with the same tube. await trackGPURope("cable", "positions", ["anchor", "link1", "link2", "weight"]); await trackGPURope("cable", "positions", []); Use one loaded object name for every path point. Freeze objects while placing them and connecting joints; unfreeze the movable links once setup is complete. freeze() is delivered to a Unity coroutine: allow it to apply before placement. Allow position/scale updates to reach Unity before creating the joints. See the Physics Rope example for separate freeze, place, attach, configure and release steps. These setup waits are not per-frame position overrides. The existing CS createJoint controls physical constraints. Tracking only reads their world positions, uploads the short path in LateUpdate and draws it. Do not also run a GPU kernel writing that tracked positions buffer. Detaching leaves its last path; a removed object automatically detaches the whole chain. Tube thickness is visual: configure physical collider thickness separately. No VBD/AVBD solver, self-collision, tearing or two-way GPU/PhysX coupling is implied. Check typed-buffer memory before the user presses Apply. var budget = await estimateGPUProgram([ {name: "positions", type: "f32", count: 100000, components: 3}, {name: "velocity", type: "f32", count: 100000, components: 3} ]); budget.bytes; budget.remainingBytes; This validates the 128 MiB typed-state budget and four-program limit without allocating. It excludes render scratch/materials/textures/browser overhead and does not reserve capacity; createGPUProgram rechecks availability. Ordering and lifecycle Browser writes/copies and compute dispatches use the shared WebGPU queue. Await a command before relying on its submission order. A query samples at its GPU dispatch; a running simulation can advance while its result travels back. Pause for a reproducible multi-buffer reset or measurement sequence. Rendered changes appear on the next frame. clearRun/removal releases buffers and tubes. The ordinary WebGL player does not gain runtime WGSL from these wrappers. Demonstrations Ten separate GPU Tools drafts cover live inputs, reset copy, fill, summary, nearest point, spherical detector, tube path, joint rope, appearance, and budget. Their complete setup and UI are stored in editor source; no RunPod is needed to play them. They are capability fixtures, not finished educational lessons.