@needle-tools/engine 5.1.9 → 5.1.11

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 (105) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/SKILL.md +64 -4
  3. package/components.needle.json +1 -1
  4. package/dist/{needle-engine.bundle-CHq9xqXv.min.js → needle-engine.bundle-d-dLyN3s.min.js} +137 -136
  5. package/dist/{needle-engine.bundle-DYPk7VZg.umd.cjs → needle-engine.bundle-n5YALNtc.umd.cjs} +140 -139
  6. package/dist/{needle-engine.bundle-XZ6cKssu.js → needle-engine.bundle-ue2Lw4bF.js} +5267 -5101
  7. package/dist/needle-engine.d.ts +138 -26
  8. package/dist/needle-engine.js +522 -518
  9. package/dist/needle-engine.min.js +1 -1
  10. package/dist/needle-engine.umd.cjs +1 -1
  11. package/dist/three-examples.js +727 -781
  12. package/dist/three-examples.min.js +12 -12
  13. package/dist/three-examples.umd.cjs +9 -9
  14. package/lib/engine/api.d.ts +1 -1
  15. package/lib/engine/api.js +1 -1
  16. package/lib/engine/api.js.map +1 -1
  17. package/lib/engine/engine_init.js +2 -2
  18. package/lib/engine/engine_init.js.map +1 -1
  19. package/lib/engine/engine_license.d.ts +7 -7
  20. package/lib/engine/engine_license.js +71 -71
  21. package/lib/engine/engine_license.js.map +1 -1
  22. package/lib/engine/engine_materialpropertyblock.d.ts +13 -4
  23. package/lib/engine/engine_materialpropertyblock.js +16 -5
  24. package/lib/engine/engine_materialpropertyblock.js.map +1 -1
  25. package/lib/engine/engine_math.d.ts +13 -0
  26. package/lib/engine/engine_math.js +17 -0
  27. package/lib/engine/engine_math.js.map +1 -1
  28. package/lib/engine/engine_networking_blob.js +3 -3
  29. package/lib/engine/engine_networking_blob.js.map +1 -1
  30. package/lib/engine/engine_utils_qrcode.js +2 -2
  31. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  32. package/lib/engine/postprocessing/postprocessing.d.ts +18 -0
  33. package/lib/engine/postprocessing/postprocessing.js +31 -2
  34. package/lib/engine/postprocessing/postprocessing.js.map +1 -1
  35. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  36. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  37. package/lib/engine/webcomponents/needle menu/needle-menu.js +5 -5
  38. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  39. package/lib/engine/webcomponents/needle-engine.js +2 -2
  40. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  41. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  42. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  43. package/lib/engine/xr/TempXRContext.js +2 -2
  44. package/lib/engine/xr/TempXRContext.js.map +1 -1
  45. package/lib/engine/xr/XRHandMeshModel.d.ts +31 -0
  46. package/lib/engine/xr/XRHandMeshModel.js +153 -0
  47. package/lib/engine/xr/XRHandMeshModel.js.map +1 -0
  48. package/lib/engine-components/DragControls.d.ts +0 -5
  49. package/lib/engine-components/DragControls.js +0 -8
  50. package/lib/engine-components/DragControls.js.map +1 -1
  51. package/lib/engine-components/ReflectionProbe.js +3 -3
  52. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  53. package/lib/engine-components/RendererInstancing.d.ts +34 -3
  54. package/lib/engine-components/RendererInstancing.js +92 -11
  55. package/lib/engine-components/RendererInstancing.js.map +1 -1
  56. package/lib/engine-components/RendererLightmap.js +1 -1
  57. package/lib/engine-components/RendererLightmap.js.map +1 -1
  58. package/lib/engine-components/SyncedRoom.js +5 -0
  59. package/lib/engine-components/SyncedRoom.js.map +1 -1
  60. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  61. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  62. package/lib/engine-components/postprocessing/Effects/DepthOfField.js +10 -2
  63. package/lib/engine-components/postprocessing/Effects/DepthOfField.js.map +1 -1
  64. package/lib/engine-components/postprocessing/index.d.ts +4 -0
  65. package/lib/engine-components/postprocessing/index.js +7 -0
  66. package/lib/engine-components/postprocessing/index.js.map +1 -1
  67. package/lib/engine-components/splines/SplineWalker.js +9 -3
  68. package/lib/engine-components/splines/SplineWalker.js.map +1 -1
  69. package/lib/engine-components/utils/LookAt.d.ts +13 -4
  70. package/lib/engine-components/utils/LookAt.js +13 -4
  71. package/lib/engine-components/utils/LookAt.js.map +1 -1
  72. package/lib/engine-components/webxr/WebXR.js +1 -1
  73. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  74. package/lib/engine-components/webxr/controllers/XRControllerModel.d.ts +1 -1
  75. package/lib/engine-components/webxr/controllers/XRControllerModel.js +12 -7
  76. package/lib/engine-components/webxr/controllers/XRControllerModel.js.map +1 -1
  77. package/package.json +2 -2
  78. package/plugins/common/license.js +4 -4
  79. package/plugins/vite/license.js +4 -4
  80. package/src/engine/api.ts +1 -1
  81. package/src/engine/engine_init.ts +2 -2
  82. package/src/engine/engine_license.ts +68 -68
  83. package/src/engine/engine_materialpropertyblock.ts +17 -5
  84. package/src/engine/engine_math.ts +17 -0
  85. package/src/engine/engine_networking_blob.ts +3 -3
  86. package/src/engine/engine_utils_qrcode.ts +2 -2
  87. package/src/engine/postprocessing/postprocessing.ts +32 -2
  88. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  89. package/src/engine/webcomponents/needle menu/needle-menu.ts +5 -5
  90. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  91. package/src/engine/webcomponents/needle-engine.ts +2 -2
  92. package/src/engine/xr/TempXRContext.ts +2 -2
  93. package/src/engine/xr/XRHandMeshModel.ts +179 -0
  94. package/src/engine-components/DragControls.ts +0 -7
  95. package/src/engine-components/ReflectionProbe.ts +3 -3
  96. package/src/engine-components/RendererInstancing.ts +92 -11
  97. package/src/engine-components/RendererLightmap.ts +1 -1
  98. package/src/engine-components/SyncedRoom.ts +5 -0
  99. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
  100. package/src/engine-components/postprocessing/Effects/DepthOfField.ts +10 -2
  101. package/src/engine-components/postprocessing/index.ts +7 -0
  102. package/src/engine-components/splines/SplineWalker.ts +9 -3
  103. package/src/engine-components/utils/LookAt.ts +13 -4
  104. package/src/engine-components/webxr/WebXR.ts +1 -1
  105. package/src/engine-components/webxr/controllers/XRControllerModel.ts +13 -7
