import * as react_jsx_runtime from 'react/jsx-runtime'; import * as React from 'react'; import React__default, { CSSProperties, ReactNode, ReactElement } from 'react'; import { Plugin, GameLoopMode, EntityId, ECSWorld, ScriptUpdateFn, NavGrid, WorldSnapshot, EventBus, AccessibilityOptions } from '@cubeforge/core'; export { AccessibilityOptions, AssetProgress, Component, DeltaSnapshot, ECSWorld, Ease, EntityId, GameLoopMode, GameTimer, HierarchyComponent, HierarchySystem, HotReloadablePlugin, MergedRect, NavGrid, Plugin, PreloadManifest, ScriptUpdateFn, SpatialHash, TimelineEntry, TransformComponent, TweenHandle, TweenOptions, TweenTimeline, Vec2Like, WorldSnapshot, WorldTransformComponent, alignment, announceToScreenReader, applyDeltaSnapshot, arrive, cohesion, createHierarchy, createTag, createTimeline, createTimer, createTransform, definePlugin, evade, findByTag, flee, getAccessibilityOptions, getDescendants, hmrClearState, hmrLoadState, hmrSaveState, hotReloadPlugin, isReducedMotionPreferred, mergeTileColliders, patrol, preloadManifest, pursuit, removeParent, seek, separation, setAccessibilityOptions, setParent, setReducedMotionOverride, smoothPath, tween, wander } from '@cubeforge/core'; import { Sampling, BlendMode, SpriteShape, AnimatorStateDefinition, AnimatorParamValue, GradientType, GradientStop, MaskShape, PostProcessEffect, PostProcessOptions } from '@cubeforge/renderer'; export { AnimationClipDefinition, AnimationStateComponent, AnimatorComponent, AnimatorCondition, AnimatorParamValue, AnimatorStateDefinition, AnimatorTransition, BlendMode, CircleShapeComponent, GradientComponent, GradientStop, GradientType, LineShapeComponent, MagFilterValue, MaskComponent, MaskShape, NineSliceComponent, ParallaxLayerComponent, Particle, ParticlePoolComponent, PolygonShapeComponent, PostProcessEffect, PostProcessOptions, PostProcessStack, RenderLayer, RenderLayerManager, RenderSystem, Sampling, SpriteComponent, SpriteShape, SquashStretchComponent, TextComponent, TextureFilter, TextureFilterValue, TrailComponent, chromaticAberrationEffect, createCircleShape, createGradient, createLineShape, createMask, createNineSlice, createPolygonShape, createPostProcessStack, createRenderLayerManager, createSprite, defaultLayers, scanlineEffect, vignetteEffect } from '@cubeforge/renderer'; import { CombineRule, ColliderShape, JointType } from '@cubeforge/physics'; export { AxisLock, BoxColliderComponent, COLLISION_DYNAMIC_DYNAMIC, COLLISION_DYNAMIC_KINEMATIC, COLLISION_DYNAMIC_STATIC, COLLISION_KINEMATIC_KINEMATIC, COLLISION_KINEMATIC_STATIC, CapsuleColliderComponent, CharacterCollision, CharacterController, CharacterControllerConfig, CircleColliderComponent, ColliderShape, CollisionPair, CollisionPipeline, CollisionPipelineResult, CombineRule, CompoundColliderComponent, ContactManifold, ContactPoint, ConvexPolygonColliderComponent, DEFAULT_ACTIVE_COLLISION_TYPES, DebugCircle, DebugLine, DebugPoint, DebugRenderBackend, DebugRenderColors, DebugRenderFlags, DebugRenderOutput, DebugRenderPipeline, HalfSpaceColliderComponent, HeightFieldColliderComponent, JointComponent, JointMotor, JointSnapshot, JointType, MotorMode, MoveResult, PhysicsBodySnapshot, PhysicsHooks, PhysicsSnapshot, PointProjection, QueryOpts, QueryShape, RaycastHit, RigidBodyComponent, SegmentColliderComponent, TriMeshColliderComponent, TriangleColliderComponent, addForce, addForceAtPoint, addTorque, applyImpulse, applyImpulseAtPoint, applyTorqueImpulse, boxArea, capsuleArea, circleArea, containsPoint, createCompoundCollider, createConvexPolygonCollider, createHalfSpaceCollider, createHeightFieldCollider, createJoint, createSegmentCollider, createTriMeshCollider, createTriangleCollider, intersectAABB, intersectRay, intersectShape, kineticEnergy, overlapBox, overlapCircle, polygonArea, polygonMassProperties, potentialEnergy, predictPosition, projectPoint, raycast, raycastAll, recomputeMassFromColliders, resetForces, resetTorques, restoreSnapshot, setAdditionalMass, setMassProperties, setNextKinematicPosition, setNextKinematicRotation, shapeCast, snapshotFromBytes, snapshotFromJSON, snapshotHash, snapshotToBytes, snapshotToJSON, sweepBox, takeSnapshot, triangleArea, triangleMassProperties, velocityAtPoint } from '@cubeforge/physics'; import { InputManager, ActionBindings, InputContextName, PlayerInput, InputRecorderControls, TouchPoint, InputBufferOptions, InputBuffer, ComboDefinition } from '@cubeforge/input'; export { ActionBindings, AxisBinding, BufferedAction, ComboDefinition, ComboDetector, ComboDetectorOptions, InputBuffer, InputBufferOptions, InputContextName, InputManager, InputMap, InputRecorderControls, InputRecording, InputRecording as InputRecordingData, PlayerInput, TouchPoint, createInputMap, createInputRecorder, createPlayerInput, globalInputContext } from '@cubeforge/input'; import { AnimationClip } from '@cubeforge/gameplay'; export { AISteering, AnimationClip, AnimationControllerResult, BTNode, BTStatus, BehaviorTreeControls, BindingControls, CharacterControls, CutsceneControls, CutsceneStep, DialogueBox, DialogueBoxProps, DialogueBoxStyle, DialogueControls, DialogueLine, DialogueScript, DialogueTreeChoice, DialogueTreeControls, DialogueTreeNode, DialogueTreeScript, DialogueVariables, ForceControls, GameState as GameStateDefinition, GameStateMachineResult, HealthControls, HealthOptions, IDBSaveControls, IDBSaveOptions, KinematicBodyControls, LevelTransitionControls, ObjectPool, PathfindingControls, PlatformerControllerOptions, RestartControls, SaveControls, SaveOptions, SaveSlot, SaveSlotMeta, SaveSlotsControls, SaveSlotsOptions, TopDownMovementOptions, TransitionOptions, TransitionType, TweenControls, btAction, btCondition, btCooldown, btFail, btInvert, btParallel, btRepeat, btRetryUntilSuccess, btSelector, btSequence, btSucceed, btWait, useAISteering, useAnimationController, useBehaviorTree, useCharacterController, useCutscene, useDamageZone, useDialogue, useDialogueTree, useDropThrough, useForces, useGameStateMachine, useGameStore, useHealth, useIDBSave, useKinematicBody, useLevelTransition, useObjectPool, usePathfinding, usePersistedBindings, usePlatformerController, useRestart, useSave, useSaveSlots, useTopDownMovement, useTween } from '@cubeforge/gameplay'; import { EngineState } from '@cubeforge/context'; export { ContactData, EngineState, useCircleEnter, useCircleExit, useCircleStay, useCollidingWith, useCollisionEnter, useCollisionExit, useCollisionStay, useTriggerEnter, useTriggerExit, useTriggerStay } from '@cubeforge/context'; export { AudioAnalyserControls, AudioAnalyserOptions, AudioGroup, AudioSchedulerControls, AudioSchedulerOptions, BarHandler, BeatHandler, CompressorEffectOptions, DelayEffectOptions, FilterEffectOptions, GroupEffectOptions, MusicControls, MusicOptions, PreloadAudioResult, ReverbEffectOptions, SoundControls, SoundOptions, SoundscapeControls, SoundscapeLayer, SoundscapeOptions, SpatialSoundControls, SpatialSoundOptions, StreamedMusicControls, StreamedMusicOptions, clearGroupEffect, duck, getGroupVolume, getListenerPosition, getMasterVolume, loadAudioSettings, saveAudioSettings, setGroupEffect, setGroupMute, setGroupVolume, setGroupVolumeFaded, setListenerPosition, setMasterVolume, stopGroup, useAudioAnalyser, useAudioScheduler, useMusic, usePreloadAudio, useSound, useSoundscape, useSpatialSound, useStreamedMusic } from '@cubeforge/audio'; export { DevToolsHandle } from '@cubeforge/devtools'; import { Room } from '@cubeforge/net'; export { BinaryNetTransport, ClientPrediction, InterpolationBuffer, InterpolationBufferConfig, InterpolationState, NetMessage, NetTransport, NetworkInputConfig, PredictionConfig, Room, RoomConfig, SyncConfig, WebRTCTransport, WebRTCTransportConfig, WebSocketTransportOptions, createWebRTCTransport, createWebSocketTransport, isBinaryTransport, syncEntity, useNetworkInput } from '@cubeforge/net'; export { BoolField, ColorField, EditorShell, EditorShellProps, EditorState, EntityInfo, EntityInspector, EntityInspectorProps, NumberField, SceneHierarchy, SceneHierarchyProps, TextField, Vec2Field, useEditorState } from '@cubeforge/editor'; interface GameControls { pause(): void; resume(): void; reset(): void; } interface GameProps$1 { width?: number; height?: number; /** Pixels per second squared downward (default 980) */ gravity?: number; /** Enable debug overlay: collider wireframes, FPS, entity count */ debug?: boolean; /** * Canvas scaling strategy (default 'none'): * - 'none' — fixed pixel size, no scaling * - 'contain' — CSS scale to fit parent while preserving aspect ratio * - 'pixel' — nearest-neighbor pixel-art scaling via CSS */ scale?: 'none' | 'contain' | 'pixel'; /** Called once the engine is ready — receives pause/resume/reset controls */ onReady?: (controls: GameControls) => void; /** Enable time-travel debugging overlay (frame scrubber + entity inspector). */ devtools?: boolean; /** Run the simulation in deterministic mode using a seeded RNG. */ deterministic?: boolean; /** Seed for the deterministic RNG (default 0). Only used when deterministic=true. */ seed?: number; /** * When true, the game loop starts immediately and sprites swap from color → image as * they load in the background. When false (default) the loop is held until every * sprite that is part of the initial scene has finished loading, so the first frame * shown is fully rendered with real assets. */ asyncAssets?: boolean; /** * Default texture sampling for all sprites (default 'nearest'). * Individual sprites can override via their own `sampling` prop. * Use `TextureFilter.NEAREST` for pixel art or `TextureFilter.LINEAR` for smooth scaling. */ sampling?: Sampling; /** Custom plugins to register after core systems. Each plugin's systems run after Render. */ plugins?: Plugin[]; /** * Loop mode (default 'realtime'): * - 'realtime' — continuous 60fps tick. Use for action games, anything with * continuous motion or physics. * - 'onDemand' — sleeps until input arrives or a component calls markDirty(). * Use for puzzle games, turn-based games, visual novels, level editors, or any * scene where nothing changes unless the user acts. Saves battery and CPU. * * **Captured at mount.** This prop is read once when the Game mounts and * baked into the loop. Changing it later has no effect — to switch modes, * unmount and remount the Game (e.g. via a `key` change). */ mode?: GameLoopMode; style?: CSSProperties; className?: string; children?: React__default.ReactNode; } declare function Game({ width, height, gravity, debug, devtools, scale, deterministic, seed, asyncAssets, sampling, onReady, plugins, mode, style, className, children, }: GameProps$1): react_jsx_runtime.JSX.Element; type GameProps = React__default.ComponentProps; /** * Stage is an alias for {@link Game} tuned for static, puzzle, turn-based, and * editor-style scenes. It defaults to: * * - `mode="onDemand"` — the loop sleeps until input arrives or a component calls * `engine.loop.markDirty()`. Saves battery and CPU. * - `gravity={0}` — no downward acceleration. Most non-action scenes don't need it. * * Every other prop behaves identically to ``. Use `` when you're * building something that isn't an action game: a level editor, a card game, a * match-3 puzzle, a visual novel, a node-graph tool, etc. * * @example * ```tsx * * * * * * * ``` */ declare function Stage(props: GameProps): react_jsx_runtime.JSX.Element; interface WorldProps { /** Gravitational acceleration in pixels/s² (default inherited from Game) */ gravity?: number; /** Canvas background color */ background?: string; children?: ReactNode; } declare function World({ gravity, background, children }: WorldProps): react_jsx_runtime.JSX.Element; interface EntityProps { /** Optional string ID for cross-entity lookups (e.g. camera follow) */ id?: string; /** Tags for grouping / querying (e.g. ['enemy', 'damageable']) */ tags?: string[]; children?: ReactNode; } declare function Entity({ id, tags, children }: EntityProps): react_jsx_runtime.JSX.Element | null; interface TransformProps { x?: number; y?: number; rotation?: number; scaleX?: number; scaleY?: number; } declare function Transform({ x, y, rotation, scaleX, scaleY }: TransformProps): null; /** Maps frame names to frameIndex numbers */ type SpriteAtlas = Record; /** * Helper to build an atlas from a grid spritesheet. * columns = number of frames per row. * names = frame names in row-major order. */ declare function createAtlas(names: string[], _columns: number): SpriteAtlas; interface SpriteProps { width: number; height: number; color?: string; src?: string; /** * ID returned by `useDynamicCanvas()`. When set the sprite samples from * the registered canvas texture and re-uploads it whenever `markDirty()` * is called on that handle. */ dynamicSrc?: string; offsetX?: number; offsetY?: number; zIndex?: number; visible?: boolean; flipX?: boolean; flipY?: boolean; anchorX?: number; anchorY?: number; frameIndex?: number; frameWidth?: number; frameHeight?: number; frameColumns?: number; atlas?: SpriteAtlas; frame?: string; tileX?: boolean; tileY?: boolean; tileSizeX?: number; tileSizeY?: number; /** Texture sampling mode — controls filtering when the sprite is scaled */ sampling?: Sampling; /** Blend mode used when drawing this sprite */ blendMode?: BlendMode; /** Render layer name — sprites are sorted by layer order first, then zIndex */ layer?: string; /** Color tint applied on top of the image (multiplied). e.g. '#ff0000' for red tint */ tint?: string; /** Tint opacity 0-1 */ tintOpacity?: number; /** Overall opacity 0-1 (default 1) */ opacity?: number; /** Shape to draw: 'rect' (default), 'circle', 'ellipse', 'roundedRect', 'triangle', 'star', 'pentagon', 'hexagon' */ shape?: SpriteShape; /** Border radius for 'roundedRect' shape (px) */ borderRadius?: number; /** Stroke outline color */ strokeColor?: string; /** Stroke outline width in pixels */ strokeWidth?: number; /** Custom draw callback */ customDraw?: (ctx: CanvasRenderingContext2D, width: number, height: number) => void; /** Number of points for 'star' shape (default 5) */ starPoints?: number; /** Inner radius ratio for 'star' shape (0-1, default 0.4) */ starInnerRadius?: number; } declare function Sprite({ width, height, color, src, dynamicSrc, offsetX, offsetY, zIndex, visible, flipX, flipY, anchorX, anchorY, frameIndex, frameWidth, frameHeight, frameColumns, atlas, frame, tileX, tileY, tileSizeX, tileSizeY, sampling, blendMode, layer, tint, tintOpacity, opacity, shape, borderRadius, strokeColor, strokeWidth, customDraw, starPoints, starInnerRadius, }: SpriteProps): null; interface TextProps { text: string; fontSize?: number; fontFamily?: string; color?: string; align?: CanvasTextAlign; baseline?: CanvasTextBaseline; zIndex?: number; visible?: boolean; maxWidth?: number; offsetX?: number; offsetY?: number; strokeColor?: string; strokeWidth?: number; shadowColor?: string; shadowOffsetX?: number; shadowOffsetY?: number; shadowBlur?: number; wordWrap?: boolean; lineHeight?: number; opacity?: number; } declare function Text({ text, fontSize, fontFamily, color, align, baseline, zIndex, visible, maxWidth, offsetX, offsetY, strokeColor, strokeWidth, shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur, wordWrap, lineHeight, opacity, }: TextProps): null; interface RigidBodyProps { /** Explicit mass. 0 (default) auto-computes from density × collider area */ mass?: number; gravityScale?: number; isStatic?: boolean; vx?: number; vy?: number; /** Prevent any horizontal movement — velocity.x is zeroed every frame */ lockX?: boolean; /** Prevent any vertical movement — velocity.y is zeroed every frame (disables gravity) */ lockY?: boolean; /** Lock rotation — angular velocity stays 0 */ lockRotation?: boolean; /** Enable continuous collision detection to prevent tunneling through thin colliders */ ccd?: boolean; /** Angular velocity in radians per second */ angularVelocity?: number; /** Angular damping (0–1): fraction of angular velocity removed each fixed step */ angularDamping?: number; /** Linear damping (0–1): velocity reduction applied every fixed step (air resistance) */ linearDamping?: number; /** Density for auto-computing mass (mass = density × area). Default 1.0 */ density?: number; /** Coefficient of restitution for this body (0 = no bounce, 1 = full bounce) */ restitution?: number; /** Dominance group (-127 to 127). Higher dominance acts as infinite mass in contacts */ dominance?: number; /** Kinematic bodies skip gravity/integration but resolve collisions without impulse response */ isKinematic?: boolean; /** Whether this body is enabled. Disabled bodies are completely skipped */ enabled?: boolean; /** Max linear velocity magnitude. 0 = unlimited */ maxLinearVelocity?: number; /** Max angular velocity magnitude. 0 = unlimited */ maxAngularVelocity?: number; /** Extra velocity solver iterations for constraints involving this body. Default 0 */ additionalSolverIterations?: number; } declare function RigidBody({ mass, gravityScale, isStatic, vx, vy, lockX, lockY, lockRotation, ccd, angularVelocity, angularDamping, linearDamping, density, restitution, dominance, isKinematic, enabled, maxLinearVelocity, maxAngularVelocity, additionalSolverIterations, }: RigidBodyProps): null; interface BoxColliderProps { width: number; height: number; offsetX?: number; offsetY?: number; isTrigger?: boolean; layer?: string; /** Which layers this collider interacts with. '*' = all (default). */ mask?: string | string[]; /** * One-way platform: only blocks entities falling onto the top surface. * Entities below pass through freely (useful for jump-through ledges). */ oneWay?: boolean; /** Per-collider friction coefficient (0–1). Default 0.5 */ friction?: number; /** Per-collider restitution (bounciness) coefficient (0–1). Default 0.0 */ restitution?: number; /** How to combine friction with the other collider. Default 'average' */ frictionCombineRule?: CombineRule; /** How to combine restitution with the other collider. Default 'average' */ restitutionCombineRule?: CombineRule; /** Whether this collider is enabled. Disabled colliders skip all detection */ enabled?: boolean; } declare function BoxCollider({ width, height, offsetX, offsetY, isTrigger, layer, mask, oneWay, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: BoxColliderProps): null; interface CircleColliderProps { radius: number; offsetX?: number; offsetY?: number; isTrigger?: boolean; layer?: string; /** Which layers this collider interacts with. '*' = all (default). */ mask?: string | string[]; /** Per-collider friction coefficient (0–1). Default 0.5 */ friction?: number; /** Per-collider restitution (bounciness) coefficient (0–1). Default 0.0 */ restitution?: number; /** How to combine friction with the other collider. Default 'average' */ frictionCombineRule?: CombineRule; /** How to combine restitution with the other collider. Default 'average' */ restitutionCombineRule?: CombineRule; /** Whether this collider is enabled. Disabled colliders skip all detection */ enabled?: boolean; } declare function CircleCollider({ radius, offsetX, offsetY, isTrigger, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: CircleColliderProps): null; interface CapsuleColliderProps { width: number; height: number; offsetX?: number; offsetY?: number; isTrigger?: boolean; layer?: string; mask?: string | string[]; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } declare function CapsuleCollider({ width, height, offsetX, offsetY, isTrigger, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: CapsuleColliderProps): null; interface CompoundColliderProps { shapes: ColliderShape[]; isTrigger?: boolean; layer?: string; /** Which layers this collider interacts with. '*' = all (default). */ mask?: string | string[]; } declare function CompoundCollider({ shapes, isTrigger, layer, mask }: CompoundColliderProps): null; interface ScriptProps { /** Called once when the entity is mounted — use to attach extra components */ init?: (entityId: EntityId, world: ECSWorld) => void; /** Called every frame */ update: ScriptUpdateFn | ((entityId: EntityId, world: ECSWorld, input: InputManager, dt: number) => void); } declare function Script({ init, update }: ScriptProps): null; interface Camera2DProps { /** String ID of entity to follow */ followEntity?: string; /** Initial camera X position in world space (default 0 = world origin at screen center) */ x?: number; /** Initial camera Y position in world space (default 0 = world origin at screen center) */ y?: number; zoom?: number; /** Lerp smoothing factor (0 = instant snap, 0.85 = smooth) */ smoothing?: number; background?: string; bounds?: { x: number; y: number; width: number; height: number; }; deadZone?: { w: number; h: number; }; /** World-space offset applied to the follow target (look-ahead, vertical bias, etc.) */ followOffsetX?: number; followOffsetY?: number; } declare function Camera2D({ followEntity, x, y, zoom, smoothing, background, bounds, deadZone, followOffsetX, followOffsetY, }: Camera2DProps): null; interface AnimationProps { /** Frame indices to play (indexes into the sprite sheet) */ frames: number[]; /** Frames per second, default 12 */ fps?: number; /** Whether to loop, default true */ loop?: boolean; /** Whether currently playing, default true */ playing?: boolean; /** Called once when a non-looping animation finishes playing */ onComplete?: () => void; /** * Callbacks fired when the animation advances to specific frame indices. * Key = 0-based position in the `frames` array. * * @example * frameEvents={{ 2: () => playFootstep(), 5: () => playFootstep() }} */ frameEvents?: Record void>; } declare function Animation({ frames, fps, loop, playing, onComplete, frameEvents }: AnimationProps): null; /** Shared sprite props used by both API forms */ interface SpriteOptions { width: number; height: number; src: string; color?: string; offsetX?: number; offsetY?: number; zIndex?: number; visible?: boolean; flipX?: boolean; flipY?: boolean; anchorX?: number; anchorY?: number; frameWidth?: number; frameHeight?: number; frameColumns?: number; atlas?: SpriteAtlas; frame?: string; tileX?: boolean; tileY?: boolean; tileSizeX?: number; tileSizeY?: number; sampling?: Sampling; blendMode?: BlendMode; } /** Simple form — single animation clip (like Sprite + Animation) */ interface SimpleAnimatedSpriteProps extends SpriteOptions { frames: number[]; fps?: number; loop?: boolean; playing?: boolean; onComplete?: () => void; frameEvents?: Record void>; animations?: never; current?: never; } /** Multi-clip form — named animation states with typed clip names */ interface MultiAnimatedSpriteProps extends SpriteOptions { /** Map of named animation clips (use `defineAnimations()` for type-safe names) */ animations: AnimationSet; /** Which animation clip is currently playing — typed to the clip names */ current: S; frames?: never; fps?: never; loop?: never; playing?: never; onComplete?: never; frameEvents?: never; } type AnimatedSpriteProps = SimpleAnimatedSpriteProps | MultiAnimatedSpriteProps; /** A typed set of animation clips. Created by `defineAnimations()`. */ type AnimationSet = Record; /** * Define a reusable, type-safe set of animation clips. * * The returned object can be shared across components and provides * autocomplete on `current` when used with ``. * * @example * ```tsx * const playerAnims = defineAnimations({ * idle: { frames: [0], fps: 1 }, * walk: { frames: [1, 2, 3, 4], fps: 10 }, * run: { frames: [5, 6, 7, 8], fps: 14 }, * jump: { frames: [9], fps: 1, loop: false }, * attack: { frames: [10, 11, 12], fps: 16, loop: false, next: 'idle' }, * }) * * // `current` is typed as 'idle' | 'walk' | 'run' | 'jump' | 'attack' * * ``` */ declare function defineAnimations(clips: Record): AnimationSet; /** * Convenience wrapper that combines `` and `` into a * single component. Must be placed inside an ``. * * Supports two API forms: * * **Simple** — single clip: * ```tsx * * ``` * * **Multi-clip** — named animation states, switch via `current`: * ```tsx * const anims = defineAnimations({ * idle: { frames: [0], fps: 1 }, * walk: { frames: [1, 2, 3, 4], fps: 10 }, * }) * * * ``` */ declare function AnimatedSprite(props: AnimatedSpriteProps): ReactElement; interface AnimatorProps { initial: string; states: Record; params?: Record; playing?: boolean; } declare function Animator({ initial, states, params, playing }: AnimatorProps): null; interface SquashStretchProps { /** How much to squash/stretch (default 0.2) */ intensity?: number; /** How fast it returns to 1.0 — lerp speed (default 8) */ recovery?: number; } declare function SquashStretch({ intensity, recovery }: SquashStretchProps): null; type ParticlePreset = 'explosion' | 'spark' | 'smoke' | 'coinPickup' | 'jumpDust' | 'fire' | 'magic' | 'rain' | 'snow' | 'confetti' | 'sparkle' | 'heal' | 'damage' | 'pickup' | 'fountain' | 'trail'; interface ParticleEmitterConfig { rate?: number; speed?: number; spread?: number; angle?: number; particleLife?: number; particleSize?: number; color?: string; gravity?: number; maxParticles?: number; /** Colors to interpolate through over particle lifetime. */ colorOverLife?: string[]; /** Start/end size ratios for per-particle size curve (end is multiplier of particleSize). */ sizeOverLife?: { start: number; end: number; }; /** Blend mode for the emitter (additive for glows, normal for solid). */ blendMode?: 'normal' | 'additive'; /** Particle shape: 'soft' gradient, 'circle' hard disc, 'square' quad. */ particleShape?: 'soft' | 'circle' | 'square'; } /** * Ready-made particle configurations. Pass via the `preset` prop on * ``: * * ```tsx * * // overrides * ``` * * Individual props always override preset values — presets are defaults. * * ## Catalog * * Action / combat: `explosion`, `spark`, `damage`, `heal`, `magic` * Environment: `fire`, `smoke`, `rain`, `snow`, `fountain` * UI / reward: `coinPickup`, `pickup`, `sparkle`, `confetti` * Character: `jumpDust`, `trail` */ declare const PARTICLE_PRESETS: Record; interface ParticleEmitterProps { active?: boolean; /** Named preset — values can be overridden by explicit props */ preset?: ParticlePreset; /** Particles per second, default 20 */ rate?: number; /** Initial particle speed (pixels/s), default 80 */ speed?: number; /** Angle spread in radians, default Math.PI */ spread?: number; /** Base emit angle in radians (0=right, -PI/2=up), default -Math.PI/2 */ angle?: number; /** Particle lifetime in seconds, default 0.8 */ particleLife?: number; /** Particle size in pixels, default 4 */ particleSize?: number; /** Particle color, default '#ffffff' */ color?: string; /** Gravity applied to particles (pixels/s²), default 200 */ gravity?: number; /** Maximum live particles, default 100 */ maxParticles?: number; /** Emit this many particles in one frame then deactivate (one-shot burst) */ burstCount?: number; /** Emission shape: 'point' (default), 'circle', or 'box' */ emitShape?: 'point' | 'circle' | 'box'; /** Radius for 'circle' emission shape */ emitRadius?: number; /** Width for 'box' emission shape */ emitWidth?: number; /** Height for 'box' emission shape */ emitHeight?: number; /** Sprite/texture source for particles (if undefined, renders as colored rect) */ textureSrc?: string; /** Enable particle rotation. Default false */ enableRotation?: boolean; /** Random rotation speed range [min, max] in radians/s */ rotationSpeedRange?: [number, number]; /** Size over lifetime: start and end size. If set, overrides particleSize */ sizeOverLife?: { start: number; end: number; }; /** Attractor points that pull particles toward them */ attractors?: Array<{ x: number; y: number; strength: number; radius: number; }>; /** Color over lifetime: array of colors to interpolate through */ colorOverLife?: string[]; /** * WebGL blend mode for particles. * - `'normal'` (default) — standard alpha blending * - `'additive'` — particles brighten the background; produces a glow effect * - `'multiply'` — darkens based on particle color * - `'screen'` — lightens, softer than additive */ blendMode?: 'normal' | 'additive' | 'multiply' | 'screen'; /** * Visual shape of each particle. * - `'soft'` (default) — radial gradient with glow halo; pairs well with `blendMode="additive"` * - `'circle'` — hard-edged anti-aliased circle, no glow falloff * - `'square'` — solid quad (fastest, no texture lookup) */ particleShape?: 'soft' | 'circle' | 'square'; /** * Formation mode: particles lerp toward fixed target positions instead of * being emitted with velocity. Enables logo reveals, constellations, shape morphing. * - `'standard'` (default) — normal emit/gravity/lifetime behaviour * - `'formation'` — particles seek `formationPoints`; no gravity, no expiry */ mode?: 'standard' | 'formation'; /** * Target positions for formation mode. One particle is spawned per point. * Change this array to morph the formation — particles smoothly lerp to new targets. */ formationPoints?: { x: number; y: number; }[]; /** * How strongly particles seek their target each frame in formation mode. * Exponential lerp factor (0–1). Default 0.055 (~5.5% per frame at 60 fps). */ seekStrength?: number; /** * Smoothly transition all particles to this color. * Works in both standard and formation modes. */ targetColor?: string; /** Duration of the global color transition in seconds. Default 0.5. */ colorTransitionDuration?: number; } declare function ParticleEmitter({ active, preset, rate, speed, spread, angle, particleLife, particleSize, color, gravity, maxParticles, burstCount, emitShape, emitRadius, emitWidth, emitHeight, textureSrc, enableRotation, rotationSpeedRange, sizeOverLife, attractors, colorOverLife, blendMode, mode, formationPoints, seekStrength, targetColor, colorTransitionDuration, particleShape, }: ParticleEmitterProps): null; interface VirtualJoystickProps { /** Diameter of the joystick base in pixels (default 120) */ size?: number; /** Screen corner to anchor to (default 'left') */ position?: 'left' | 'right'; /** Extra CSS applied to the outer container */ style?: React__default.CSSProperties; /** Show an action button (e.g. jump) alongside the joystick (default false) */ actionButton?: boolean; /** Label shown on the action button (default 'A') */ actionLabel?: string; /** Name of the virtual button to set (default 'action') */ actionName?: string; } /** * On-screen virtual joystick for touch / mobile. Place it as a sibling of the * `` canvas (inside a `position: relative` container). * * Read the joystick state with `useVirtualInput()`. * * @example *
* ... * *
* * // Inside an entity: * function MobilePlayer() { * const virt = useVirtualInput() * // virt.axisX, virt.axisY, virt.button('action') * } */ declare function VirtualJoystick({ size, position, style, actionButton, actionLabel, actionName, }: VirtualJoystickProps): react_jsx_runtime.JSX.Element; interface Waypoint { x: number; y: number; } type TwoPointProps = { /** Start position (two-point shorthand) */ x1: number; y1: number; /** End position (two-point shorthand) */ x2: number; y2: number; waypoints?: never; /** Seconds for a full round trip in two-point mode (default 3). Ignored when waypoints is set. */ duration?: number; }; type WaypointProps = { x1?: never; y1?: never; x2?: never; y2?: never; /** * Ordered list of world-space positions to travel through. * The platform ping-pongs between the first and last waypoint. */ waypoints: Waypoint[]; duration?: never; }; type MovingPlatformProps = (TwoPointProps | WaypointProps) & { width?: number; height?: number; /** * Movement speed in world pixels per second (waypoint mode only, default 120). * In two-point mode use `duration` to control timing. */ speed?: number; color?: string; }; /** * A static platform that moves along a path. * * **Two-point mode** (backward-compatible) — oscillates sinusoidally between * `(x1,y1)` and `(x2,y2)` over `duration` seconds: * ```tsx * * ``` * * **Waypoint mode** — travels through an ordered list of positions at a fixed * speed, ping-ponging between the first and last point: * ```tsx * * ``` */ declare function MovingPlatform(props: MovingPlatformProps): React__default.ReactElement; interface CheckpointProps { x: number; y: number; width?: number; height?: number; color?: string; /** Called once when a 'player'-tagged entity enters the checkpoint */ onActivate?: () => void; } /** * A trigger zone that fires `onActivate` once when a player-tagged entity enters it. * * @example * setCheckpoint(800)} /> */ declare function Checkpoint({ x, y, width, height, color, onActivate, }: CheckpointProps): React__default.ReactElement; interface TiledProperty { name: string; type: string; value: string | number | boolean; } interface TiledObject { id: number; name: string; type: string; x: number; y: number; width: number; height: number; properties?: TiledProperty[]; } interface TiledLayer { type: 'tilelayer' | 'objectgroup'; name: string; visible: boolean; opacity: number; data?: number[]; objects?: TiledObject[]; properties?: TiledProperty[]; } interface TilemapProps { /** URL to the Tiled JSON file */ src: string; /** * Object layer spawner: called for each object in object layers. * Return a React element or null. */ onSpawnObject?: (obj: TiledObject, layer: TiledLayer) => React__default.ReactNode; /** * Layer filter: return false to skip rendering/processing a layer. * Default: all layers rendered. */ layerFilter?: (layer: TiledLayer) => boolean; /** Z-index for tile sprites (default 0) */ zIndex?: number; /** * Name of the layer (or layers with property `collision: true`) that * should create invisible solid colliders. Default: "collision". */ collisionLayer?: string; /** * Name of the layer (or layers with property `trigger: true`) that * should create trigger BoxColliders (no sprite). Default: "triggers". */ triggerLayer?: string; /** * Called for every tile that has custom properties defined in the tileset. * Receives the global tile ID, the property map, and the tile's world position. */ onTileProperty?: (tileId: number, properties: Record, x: number, y: number) => void; /** * If provided, collision-layer tiles automatically mark the corresponding * NavGrid cells as non-walkable. The grid must already be created with the * correct dimensions (map.width × map.height) and cellSize (map.tilewidth). */ navGrid?: NavGrid; /** * Name of the object layer that contains spawn markers. * Objects in this layer are forwarded to `onSpawnObject` just like any * other object layer, but they are also identified as spawn points so you * can filter them by `layer.name === spawnLayer` inside the callback. */ spawnLayer?: string; /** * When true (default), adjacent solid tiles in collision/trigger layers * are merged into larger rectangles using a 2D greedy algorithm, reducing * the number of collider entities. Set to false to create one collider per * row-run (legacy behaviour). */ mergeColliders?: boolean; /** * Array of tile GIDs (global IDs) to treat as solid, regardless of layer. * When set, only tiles whose GID is in this array generate colliders in * the collision layer. Without this, ALL non-zero tiles in the collision * layer produce colliders. */ solidTiles?: number[]; /** * When true, also scan visual layers for tiles whose GID matches * `solidTiles` and auto-generate colliders from them — no separate * collision layer required. Default: false. */ autoColliders?: boolean; /** * Per-tile-GID collider properties. Keys are tile GIDs. * Example: `{ 6: { isTrigger: true }, 7: { oneWay: true } }` */ tileColliderProps?: Record; } declare function Tilemap({ src, onSpawnObject, layerFilter, zIndex, collisionLayer, triggerLayer: triggerLayerName, onTileProperty, navGrid, mergeColliders, solidTiles, autoColliders, tileColliderProps: _tileColliderProps, }: TilemapProps): React__default.ReactElement | null; interface ParallaxLayerProps { /** Image URL to use as the background layer */ src: string; /** Scroll speed relative to camera (0 = fixed, 1 = moves with camera, 0.3 = slow parallax). Default 0.5 */ speedX?: number; /** Vertical scroll speed relative to camera. Default 0 */ speedY?: number; /** Tile image horizontally. Default true */ repeatX?: boolean; /** Tile image vertically. Default false */ repeatY?: boolean; /** Render order — use negative values to render behind sprites. Default -10 */ zIndex?: number; /** Manual horizontal offset in pixels. Default 0 */ offsetX?: number; /** Manual vertical offset in pixels. Default 0 */ offsetY?: number; } /** * A background layer that scrolls at a fraction of the camera speed to create depth. * * @example * * */ declare function ParallaxLayer({ src, speedX, speedY, repeatX, repeatY, zIndex, offsetX, offsetY, }: ParallaxLayerProps): React__default.ReactElement; interface ScreenFlashHandle { flash(color: string, duration: number): void; } declare const ScreenFlash: React.ForwardRefExoticComponent>; interface CameraZoneProps { /** World-space center X of the trigger zone */ x: number; /** World-space center Y of the trigger zone */ y: number; /** Half-width of the trigger zone */ width: number; /** Half-height of the trigger zone */ height: number; /** * When an entity with this tag enters the zone, the camera stops following * its entity and locks to the fixed position (targetX, targetY). */ watchTag?: string; /** Fixed world-space X the camera moves to when activated (defaults to zone center) */ targetX?: number; /** Fixed world-space Y the camera moves to when activated (defaults to zone center) */ targetY?: number; children?: React__default.ReactNode; } /** * Invisible trigger area. When the player (or another tagged entity) enters * the zone, the camera follow entity is cleared and the camera locks to the * zone's center (or a custom target). On exit, the camera resumes following. * * Zone detection runs inside the ScriptSystem tick — it respects pause and * deterministic stepping. * * @example * ```tsx * * ``` */ declare function CameraZone({ x, y, width, height, watchTag, targetX, targetY, children }: CameraZoneProps): react_jsx_runtime.JSX.Element; interface VirtualCameraConfig { /** Unique identifier for this virtual camera. */ id: string; /** Higher-priority cameras take control when active. Default 0. */ priority: number; /** Whether this camera is currently contending for control. Default true. */ active: boolean; /** Entity ID string to follow (same as Camera2D.followEntityId). */ followEntityId?: string; /** Static world-space X when not following an entity. */ x?: number; /** Static world-space Y when not following an entity. */ y?: number; /** Zoom level. Default 1. */ zoom?: number; /** Follow smoothing (0 = instant, 0.85 = smooth). Inherits Camera2D value when omitted. */ smoothing?: number; /** World-space camera bounds clamp. */ bounds?: { x: number; y: number; width: number; height: number; }; /** How long (seconds) to blend when transitioning to this camera. Default 0.4. */ blendDuration: number; } interface VirtualCameraProps { /** Unique ID used to identify and blend between cameras. */ id: string; /** * Higher values win when multiple virtual cameras are active simultaneously. * Default 0. */ priority?: number; /** Whether this camera is currently competing for control. Default true. */ active?: boolean; /** * Entity string ID to follow (same semantics as ``). * Takes precedence over x/y when set. */ followEntity?: string; /** Static world-space X to center on (when not following an entity). */ x?: number; /** Static world-space Y to center on (when not following an entity). */ y?: number; /** Zoom level applied while this camera is active. Default 1. */ zoom?: number; /** * Follow-smoothing factor (0 = instant snap, 0.85 = very smooth). * When omitted, inherits the current Camera2D smoothing. */ smoothing?: number; /** World-space bounds clamping while this camera is active. */ bounds?: { x: number; y: number; width: number; height: number; }; /** * Blend-in duration in seconds when transitioning to this camera. * Use 0 for an instant cut. Default 0.4. */ blendDuration?: number; } /** * Declares a virtual camera that competes for control of the scene's * `Camera2D`. The active virtual camera with the highest `priority` wins. * Transitions between cameras blend smoothly over `blendDuration` seconds. * * Multiple `` components can coexist. Toggle `active` to hand * off camera control — ideal for cutscenes, boss arenas, and split focus. * * Must be placed inside `` alongside a ``. * * @example * ```tsx * // Normal gameplay: follow the player * * * // Boss fight: zoom out to show the arena * * ``` */ declare function VirtualCamera({ id, priority, active, followEntity, x, y, zoom, smoothing, bounds, blendDuration, }: VirtualCameraProps): null; interface TrailProps { /** Maximum number of trail points (default 20) */ length?: number; /** CSS color string (default '#ffffff') */ color?: string; /** Trail width in pixels (default 3) */ width?: number; } /** * Renders a fading polyline that follows the entity's position. * * The trail is drawn in the render pass — it uses the entity's Transform * history collected each frame. * * Must be used inside an `` with a ``. * * @example * ```tsx * * * * * * ``` */ declare function Trail({ length, color, width }: TrailProps): null; interface NineSliceProps { /** Image source URL */ src: string; /** Rendered width in pixels */ width: number; /** Rendered height in pixels */ height: number; /** Top border inset in source pixels (default 8) */ borderTop?: number; /** Right border inset in source pixels (default 8) */ borderRight?: number; /** Bottom border inset in source pixels (default 8) */ borderBottom?: number; /** Left border inset in source pixels (default 8) */ borderLeft?: number; /** Draw order (default 0) */ zIndex?: number; } /** * Renders a 9-slice sprite that scales while preserving its border regions. * * Must be used inside an `` with a ``. * * @example * ```tsx * * * * * ``` */ declare function NineSlice({ src, width, height, borderTop, borderRight, borderBottom, borderLeft, zIndex, }: NineSliceProps): null; interface AssetLoaderProps { /** List of asset URLs to preload */ assets: string[]; /** Shown while assets are loading */ fallback?: React__default.ReactNode; /** Called if any asset fails to load */ onError?: (err: Error) => void; children: React__default.ReactNode; } /** * Suspense-style asset loading boundary. * * Shows `fallback` until all assets in the list are loaded (or errored). * Once loaded, renders `children`. * * @example * ```tsx * Loading…} * > * * * ``` */ declare function AssetLoader({ assets, fallback, onError, children }: AssetLoaderProps): react_jsx_runtime.JSX.Element; interface CircleProps { radius?: number; color?: string; strokeColor?: string; strokeWidth?: number; zIndex?: number; opacity?: number; } declare function Circle({ radius, color, strokeColor, strokeWidth, zIndex, opacity, }: CircleProps): null; interface LineProps { endX: number; endY: number; color?: string; lineWidth?: number; zIndex?: number; opacity?: number; lineCap?: CanvasLineCap; } declare function Line({ endX, endY, color, lineWidth, zIndex, opacity, lineCap, }: LineProps): null; interface PolygonProps { points: { x: number; y: number; }[]; color?: string; strokeColor?: string; strokeWidth?: number; zIndex?: number; opacity?: number; closed?: boolean; } declare function Polygon({ points, color, strokeColor, strokeWidth, zIndex, opacity, closed, }: PolygonProps): null; interface GradientProps { gradientType?: GradientType; stops: GradientStop[]; /** For linear: angle in radians (0 = left to right) */ angle?: number; /** For radial: inner radius ratio (0-1) */ innerRadius?: number; width: number; height: number; zIndex?: number; visible?: boolean; anchorX?: number; anchorY?: number; } declare function Gradient({ gradientType, stops, angle, innerRadius, width, height, zIndex, visible, anchorX, anchorY, }: GradientProps): null; interface MaskProps { shape?: MaskShape; width?: number; height?: number; radius?: number; inverted?: boolean; } /** * Clips the parent entity's sprite to a shape. * * @example * * * * * */ declare function Mask({ shape, width, height, radius, inverted }: MaskProps): null; interface JointProps { type: JointType; /** Entity ID of the connected entity */ target: string; anchorA?: { x: number; y: number; }; anchorB?: { x: number; y: number; }; length?: number; stiffness?: number; damping?: number; maxLength?: number; } declare function Joint({ type, target, anchorA, anchorB, length, stiffness, damping, maxLength }: JointProps): null; interface ConvexColliderProps { /** Vertices in CCW order (max 8 for performance). Positions relative to entity center. */ vertices: { x: number; y: number; }[]; offsetX?: number; offsetY?: number; isTrigger?: boolean; layer?: string; mask?: string | string[]; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } /** * @experimental Physics response for convex polygons is not yet fully implemented. * This collider generates contact events but impulse resolution may be incomplete. */ declare function ConvexCollider({ vertices, offsetX, offsetY, isTrigger, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: ConvexColliderProps): null; interface TriangleColliderProps { a: { x: number; y: number; }; b: { x: number; y: number; }; c: { x: number; y: number; }; offsetX?: number; offsetY?: number; isTrigger?: boolean; layer?: string; mask?: string | string[]; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } /** * @experimental Triangle collider support is not yet complete. * Collision events are generated but physics response may be unreliable. */ declare function TriangleCollider({ a, b, c, offsetX, offsetY, isTrigger, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: TriangleColliderProps): null; interface SegmentColliderProps { start: { x: number; y: number; }; end: { x: number; y: number; }; isTrigger?: boolean; layer?: string; mask?: string | string[]; oneWay?: boolean; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } /** * @experimental Segment (edge) collider support is not yet complete. * Suitable for static one-way platforms; dynamic response is not guaranteed. */ declare function SegmentCollider({ start, end, isTrigger, layer, mask, oneWay, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: SegmentColliderProps): null; interface HeightFieldColliderProps { heights: number[]; scaleX?: number; scaleY?: number; layer?: string; mask?: string | string[]; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } /** * @experimental Height field terrain collider is not yet fully implemented. * Static terrain collision works; complex interactions may have edge cases. */ declare function HeightFieldCollider({ heights, scaleX, scaleY, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: HeightFieldColliderProps): null; interface HalfSpaceColliderProps { normalX?: number; normalY?: number; layer?: string; mask?: string | string[]; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } /** * @experimental Infinite half-space collider is not yet fully implemented. * Useful as a static world boundary; dynamic body response may be incomplete. */ declare function HalfSpaceCollider({ normalX, normalY, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: HalfSpaceColliderProps): null; interface TriMeshColliderProps { vertices: { x: number; y: number; }[]; indices: number[]; layer?: string; mask?: string | string[]; friction?: number; restitution?: number; frictionCombineRule?: CombineRule; restitutionCombineRule?: CombineRule; enabled?: boolean; } /** * @experimental Triangle mesh collider is not yet fully implemented. * Suitable for static complex geometry; dynamic body response may be incomplete. */ declare function TriMeshCollider({ vertices, indices, layer, mask, friction, restitution, frictionCombineRule, restitutionCombineRule, enabled, }: TriMeshColliderProps): null; declare function useGame(): EngineState; interface CameraControls { /** * Trigger a screen-shake effect. * @param intensity - Maximum pixel displacement per frame. * @param duration - How long the shake lasts in seconds. */ shake(intensity: number, duration: number): void; /** * Set the world-space offset applied to the camera follow target. * Useful for look-ahead: `setFollowOffset(facing * 80, 0)`. */ setFollowOffset(x: number, y: number): void; /** * Instantly move the camera center to a world-space position. * Bypasses smoothing - useful for instant scene cuts. */ setPosition(x: number, y: number): void; /** * Returns the current camera world-space position. */ getPosition(): { x: number; y: number; }; /** * Programmatically set the camera zoom level. */ setZoom(zoom: number): void; /** * Returns the current camera zoom level. */ getZoom(): number; } /** * Returns controls for the active Camera2D in the scene. * Must be used inside ``. * * @example * ```tsx * function HUD() { * const camera = useCamera() * return ( * * ) * } * ``` */ declare function useCamera(): CameraControls; interface CameraLookaheadOptions { /** * Maximum lookahead offset in world pixels (default 100). * The camera leads by this many pixels in the entity's movement direction. */ distance?: number; /** * Lerp factor per second controlling how quickly the offset follows velocity (default 3). * Higher = snappier, lower = smoother. */ smoothing?: number; /** * Whether to apply vertical lookahead in addition to horizontal (default false). * Useful for top-down or platformers with vertical sections. */ vertical?: boolean; } /** * Automatically adjusts the active Camera2D's follow offset based on the * tracked entity's velocity, creating a smooth look-ahead effect. * * Must be used inside ``. The entity must have a `RigidBody` component. * * @example * function Player() { * const id = useEntity() * useCameraLookahead(id, { distance: 120, smoothing: 4 }) * return * } */ declare function useCameraLookahead(entityId: EntityId, opts?: CameraLookaheadOptions): void; interface CameraBlendControls { /** * Activate a registered virtual camera by id. * If the camera has a lower priority than the current one, raising its * priority temporarily is more ergonomic — but activating it is the * simplest way to hand off control from code. */ activate(id: string): void; /** * Deactivate a registered virtual camera by id. * The next highest-priority active camera takes over automatically. */ deactivate(id: string): void; /** * Force a specific virtual camera to take over immediately, regardless of * priority, by temporarily setting its priority to a very high value and * activating it. Call `restore()` to return to normal priority-based control. */ override(id: string): void; /** * Remove any priority override set by `override()`, restoring the camera's * original priority. */ restore(id: string): void; /** * Returns the id of the virtual camera currently in control, or null if * no virtual cameras are active. */ getActiveId(): string | null; } /** * Imperative controls for the virtual camera system. Lets you activate, * deactivate, and force-override virtual cameras from game logic. * * Must be used inside ``. * * @example * ```tsx * function BossEncounter() { * const cam = useCameraBlend() * * useEffect(() => { * cam.override('bossArena') * return () => cam.restore('bossArena') * }, []) * } * ``` */ declare function useCameraBlend(): CameraBlendControls; interface CinematicStep { /** ID of the virtual camera to activate for this step. */ cameraId: string; /** * How long to hold this camera in seconds before advancing. * Use `Infinity` to hold until `stop()` is called or the sequence is unmounted. */ holdFor: number; /** * Override the virtual camera's `blendDuration` for this specific step. * When omitted, uses the camera's configured `blendDuration`. */ blendDuration?: number; } interface CinematicSequenceControls { /** Start the sequence from the beginning. */ play(): void; /** Stop the sequence and deactivate the current camera step. */ stop(): void; /** Whether the sequence is currently playing. */ readonly isPlaying: boolean; /** Zero-based index of the current step, or -1 when stopped. */ readonly currentStep: number; } /** * Plays an ordered sequence of virtual camera shots inside the engine loop. * Each step activates a named `` for `holdFor` seconds, then * automatically advances to the next step. Respects engine pause. * * The virtual cameras referenced in the steps must be mounted in the scene * tree via `` before calling `play()`. * * @example * ```tsx * const { play, stop, isPlaying } = useCinematicSequence([ * { cameraId: 'intro', holdFor: 2, blendDuration: 0 }, * { cameraId: 'overview', holdFor: 3, blendDuration: 1 }, * { cameraId: 'mainFollow', holdFor: Infinity, blendDuration: 0.5 }, * ], { onComplete: () => console.log('cutscene done') }) * * // Trigger on mount: * useEffect(() => { play() }, []) * ``` */ declare function useCinematicSequence(steps: CinematicStep[], opts?: { onComplete?: () => void; }): CinematicSequenceControls; interface SnapshotControls { /** * Capture a full serialisable snapshot of all ECS entity/component data. * Safe to JSON-stringify and store externally (localStorage, server, etc.) * * @example * ```ts * const { save, restore } = useSnapshot() * const checkpoint = save() // capture at checkpoint * restore(checkpoint) // reset to that state * ``` */ save(): WorldSnapshot; /** * Restore the world to a previously captured snapshot. * All current entities are replaced with the snapshot's entities. * * Note: React component state is NOT rolled back — only ECS data is restored. * For a full game reset, prefer remounting the `` key instead. */ restore(snapshot: WorldSnapshot): void; } /** * Returns save/restore controls for the ECS world snapshot system. * Must be used inside ``. * * @example * ```tsx * function SaveButton() { * const { save, restore } = useSnapshot() * const [slot, setSlot] = useState(null) * return ( * <> * * * * ) * } * ``` */ declare function useSnapshot(): SnapshotControls; declare function useEntity(): EntityId; /** * Returns a function that destroys the current entity on the next ECS update. * Must be used inside ``. * * Useful for collectibles, projectiles, or any entity that needs to destroy * itself in response to a collision or trigger event. * * @example * function CoinPickup() { * const destroy = useDestroyEntity() * useTriggerEnter(() => { * collectCoin() * destroy() * }, { tag: 'player' }) * return null * } */ declare function useDestroyEntity(): () => void; interface VirtualInputState { /** Left–right axis in [−1, 1]. Positive = right. */ readonly axisX: number; /** Up–down axis in [−1, 1]. Positive = down. */ readonly axisY: number; /** Whether a named virtual button is currently pressed. */ button(name: string): boolean; } /** * Returns the current state of the on-screen virtual joystick and buttons. * Reads synchronously from the module-level store — safe to call in a Script * update function every frame without triggering React re-renders. * * Combine with keyboard or gamepad input for multi-input support: * * @example * function MobilePlayer() { * const input = useInput() * const virt = useVirtualInput() * * // Script update: * const moveX = input.isHeld('ArrowRight') ? 1 * : input.isHeld('ArrowLeft') ? -1 * : virt.axisX * const jump = input.isPressed('Space') || virt.button('action') * } */ declare function useVirtualInput(): VirtualInputState; declare function useInput(): InputManager; interface BoundInputMap { /** True every frame any bound key is held. */ isActionDown(action: string): boolean; /** True only on the first frame any bound key was pressed. */ isActionPressed(action: string): boolean; /** True only on the frame any bound key was released. */ isActionReleased(action: string): boolean; /** * Returns -1..1 for axis bindings. For key bindings, 1 if down, 0 otherwise. * @see {@link AxisBinding} */ getAxis(action: string): number; /** * Alias for `getAxis`. Matches the `PlayerInput` naming convention — use this * when writing code that needs to work with both `useInputMap` and `usePlayerInput`. */ getActionAxis(action: string): number; } /** * React hook that returns a pre-bound action map for use inside ``. * * @example * ```tsx * function MyScript() { * const actions = useInputMap({ * left: ['ArrowLeft', 'KeyA'], * right: ['ArrowRight', 'KeyD'], * jump: ['Space', 'ArrowUp', 'KeyW'], * }) * // use actions.isActionDown('left') in a Script update or game loop callback * } * ``` */ declare function useInputMap(bindings: ActionBindings): BoundInputMap; declare function useEvents(): EventBus; declare function useEvent(event: string, handler: (data: T) => void): void; interface CoordinateHelpers { /** * Convert a world-space position to canvas pixel coordinates. * Takes current camera position and zoom into account. */ worldToScreen(wx: number, wy: number): { x: number; y: number; }; /** * Convert canvas pixel coordinates to world-space position. * Takes current camera position and zoom into account. */ screenToWorld(sx: number, sy: number): { x: number; y: number; }; } /** * Returns helpers for converting between world-space and screen (canvas pixel) coordinates. * * @example * ```tsx * function Minimap() { * const { worldToScreen, screenToWorld } = useCoordinates() * // worldToScreen(player.x, player.y) → canvas pixel position of player * } * ``` */ declare function useCoordinates(): CoordinateHelpers; /** * Reactively queries the ECS world for entities that have all the given components. * Re-syncs on every animation frame, returning an up-to-date array of entity IDs. * * @example * ```tsx * function EnemyCounter() { * const enemies = useWorldQuery('Enemy', 'Transform') * return * } * ``` */ declare function useWorldQuery(...components: string[]): EntityId[]; interface PreloadState { /** 0–1 loading progress */ progress: number; /** True when all assets have finished loading (or errored) */ loaded: boolean; /** First error encountered, if any */ error: Error | null; } /** * Preloads a list of asset URLs using the engine's AssetManager. * Returns loading progress and a `loaded` flag. * * Works with images (any extension) — audio goes through the engine's audio API. * * @example * ```tsx * function Level() { * const { progress, loaded } = usePreload(['/hero.png', '/tiles.png']) * if (!loaded) return * return * } * ``` */ declare function usePreload(assets: string[]): PreloadState; interface InputContextControls { push(ctx: InputContextName): void; pop(ctx: InputContextName): void; readonly active: InputContextName; } /** * Access and manipulate the global input context stack. * * If you pass a `ctx` argument, that context is automatically pushed on mount * and popped on unmount — ideal for pause menus, cutscenes, etc. * * @example * ```tsx * function PauseMenu() { * useInputContext('pause') // auto-push/pop * return
Paused
* } * ``` */ declare function useInputContext(ctx?: InputContextName): InputContextControls; /** * Returns a `PlayerInput` bound to the shared InputManager for the given player ID. * * @param playerId - Player number (1-based). * @param bindings - Action bindings for this player. * * @example * ```tsx * function P1({ x, y }: Props) { * const p1 = usePlayerInput(1, { jump: 'Space', left: 'ArrowLeft', right: 'ArrowRight' }) * return ( * *