/** * Standalone package entry for hosts pinned to the current Engine SDK; bundle this file * independently from the Gen3D CLI/main entry. The host owns World, * GameHost and SceneInstance. * The host implements these callbacks with @forgeax/engine/animation's * AnimationPlayer/bindAnimationTargets, @forgeax/engine/pack/guid's AssetGuid, * GameHost.assets.loadByGuid, and World shared refs. No game * project or package dependency is introduced into the Gen3D extension. * * The newly installed AnimationPlayer leaves graph at its SDK default (zero), * so clips/times/weights/speeds remain the direct-write playback surface. * Call afterAnimationFrame after the Engine animation update. The Engine's * looping flag belongs to the currently selected clip; once/freeze policy is * completed here on the following host frame, never inferred from GLB extras. */ export interface CharacterPlaybackPort { readonly sceneMapping: ArrayLike; readonly absentEntity: number; isImportedAnimationTarget(entity: number): boolean; targetOwnership(entity: number): 'unbound' | 'self' | 'foreign'; hasPlayer(): boolean; bindTargets(entities: readonly number[]): void; unbindTargetIfSelf(entity: number): void; loadClip(guid: string): Promise<{ handle: number; duration: number; release(): void; }>; installPlayer(data: PlayerColumns): void; setPlayer(data: PlayerColumns): void; readTime(): number; removePlayer(): void; } export interface PlayerColumns { clips: [number]; times: [number]; weights: [number]; speeds: [number]; paused: boolean; looping: boolean; } /** Structural shape of each verified .playable.json clip; this entry has no * runtime or declaration dependency on the delivery/CLI module. */ export interface RuntimeClipBinding { guid: string; sourceIndex: number; motionRefKey: string | null; playbackMode: 'loop' | 'once' | 'freeze_frame'; speed: number; rootMotion: string; } export interface PlayableRuntimeManifest { kind: 'playable-character'; engineImportStatus: 'verified-host'; engine: { version: string; commit: string; }; clips: Readonly>; } export interface CharacterPlaybackController { readonly currentSlot: string | null; play(slotId: string): void; afterAnimationFrame(): void; dispose(): void; } export declare function installCharacterPlayback(manifest: PlayableRuntimeManifest, port: CharacterPlaybackPort, options?: { initialSlot?: string; onComplete?: (slotId: string, mode: 'once' | 'freeze_frame') => void; cancellation?: AbortSignal; }): Promise;