@vib3code/sdk 2.0.3-canary.60bc0f0 → 2.0.3-canary.74aebb4

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 (44) hide show
  1. package/DOCS/EXPANSION_DESIGN.md +977 -0
  2. package/DOCS/EXPANSION_DESIGN_ULTRA.md +387 -0
  3. package/DOCS/MASTER_PLAN_2026-01-31.md +2 -2
  4. package/DOCS/OPTIMIZATION_PLAN_MATH.md +118 -0
  5. package/DOCS/SYSTEM_INVENTORY.md +2 -2
  6. package/DOCS/WEBGPU_STATUS.md +119 -38
  7. package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +38 -0
  8. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +108 -0
  9. package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +308 -0
  10. package/docs/webgpu-live.html +1 -1
  11. package/package.json +1 -1
  12. package/src/agent/mcp/MCPServer.js +195 -136
  13. package/src/agent/mcp/tools.js +45 -32
  14. package/src/experimental/GameLoop.js +72 -0
  15. package/src/experimental/LatticePhysics.js +100 -0
  16. package/src/experimental/LiveDirector.js +143 -0
  17. package/src/experimental/PlayerController4D.js +154 -0
  18. package/src/experimental/VIB3Actor.js +138 -0
  19. package/src/experimental/VIB3Compositor.js +117 -0
  20. package/src/experimental/VIB3Link.js +122 -0
  21. package/src/experimental/VIB3Orchestrator.js +146 -0
  22. package/src/experimental/VIB3Universe.js +109 -0
  23. package/src/experimental/demos/CrystalLabyrinth.js +202 -0
  24. package/src/faceted/FacetedSystem.js +19 -6
  25. package/src/geometry/generators/Crystal.js +2 -2
  26. package/src/holograms/HolographicVisualizer.js +58 -89
  27. package/src/math/Mat4x4.js +122 -6
  28. package/src/math/Rotor4D.js +93 -39
  29. package/src/math/Vec4.js +119 -78
  30. package/src/quantum/QuantumVisualizer.js +24 -20
  31. package/src/render/ShaderLoader.js +38 -0
  32. package/src/render/ShaderProgram.js +4 -4
  33. package/src/render/UnifiedRenderBridge.js +1 -1
  34. package/src/render/backends/WebGPUBackend.js +8 -4
  35. package/src/shaders/common/geometry24.glsl +65 -0
  36. package/src/shaders/common/geometry24.wgsl +54 -0
  37. package/src/shaders/common/rotation4d.glsl +4 -4
  38. package/src/shaders/common/rotation4d.wgsl +2 -2
  39. package/src/shaders/common/uniforms.wgsl +15 -8
  40. package/src/shaders/faceted/faceted.frag.wgsl +19 -6
  41. package/src/shaders/holographic/holographic.frag.wgsl +7 -5
  42. package/src/shaders/quantum/quantum.frag.wgsl +7 -5
  43. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
  44. package/tools/shader-sync-verify.js +6 -4
