handler-playable-sdk 0.2.7 → 0.3.2

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.
@@ -1,4 +1,6 @@
1
+ import * as PixiJS from 'pixi.js';
1
2
  import { Application, Container, Texture, Sprite, Text, Graphics, Point } from 'pixi.js';
3
+ import { O as ObjectCentricConfig$1 } from '../loader-object-centric-C1QteFfG.js';
2
4
 
3
5
  /**
4
6
  * Handler SDK - PixiJS Base Context
@@ -136,6 +138,14 @@ declare class GameObject {
136
138
  * Update config and sync (for hot-reload)
137
139
  */
138
140
  updateConfig(newConfig: any): void;
141
+ /**
142
+ * Apply anchor from render/transform config (sprites only)
143
+ */
144
+ private applyAnchor;
145
+ /**
146
+ * Apply optional non-uniform scale from effects (if provided)
147
+ */
148
+ private applyEffectsScale;
139
149
  /**
140
150
  * Get component value
141
151
  */
@@ -247,100 +257,12 @@ declare function registerFont(fontId: string, definition: FontDefinition): void;
247
257
  declare function getRegisteredFontIds(): string[];
248
258
 
249
259
  /**
250
- * Handler SDK - Type Definitions for PixiJS Integration
260
+ * Object-centric configuration
251
261
  *
252
- * DO NOT EDIT - Handler SDK Core
253
- */
254
- /**
255
- * Object configuration from JSON files
256
- */
257
- interface ObjectConfig {
258
- object_config?: string;
259
- transform?: {
260
- position?: {
261
- x: number;
262
- y: number;
263
- };
264
- scale?: number;
265
- rotation?: number;
266
- offset?: {
267
- x?: number;
268
- y?: number;
269
- };
270
- };
271
- render?: {
272
- z_index?: number;
273
- alpha?: number;
274
- visible?: boolean;
275
- tint?: number | string | null;
276
- background_color?: string;
277
- background_alpha?: number;
278
- border_color?: string;
279
- };
280
- gameplay?: {
281
- rules?: Record<string, unknown>;
282
- tuning?: Record<string, unknown>;
283
- };
284
- ui?: {
285
- text?: string;
286
- font?: string;
287
- fontSize?: number;
288
- letterSpacing?: number;
289
- align?: string;
290
- };
291
- effects?: Record<string, unknown>;
292
- audio?: Record<string, unknown>;
293
- physics?: Record<string, unknown>;
294
- interaction?: Record<string, unknown>;
295
- identity?: Record<string, unknown>;
296
- visibility?: Record<string, unknown>;
297
- }
298
- /**
299
- * Engine configuration
262
+ * Single source of truth is the config loader type.
263
+ * Pixi systems/engine should never diverge from that shape.
300
264
  */
301
- interface EngineConfig {
302
- assets?: Record<string, string>;
303
- runtime?: {
304
- ui?: Record<string, unknown>;
305
- theme?: Record<string, unknown>;
306
- ui_styles?: Record<string, unknown>;
307
- timeline?: Record<string, number>;
308
- };
309
- }
310
- /**
311
- * Theme configuration
312
- */
313
- interface ThemeConfig {
314
- background_color?: string;
315
- text_color?: string;
316
- square_color?: string;
317
- cta_background?: string;
318
- cta_text?: string;
319
- melt_color?: string;
320
- danger_color?: string;
321
- brush_color?: string;
322
- success_color?: string;
323
- }
324
- /**
325
- * Gameplay configuration
326
- */
327
- interface GameplayConfig {
328
- [key: string]: unknown;
329
- }
330
- /**
331
- * Object-centric configuration
332
- * This is the main config type that students work with
333
- */
334
- interface ObjectCentricConfig {
335
- /** Map of object instance IDs to their configurations */
336
- objects: Map<string, ObjectConfig>;
337
- /** Engine configuration (assets, runtime settings) */
338
- engine: EngineConfig;
339
- /** Theme configuration */
340
- theme: ThemeConfig;
341
- /** Gameplay configuration */
342
- gameplay: GameplayConfig;
343
- }
265
+ type ObjectCentricConfig = ObjectCentricConfig$1;
344
266
 
