@yagejs/core 0.1.0 → 0.2.0
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.
- package/dist/index.cjs +624 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +361 -23
- package/dist/index.d.ts +361 -23
- package/dist/index.js +620 -87
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -209,6 +209,17 @@ declare class EventToken<T = void> {
|
|
|
209
209
|
/** Create a typed event token. */
|
|
210
210
|
declare function defineEvent<T = void>(name: string): EventToken<T>;
|
|
211
211
|
|
|
212
|
+
/**
|
|
213
|
+
* A reusable entity template. Blueprints define how to assemble
|
|
214
|
+
* an entity from components, given optional parameters.
|
|
215
|
+
*/
|
|
216
|
+
interface Blueprint<P = void> {
|
|
217
|
+
readonly name: string;
|
|
218
|
+
build(entity: Entity, params: P): void;
|
|
219
|
+
}
|
|
220
|
+
/** Create a blueprint from a name and a build function. */
|
|
221
|
+
declare function defineBlueprint<P = void>(name: string, build: (entity: Entity, params: P) => void): Blueprint<P>;
|
|
222
|
+
|
|
212
223
|
/**
|
|
213
224
|
* Passed to `afterRestore` hooks so user code can resolve entity references
|
|
214
225
|
* that were captured as IDs at save time.
|
|
@@ -330,8 +341,20 @@ declare class Entity {
|
|
|
330
341
|
private _parent;
|
|
331
342
|
private _children;
|
|
332
343
|
constructor(name?: string, tags?: Iterable<string>);
|
|
333
|
-
/**
|
|
334
|
-
|
|
344
|
+
/**
|
|
345
|
+
* The scene this entity belongs to. Throws if the entity is not attached
|
|
346
|
+
* to a scene — which in practice only happens before `scene.spawn` /
|
|
347
|
+
* `addChild` wires it up, or after `destroy()` tears it down. Inside
|
|
348
|
+
* lifecycle methods (`setup`, component `onAdd`, `update`, etc.) this is
|
|
349
|
+
* always safe to access.
|
|
350
|
+
*
|
|
351
|
+
* For the rare case where you genuinely need to inspect whether an
|
|
352
|
+
* entity has a scene (e.g. defensive code in systems iterating a query
|
|
353
|
+
* result), use `tryScene` instead.
|
|
354
|
+
*/
|
|
355
|
+
get scene(): Scene;
|
|
356
|
+
/** The scene this entity belongs to, or `null` if detached. */
|
|
357
|
+
get tryScene(): Scene | null;
|
|
335
358
|
/** True if destroy() has been called. */
|
|
336
359
|
get isDestroyed(): boolean;
|
|
337
360
|
/** The parent entity, or null if this is a root entity. */
|
|
@@ -340,6 +363,28 @@ declare class Entity {
|
|
|
340
363
|
get children(): ReadonlyMap<string, Entity>;
|
|
341
364
|
/** Add a named child entity. Auto-adds to parent's scene if not already in one. */
|
|
342
365
|
addChild(name: string, child: Entity): void;
|
|
366
|
+
/**
|
|
367
|
+
* Spawn a new entity in this entity's scene and add it as a named child.
|
|
368
|
+
* Combines `scene.spawn(...)` + `this.addChild(name, ...)` in one call —
|
|
369
|
+
* the idiomatic way to compose entity trees (logical root + visual body
|
|
370
|
+
* + UI sibling + ...).
|
|
371
|
+
*
|
|
372
|
+
* Mirrors the overload shape of `Scene.spawn`: pass an Entity subclass
|
|
373
|
+
* (with optional setup params), a `Blueprint`, or omit for an anonymous
|
|
374
|
+
* base Entity.
|
|
375
|
+
*
|
|
376
|
+
* ```ts
|
|
377
|
+
* this.spawnChild("body", EnemyBody, { color: 0xff6b6b });
|
|
378
|
+
* this.spawnChild("hp", EnemyHealthBar);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
spawnChild(name: string): Entity;
|
|
382
|
+
spawnChild<E extends Entity>(name: string, Class: new () => E): E;
|
|
383
|
+
spawnChild<E extends Entity, P>(name: string, Class: new () => E & {
|
|
384
|
+
setup(params: P): void;
|
|
385
|
+
}, params: P): E;
|
|
386
|
+
spawnChild<P>(name: string, blueprint: Blueprint<P>, params: P): Entity;
|
|
387
|
+
spawnChild(name: string, blueprint: Blueprint<void>): Entity;
|
|
343
388
|
/** Remove a named child. Returns the detached entity. */
|
|
344
389
|
removeChild(name: string): Entity;
|
|
345
390
|
/** Get a child by name. Throws if not found. */
|
|
@@ -390,16 +435,45 @@ declare class Entity {
|
|
|
390
435
|
_setScene(scene: Scene | null, callbacks: EntityCallbacks | null): void;
|
|
391
436
|
}
|
|
392
437
|
|
|
438
|
+
/** Which scene op triggered this transition. */
|
|
439
|
+
type SceneTransitionKind = "push" | "pop" | "replace";
|
|
440
|
+
/** Context passed to a transition each frame. */
|
|
441
|
+
interface SceneTransitionContext {
|
|
442
|
+
/** Wall-clock ms elapsed since begin(). */
|
|
443
|
+
readonly elapsed: number;
|
|
444
|
+
readonly kind: SceneTransitionKind;
|
|
445
|
+
readonly engineContext: EngineContext;
|
|
446
|
+
/** The scene being left or removed (undefined on first push). */
|
|
447
|
+
readonly fromScene: Scene | undefined;
|
|
448
|
+
/** The scene being entered or revealed (undefined on last pop). */
|
|
449
|
+
readonly toScene: Scene | undefined;
|
|
450
|
+
}
|
|
393
451
|
/**
|
|
394
|
-
* A
|
|
395
|
-
*
|
|
452
|
+
* A scene transition animates the handoff between scene stack states.
|
|
453
|
+
*
|
|
454
|
+
* `SceneManager` keeps both the outgoing and incoming scenes on the stack
|
|
455
|
+
* for the transition's duration, then removes the outgoing scene afterward.
|
|
456
|
+
* Transitions use raw wall-clock dt and ignore engine + scene `timeScale`.
|
|
396
457
|
*/
|
|
397
|
-
interface
|
|
398
|
-
|
|
399
|
-
|
|
458
|
+
interface SceneTransition {
|
|
459
|
+
/** Total duration in wall-clock ms. */
|
|
460
|
+
readonly duration: number;
|
|
461
|
+
/** Called once when the transition starts. Set up resources here. */
|
|
462
|
+
begin?(ctx: SceneTransitionContext): void;
|
|
463
|
+
/** Called each frame with frame dt in ms. `ctx.elapsed` is clamped to `duration`. */
|
|
464
|
+
tick(dt: number, ctx: SceneTransitionContext): void;
|
|
465
|
+
/** Called when the transition ends. Tear down resources here. */
|
|
466
|
+
end?(ctx: SceneTransitionContext): void;
|
|
400
467
|
}
|
|
401
|
-
/**
|
|
402
|
-
|
|
468
|
+
/** Options accepted by `SceneManager.push/pop/replace`. */
|
|
469
|
+
interface SceneTransitionOptions {
|
|
470
|
+
transition?: SceneTransition;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Resolve the effective transition for a scene op.
|
|
474
|
+
* Precedence: call-site option → destination's `defaultTransition` → undefined.
|
|
475
|
+
*/
|
|
476
|
+
declare function resolveTransition(callSite: SceneTransition | undefined, destination: Scene | undefined): SceneTransition | undefined;
|
|
403
477
|
|
|
404
478
|
/** Filter criteria for entity queries. All fields are AND'd together. */
|
|
405
479
|
interface EntityFilter {
|
|
@@ -428,6 +502,8 @@ declare abstract class Scene {
|
|
|
428
502
|
readonly transparentBelow: boolean;
|
|
429
503
|
/** Asset handles to load before onEnter(). Override in subclasses. */
|
|
430
504
|
readonly preload?: readonly AssetHandle<unknown>[];
|
|
505
|
+
/** Default transition used when this scene is the destination of a push/pop/replace. */
|
|
506
|
+
readonly defaultTransition?: SceneTransition;
|
|
431
507
|
/** Manual pause flag. Set by game code to pause this scene regardless of stack position. */
|
|
432
508
|
paused: boolean;
|
|
433
509
|
/** Time scale multiplier for this scene. 1.0 = normal, 0.5 = half speed. Default: 1. */
|
|
@@ -439,10 +515,13 @@ declare abstract class Scene {
|
|
|
439
515
|
private queryCache;
|
|
440
516
|
private bus;
|
|
441
517
|
private _entityEventHandlers?;
|
|
518
|
+
private _scopedServices?;
|
|
442
519
|
/** Access the EngineContext. */
|
|
443
520
|
get context(): EngineContext;
|
|
444
521
|
/** Whether this scene is effectively paused (manual pause or paused by stack). */
|
|
445
522
|
get isPaused(): boolean;
|
|
523
|
+
/** Whether a scene transition is currently running. */
|
|
524
|
+
get isTransitioning(): boolean;
|
|
446
525
|
/** Convenience accessor for the AssetManager. */
|
|
447
526
|
get assets(): AssetManager;
|
|
448
527
|
/**
|
|
@@ -507,6 +586,24 @@ declare abstract class Scene {
|
|
|
507
586
|
serialize?(): unknown;
|
|
508
587
|
/** Called after entities are restored during save/load. Rebuild non-serializable state here. */
|
|
509
588
|
afterRestore?(data: unknown, resolve: SnapshotResolver): void;
|
|
589
|
+
/**
|
|
590
|
+
* Register a scene-scoped service. Called from a plugin's `beforeEnter`
|
|
591
|
+
* hook to make per-scene state (render tree, physics world) resolvable via
|
|
592
|
+
* `Component.use(key)`.
|
|
593
|
+
* @internal
|
|
594
|
+
*/
|
|
595
|
+
_registerScoped<T>(key: ServiceKey<T>, value: T): void;
|
|
596
|
+
/**
|
|
597
|
+
* Resolve a scene-scoped service, or `undefined` if none was registered.
|
|
598
|
+
* @internal
|
|
599
|
+
*/
|
|
600
|
+
_resolveScoped<T>(key: ServiceKey<T>): T | undefined;
|
|
601
|
+
/**
|
|
602
|
+
* Clear all scene-scoped services. Called by the SceneManager after
|
|
603
|
+
* `afterExit` hooks run, so plugin cleanup code still sees scoped state.
|
|
604
|
+
* @internal
|
|
605
|
+
*/
|
|
606
|
+
_clearScopedServices(): void;
|
|
510
607
|
/**
|
|
511
608
|
* Set the engine context. Called by SceneManager when the scene is pushed.
|
|
512
609
|
* @internal
|
|
@@ -544,7 +641,8 @@ declare abstract class Component {
|
|
|
544
641
|
private _cleanups?;
|
|
545
642
|
/**
|
|
546
643
|
* Access the entity's scene. Throws if the entity is not in a scene.
|
|
547
|
-
* Prefer this over `this.entity.scene
|
|
644
|
+
* Prefer this over threading through `this.entity.scene` in component
|
|
645
|
+
* code.
|
|
548
646
|
*/
|
|
549
647
|
get scene(): Scene;
|
|
550
648
|
/**
|
|
@@ -552,12 +650,19 @@ declare abstract class Component {
|
|
|
552
650
|
* Throws if the entity is not in a scene.
|
|
553
651
|
*/
|
|
554
652
|
get context(): EngineContext;
|
|
555
|
-
/**
|
|
653
|
+
/**
|
|
654
|
+
* Resolve a service by key, cached after first lookup. Scene-scoped values
|
|
655
|
+
* (registered via `scene._registerScoped`) take precedence over engine
|
|
656
|
+
* scope. A key declared with `scope: "scene"` that falls back to engine
|
|
657
|
+
* scope emits a one-shot dev warning — almost always signals a missed
|
|
658
|
+
* `beforeEnter` hook.
|
|
659
|
+
*/
|
|
556
660
|
protected use<T>(key: ServiceKey<T>): T;
|
|
661
|
+
private _warnScopedFallback;
|
|
557
662
|
/**
|
|
558
663
|
* Lazy proxy-based service resolution. Can be used at field-declaration time:
|
|
559
664
|
* ```ts
|
|
560
|
-
* readonly
|
|
665
|
+
* readonly input = this.service(InputManagerKey);
|
|
561
666
|
* ```
|
|
562
667
|
* The actual resolution is deferred until first property access.
|
|
563
668
|
*/
|
|
@@ -727,6 +832,12 @@ declare class SceneManager {
|
|
|
727
832
|
private _context;
|
|
728
833
|
private bus;
|
|
729
834
|
private assetManager;
|
|
835
|
+
private hookRegistry;
|
|
836
|
+
private logger;
|
|
837
|
+
private _currentRun;
|
|
838
|
+
private _pendingChain;
|
|
839
|
+
private _mutationDepth;
|
|
840
|
+
private _destroyed;
|
|
730
841
|
/**
|
|
731
842
|
* Set the engine context.
|
|
732
843
|
* @internal
|
|
@@ -738,27 +849,77 @@ declare class SceneManager {
|
|
|
738
849
|
get all(): readonly Scene[];
|
|
739
850
|
/** All non-paused scenes in the stack, bottom to top. */
|
|
740
851
|
get activeScenes(): readonly Scene[];
|
|
852
|
+
/** Whether a scene transition is currently running. */
|
|
853
|
+
get isTransitioning(): boolean;
|
|
741
854
|
/**
|
|
742
855
|
* Push a scene onto the stack. Scenes below may receive onPause().
|
|
743
856
|
* If the scene declares a `preload` array, assets are loaded before onEnter().
|
|
744
|
-
* Await the returned promise when using preloaded scenes.
|
|
745
857
|
*/
|
|
746
|
-
push(scene: Scene): Promise<void>;
|
|
858
|
+
push(scene: Scene, opts?: SceneTransitionOptions): Promise<void>;
|
|
747
859
|
/** Pop the top scene. Scenes below may receive onResume(). */
|
|
748
|
-
pop(): Scene | undefined
|
|
860
|
+
pop(opts?: SceneTransitionOptions): Promise<Scene | undefined>;
|
|
749
861
|
/**
|
|
750
|
-
* Replace the top scene.
|
|
751
|
-
*
|
|
862
|
+
* Replace the top scene. Without a transition the old scene exits first,
|
|
863
|
+
* then the new scene enters. With a transition the new scene is pushed
|
|
864
|
+
* first, both scenes coexist for the transition duration, then the old
|
|
865
|
+
* scene is removed at the end.
|
|
752
866
|
*/
|
|
753
|
-
replace(scene: Scene): Promise<void>;
|
|
754
|
-
/**
|
|
755
|
-
|
|
867
|
+
replace(scene: Scene, opts?: SceneTransitionOptions): Promise<void>;
|
|
868
|
+
/**
|
|
869
|
+
* Pop every scene on the stack, top to bottom. Each receives onExit().
|
|
870
|
+
* Queued like push/pop/replace — runs after any in-flight transition.
|
|
871
|
+
* Use for "restart from menu"-style flows. Does not run transitions.
|
|
872
|
+
*/
|
|
873
|
+
popAll(): Promise<void>;
|
|
874
|
+
/**
|
|
875
|
+
* Run the full scene-enter lifecycle (beforeEnter hooks, preload, onEnter)
|
|
876
|
+
* for a scene that is NOT placed on the stack. Used by infrastructure
|
|
877
|
+
* plugins like DebugPlugin that render a scene off-stack.
|
|
878
|
+
* @internal
|
|
879
|
+
*/
|
|
880
|
+
_mountDetached(scene: Scene): Promise<void>;
|
|
881
|
+
/**
|
|
882
|
+
* Run the scene-exit lifecycle (onExit, entity destruction, afterExit
|
|
883
|
+
* hooks, scoped-service clear) for a detached scene.
|
|
884
|
+
* @internal
|
|
885
|
+
*/
|
|
886
|
+
_unmountDetached(scene: Scene): void;
|
|
887
|
+
/**
|
|
888
|
+
* Mark the manager destroyed and synchronously tear down every scene.
|
|
889
|
+
* Called by Engine.destroy(). Any queued async work short-circuits on
|
|
890
|
+
* resume; in-flight transitions' pending promises are resolved via
|
|
891
|
+
* _cleanupRun so they don't leak.
|
|
892
|
+
* @internal
|
|
893
|
+
*/
|
|
894
|
+
_destroy(): void;
|
|
756
895
|
/**
|
|
757
896
|
* Flush destroy queues for all active scenes.
|
|
758
897
|
* Called by the engine during endOfFrame.
|
|
759
898
|
* @internal
|
|
760
899
|
*/
|
|
761
900
|
_flushDestroyQueues(): void;
|
|
901
|
+
/**
|
|
902
|
+
* Advance the active transition by `dt` ms. Called by Engine's earlyUpdate
|
|
903
|
+
* callback with raw (unscaled) wall-clock dt.
|
|
904
|
+
* @internal
|
|
905
|
+
*/
|
|
906
|
+
_tickTransition(dt: number): void;
|
|
907
|
+
private _enqueue;
|
|
908
|
+
private _pushScene;
|
|
909
|
+
private _popScene;
|
|
910
|
+
private _replaceScene;
|
|
911
|
+
private _removeScene;
|
|
912
|
+
private _preloadScene;
|
|
913
|
+
private _teardownScene;
|
|
914
|
+
private _runTransition;
|
|
915
|
+
private _cleanupRun;
|
|
916
|
+
private _safeTick;
|
|
917
|
+
private _safeCall;
|
|
918
|
+
private _makeContext;
|
|
919
|
+
private _snapshotPauseStates;
|
|
920
|
+
private _assertNotMutating;
|
|
921
|
+
private _withMutation;
|
|
922
|
+
private _withMutationSync;
|
|
762
923
|
/** Fire onPause() for scenes that transitioned from not-paused to paused. */
|
|
763
924
|
private _firePauseTransitions;
|
|
764
925
|
/** Fire onResume() for scenes that transitioned from paused to not-paused. */
|
|
@@ -883,6 +1044,23 @@ interface EngineEvents {
|
|
|
883
1044
|
oldScene: SceneRef;
|
|
884
1045
|
newScene: SceneRef;
|
|
885
1046
|
};
|
|
1047
|
+
"scene:transition:started": {
|
|
1048
|
+
kind: SceneTransitionKind;
|
|
1049
|
+
fromScene: SceneRef | undefined;
|
|
1050
|
+
toScene: SceneRef | undefined;
|
|
1051
|
+
};
|
|
1052
|
+
"scene:transition:ended": {
|
|
1053
|
+
kind: SceneTransitionKind;
|
|
1054
|
+
fromScene: SceneRef | undefined;
|
|
1055
|
+
toScene: SceneRef | undefined;
|
|
1056
|
+
};
|
|
1057
|
+
"scene:loading:progress": {
|
|
1058
|
+
scene: Scene;
|
|
1059
|
+
ratio: number;
|
|
1060
|
+
};
|
|
1061
|
+
"scene:loading:done": {
|
|
1062
|
+
scene: Scene;
|
|
1063
|
+
};
|
|
886
1064
|
"engine:started": undefined;
|
|
887
1065
|
"engine:stopped": undefined;
|
|
888
1066
|
}
|
|
@@ -899,6 +1077,39 @@ declare class EventBus<E = EventMap> {
|
|
|
899
1077
|
clear(event?: keyof E): void;
|
|
900
1078
|
}
|
|
901
1079
|
|
|
1080
|
+
/**
|
|
1081
|
+
* Plugin hooks invoked by the SceneManager at scene lifecycle points.
|
|
1082
|
+
* Plugins register hooks via `engine.registerSceneHooks(hooks)` to set up or
|
|
1083
|
+
* tear down per-scene state (e.g. render containers, physics worlds).
|
|
1084
|
+
*/
|
|
1085
|
+
interface SceneHooks {
|
|
1086
|
+
/**
|
|
1087
|
+
* Runs after the scene's context is bound but before preload / `onEnter`.
|
|
1088
|
+
* Awaited serially so scoped services registered here are ready when the
|
|
1089
|
+
* scene's own code runs. Fires on `push`, `replace`, and `_mountDetached`.
|
|
1090
|
+
*/
|
|
1091
|
+
beforeEnter?(scene: Scene): void | Promise<void>;
|
|
1092
|
+
/**
|
|
1093
|
+
* Runs after `onExit` + `_destroyAllEntities` and before the scene's
|
|
1094
|
+
* scoped-service map is cleared. Fires on `pop`, `replace`, `clear`, and
|
|
1095
|
+
* `_unmountDetached`.
|
|
1096
|
+
*/
|
|
1097
|
+
afterExit?(scene: Scene): void;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Registry of scene hooks. Held by the engine, consumed by the SceneManager.
|
|
1101
|
+
* @internal
|
|
1102
|
+
*/
|
|
1103
|
+
declare class SceneHookRegistry {
|
|
1104
|
+
private readonly hooks;
|
|
1105
|
+
register(hooks: SceneHooks): () => void;
|
|
1106
|
+
/** Run all `beforeEnter` hooks serially. */
|
|
1107
|
+
runBeforeEnter(scene: Scene): Promise<void>;
|
|
1108
|
+
runAfterExit(scene: Scene): void;
|
|
1109
|
+
}
|
|
1110
|
+
/** DI key for the scene-hook registry. @internal */
|
|
1111
|
+
declare const SceneHookRegistryKey: ServiceKey<SceneHookRegistry>;
|
|
1112
|
+
|
|
902
1113
|
/** Engine configuration. */
|
|
903
1114
|
interface EngineConfig {
|
|
904
1115
|
/** Enable debug mode (Inspector API, debug logging). */
|
|
@@ -930,6 +1141,7 @@ declare class Engine {
|
|
|
930
1141
|
private readonly scheduler;
|
|
931
1142
|
private readonly errorBoundary;
|
|
932
1143
|
private readonly queryCache;
|
|
1144
|
+
private readonly sceneHooks;
|
|
933
1145
|
/** The asset manager. */
|
|
934
1146
|
readonly assets: AssetManager;
|
|
935
1147
|
private readonly plugins;
|
|
@@ -937,6 +1149,12 @@ declare class Engine {
|
|
|
937
1149
|
private started;
|
|
938
1150
|
private readonly debug;
|
|
939
1151
|
constructor(config?: EngineConfig);
|
|
1152
|
+
/**
|
|
1153
|
+
* Register scene lifecycle hooks. The returned function unregisters the
|
|
1154
|
+
* hooks. Infrastructure plugins (renderer, physics, debug) register hooks
|
|
1155
|
+
* in their `install` or `onStart` to set up and tear down per-scene state.
|
|
1156
|
+
*/
|
|
1157
|
+
registerSceneHooks(hooks: SceneHooks): () => void;
|
|
940
1158
|
/** Register a plugin. Must be called before start(). */
|
|
941
1159
|
use(plugin: Plugin): this;
|
|
942
1160
|
/** Start the engine. Installs plugins in topological order, starts the game loop. */
|
|
@@ -951,13 +1169,27 @@ declare class Engine {
|
|
|
951
1169
|
private topologicalSort;
|
|
952
1170
|
}
|
|
953
1171
|
|
|
1172
|
+
/** The resolution scope for a service. */
|
|
1173
|
+
type ServiceScope = "engine" | "scene";
|
|
1174
|
+
/** Options passed to `new ServiceKey(id, options)`. */
|
|
1175
|
+
interface ServiceKeyOptions {
|
|
1176
|
+
/**
|
|
1177
|
+
* Declared scope. `"scene"` keys are expected to be registered per-scene
|
|
1178
|
+
* via a `beforeEnter` hook; `Component.use` will check scene scope first
|
|
1179
|
+
* and warn if it falls back to engine scope.
|
|
1180
|
+
* Default: `"engine"`.
|
|
1181
|
+
*/
|
|
1182
|
+
scope?: ServiceScope;
|
|
1183
|
+
}
|
|
954
1184
|
/** A typed key for service registration and resolution. */
|
|
955
1185
|
declare class ServiceKey<T> {
|
|
956
1186
|
/** Unique string identifier for this service. */
|
|
957
1187
|
readonly id: string;
|
|
1188
|
+
/** Declared scope (engine or scene). Defaults to `"engine"`. */
|
|
1189
|
+
readonly scope: ServiceScope;
|
|
958
1190
|
constructor(
|
|
959
1191
|
/** Unique string identifier for this service. */
|
|
960
|
-
id: string);
|
|
1192
|
+
id: string, options?: ServiceKeyOptions);
|
|
961
1193
|
/** Phantom field to preserve the generic type. */
|
|
962
1194
|
readonly _type: T;
|
|
963
1195
|
}
|
|
@@ -1072,7 +1304,7 @@ interface Plugin {
|
|
|
1072
1304
|
/** Register systems with the scheduler. Called after install. */
|
|
1073
1305
|
registerSystems?(scheduler: SystemScheduler): void;
|
|
1074
1306
|
/** Called after all plugins are installed and the engine has started. */
|
|
1075
|
-
onStart?(): void
|
|
1307
|
+
onStart?(): void | Promise<void>;
|
|
1076
1308
|
/** Called when the engine is destroyed. */
|
|
1077
1309
|
onDestroy?(): void;
|
|
1078
1310
|
}
|
|
@@ -1265,6 +1497,112 @@ declare class ComponentUpdateSystem extends BaseComponentUpdateSystem {
|
|
|
1265
1497
|
update(dt: number): void;
|
|
1266
1498
|
}
|
|
1267
1499
|
|
|
1500
|
+
/**
|
|
1501
|
+
* Base class for a progress-bar style loading screen.
|
|
1502
|
+
*
|
|
1503
|
+
* Preloads the target scene's assets through the `AssetManager`, exposes
|
|
1504
|
+
* `progress` and emits `scene:loading:progress` / `scene:loading:done` on
|
|
1505
|
+
* the engine event bus, enforces `minDuration` to prevent flicker on cached
|
|
1506
|
+
* loads, then replaces itself with `target` — optionally through a
|
|
1507
|
+
* transition.
|
|
1508
|
+
*
|
|
1509
|
+
* LoadingScene owns orchestration only. It does not render anything. To show
|
|
1510
|
+
* a progress UI, spawn an entity that subscribes to the loading events (the
|
|
1511
|
+
* canonical default is `LoadingSceneProgressBar` in `@yagejs/ui`, or any
|
|
1512
|
+
* custom component). The loading scene is a normal Scene, so you can use
|
|
1513
|
+
* `onEnter` to spawn whatever you want.
|
|
1514
|
+
*
|
|
1515
|
+
* ```ts
|
|
1516
|
+
* class Boot extends LoadingScene {
|
|
1517
|
+
* readonly target = new GameScene();
|
|
1518
|
+
* readonly minDuration = 500;
|
|
1519
|
+
* readonly transition = fade({ duration: 300 });
|
|
1520
|
+
* override onEnter() {
|
|
1521
|
+
* this.spawn(LoadingSceneProgressBar);
|
|
1522
|
+
* this.startLoading();
|
|
1523
|
+
* }
|
|
1524
|
+
* }
|
|
1525
|
+
*
|
|
1526
|
+
* await engine.scenes.replace(new Boot());
|
|
1527
|
+
* ```
|
|
1528
|
+
*
|
|
1529
|
+
* Set `autoContinue = false` to gate the handoff behind a `continue()` call
|
|
1530
|
+
* — useful for "press any key to continue" flows. `scene:loading:done`
|
|
1531
|
+
* still fires so UI can react (show a prompt), and whoever eventually
|
|
1532
|
+
* calls `this.continue()` triggers the transition.
|
|
1533
|
+
*/
|
|
1534
|
+
declare abstract class LoadingScene extends Scene {
|
|
1535
|
+
readonly name: string;
|
|
1536
|
+
/**
|
|
1537
|
+
* Scene to load and transition to. Accepts an instance or a factory —
|
|
1538
|
+
* use a factory when target construction should be deferred until
|
|
1539
|
+
* loading starts (heavy constructors, side effects). The factory runs
|
|
1540
|
+
* before `assets.loadAll` so `target.preload` can be inspected.
|
|
1541
|
+
*/
|
|
1542
|
+
abstract readonly target: Scene | (() => Scene);
|
|
1543
|
+
/**
|
|
1544
|
+
* Minimum wall-clock ms the scene stays visible before handing off.
|
|
1545
|
+
* Prevents flicker on cached loads. Default 0.
|
|
1546
|
+
*/
|
|
1547
|
+
readonly minDuration: number;
|
|
1548
|
+
/** Transition used for the loading → target handoff. */
|
|
1549
|
+
readonly transition?: SceneTransition;
|
|
1550
|
+
/**
|
|
1551
|
+
* When true (default), the handoff fires automatically after loading and
|
|
1552
|
+
* `minDuration`. Set false to gate it behind `continue()` — useful when
|
|
1553
|
+
* the loading scene also asks the player to press a key or click.
|
|
1554
|
+
*/
|
|
1555
|
+
readonly autoContinue: boolean;
|
|
1556
|
+
/**
|
|
1557
|
+
* Optional hook; fires if asset loading rejects. The scene stays mounted
|
|
1558
|
+
* whether or not this is set. When set, the hook is the recovery channel:
|
|
1559
|
+
* draw a retry UI, push an error scene, or call `this.startLoading()`
|
|
1560
|
+
* again to retry the load. When unset, the error is logged via the engine
|
|
1561
|
+
* logger and the scene remains mounted in a failed state with no
|
|
1562
|
+
* automatic recovery.
|
|
1563
|
+
*
|
|
1564
|
+
* The hook may still be running when the scene is replaced externally —
|
|
1565
|
+
* don't assume the scene is live (check `this.context.tryResolve` rather
|
|
1566
|
+
* than `this.service` before touching engine services, and avoid spawning
|
|
1567
|
+
* new entities after an `await`).
|
|
1568
|
+
*/
|
|
1569
|
+
onLoadError?(error: Error): void | Promise<void>;
|
|
1570
|
+
private _progress;
|
|
1571
|
+
private _started;
|
|
1572
|
+
private _active;
|
|
1573
|
+
private _continueRequested;
|
|
1574
|
+
private _continueGate?;
|
|
1575
|
+
private _attempt;
|
|
1576
|
+
/** Current load progress, 0 → 1. Updated as the AssetManager reports progress. */
|
|
1577
|
+
get progress(): number;
|
|
1578
|
+
/**
|
|
1579
|
+
* Kick off asset loading. While a load is in flight, subsequent calls
|
|
1580
|
+
* are no-ops. After a load failure the guard is released, so calling
|
|
1581
|
+
* `startLoading()` from `onLoadError` (or from a retry button) kicks off
|
|
1582
|
+
* a fresh load against the same target.
|
|
1583
|
+
*
|
|
1584
|
+
* Usually called once from `onEnter` after spawning the loading UI:
|
|
1585
|
+
* ```ts
|
|
1586
|
+
* override onEnter() {
|
|
1587
|
+
* this.spawn(LoadingSceneProgressBar);
|
|
1588
|
+
* this.startLoading();
|
|
1589
|
+
* }
|
|
1590
|
+
* ```
|
|
1591
|
+
*
|
|
1592
|
+
* Deferring the call lets you gate the start of the load behind a
|
|
1593
|
+
* title screen, "press any key" prompt, intro animation, etc.
|
|
1594
|
+
*/
|
|
1595
|
+
startLoading(): void;
|
|
1596
|
+
/**
|
|
1597
|
+
* Trigger the handoff to `target`. No-op if already called or if
|
|
1598
|
+
* `autoContinue` already fired it. If called before loading finishes,
|
|
1599
|
+
* the handoff runs as soon as loading + `minDuration` complete.
|
|
1600
|
+
*/
|
|
1601
|
+
continue(): void;
|
|
1602
|
+
onExit(): void;
|
|
1603
|
+
private _run;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1268
1606
|
/** Static factory for creating tween Processes. */
|
|
1269
1607
|
declare const Tween: {
|
|
1270
1608
|
/** Tween a numeric property on a target object. */
|
|
@@ -1509,4 +1847,4 @@ declare function advanceFrames(engine: Engine, n: number, dtMs?: number): void;
|
|
|
1509
1847
|
|
|
1510
1848
|
declare const VERSION = "0.0.0";
|
|
1511
1849
|
|
|
1512
|
-
export { AssetHandle, type AssetLoader, AssetManager, AssetManagerKey, type Blueprint, Component, type ComponentClass, ComponentFixedUpdateSystem, ComponentUpdateSystem, type EasingFunction, Engine, type EngineConfig, EngineContext, type EngineEvents, EngineKey, type EngineSnapshot, Entity, type EntityCallbacks, type EntityFilter, type EntitySnapshot, ErrorBoundary, ErrorBoundaryKey, type ErrorSnapshot, EventBus, EventBusKey, type EventMap, EventToken, GameLoop, type GameLoopCallbacks, type GameLoopConfig, GameLoopKey, Inspector, InspectorKey, type Interpolatable, type Keyframe, type KeyframeAnimationDef, KeyframeAnimator, type KeyframeTrackOptions, type LogEntry, LogLevel, Logger, type LoggerConfig, LoggerKey, MathUtils, Phase, type Plugin, Process, ProcessComponent, type ProcessOptions, ProcessSlot, type ProcessSlotConfig, ProcessSystem, ProcessSystemKey, QueryCache, QueryCacheKey, QueryResult, SERIALIZABLE_KEY, Scene, SceneManager, SceneManagerKey, type SceneSnapshot, Sequence, SerializableRegistry, ServiceKey, type SnapshotResolver, System, SystemScheduler, SystemSchedulerKey, type SystemSnapshot, TimerEntity, TraitToken, Transform, type TransformData, Tween, VERSION, Vec2, type Vec2Like, _resetEntityIdCounter, advanceFrames, createKeyframeTrack, createMockEntity, createMockScene, createTestEngine, defineBlueprint, defineEvent, defineTrait, easeInOutQuad, easeInQuad, easeLinear, easeOutBounce, easeOutQuad, filterEntities, getSerializableType, interpolate, isSerializable, serializable, trait };
|
|
1850
|
+
export { AssetHandle, type AssetLoader, AssetManager, AssetManagerKey, type Blueprint, Component, type ComponentClass, ComponentFixedUpdateSystem, ComponentUpdateSystem, type EasingFunction, Engine, type EngineConfig, EngineContext, type EngineEvents, EngineKey, type EngineSnapshot, Entity, type EntityCallbacks, type EntityFilter, type EntitySnapshot, ErrorBoundary, ErrorBoundaryKey, type ErrorSnapshot, EventBus, EventBusKey, type EventMap, EventToken, GameLoop, type GameLoopCallbacks, type GameLoopConfig, GameLoopKey, Inspector, InspectorKey, type Interpolatable, type Keyframe, type KeyframeAnimationDef, KeyframeAnimator, type KeyframeTrackOptions, LoadingScene, type LogEntry, LogLevel, Logger, type LoggerConfig, LoggerKey, MathUtils, Phase, type Plugin, Process, ProcessComponent, type ProcessOptions, ProcessSlot, type ProcessSlotConfig, ProcessSystem, ProcessSystemKey, QueryCache, QueryCacheKey, QueryResult, SERIALIZABLE_KEY, Scene, SceneHookRegistry, SceneHookRegistryKey, type SceneHooks, SceneManager, SceneManagerKey, type SceneSnapshot, type SceneTransition, type SceneTransitionContext, type SceneTransitionKind, type SceneTransitionOptions, Sequence, SerializableRegistry, ServiceKey, type ServiceKeyOptions, type ServiceScope, type SnapshotResolver, System, SystemScheduler, SystemSchedulerKey, type SystemSnapshot, TimerEntity, TraitToken, Transform, type TransformData, Tween, VERSION, Vec2, type Vec2Like, _resetEntityIdCounter, advanceFrames, createKeyframeTrack, createMockEntity, createMockScene, createTestEngine, defineBlueprint, defineEvent, defineTrait, easeInOutQuad, easeInQuad, easeLinear, easeOutBounce, easeOutQuad, filterEntities, getSerializableType, interpolate, isSerializable, resolveTransition, serializable, trait };
|