@@ -173,10 +173,13 @@ export class MCPServer {
173
173
  result = this.getParameterSchema();
174
174
  break;
175
175
  case 'get_sdk_context':
176
- result = this.getSDKContext();
176
+ result = this.getSDKContext(args);
177
177
  break;
178
- case 'verify_knowledge':
179
- result = this.verifyKnowledge(args);
178
+ case 'inspect_layers':
179
+ result = this.inspectLayers(args);
180
+ break;
181
+ case 'set_holographic_layer':
182
+ result = this.setHolographicLayer(args);
180
183
  break;
181
184
  // Reactivity tools (Phase 6.5)
182
185
  case 'set_reactivity_config':
@@ -650,162 +653,218 @@ export class MCPServer {
650
653
  /**
651
654
  * Get SDK context for agent onboarding
652
655
  */
653
- getSDKContext() {
654
- return {
655
- sdk_name: 'VIB3+ SDK',
656
- version: '1.9.0',
657
- purpose: 'General-purpose 4D rotation visualization SDK for plugins, extensions, wearables, and agentic use',
658
-
659
- quick_reference: {
660
- active_visualization_systems: 3,
661
- placeholder_systems: 1,
662
- rotation_planes: 6,
663
- base_geometries: 8,
664
- core_warp_types: 3,
665
- total_geometries: 24,
666
- canvas_layers_per_system: 5
667
- },
668
-
669
- systems: {
670
- ACTIVE: [
671
- { name: 'quantum', description: 'Complex quantum lattice visualizations with 24 geometries' },
672
- { name: 'faceted', description: 'Clean 2D geometric patterns with 4D rotation' },
673
- { name: 'holographic', description: '5-layer audio-reactive holographic effects' }
674
- ],
675
- PLACEHOLDER_TBD: [
676
- { name: 'polychora', status: 'TBD', description: '4D polytopes - placeholder, not production ready' }
677
- ]
656
+ getSDKContext(args = {}) {
657
+ const { include_state = true, include_tools = false } = args;
658
+
659
+ const context = {
660
+ sdk: 'VIB3+ 4D Visualization Engine',
661
+ version: '2.0.3',
662
+
663
+ // Capability manifest — what this engine can do
664
+ capabilities: {
665
+ systems: ['quantum', 'faceted', 'holographic'],
666
+ geometries: { count: 24, formula: 'core_type * 8 + base_geometry', base: 8, warps: 3 },
667
+ rotation: { planes: 6, '3D': ['XY', 'XZ', 'YZ'], '4D': ['XW', 'YW', 'ZW'], range: '±6.28 rad' },
668
+ layers: { count: 5, roles: ['background', 'shadow', 'content', 'highlight', 'accent'], addressable: true },
669
+ audio: { bands: ['bass', 'mid', 'high'], modes: ['add', 'multiply', 'replace', 'max', 'min'] },
670
+ input: { sources: ['deviceTilt', 'mousePosition', 'gyroscope', 'gamepad', 'perspective', 'programmatic', 'audio', 'midi'] },
671
+ creative: {
672
+ color_presets: 22,
673
+ easing_functions: 14,
674
+ post_effects: 14,
675
+ aesthetic_keywords: '130+',
676
+ choreography: true,
677
+ timeline_bpm_sync: true
678
+ },
679
+ environment: {
680
+ browser: typeof document !== 'undefined',
681
+ screenshot: typeof document !== 'undefined',
682
+ webgpu: typeof navigator !== 'undefined' && !!navigator.gpu,
683
+ wasm: typeof WebAssembly !== 'undefined'
684
+ }
678
685
  },
679
686
 
680
- geometry_encoding: {
681
- formula: 'geometry_index = core_index * 8 + base_index',
682
- base_geometries: ['tetrahedron', 'hypercube', 'sphere', 'torus', 'klein_bottle', 'fractal', 'wave', 'crystal'],
683
- core_types: ['base (0)', 'hypersphere (1)', 'hypertetrahedron (2)'],
684
- example: 'geometry 10 = hypersphere(sphere) because 1*8+2=10'
687
+ // Parameter ranges — the agent needs these to generate valid values
688
+ parameter_ranges: {
689
+ geometry: { min: 0, max: 23, type: 'integer' },
690
+ hue: { min: 0, max: 360, type: 'integer' },
691
+ saturation: { min: 0, max: 1 },
692
+ intensity: { min: 0, max: 1 },
693
+ speed: { min: 0.1, max: 3 },
694
+ chaos: { min: 0, max: 1 },
695
+ morphFactor: { min: 0, max: 2 },
696
+ gridDensity: { min: 4, max: 100 },
697
+ dimension: { min: 3.0, max: 4.5 },
698
+ rot4dXY: { min: -6.28, max: 6.28 },
699
+ rot4dXW: { min: -6.28, max: 6.28 }
685
700
  },
686
701
 
687
- rotation_planes: {
688
- total: 6,
689
- '3D_space': ['XY', 'XZ', 'YZ'],
690
- '4D_hyperspace': ['XW', 'YW', 'ZW'],
691
- range: '-6.28 to 6.28 radians'
702
+ // Workflow hints — what tool sequences accomplish creative goals
703
+ workflows: {
704
+ quick_design: 'design_from_description describe_visual_state → batch_set_parameters',
705
+ choreography: 'create_choreography play_choreography → describe_visual_state',
706
+ evolve: 'batch_set_parameters describe_visual_state → batch_set_parameters (iterate)',
707
+ layer_control: 'inspect_layers → set_holographic_layer → inspect_layers',
708
+ audio_reactive: 'configure_audio_band → apply_behavior_preset → describe_visual_state'
692
709
  },
693
710
 
694
- canvas_layers: {
695
- count: 5,
696
- names: ['background', 'shadow', 'content', 'highlight', 'accent']
697
- },
711
+ // Geometry quick-reference
712
+ geometry_map: {
713
+ 'sphere': 2, 'hypersphere+sphere': 10, 'hypertetra+sphere': 18,
714
+ 'torus': 3, 'hypersphere+torus': 11, 'hypertetra+torus': 19,
715
+ 'fractal': 5, 'hypersphere+fractal': 13, 'hypertetra+fractal': 21,
716
+ 'crystal': 7, 'wave': 6, 'klein_bottle': 4, 'hypercube': 1, 'tetrahedron': 0
717
+ }
718
+ };
698
719
 
699
- knowledge_quiz: {
700
- IMPORTANT: 'Call verify_knowledge with multiple choice answers (a/b/c/d) to confirm understanding',
701
- questions: [
702
- 'Q1: How many rotation planes? a)3 b)4 c)6 d)8',
703
- 'Q2: Geometry encoding formula? a)base*3+core b)core*8+base c)base+core d)core*base',
704
- 'Q3: Canvas layers per system? a)3 b)4 c)5 d)6',
705
- 'Q4: Which are the 3 ACTIVE systems? a)quantum,faceted,holographic b)quantum,faceted,polychora c)all four d)none',
706
- 'Q5: How many base geometry types? a)6 b)8 c)10 d)24',
707
- 'Q6: Core warp types? a)base,sphere,cube b)base,hypersphere,hypertetrahedron c)2D,3D,4D d)none'
708
- ]
709
- },
720
+ if (include_state) {
721
+ context.current_state = this.getState();
722
+ }
710
723
 
711
- documentation: {
712
- primary: 'DOCS/SYSTEM_INVENTORY.md',
713
- geometry: '24-GEOMETRY-6D-ROTATION-SUMMARY.md',
714
- controls: 'DOCS/CONTROL_REFERENCE.md',
715
- cli: 'DOCS/CLI_ONBOARDING.md'
716
- },
724
+ if (include_tools) {
725
+ context.tool_summary = Object.entries(toolDefinitions).map(([name, def]) => ({
726
+ name,
727
+ description: def.description.split('.')[0] // First sentence only
728
+ }));
729
+ }
717
730
 
718
- suggested_next_actions: ['verify_knowledge', 'create_4d_visualization', 'search_geometries']
719
- };
731
+ return context;
720
732
  }
721
733
 
722
734
  /**
723
- * Verify agent knowledge of SDK (multiple choice)
735
+ * Inspect holographic layer state returns per-layer metadata in JSON format.
736
+ * This replaces the old verify_knowledge quiz with something actually useful.
724
737
  */
725
- verifyKnowledge(answers) {
726
- const correctAnswers = {
727
- q1_rotation_planes: 'c', // 6 rotation planes
728
- q2_geometry_formula: 'b', // core*8+base
729
- q3_canvas_layers: 'c', // 5 layers
730
- q4_active_systems: 'a', // quantum, faceted, holographic (polychora is TBD)
731
- q5_base_geometries: 'b', // 8 base geometries
732
- q6_core_types: 'b' // base, hypersphere, hypertetrahedron
733
- };
738
+ inspectLayers(args = {}) {
739
+ const { layer = 'all' } = args;
734
740
 
735
- const docReferences = {
736
- q1_rotation_planes: {
737
- topic: '6D ROTATION SYSTEM',
738
- doc: 'DOCS/SYSTEM_INVENTORY.md#the-6d-rotation-system',
739
- reason: '6 planes: XY, XZ, YZ (3D) + XW, YW, ZW (4D hyperspace)'
740
- },
741
- q2_geometry_formula: {
742
- topic: 'GEOMETRY ENCODING',
743
- doc: '24-GEOMETRY-6D-ROTATION-SUMMARY.md',
744
- reason: 'geometry = coreIndex * 8 + baseIndex. Example: 10 = 1*8+2 = hypersphere+sphere'
745
- },
746
- q3_canvas_layers: {
747
- topic: 'CANVAS LAYER SYSTEM',
748
- doc: 'DOCS/SYSTEM_INVENTORY.md#the-4-visualization-systems',
749
- reason: '5 layers: background, shadow, content, highlight, accent'
750
- },
751
- q4_active_systems: {
752
- topic: 'ACTIVE VS PLACEHOLDER SYSTEMS',
753
- doc: 'DOCS/SYSTEM_INVENTORY.md',
754
- reason: 'Only 3 ACTIVE: quantum, faceted, holographic. Polychora is TBD/placeholder!'
755
- },
756
- q5_base_geometries: {
757
- topic: 'BASE GEOMETRY TYPES',
758
- doc: '24-GEOMETRY-6D-ROTATION-SUMMARY.md',
759
- reason: '8 base: tetrahedron, hypercube, sphere, torus, klein, fractal, wave, crystal'
760
- },
761
- q6_core_types: {
762
- topic: 'CORE WARP TYPES',
763
- doc: '24-GEOMETRY-6D-ROTATION-SUMMARY.md',
764
- reason: '3 cores: base (no warp), hypersphere, hypertetrahedron'
765
- }
741
+ const systemName = this.engine?.currentSystemName || 'unknown';
742
+ const isHolographic = systemName === 'holographic';
743
+
744
+ if (!isHolographic) {
745
+ return {
746
+ system: systemName,
747
+ note: 'Layer inspection is most detailed for the holographic system (5 independent canvas layers). Switch with switch_system("holographic").',
748
+ layers: [{
749
+ role: 'main',
750
+ system: systemName,
751
+ opacity: 1.0,
752
+ enabled: true,
753
+ description: `Single canvas for ${systemName} system`
754
+ }],
755
+ suggested_next_actions: ['switch_system', 'describe_visual_state']
756
+ };
757
+ }
758
+
759
+ // Build layer metadata from the holographic system
760
+ const system = this.engine?.currentSystem;
761
+ const layerRoles = ['background', 'shadow', 'content', 'highlight', 'accent'];
762
+ const defaultConfigs = {
763
+ background: { densityMult: 0.4, speedMult: 0.2, colorShift: 0, intensity: 0.2, reactivity: 0.5 },
764
+ shadow: { densityMult: 0.8, speedMult: 0.3, colorShift: 180, intensity: 0.4, reactivity: 0.7 },
765
+ content: { densityMult: 1.0, speedMult: 1.0, colorShift: 0, intensity: 1.0, reactivity: 0.9 },
766
+ highlight: { densityMult: 1.5, speedMult: 0.8, colorShift: 60, intensity: 0.6, reactivity: 1.1 },
767
+ accent: { densityMult: 2.5, speedMult: 0.4, colorShift: 300, intensity: 0.3, reactivity: 1.5 }
766
768
  };
767
769
 
768
- const results = {
769
- score: 0,
770
- max_score: 6,
771
- details: [],
772
- REVIEW_REQUIRED: []
770
+ const buildLayerInfo = (role) => {
771
+ const config = defaultConfigs[role] || {};
772
+ const visualizer = system?.visualizers?.find?.(v => v?.role === role);
773
+ const overrides = this._layerOverrides?.get(role) || {};
774
+
775
+ return {
776
+ role,
777
+ enabled: overrides.enabled !== undefined ? overrides.enabled : true,
778
+ opacity: overrides.opacity !== undefined ? overrides.opacity : 1.0,
779
+ blendMode: overrides.blendMode || 'normal',
780
+ densityMult: overrides.densityMult ?? config.densityMult,
781
+ speedMult: overrides.speedMult ?? config.speedMult,
782
+ colorShift: overrides.colorShift ?? config.colorShift,
783
+ intensity: overrides.intensity ?? config.intensity,
784
+ reactivity: overrides.reactivity ?? config.reactivity,
785
+ has_visualizer: !!visualizer
786
+ };
773
787
  };
774
788
 
775
- // Check each answer
776
- for (const [question, correct] of Object.entries(correctAnswers)) {
777
- const given = answers[question]?.toLowerCase?.() || answers[question];
778
- if (given === correct) {
779
- results.score++;
780
- results.details.push({ question, status: '✓ CORRECT' });
781
- } else if (given !== undefined) {
782
- results.details.push({
783
- question,
784
- status: '✗ WRONG',
785
- your_answer: given,
786
- correct_answer: correct
787
- });
788
- results.REVIEW_REQUIRED.push(docReferences[question]);
789
- }
790
- }
789
+ const layers = layer === 'all'
790
+ ? layerRoles.map(buildLayerInfo)
791
+ : [buildLayerInfo(layer)];
791
792
 
792
- results.percentage = Math.round((results.score / results.max_score) * 100);
793
+ return {
794
+ system: 'holographic',
795
+ layer_count: layerRoles.length,
796
+ layers,
797
+ suggested_next_actions: ['set_holographic_layer', 'batch_set_parameters', 'describe_visual_state']
798
+ };
799
+ }
793
800
 
794
- // Build response
795
- if (results.REVIEW_REQUIRED.length > 0) {
796
- results.MESSAGE = `Score: ${results.score}/${results.max_score}. YOU MAY PROCEED but PLEASE review the topics below to avoid errors.`;
797
- results.URGENT = results.REVIEW_REQUIRED.map(ref => ({
798
- TOPIC: ref.topic,
799
- READ: ref.doc,
800
- WHY: ref.reason
801
- }));
802
- } else {
803
- results.MESSAGE = `PERFECT SCORE! You understand the VIB3+ SDK architecture.`;
801
+ /**
802
+ * Set properties on an individual holographic layer.
803
+ * Stores overrides in a layer override map and applies them to the visualizer.
804
+ */
805
+ setHolographicLayer(args) {
806
+ const { layer, opacity, blendMode, enabled, colorShift, densityMult, speedMult, reactivity } = args;
807
+
808
+ const systemName = this.engine?.currentSystemName || 'unknown';
809
+ if (systemName !== 'holographic') {
810
+ return {
811
+ error: {
812
+ type: 'SystemError',
813
+ code: 'NOT_HOLOGRAPHIC',
814
+ message: `set_holographic_layer requires holographic system (current: ${systemName})`,
815
+ suggestion: 'Call switch_system("holographic") first'
816
+ }
817
+ };
804
818
  }
805
819
 
806
- results.suggested_next_actions = ['create_4d_visualization', 'get_state', 'search_geometries'];
820
+ // Initialize layer override storage
821
+ if (!this._layerOverrides) this._layerOverrides = new Map();
822
+ const existing = this._layerOverrides.get(layer) || {};
823
+ const updates = {};
824
+
825
+ if (opacity !== undefined) { existing.opacity = opacity; updates.opacity = opacity; }
826
+ if (blendMode !== undefined) { existing.blendMode = blendMode; updates.blendMode = blendMode; }
827
+ if (enabled !== undefined) { existing.enabled = enabled; updates.enabled = enabled; }
828
+ if (colorShift !== undefined) { existing.colorShift = colorShift; updates.colorShift = colorShift; }
829
+ if (densityMult !== undefined) { existing.densityMult = densityMult; updates.densityMult = densityMult; }
830
+ if (speedMult !== undefined) { existing.speedMult = speedMult; updates.speedMult = speedMult; }
831
+ if (reactivity !== undefined) { existing.reactivity = reactivity; updates.reactivity = reactivity; }
832
+
833
+ this._layerOverrides.set(layer, existing);
834
+
835
+ // Apply to visualizer if available
836
+ const system = this.engine?.currentSystem;
837
+ const visualizer = system?.visualizers?.find?.(v => v?.role === layer);
838
+ if (visualizer) {
839
+ if (opacity !== undefined && visualizer.canvas) {
840
+ visualizer.canvas.style.opacity = String(opacity);
841
+ }
842
+ if (blendMode !== undefined && visualizer.canvas) {
843
+ visualizer.canvas.style.mixBlendMode = blendMode;
844
+ }
845
+ if (enabled !== undefined && visualizer.canvas) {
846
+ visualizer.canvas.style.display = enabled ? '' : 'none';
847
+ }
848
+ if (colorShift !== undefined && visualizer.roleParams) {
849
+ visualizer.roleParams.colorShift = colorShift;
850
+ }
851
+ if (densityMult !== undefined && visualizer.roleParams) {
852
+ visualizer.roleParams.densityMult = densityMult;
853
+ }
854
+ if (speedMult !== undefined && visualizer.roleParams) {
855
+ visualizer.roleParams.speedMult = speedMult;
856
+ }
857
+ if (reactivity !== undefined) {
858
+ visualizer.reactivity = reactivity;
859
+ }
860
+ }
807
861
 
808
- return results;
862
+ return {
863
+ layer,
864
+ applied: updates,
865
+ current_state: this.inspectLayers({ layer }).layers[0],
866
+ suggested_next_actions: ['inspect_layers', 'set_holographic_layer', 'describe_visual_state']
867
+ };
809
868
  }
810
869
 
811
870
  /**
@@ -222,51 +222,64 @@ export const toolDefinitions = {
222
222
  // Onboarding Tools
223
223
  get_sdk_context: {
224
224
  name: 'get_sdk_context',
225
- description: 'Returns essential SDK context for agent onboarding. Call this first to understand the system.',
225
+ description: 'Returns a compact capability manifest: what systems exist, what tools are available, what parameter ranges are valid, and what the current engine state is. Designed for injection into agent context call once at session start, not repeatedly.',
226
226
  inputSchema: {
227
227
  type: 'object',
228
- properties: {}
228
+ properties: {
229
+ include_state: {
230
+ type: 'boolean',
231
+ default: true,
232
+ description: 'Include current engine state in response'
233
+ },
234
+ include_tools: {
235
+ type: 'boolean',
236
+ default: false,
237
+ description: 'Include tool summary list (names + one-line descriptions)'
238
+ }
239
+ }
229
240
  }
230
241
  },
231
242
 
232
- verify_knowledge: {
233
- name: 'verify_knowledge',
234
- description: 'Verifies agent has absorbed SDK context. Multiple choice quiz - submit letter answers (a/b/c/d).',
243
+ inspect_layers: {
244
+ name: 'inspect_layers',
245
+ description: 'Returns the current state of all holographic canvas layers with per-layer metadata: role, opacity, blend mode, reactivity multiplier, role-specific parameters, and enabled state. Only meaningful when holographic system is active.',
235
246
  inputSchema: {
236
247
  type: 'object',
237
248
  properties: {
238
- q1_rotation_planes: {
239
- type: 'string',
240
- enum: ['a', 'b', 'c', 'd'],
241
- description: 'Q1: How many rotation planes? a)3 b)4 c)6 d)8'
242
- },
243
- q2_geometry_formula: {
244
- type: 'string',
245
- enum: ['a', 'b', 'c', 'd'],
246
- description: 'Q2: Geometry encoding formula? a)base*3+core b)core*8+base c)base+core d)core*base'
247
- },
248
- q3_canvas_layers: {
249
+ layer: {
249
250
  type: 'string',
250
- enum: ['a', 'b', 'c', 'd'],
251
- description: 'Q3: Canvas layers per system? a)3 b)4 c)5 d)6'
252
- },
253
- q4_active_systems: {
251
+ enum: ['background', 'shadow', 'content', 'highlight', 'accent', 'all'],
252
+ default: 'all',
253
+ description: 'Inspect a specific layer or all layers'
254
+ }
255
+ }
256
+ }
257
+ },
258
+
259
+ set_holographic_layer: {
260
+ name: 'set_holographic_layer',
261
+ description: 'Controls individual holographic layer properties. Set opacity, blend mode, enable/disable, or override role parameters for any of the 5 layers (background, shadow, content, highlight, accent). Only works when holographic system is active.',
262
+ inputSchema: {
263
+ type: 'object',
264
+ properties: {
265
+ layer: {
254
266
  type: 'string',
255
- enum: ['a', 'b', 'c', 'd'],
256
- description: 'Q4: Which are the 3 ACTIVE systems? a)quantum,faceted,holographic b)quantum,faceted,polychora c)faceted,holographic,polychora d)all four'
267
+ enum: ['background', 'shadow', 'content', 'highlight', 'accent'],
268
+ description: 'Target layer role name'
257
269
  },
258
- q5_base_geometries: {
270
+ opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Layer opacity (0=invisible, 1=full)' },
271
+ blendMode: {
259
272
  type: 'string',
260
- enum: ['a', 'b', 'c', 'd'],
261
- description: 'Q5: How many base geometry types? a)6 b)8 c)10 d)24'
273
+ enum: ['normal', 'screen', 'multiply', 'add', 'overlay'],
274
+ description: 'CSS blend mode for this layer'
262
275
  },
263
- q6_core_types: {
264
- type: 'string',
265
- enum: ['a', 'b', 'c', 'd'],
266
- description: 'Q6: Core warp types? a)base,sphere,cube b)base,hypersphere,hypertetrahedron c)none,partial,full d)2D,3D,4D'
267
- }
276
+ enabled: { type: 'boolean', description: 'Show/hide this layer' },
277
+ colorShift: { type: 'number', minimum: 0, maximum: 360, description: 'Hue offset for this layer' },
278
+ densityMult: { type: 'number', minimum: 0.1, maximum: 5, description: 'Grid density multiplier' },
279
+ speedMult: { type: 'number', minimum: 0, maximum: 3, description: 'Animation speed multiplier' },
280
+ reactivity: { type: 'number', minimum: 0, maximum: 3, description: 'Mouse/touch reactivity multiplier' }
268
281
  },
269
- required: ['q1_rotation_planes', 'q2_geometry_formula', 'q3_canvas_layers']
282
+ required: ['layer']
270
283
  }
271
284
  },
272
285
 
@@ -651,7 +664,7 @@ export const toolDefinitions = {
651
664
 
652
665
  capture_screenshot: {
653
666
  name: 'capture_screenshot',
654
- description: 'Captures the current visualization as a base64-encoded PNG image by compositing all 5 canvas layers. Only works in browser context. Returns image data that multimodal agents can analyze for visual feedback.',
667
+ description: 'Captures current visualization as a base64-encoded PNG by compositing canvas layers. BROWSER-ONLY: returns an EnvironmentError with capability report in headless/Node contexts. When available, returns data_url for multimodal analysis. Use describe_visual_state as a text-based alternative in non-browser environments.',
655
668
  inputSchema: {
656
669
  type: 'object',
657
670
  properties: {
@@ -0,0 +1,72 @@
1
+ /**
2
+ * GameLoop - Fixed-Timestep Physics Loop
3
+ *
4
+ * Provides a robust game loop that decouples physics updates (fixed step)
5
+ * from rendering (variable step). This is crucial for consistent physics
6
+ * and smooth rendering across different device capabilities.
7
+ *
8
+ * @experimental
9
+ */
10
+ export class GameLoop {
11
+ /**
12
+ * @param {function(number)} updateFn - Physics update (fixed dt)
13
+ * @param {function(number)} renderFn - Render update (interpolated alpha)
14
+ * @param {number} step - Physics step size in seconds (default 1/60)
15
+ */
16
+ constructor(updateFn, renderFn, step = 1 / 60) {
17
+ this.updateFn = updateFn;
18
+ this.renderFn = renderFn;
19
+ this.step = step;
20
+ this.dt = 0;
21
+ this.last = 0;
22
+ this.now = 0;
23
+ this.accumulator = 0;
24
+ this.running = false;
25
+ this.rafId = null;
26
+
27
+ // Bind loop
28
+ this.frame = this.frame.bind(this);
29
+ }
30
+
31
+ start() {
32
+ if (this.running) return;
33
+ this.running = true;
34
+ this.last = performance.now();
35
+ this.accumulator = 0;
36
+ this.rafId = requestAnimationFrame(this.frame);
37
+ console.log('GameLoop: Started.');
38
+ }
39
+
40
+ stop() {
41
+ this.running = false;
42
+ if (this.rafId) {
43
+ cancelAnimationFrame(this.rafId);
44
+ this.rafId = null;
45
+ }
46
+ console.log('GameLoop: Stopped.');
47
+ }
48
+
49
+ frame(timestamp) {
50
+ if (!this.running) return;
51
+
52
+ this.now = timestamp;
53
+ // Cap dt to avoid "spiral of death" on lag spikes (max 1s)
54
+ this.dt = Math.min(1, (this.now - this.last) / 1000);
55
+ this.last = this.now;
56
+
57
+ this.accumulator += this.dt;
58
+
59
+ // Consume accumulator in fixed steps
60
+ while (this.accumulator >= this.step) {
61
+ this.updateFn(this.step);
62
+ this.accumulator -= this.step;
63
+ }
64
+
65
+ // Render with interpolation factor alpha
66
+ // alpha = accumulator / step
67
+ // Allows renderer to interpolate between previous and current physics state
68
+ this.renderFn(this.accumulator / this.step);
69
+
70
+ this.rafId = requestAnimationFrame(this.frame);
71
+ }
72
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * LatticePhysics - Function-Based Collision Detection
3
+ *
4
+ * Provides a physics engine for "Lattice Worlds" where geometry is defined
5
+ * by mathematical density functions (SDFs, fractals).
6
+ *
7
+ * @experimental
8
+ */
9
+ export class LatticePhysics {
10
+ constructor() {
11
+ this.gravity = 9.8; // m/s²
12
+ this.friction = 0.95; // Velocity decay per step
13
+ this.densityThreshold = 0.8; // Collision threshold (0-1)
14
+ }
15
+
16
+ /**
17
+ * Update physics for all entities in the universe.
18
+ * @param {Map<string, object>} entities
19
+ * @param {number} dt
20
+ */
21
+ update(entities, dt) {
22
+ entities.forEach(entity => {
23
+ if (entity.physics && entity.active) {
24
+ this.updateEntity(entity, dt);
25
+ }
26
+ });
27
+ }
28
+
29
+ /**
30
+ * Update a single entity's physics state.
31
+ * @param {object} entity
32
+ * @param {number} dt
33
+ */
34
+ updateEntity(entity, dt) {
35
+ const { pos, vel, acc } = entity.physics;
36
+
37
+ // Apply forces (Gravity)
38
+ // In this abstract world, gravity pulls "down" in Y
39
+ acc.y -= this.gravity * dt;
40
+
41
+ // Integrate Velocity (Euler)
42
+ vel.x += acc.x * dt;
43
+ vel.y += acc.y * dt;
44
+ vel.z += acc.z * dt;
45
+
46
+ // Reset acceleration (forces are transient)
47
+ acc.x = 0; acc.y = 0; acc.z = 0;
48
+
49
+ // Collision Check (Projected Position)
50
+ const nextX = pos.x + vel.x * dt;
51
+ const nextY = pos.y + vel.y * dt;
52
+ const nextZ = pos.z + vel.z * dt;
53
+
54
+ // Sample density at next position
55
+ const density = this.getDensityAt(nextX, nextY, nextZ);
56
+
57
+ if (density > this.densityThreshold) {
58
+ // Collision!
59
+ // Simple response: Stop velocity component and push out
60
+ // A real engine would calculate surface normal from gradient
61
+
62
+ // Simplified: Just stop movement and bounce slightly
63
+ vel.x *= -0.5;
64
+ vel.y *= -0.5;
65
+ vel.z *= -0.5;
66
+
67
+ // Don't update position into solid
68
+ } else {
69
+ // Move freely
70
+ pos.x = nextX;
71
+ pos.y = nextY;
72
+ pos.z = nextZ;
73
+ }
74
+
75
+ // Apply Friction (Air/Ether drag)
76
+ vel.x *= this.friction;
77
+ vel.y *= this.friction;
78
+ vel.z *= this.friction;
79
+ }
80
+
81
+ /**
82
+ * Sample the "world density" at a given point.
83
+ * This mimics the shader's generation logic (e.g., fractal noise).
84
+ * @param {number} x
85
+ * @param {number} y
86
+ * @param {number} z
87
+ * @returns {number} Density 0.0 to 1.0
88
+ */
89
+ getDensityAt(x, y, z) {
90
+ // Mock function: simple floor plane at y = -2
91
+ if (y < -2) return 1.0;
92
+
93
+ // Mock function: occasional "floating islands" based on sine waves
94
+ // simulating the VIB3 lattice structure
95
+ const noise = (Math.sin(x * 0.5) + Math.cos(z * 0.5)) * 0.5 + 0.5;
96
+ if (y > 0 && y < 1 && noise > 0.8) return 1.0;
97
+
98
+ return 0.0;
99
+ }
100
+ }