345
267
  /**
346
268
  * Handler SDK - EndGame UI Panel
@@ -375,6 +297,69 @@ declare function animatePanelEntrance(elements: EndGamePanelElements, config: Ob
375
297
  */
376
298
  declare function animateHandClick(hand: Sprite, ctaButton: Graphics, config: ObjectCentricConfig, onClick: () => void): void;
377
299
 
300
+ interface SplashScreenConfig {
301
+ enabled: boolean;
302
+ show_on_start: boolean;
303
+ background_color: string;
304
+ background_alpha: number;
305
+ title: string;
306
+ subtitle: string;
307
+ button_label: string;
308
+ title_color: string;
309
+ subtitle_color: string;
310
+ button_bg: string;
311
+ button_text: string;
312
+ button_width: number;
313
+ button_height: number;
314
+ button_radius: number;
315
+ loading_blur: boolean;
316
+ loading_blur_strength: number;
317
+ loading_overlay_alpha: number;
318
+ font_family: string;
319
+ title_size: number;
320
+ subtitle_size: number;
321
+ loading_text: string;
322
+ loading_text_scale: number;
323
+ }
324
+ declare class SplashScreen {
325
+ private app;
326
+ private stage;
327
+ private activeConfig;
328
+ private splashConfig;
329
+ private splashEnabled;
330
+ private loadingBlurEnabled;
331
+ private loadingBlurStrength;
332
+ private loadingOverlayAlpha;
333
+ private splashLayer;
334
+ private splashBg;
335
+ private splashTitle;
336
+ private splashSubtitle;
337
+ private splashButton;
338
+ private splashButtonText;
339
+ private loadingLayer;
340
+ private loadingBg;
341
+ private loadingText;
342
+ private loadingTime;
343
+ private tickLoadingHandler;
344
+ constructor(app: Application, stage: Container, activeConfig: ObjectCentricConfig);
345
+ private resolveLoadingTextStyle;
346
+ syncConfig(next?: any): void;
347
+ updateLayout(width: number, height: number): void;
348
+ private updateSplashLayout;
349
+ private updateLoadingLayout;
350
+ show(): void;
351
+ hide(): void;
352
+ startLoadingAnimation(): void;
353
+ stopLoadingAnimation(): void;
354
+ destroyLoadingLayer(): void;
355
+ applyLoadingBlur(background: Sprite | Graphics): any[] | null;
356
+ removeLoadingBlur(background: Sprite | Graphics, prevFilters: any[] | null): void;
357
+ setupWindowGlobals(): void;
358
+ getSplashButton(): Graphics;
359
+ shouldShowOnStart(): boolean;
360
+ destroy(): void;
361
+ }
362
+
378
363
  /**
379
364
  * Handler SDK - Tutorial UI Components
380
365
  *
@@ -460,6 +445,17 @@ declare function playLottieOverlay(objectId: string, root: HTMLElement, config:
460
445
  *
461
446
  * DO NOT EDIT - Handler SDK Core
462
447
  */