package/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [5.1.11] - 2026-08-13
8
+ - Fix: mirrored and negatively-scaled instanced meshes now render correctly (NE-7069)
9
+
10
+ ## [5.1.10] - 2026-08-07
11
+ - Add: turn the whole postprocessing stack on or off at runtime with `PostProcessing.enabled`
12
+ - Fix: scene brightness no longer shifts when XR hand models are shown or hidden
13
+ - Fix: the `showHandModels` toggle now reliably shows or hides XR hand models
14
+ - Change: `SyncedRoom` warns (in development) when a room-name URL parameter overrides the `roomName` set on the component, making it easier to diagnose ending up in an unexpected room
15
+
7
16
  ## [5.1.9] - 2026-07-30
8
17
  **Added**
9
18
  - `WebXRImageTracking`: friendlier `addImage` API for registering marker images
package/SKILL.md CHANGED
@@ -13,7 +13,10 @@ description: >
13
13
  or error without mentioning Needle Engine — check if @needle-tools/engine is in
14
14
  package.json or imports. If the project uses Needle Engine, always load this skill.
15
15
  compatibility:
16
- - optional: needle_search MCP tool (search Needle Engine docs, forum posts, and community answers)
16
+ - optional: >
17
+ needle_search MCP tool (search Needle Engine docs, forum posts, and community answers).
18
+ Without it, the same corpus is reachable over HTTP at
19
+ https://search.needle.tools/api/semantic-search?q=... (public, no key) — see references/mcp.md
17
20
  ---
