@vulfram/engine 0.17.1-alpha → 0.19.2-alpha

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 (36) hide show
  1. package/README.md +3 -3
  2. package/package.json +9 -4
  3. package/src/engine/api.ts +12 -25
  4. package/src/engine/bridge/dispatch.ts +3 -8
  5. package/src/engine/ecs/components.ts +340 -0
  6. package/src/engine/ecs/index.ts +3 -661
  7. package/src/engine/ecs/intents.ts +184 -0
  8. package/src/engine/ecs/systems.ts +26 -0
  9. package/src/engine/intents/store.ts +72 -0
  10. package/src/engine/state.ts +3 -3
  11. package/src/engine/systems/command-intent.ts +11 -16
  12. package/src/engine/systems/diagnostics.ts +3 -13
  13. package/src/engine/systems/input-mirror.ts +156 -18
  14. package/src/engine/systems/resource-upload.ts +12 -14
  15. package/src/engine/systems/response-decode.ts +17 -0
  16. package/src/engine/systems/scene-sync.ts +12 -13
  17. package/src/engine/systems/ui-bridge.ts +31 -10
  18. package/src/engine/systems/utils.ts +46 -3
  19. package/src/engine/systems/world-lifecycle.ts +9 -15
  20. package/src/engine/world/entities.ts +201 -37
  21. package/src/engine/world/mount.ts +27 -6
  22. package/src/engine/world/world-ui.ts +77 -30
  23. package/src/engine/world/world3d.ts +282 -33
  24. package/src/helpers/collision.ts +487 -0
  25. package/src/helpers/index.ts +2 -0
  26. package/src/helpers/raycast.ts +442 -0
  27. package/src/types/cmds/geometry.ts +2 -2
  28. package/src/types/cmds/index.ts +42 -0
  29. package/src/types/cmds/input.ts +39 -0
  30. package/src/types/cmds/material.ts +10 -10
  31. package/src/types/cmds/realm.ts +0 -2
  32. package/src/types/cmds/system.ts +10 -0
  33. package/src/types/cmds/target.ts +14 -0
  34. package/src/types/events/keyboard.ts +2 -2
  35. package/src/types/events/pointer.ts +43 -0
  36. package/src/types/events/system.ts +44 -0