448
+ type BuildMode = 'dev' | 'brand' | 'publish';
449
+ type BuildSettings = {
450
+ buildMode?: BuildMode;
451
+ assetsInlined?: boolean;
452
+ };
453
+ declare global {
454
+ interface Window {
455
+ INLINE_ASSETS?: Record<string, string>;
456
+ __BUILD_SETTINGS__?: BuildSettings;
457
+ }
458
+ }
463
459
  type AssetDefinition = {
464
460
  type: string;
465
461
  path: string;
@@ -539,4 +535,322 @@ declare class ObjectFactory {
539
535
  private static applyTransform;
540
536
  }
541
537
 
542
- export { AssetCache, type AssetDefinition, AssetLoader, type EndGamePanelElements, GameObject, GameObjectManager, type ObjectCentricConfig, ObjectFactory, type PixiBaseContext, type PixiTheme, Renderer, Transform, animateHandClick, animatePanelEntrance, createEndGamePanel, createHandTutorial, createPixiBase, createTutorialLabel, getRegisteredFontIds, playLottieOverlay, registerFont, registerType, resolveFont, resolveFontWeight, setLottieInstance, updateHandAnimation };
538
+ /**
539
+ * Base context provided to all systems
540
+ */
541
+ interface SystemContext {
542
+ app: Application;
543
+ stage: Container;
544
+ config: ObjectCentricConfig$1;
545
+ gameObjectManager: GameObjectManager;
546
+ destinationUrl: string;
547
+ root: HTMLElement;
548
+ engine: GameEngine;
549
+ }
550
+ /**
551
+ * Base class for all game systems
552
+ */
553
+ declare abstract class BaseSystem {
554
+ protected context: SystemContext;
555
+ /**
556
+ * Internal initialization by GameEngine
557
+ */
558
+ setContext(context: SystemContext): void;
559
+ /**
560
+ * Called once during engine initialization
561
+ */
562
+ init?(): void | Promise<void>;
563
+ /**
564
+ * Called after all systems are initialized
565
+ */
566
+ onStart?(): void | Promise<void>;
567
+ /**
568
+ * Called every frame
569
+ * @param deltaTime normalized time since last frame
570
+ * @param totalTime total time elapsed since start
571
+ */
572
+ update?(deltaTime: number, totalTime: number): void;
573
+ /**
574
+ * Called when the screen is resized
575
+ */
576
+ onResize?(width: number, height: number): void;
577
+ /**
578
+ * Called when config changes (hot-reload)
579
+ */
580
+ onConfigUpdate?(newConfig: ObjectCentricConfig$1): void;
581
+ /**
582
+ * Cleanup system
583
+ */
584
+ onDestroy?(): void;
585
+ }
586
+
587
+ declare class GameEngine {
588
+ private app;
589
+ private stage;
590
+ private gameObjectManager;
591
+ private systems;
592
+ private totalTime;
593
+ private config;
594
+ private destinationUrl;
595
+ private root;
596
+ constructor(root: HTMLElement, config: ObjectCentricConfig$1, destinationUrl: string);
597
+ /**
598
+ * Initialize PIXI and systems
599
+ */
600
+ init(theme: any): Promise<{
601
+ app: Application;
602
+ gameObjectManager: GameObjectManager;
603
+ }>;
604
+ /**
605
+ * Register systems before starting
606
+ */
607
+ registerSystems(systems: BaseSystem[]): void;
608
+ /**
609
+ * Start the game loop
610
+ */
611
+ start(): Promise<void>;
612
+ /**
613
+ * Central update loop
614
+ */
615
+ private update;
616
+ /**
617
+ * Propagate resize
618
+ */
619
+ resize(width: number, height: number): void;
620
+ /**
621
+ * Handle hot-reload
622
+ */
623
+ updateConfig(newConfig: ObjectCentricConfig$1): void;
624
+ /**
625
+ * Destroy engine and systems
626
+ */
627
+ destroy(): void;
628
+ getApp(): Application;
629
+ getGameObjectManager(): GameObjectManager;
630
+ getTotalTime(): number;
631
+ /**
632
+ * Find a registered system by its class
633
+ */
634
+ getSystem<T extends BaseSystem>(type: new (...args: any[]) => T): T;
635
+ }
636
+
637
+ /**
638
+ * Runtime Object Registry
639
+ *
640
+ * Passive config registry that reads object configs from loaded ObjectCentricConfig.
641
+ * Hot-reload friendly - config passed at runtime.
642
+ *
643
+ * DO NOT EDIT - Base Layer
644
+ */
645
+
646
+ /**
647
+ * Runtime object registry - provides access to object configs
648
+ */
649
+ declare class RuntimeObjectRegistry {
650
+ private config;
651
+ /**
652
+ * Initialize registry with config
653
+ */
654
+ init(config: ObjectCentricConfig$1): void;
655
+ /**
656
+ * Get object config by instance ID
657
+ */
658
+ get(instanceId: string): any;
659
+ /**
660
+ * Get all object instance IDs
661
+ */
662
+ getAllIds(): string[];
663
+ /**
664
+ * Check if object exists
665
+ */
666
+ has(instanceId: string): boolean;
667
+ }
668
+
669
+ /**
670
+ * Base Layer - PixiJS Instance
671
+ *
672
+ * Provides isolated pixi.js instance for base layer.
673
+ * Prevents conflicts with student layer's pixi instance.
674
+ *
675
+ * DO NOT EDIT - Base Layer
676
+ */
677
+
678
+ declare const basePixi: typeof PixiJS;
679
+
680
+ /**
681
+ * Assets Proxy - Student-Facing API
682
+ *
683
+ * Provides simple API: Assets.ready() then Assets.xxx
684
+ *
685
+ * RULES:
686
+ * - Singleton instances by default
687
+ * - Assets.ready() resolves when all objects preloaded and Assets.xxx accesses are sync/safe
688
+ * - resetScene() clears instance cache only (NOT asset cache)
689
+ * - reloadObject(id) explicitly recreates single object
690
+ * - Separate asset cache (global) and instance cache (scene-scoped, strong references)
691
+ *
692
+ * DO NOT EDIT - Base Layer
693
+ */
694
+
695
+ /**
696
+ * Assets core implementation
697
+ */
698
+ declare class AssetsCore {
699
+ private registry;
700
+ private instanceCache;
701
+ private readyPromise;
702
+ private app;
703
+ constructor();
704
+ /**
705
+ * Initialize with config and app
706
+ */
707
+ init(config: ObjectCentricConfig$1, app: any): void;
708
+ /**
709
+ * Update config (for hot-reload)
710
+ * Re-initializes registry and clears instance cache
711
+ */
712
+ updateConfig(config: ObjectCentricConfig$1): void;
713
+ /**
714
+ * Preload all objects
715
+ * RULE: Resolves when all objects are preloaded and Assets.xxx accesses are sync/safe
716
+ * RULE: Idempotent - subsequent calls only reload changed objects
717
+ */
718
+ ready(): Promise<void>;
719
+ /**
720
+ * Reset scene - clears instance cache but NOT asset cache
721
+ * RULE: Strong references, cleared ONLY by resetScene()
722
+ */
723
+ resetScene(): void;
724
+ /**
725
+ * Reload a single object explicitly
726
+ */
727
+ reloadObject(id: string): Promise<void>;
728
+ /**
729
+ * Get object instance by ID
730
+ */
731
+ get(id: string): any;
732
+ }
733
+ declare const Assets: AssetsCore & {
734
+ [key: string]: any;
735
+ };
736
+ /**
737
+ * Initialize Assets with config and app
738
+ * Must be called before Assets.ready()
739
+ */
740
+ declare function initAssets(config: ObjectCentricConfig$1, app: any): void;
741
+
742
+ declare class AssetSystem extends BaseSystem {
743
+ private splashScreen;
744
+ init(): Promise<void>;
745
+ onStart(): Promise<void>;
746
+ onConfigUpdate(): void;
747
+ }
748
+
749
+ declare let globalResponsiveMultipliers: {
750
+ scale: number;
751
+ position: number;
752
+ };
753
+ declare function clearResponsiveElements(): void;
754
+ declare function updateScreenState(width: number, height: number): void;
755
+ type AnchorSpec = string | {
756
+ x: number;
757
+ y: number;
758
+ } | [number, number] | null | undefined;
759
+ type RatioSpec = {
760
+ x: number;
761
+ y: number;
762
+ } | [number, number] | null | undefined;
763
+ type ScreenInset = {
764
+ top?: number;
765
+ right?: number;
766
+ bottom?: number;
767
+ left?: number;
768
+ };
769
+ declare function resolveAnchorVec2(anchor: AnchorSpec, fallback?: {
770
+ x: number;
771
+ y: number;
772
+ }): {
773
+ x: number;
774
+ y: number;
775
+ };
776
+ declare function resolveScreenAnchorPoint(screenWidth: number, screenHeight: number, anchor: AnchorSpec, opts?: {
777
+ inset?: ScreenInset;
778
+ padding?: {
779
+ x: number;
780
+ y: number;
781
+ };
782
+ }): {
783
+ x: number;
784
+ y: number;
785
+ };
786
+ declare function resolveScreenRatioPoint(screenWidth: number, screenHeight: number, ratio: RatioSpec, opts?: {
787
+ inset?: ScreenInset;
788
+ padding?: {
789
+ x: number;
790
+ y: number;
791
+ };
792
+ }): {
793
+ x: number;
794
+ y: number;
795
+ };
796
+ declare function applyScreenAnchor(element: any, screenWidth: number, screenHeight: number, options?: {
797
+ anchor?: AnchorSpec;
798
+ positionRatio?: RatioSpec;
799
+ offset?: {
800
+ x: number;
801
+ y: number;
802
+ };
803
+ inset?: ScreenInset;
804
+ screenPadding?: {
805
+ x: number;
806
+ y: number;
807
+ };
808
+ renderAnchor?: {
809
+ x: number;
810
+ y: number;
811
+ };
812
+ scale?: number;
813
+ scaleMultiplier?: number;
814
+ }): void;
815
+ /**
816
+ * Layout Manager
817
+ * Strategy: ADAPTIVE ANCHOR
818
+ * - Tall Screens: Show full rope (Anchor Top).
819
+ * - Short Screens: Prioritize Character (Anchor Character Position).
820
+ */
821
+ interface LayoutScreen {
822
+ width: number;
823
+ height: number;
824
+ }
825
+ interface LayoutElements {
826
+ mainContainer: any;
827
+ label: any;
828
+ background: any;
829
+ backgroundTexture: any;
830
+ app: any;
831
+ }
832
+ declare function layout(elements: LayoutElements, config: ObjectCentricConfig, time: number, screen: LayoutScreen, gameObjectManager?: any, options?: {
833
+ skipInstanceIds?: string[];
834
+ enableDebugLogs?: boolean;
835
+ skipMainContainerTransform?: boolean;
836
+ }): void;
837
+
838
+ interface InitSequenceStates<State = unknown> {
839
+ showHook: State;
840
+ waitInput: State;
841
+ }
842
+ interface InitSequenceOptions<State = unknown> {
843
+ setState: (state: State) => void;
844
+ updateLabelAlpha: (alpha: number) => void;
845
+ updateHandAlpha: (alpha: number) => void;
846
+ config: ObjectCentricConfig;
847
+ states: InitSequenceStates<State>;
848
+ }
849
+ /**
850
+ * Shared, config-driven init sequence.
851
+ *
852
+ * Keeps the SDK generic by letting the caller pass game-specific state values.
853
+ */
854
+ declare function runInitSequence<State = unknown>(options: InitSequenceOptions<State>): void;
855
+
856
+ export { AssetCache, type AssetDefinition, AssetLoader, AssetSystem, Assets, BaseSystem, type EndGamePanelElements, GameEngine, GameObject, GameObjectManager, type ObjectCentricConfig, ObjectFactory, type PixiBaseContext, type PixiTheme, Renderer, RuntimeObjectRegistry, SplashScreen, type SplashScreenConfig, type SystemContext, Transform, animateHandClick, animatePanelEntrance, applyScreenAnchor, basePixi, clearResponsiveElements, createEndGamePanel, createHandTutorial, createPixiBase, createTutorialLabel, getRegisteredFontIds, globalResponsiveMultipliers, initAssets, layout, playLottieOverlay, registerFont, registerType, resolveAnchorVec2, resolveFont, resolveFontWeight, resolveScreenAnchorPoint, resolveScreenRatioPoint, runInitSequence, setLottieInstance, updateHandAnimation, updateScreenState };