18
21
 
19
22
  # Needle Engine
@@ -47,6 +50,33 @@ export class HelloWorld extends Behaviour {
47
50
 
48
51
  > ⚠️ **TypeScript config required:** `tsconfig.json` must have `"experimentalDecorators": true` and `"useDefineForClassFields": false` for decorators to work. Without `useDefineForClassFields: false`, TypeScript overwrites `@serializable()` properties with their default values *after* the decorator runs, silently breaking deserialization.
49
52
 
53
+ On **5.1+**, scenes expose auto-generated typed bindings, and `needle` gives you the context from
54
+ anywhere — often shorter than `getComponent` lookups:
55
+ ```ts
56
+ import { needle, onStart } from "@needle-tools/engine";
57
+
58
+ // `needle` resolves to the current context when the handler runs — no wrapper needed
59
+ button.onclick = () => {
60
+ needle.sceneData.MyScene.MainCamera.$components.OrbitControls.autoRotate = false;
61
+ };
62
+
63
+ // Without it, you'd wrap the wiring in onStart purely to capture a ctx:
64
+ onStart(ctx => {
65
+ button.onclick = () => {
66
+ ctx.sceneData.MyScene.MainCamera.$components.OrbitControls.autoRotate = false;
67
+ };
68
+ });
69
+ ```
70
+ `onStart(ctx => …)` is still the right tool for setup that must run once the scene is ready —
71
+ `needle` is for reaching the context from code that runs later.
72
+ > ⚠️ **Don't touch `needle` at module top-level.** It's a lazy Proxy resolving to the *current*
73
+ > context — module bodies evaluate before any scene exists, so it logs an error and returns a
74
+ > no-op proxy. Use it inside callbacks and event handlers; use `onStart(ctx => …)` for setup.
75
+ > (Importing it at top level is fine, including under SSR — only *access* is the problem.)
76
+
77
+ Components need `$components`; bare names are child nodes. Both APIs are experimental — see
78
+ [What's New](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/whats-new.md).
79
+
50
80
  ---
51
81
 
52
82
  ## Key Concepts
@@ -137,7 +167,9 @@ Boolean attributes can be disabled with `="0"` (e.g. `camera-controls="0"`).
137
167
  | `background-color` | Hex or RGB background color (e.g. `#ff0000`) |
138
168
  | `background-image` | Skybox URL or preset: `studio`, `blurred-skybox`, `quicklook`, `quicklook-ar` |
139
169
  | `background-blurriness` | Blur intensity for background (0–1) |
170
+ | `background-rotation` | Rotate the background skybox (5.1+) |
140
171
  | `environment-image` | Environment lighting image URL or preset (same presets as `background-image`) |
172
+ | `environment-rotation` | Rotate the environment lighting (5.1+) |
141
173
  | `contactshadows` | Enable contact shadows |
142
174
  | `tone-mapping` | `none`, `linear`, `neutral`, `agx` |
143
175
  | `poster` | Placeholder image URL shown while loading |
@@ -245,6 +277,13 @@ export default defineConfig(async ({ command }) => ({
245
277
  }));
246
278
  ```
247
279
 
280
+ As of 5.1, `needlePlugins()` resolves the Vite command itself, so it can be called with no
281
+ arguments and without `await`/spread — handy when composing with other framework plugins:
282
+ ```js
283
+ export default defineConfig({ plugins: [sveltekit(), needlePlugins()] });
284
+ ```
285
+ Still pass `(command, config, settings)` when you need options like `makeFilesLocal`.
286
+
248
287
  ---
249
288
 
250
289
  ## `needle.config.json`
@@ -375,7 +414,9 @@ Use this when you need exact method signatures, constructor parameters, or prope
375
414
 
376
415
  ## Searching the Documentation
377
416
 
378
- Use the `needle_search` MCP tool to find relevant docs, forum posts, and community answers:
417
+ Search the docs *before* guessing at API details — they are the source of truth. The corpus covers Needle Engine documentation, the API reference, the community forum, Discord, and Needle source code.
418
+
419
+ **If the `needle_search` MCP tool is available, use it:**
379
420
 
380
421
  ```
381
422
  needle_search("how to play animation clip from code")
@@ -383,12 +424,25 @@ needle_search("SyncedTransform multiplayer")
383
424
  needle_search("deploy to Needle Cloud CI")
384
425
  ```
385
426
 
386
- Use this *before* guessing at API details the docs are the source of truth.
427
+ **Otherwise, hit the public search API — no key, no setup:**
428
+
429
+ ```bash
430
+ curl -s -H "Accept: application/json" \
431
+ "https://search.needle.tools/api/semantic-search?q=how+to+play+animation+clip+from+code&limit=5"
432
+ ```
433
+
434
+ Returns JSON `{ query, results: [{ title, source, content, url, score, truncated }], durationMs }`. Optional `limit` (1–20, default 10) and `max_chars` (200–10000, default 2000). Rate-limited to 10 requests/minute for unauthenticated callers.
435
+
436
+ Both are **semantic** search — phrase queries as full questions ("how do I make an object follow the camera in VR"), not keyword soup ("vr camera follow"). Result `url`s include a `#:~:text=` fragment linking to the exact passage; pass them on to the user.
437
+
438
+ See 🔌 [MCP & Search API](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/mcp.md) for the full tool inventory — project file access, live scene inspection via the Needle Inspector, Unity/Blender tools — and for MCP server setup.
387
439
 
388
440
  ---
389
441
 
390
442
  ## Common Gotchas
391
443
 
444
+ - **Scene Bindings: bare names are child nodes, components need `$components`.** `ctx.sceneData.MyGlb.Camera.OrbitControls` looks for a child *object* named OrbitControls; the component is `ctx.sceneData.MyGlb.Camera.$components.OrbitControls`. Worse, misses don't throw — they return an error proxy that swallows every get/set and only warns. If a scene-bindings assignment appears to run but changes nothing, check the console for `[SceneData]`.
445
+ - **`autoCleanup`'s teardown timing depends on where you call it.** In `onEnable` → cleaned on disable. In `awake`/`start` → cleaned on destroy, so it survives disable/enable. Registering a subscription in `start()` and expecting it to stop when the component is disabled is the common mistake.
392
446
  - **`obj.visible = false` disables components!** Setting `visible = false` on a parent disables the entire hierarchy including component lifecycle (SyncedTransform, etc.) — like Unity's `setActive`. To hide visually but keep components running, hide child meshes instead: `obj.traverse(c => { if (c.isMesh) c.visible = false; })`. Or use `Renderer.setVisible(obj, false)` which only affects rendering.
393
447
  - `@registerType` is required or the component won't be instantiated from GLB. Unity/Blender export adds this automatically via codegen; hand-written components need it explicitly.
394
448
  - GLB assets go in `assets/`, static files (fonts, images, videos) in `public/` (configurable via `needle.config.json`)
@@ -406,6 +460,7 @@ Use this *before* guessing at API details — the docs are the source of truth.
406
460
  - WebXR requires HTTPS — the Needle project templates include a local HTTPS dev server by default. Use `--host` when running the dev server (e.g. `npx vite --host`) to expose it on your local network IP, allowing you to test on phones/headsets via QR code
407
461
  - **Avoid unnecessary allocations.** Do NOT write `obj.worldPosition.clone()` or `new Vector3()` in per-frame code. The `world___` getters (`worldPosition`, `worldQuaternion`, `worldScale`) return temp vectors that can be read directly and re-assigned (`obj.worldPosition = otherObj.worldPosition`). When you need a temporary vector for math, use `getTempVector()` / `getTempQuaternion()` from `@needle-tools/engine` — these come from a circular buffer with zero GC pressure. Only use `.clone()` when you truly need to store a value across frames.
408
462
  - **NEVER import from `@needle-tools/engine` subpaths** like `@needle-tools/engine/lib/...` or `@needle-tools/engine/src/...`. These are internal paths that break across versions. Everything is exported from the package root: `import { NEEDLE_ENGINE_MODULES, Rigidbody, BloomEffect, ... } from "@needle-tools/engine"`. The only exception is the vite plugin: `import { needlePlugins } from "@needle-tools/engine/vite"`.
463
+ - **Optimization & compression run at build time (not a scene upload).** Texture (KTX2/WebP) and mesh (Draco/Meshopt) compression, progressive loading, and automatic LODs are applied during the production build (Compression & LOD Settings component). It's **license-gated**, so the user must be logged in to Needle Cloud (`npx needle-cloud start`, or the Unity/Blender integration which handles it) — but that's a login/license check, not uploading their scene. Details: [Optimization & Compression](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/optimization.md).
409
464
 
410
465
  ---
411
466
 
@@ -413,6 +468,7 @@ Use this *before* guessing at API details — the docs are the source of truth.
413
468
 
414
469
  Read these **only when needed** — don't load them all upfront:
415
470
 
471
+ - 🆕 [What's New (5.1 → 6.0)](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/whats-new.md) — Scene Bindings (`ctx.sceneData`), `needle` shorthand, `Context.events`, `autoCleanup`, builder APIs, `<needle-app>`, GaussianSplat. **Check this before assuming an API doesn't exist** — much of it postdates the rest of these references.
416
472
  - 📖 [Core API](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/api.md) — lifecycle, decorators, context (input, physics, time), gameobject, coroutines, asset loading, renderer/materials, async modules
417
473
  - 🧩 [Components](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/components.md) — animation, audio, video, lighting, camera, scene switching, interaction, splines, particles, debug tools
418
474
  - ⚡ [Physics](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/physics.md) — colliders, Rigidbody (forces, velocity, impulse), raycasting, async Rapier loading
@@ -420,14 +476,18 @@ Read these **only when needed** — don't load them all upfront:
420
476
  - 🌐 [Networking](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/networking.md) — connection API, SyncedRoom, PlayerSync, @syncField, SyncedTransform, Voip, ScreenCapture, guid persistence
421
477
  - 🥽 [WebXR](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/xr.md) — VR/AR sessions, XRRig, controllers, pointer events in XR, image tracking, depth sensing, camera access, mesh detection, DOM overlay, iOS AR, multiplayer avatars
422
478
  - 🚀 [Deployment](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/deployment.md) — Needle Cloud (GitHub Actions, CLI), Vercel, Netlify, other platforms
479
+ - 📦 [Optimization & Compression](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/optimization.md) — build-time (local) texture/mesh compression (KTX2, Draco/Meshopt), progressive loading, automatic LODs — **not** a cloud upload
423
480
  - 🔗 [Framework Integration](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/integration.md) — React, Svelte, Vue, Next.js, SvelteKit patterns, CDN with import maps
424
481
  - 💡 [Component Examples](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/examples.md) — practical examples: click handling, runtime loading, networking, materials, code-only scenes, input, coroutines
425
482
  - 🐛 [Troubleshooting](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/troubleshooting.md) — error messages, unexpected behavior, build failures, **runtime logs at `node_modules/.needle/logs/`**, build info
483
+ - 🔌 [MCP & Search API](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/references/mcp.md) — `needle_search`, the public search HTTP API, MCP server setup, project file tools, live scene inspection via the Needle Inspector, Unity/Blender tools
426
484
  - 🧩 [Component Template](https://raw.githubusercontent.com/needle-tools/ai/refs/heads/main/providers/claude/plugin/skills/needle-engine/templates/my-component.ts) — annotated starting point for new components
427
485
 
428
486
  ## Important URLs
429
487
 
430
- - Docs: https://engine.needle.tools/docs/
488
+ - Docs: https://engine.needle.tools/docs/ (any page also available as markdown — swap `.html` for `.md`)
489
+ - Search API: https://search.needle.tools/api/semantic-search?q=your+question ([API reference](https://search.needle.tools/api-docs))
490
+ - AI & MCP docs: https://engine.needle.tools/docs/ai/
431
491
  - Samples: https://engine.needle.tools/samples/
432
492
  - Samples index (all official samples with source): https://github.com/needle-tools/needle-engine-samples/blob/main/samples.json
433
493
  - GitHub: https://github.com/needle-tools/needle-engine-support