@@ -1,661 +1,3 @@
1
- import type { ViewPosition } from '../../types/cmds/camera';
2
- import type { GeometryPrimitiveEntry } from '../../types/cmds/geometry';
3
- import type { MaterialOptions } from '../../types/cmds/material';
4
- import type { ShadowConfig } from '../../types/cmds/shadow';
5
- import type { ForwardAtlasOptions } from '../../types/cmds/texture';
6
- import type { EnvironmentConfig } from '../../types/cmds/environment';
7
- import type { GamepadEvent, SystemEvent, UiEvent } from '../../types/events';
8
- import type {
9
- CmdUiAccessKitActionRequestArgs,
10
- CmdUiApplyOpsArgs,
11
- CmdUiClipboardPasteArgs,
12
- CmdUiDebugSetArgs,
13
- CmdUiDocumentCreateArgs,
14
- CmdUiDocumentDisposeArgs,
15
- CmdUiDocumentGetLayoutRectsArgs,
16
- CmdUiDocumentGetTreeArgs,
17
- CmdUiDocumentSetRectArgs,
18
- CmdUiDocumentSetThemeArgs,
19
- CmdUiEventTraceSetArgs,
20
- CmdUiFocusGetArgs,
21
- CmdUiFocusSetArgs,
22
- CmdUiImageCreateFromBufferArgs,
23
- CmdUiImageDisposeArgs,
24
- CmdUiScreenshotReplyArgs,
25
- CmdUiThemeDefineArgs,
26
- CmdUiThemeDisposeArgs,
27
- } from '../../types/cmds/ui';
28
- import type {
29
- CameraKind,
30
- LightKind,
31
- MaterialKind,
32
- TextureCreateMode,
33
- NotificationLevel,
34
- } from '../../types/kinds';
35
- import type { JsonObject, JsonValue } from '../../types/json';
36
- import type { WorldState } from '../state';
37
-
38
- /**
39
- * Standard ECS components for Vulfram.
40
- *
41
- * Rules:
42
- * 1. Components are plain data.
43
- * 2. They are NEVER modified directly by the user during a frame.
44
- * 3. Changes are requested via Intents.
45
- */
46
-
47
- /**
48
- * Transform component data used to position entities.
49
- */
50
- export interface TransformProps {
51
- position?: [number, number, number];
52
- rotation?: [number, number, number, number]; // Quaternion
53
- scale?: [number, number, number];
54
- layerMask?: number;
55
- visible?: boolean;
56
- }
57
-
58
- /**
59
- * Fully-resolved transform component stored in the ECS.
60
- */
61
- export interface TransformComponent extends Required<
62
- Omit<TransformProps, never>
63
- > {
64
- type: 'Transform';
65
- }
66
-
67
- /**
68
- * Parent link data used for hierarchical transforms.
69
- */
70
- export interface ParentProps {
71
- parentId: number;
72
- }
73
-
74
- /**
75
- * Parent component stored in the ECS.
76
- */
77
- export interface ParentComponent extends ParentProps {
78
- type: 'Parent';
79
- }
80
-
81
- /**
82
- * Camera component configuration.
83
- */
84
- export interface CameraProps {
85
- kind?: CameraKind;
86
- near?: number;
87
- far?: number;
88
- order?: number;
89
- viewPosition?: ViewPosition;
90
- orthoScale?: number;
91
- }
92
-
93
- /**
94
- * Camera component stored in the ECS.
95
- */
96
- export interface CameraComponent extends Required<
97
- Omit<CameraProps, 'viewPosition'>
98
- > {
99
- type: 'Camera';
100
- id: number; // Core Camera ID
101
- viewPosition?: ViewPosition;
102
- skipUpdate?: boolean; // Internal flag to skip next transform update
103
- }
104
-
105
- /**
106
- * Light component configuration.
107
- */
108
- export interface LightProps {
109
- kind?: LightKind;
110
- color?: [number, number, number];
111
- intensity?: number;
112
- range?: number;
113
- castShadow?: boolean;
114
- direction?: [number, number, number];
115
- spotInnerOuter?: [number, number];
116
- }
117
-
118
- /**
119
- * Light component stored in the ECS.
120
- */
121
- export interface LightComponent extends Required<Omit<LightProps, never>> {
122
- type: 'Light';
123
- id: number; // Core Light ID
124
- skipUpdate?: boolean; // Internal flag to skip next transform update
125
- }
126
-
127
- /**
128
- * Model component configuration.
129
- */
130
- export interface ModelProps {
131
- geometryId: number;
132
- materialId?: number;
133
- castShadow?: boolean;
134
- receiveShadow?: boolean;
135
- castOutline?: boolean;
136
- outlineColor?: [number, number, number, number];
137
- }
138
-
139
- /**
140
- * Model component stored in the ECS.
141
- */
142
- export interface ModelComponent extends Required<
143
- Omit<ModelProps, 'materialId'>
144
- > {
145
- type: 'Model';
146
- id: number; // Core Model ID
147
- materialId?: number;
148
- skipUpdate?: boolean; // Internal flag to skip next transform update
149
- }
150
-
151
- /**
152
- * Tag component configuration.
153
- */
154
- export interface TagProps {
155
- name?: string;
156
- labels?: string[];
157
- }
158
-
159
- /**
160
- * Tag component stored in the ECS.
161
- */
162
- export interface TagComponent {
163
- type: 'Tag';
164
- name: string;
165
- labels: Set<string>;
166
- }
167
-
168
- /**
169
- * InputState: Stores the current input state for a world.
170
- * This is updated each frame based on incoming events.
171
- */
172
- export interface InputStateComponent {
173
- type: 'InputState';
174
- keysPressed: Set<number>; // KeyCodes currently held down
175
- keysJustPressed: Set<number>; // KeyCodes pressed this frame
176
- keysJustReleased: Set<number>; // KeyCodes released this frame
177
- mouseButtons: Set<number>; // Mouse buttons currently held
178
- mousePosition: [number, number]; // Current mouse position
179
- mouseJustPressed: Set<number>; // Mouse buttons pressed this frame
180
- mouseJustReleased: Set<number>; // Mouse buttons released this frame
181
- mouseDelta: [number, number]; // Mouse movement delta this frame
182
- scrollDelta: [number, number]; // Scroll delta this frame
183
- }
184
-
185
- /**
186
- * WindowState: Stores window events and state.
187
- */
188
- export interface WindowStateComponent {
189
- type: 'WindowState';
190
- focused: boolean;
191
- size: [number, number];
192
- position: [number, number];
193
- scaleFactor: number;
194
- closeRequested: boolean;
195
- resizedThisFrame: boolean;
196
- movedThisFrame: boolean;
197
- focusChangedThisFrame: boolean;
198
- }
199
-
200
- /**
201
- * Gamepad state mirrored from core gamepad events.
202
- */
203
- export interface GamepadStateComponent {
204
- type: 'GamepadState';
205
- connected: Map<number, { name: string }>;
206
- buttons: Map<number, Map<number, { pressed: boolean; value: number }>>;
207
- axes: Map<number, Map<number, number>>;
208
- eventsThisFrame: GamepadEvent[];
209
- }
210
-
211
- /**
212
- * System events mirrored for host-level integrations.
213
- */
214
- export interface SystemEventStateComponent {
215
- type: 'SystemEventState';
216
- eventsThisFrame: SystemEvent[];
217
- lastError?: {
218
- scope: string;
219
- message: string;
220
- commandId?: number;
221
- commandType?: string;
222
- };
223
- }
224
-
225
- /**
226
- * UI events mirrored from core UI event channel.
227
- */
228
- export interface UiEventStateComponent {
229
- type: 'UiEventState';
230
- eventsThisFrame: UiEvent[];
231
- }
232
-
233
- /**
234
- * Focus traversal behavior when reaching first/last input.
235
- */
236
- export type UiFocusCycleMode = 'wrap' | 'clamp';
237
-
238
- /**
239
- * Form scope state used to control focus traversal.
240
- */
241
- export interface UiFormScope {
242
- formId: string;
243
- windowId: number;
244
- realmId: number;
245
- documentId: number;
246
- disabled: boolean;
247
- cycleMode: UiFocusCycleMode;
248
- activeFieldsetId?: string;
249
- activeNodeId?: number;
250
- }
251
-
252
- /**
253
- * Fieldset scope metadata.
254
- */
255
- export interface UiFieldsetScope {
256
- formId: string;
257
- fieldsetId: string;
258
- disabled: boolean;
259
- legendNodeId?: number;
260
- }
261
-
262
- /**
263
- * Focusable node metadata for tab ordering.
264
- */
265
- export interface UiFocusableNode {
266
- formId: string;
267
- nodeId: number;
268
- tabIndex: number;
269
- fieldsetId?: string;
270
- disabled: boolean;
271
- orderHint: number;
272
- }
273
-
274
- /**
275
- * UI runtime state mirrored in the ECS world.
276
- */
277
- export interface UiStateComponent {
278
- type: 'UiState';
279
- forms: Map<string, UiFormScope>;
280
- fieldsets: Map<string, UiFieldsetScope>;
281
- nodes: Map<number, UiFocusableNode>;
282
- focusByWindow: Map<number, { formId: string; nodeId: number }>;
283
- }
284
-
285
- /**
286
- * Resource Properties
287
- */
288
-
289
- /**
290
- * Base properties shared by resources.
291
- */
292
- export interface BaseResourceProps {
293
- label?: string;
294
- }
295
-
296
- /**
297
- * Material resource configuration.
298
- */
299
- export interface MaterialProps extends BaseResourceProps {
300
- kind: MaterialKind;
301
- options: MaterialOptions;
302
- }
303
-
304
- /**
305
- * Options for cube primitive geometry.
306
- */
307
- export interface CubeOptions {
308
- size?: [number, number, number];
309
- }
310
-
311
- /**
312
- * Options for plane primitive geometry.
313
- */
314
- export interface PlaneOptions {
315
- size?: [number, number, number];
316
- subdivisions?: number;
317
- }
318
-
319
- /**
320
- * Options for sphere primitive geometry.
321
- */
322
- export interface SphereOptions {
323
- radius?: number;
324
- sectors?: number;
325
- stacks?: number;
326
- }
327
-
328
- /**
329
- * Options for cylinder primitive geometry.
330
- */
331
- export interface CylinderOptions {
332
- radius?: number;
333
- height?: number;
334
- sectors?: number;
335
- /** @deprecated use `sectors` */
336
- segments?: number;
337
- }
338
-
339
- /**
340
- * Options for torus primitive geometry.
341
- */
342
- export interface TorusOptions {
343
- majorRadius?: number;
344
- minorRadius?: number;
345
- majorSegments?: number;
346
- minorSegments?: number;
347
- /** @deprecated use `majorSegments` */
348
- radialSegments?: number;
349
- /** @deprecated use `minorSegments` */
350
- tubularSegments?: number;
351
- }
352
-
353
- /**
354
- * Options for pyramid primitive geometry.
355
- */
356
- export interface PyramidOptions {
357
- size?: [number, number, number];
358
- subdivisions?: number;
359
- }
360
-
361
- /**
362
- * Geometry resource configuration (primitive or custom).
363
- */
364
- export type GeometryProps = BaseResourceProps &
365
- (
366
- | {
367
- type: 'custom';
368
- entries: GeometryPrimitiveEntry[];
369
- }
370
- | ({ type: 'primitive' } & (
371
- | { shape: 'cube'; options?: CubeOptions }
372
- | { shape: 'plane'; options?: PlaneOptions }
373
- | { shape: 'sphere'; options?: SphereOptions }
374
- | { shape: 'cylinder'; options?: CylinderOptions }
375
- | { shape: 'torus'; options?: TorusOptions }
376
- | { shape: 'pyramid'; options?: PyramidOptions }
377
- ))
378
- );
379
-
380
- /**
381
- * Texture resource configuration.
382
- */
383
- export interface TextureProps extends BaseResourceProps {
384
- srgb?: boolean;
385
- mode?: TextureCreateMode;
386
- atlasOptions?: ForwardAtlasOptions;
387
- source:
388
- | { type: 'buffer'; bufferId: number }
389
- | { type: 'color'; color: [number, number, number, number] };
390
- }
391
-
392
- /**
393
- * Union of all built-in component types.
394
- */
395
- export type Component =
396
- | TransformComponent
397
- | ParentComponent
398
- | CameraComponent
399
- | LightComponent
400
- | ModelComponent
401
- | TagComponent
402
- | InputStateComponent
403
- | WindowStateComponent
404
- | GamepadStateComponent
405
- | SystemEventStateComponent
406
- | UiEventStateComponent
407
- | UiStateComponent
408
- | CustomComponent;
409
-
410
- /**
411
- * Custom components are dynamic and registered via schema.
412
- */
413
- /**
414
- * Custom component payload stored in the ECS.
415
- */
416
- export interface CustomComponent {
417
- type: string;
418
- data: JsonObject;
419
- }
420
-
421
- /**
422
- * String literal type for component identifiers.
423
- */
424
- export type ComponentType = Component['type'];
425
-
426
- /**
427
- * Extension Schemas
428
- */
429
-
430
- /**
431
- * Supported property types for custom schemas.
432
- */
433
- export type PropertyType =
434
- | 'number'
435
- | 'string'
436
- | 'boolean'
437
- | 'vec2'
438
- | 'vec3'
439
- | 'vec4'
440
- | 'quat'
441
- | 'entity'
442
- | 'resource'
443
- | 'array'
444
- | 'object';
445
-
446
- /**
447
- * Schema entry describing a custom component field.
448
- */
449
- export interface SchemaProperty {
450
- type: PropertyType;
451
- default?: JsonValue;
452
- optional?: boolean;
453
- }
454
-
455
- /**
456
- * Schema definition for a custom component.
457
- */
458
- export interface ComponentSchema {
459
- [key: string]: SchemaProperty;
460
- }
461
-
462
- /**
463
- * Intents:
464
- * Requests to change the state of the World.
465
- * Systems process Intents and generate Core Commands.
466
- */
467
-
468
- export type Intent =
469
- | { type: 'configure-environment'; config: EnvironmentConfig }
470
- | {
471
- type: 'request-resource-list';
472
- resourceType:
473
- | 'model'
474
- | 'material'
475
- | 'texture'
476
- | 'geometry'
477
- | 'light'
478
- | 'camera';
479
- }
480
- | { type: 'create-entity'; worldId: number; entityId: number }
481
- | { type: 'remove-entity'; entityId: number }
482
- | {
483
- type: 'update-transform';
484
- entityId: number;
485
- props: TransformProps;
486
- }
487
- | {
488
- type: 'attach-camera';
489
- entityId: number;
490
- props: CameraProps;
491
- }
492
- | {
493
- type: 'attach-model';
494
- entityId: number;
495
- props: ModelProps;
496
- }
497
- | {
498
- type: 'attach-light';
499
- entityId: number;
500
- props: LightProps;
501
- }
502
- | {
503
- type: 'attach-tag';
504
- entityId: number;
505
- props: TagProps;
506
- }
507
- | { type: 'create-material'; resourceId: number; props: MaterialProps }
508
- | { type: 'create-geometry'; resourceId: number; props: GeometryProps }
509
- | { type: 'create-texture'; resourceId: number; props: TextureProps }
510
- | { type: 'dispose-material'; resourceId: number }
511
- | { type: 'dispose-texture'; resourceId: number }
512
- | { type: 'dispose-geometry'; resourceId: number }
513
- | { type: 'detach-component'; entityId: number; componentType: ComponentType }
514
- | { type: 'set-parent'; entityId: number; parentId: number | null }
515
- | {
516
- type: 'send-notification';
517
- level: NotificationLevel;
518
- title: string;
519
- message: string;
520
- }
521
- | { type: 'configure-shadows'; config: ShadowConfig }
522
- | {
523
- type: 'gizmo-draw-line';
524
- start: [number, number, number];
525
- end: [number, number, number];
526
- color: [number, number, number, number];
527
- }
528
- | {
529
- type: 'gizmo-draw-aabb';
530
- min: [number, number, number];
531
- max: [number, number, number];
532
- color: [number, number, number, number];
533
- }
534
- | { type: 'ui-theme-define'; args: CmdUiThemeDefineArgs }
535
- | { type: 'ui-theme-dispose'; args: CmdUiThemeDisposeArgs }
536
- | { type: 'ui-document-create'; args: CmdUiDocumentCreateArgs }
537
- | { type: 'ui-document-dispose'; args: CmdUiDocumentDisposeArgs }
538
- | { type: 'ui-document-set-rect'; args: CmdUiDocumentSetRectArgs }
539
- | { type: 'ui-document-set-theme'; args: CmdUiDocumentSetThemeArgs }
540
- | { type: 'ui-document-get-tree'; args: CmdUiDocumentGetTreeArgs }
541
- | {
542
- type: 'ui-document-get-layout-rects';
543
- args: CmdUiDocumentGetLayoutRectsArgs;
544
- }
545
- | { type: 'ui-apply-ops'; args: CmdUiApplyOpsArgs }
546
- | { type: 'ui-debug-set'; args: CmdUiDebugSetArgs }
547
- | { type: 'ui-focus-set'; args: CmdUiFocusSetArgs }
548
- | { type: 'ui-focus-get'; args: CmdUiFocusGetArgs }
549
- | { type: 'ui-event-trace-set'; args: CmdUiEventTraceSetArgs }
550
- | { type: 'ui-image-create-from-buffer'; args: CmdUiImageCreateFromBufferArgs }
551
- | { type: 'ui-image-dispose'; args: CmdUiImageDisposeArgs }
552
- | { type: 'ui-clipboard-paste'; args: CmdUiClipboardPasteArgs }
553
- | { type: 'ui-screenshot-reply'; args: CmdUiScreenshotReplyArgs }
554
- | {
555
- type: 'ui-access-kit-action-request';
556
- args: CmdUiAccessKitActionRequestArgs;
557
- }
558
- | {
559
- type: 'ui-form-upsert';
560
- form: {
561
- formId: string;
562
- windowId: number;
563
- realmId: number;
564
- documentId: number;
565
- disabled?: boolean;
566
- cycleMode?: UiFocusCycleMode;
567
- activeFieldsetId?: string;
568
- };
569
- }
570
- | { type: 'ui-form-dispose'; formId: string }
571
- | {
572
- type: 'ui-fieldset-upsert';
573
- fieldset: {
574
- formId: string;
575
- fieldsetId: string;
576
- disabled?: boolean;
577
- legendNodeId?: number;
578
- };
579
- }
580
- | { type: 'ui-fieldset-dispose'; formId: string; fieldsetId: string }
581
- | {
582
- type: 'ui-focusable-upsert';
583
- focusable: {
584
- formId: string;
585
- nodeId: number;
586
- tabIndex?: number;
587
- fieldsetId?: string;
588
- disabled?: boolean;
589
- orderHint?: number;
590
- };
591
- }
592
- | { type: 'ui-focusable-dispose'; nodeId: number }
593
- | {
594
- type: 'ui-focus-next';
595
- windowId: number;
596
- backwards?: boolean;
597
- formId?: string;
598
- }
599
- | {
600
- type: 'custom';
601
- name: string;
602
- data: JsonObject;
603
- };
604
-
605
- /**
606
- * Internal World Events:
607
- * Events emitted by systems or the engine to be consumed by other systems.
608
- */
609
- export type WorldEvent =
610
- | { type: 'entity-created'; entityId: number }
611
- | { type: 'entity-destroyed'; entityId: number }
612
- | { type: 'component-added'; entityId: number; componentType: ComponentType }
613
- | {
614
- type: 'component-removed';
615
- entityId: number;
616
- componentType: ComponentType;
617
- };
618
-
619
- /**
620
- * System Types
621
- */
622
-
623
- /**
624
- * Pipeline stage at which a system runs.
625
- */
626
- export type SystemStep = 'input' | 'update' | 'preRender' | 'postRender';
627
-
628
- /**
629
- * System execution context provided each frame.
630
- */
631
- export interface SystemContext {
632
- dt: number; // Delta time in seconds
633
- time: number; // Total time in seconds
634
- worldId: number;
635
- }
636
-
637
- /**
638
- * A System is a function that processes the WorldState.
639
- * It can emit new Intents, generate Core Commands, or interpret Events.
640
- */
641
- /**
642
- * System function signature.
643
- */
644
- export type System = (state: WorldState, context: SystemContext) => void;
645
-
646
- /**
647
- * Registration Hooks
648
- */
649
-
650
- /**
651
- * Registry of components and systems.
652
- */
653
- export interface EngineRegistry {
654
- components: Map<string, ComponentSchema>;
655
- systems: {
656
- input: System[];
657
- update: System[];
658
- preRender: System[];
659
- postRender: System[];
660
- };
661
- }
1
+ export * from './components';
2
+ export * from './intents';
3
+ export * from './systems';