import type { Vec2, Vec3, Rect, Color, EntityId, Component, ComponentType } from './types';
/**
 * Discriminated union of all built-in component types.
 * Use `component.type` to narrow the type safely.
 */
export type BuiltInComponentType = 'Transform' | 'Sprite' | 'Shape' | 'Collider2D' | 'RigidBody2D' | 'Text' | 'Animator' | 'Script' | 'AudioSource' | 'ParticleEmitter' | 'CameraTarget';
/**
 * Discriminated union mapping.
 * Given a component `type` literal, resolves to the concrete component interface.
 */
export interface ComponentTypeMap {
    Transform: {
        type: 'Transform';
        position: Vec2;
        rotation: number;
        scale: Vec2;
        prevPosition: Vec2;
        prevRotation: number;
    };
    Sprite: {
        type: 'Sprite';
        assetId: string | null;
        width: number;
        height: number;
        opacity: number;
        layer: number;
        visible: boolean;
    };
    Shape: {
        type: 'Shape';
        shape: 'rect' | 'circle' | 'polygon' | 'line';
        fillColor: Color;
        strokeColor: Color;
        layer: number;
        visible: boolean;
    };
    Collider2D: {
        type: 'Collider2D';
        shape: 'aabb' | 'circle' | 'polygon';
        width: number;
        height: number;
        radius: number;
        isTrigger: boolean;
    };
    RigidBody2D: {
        type: 'RigidBody2D';
        bodyType: 'dynamic' | 'static' | 'kinematic';
        velocity: Vec2;
        mass: number;
    };
    Text: {
        type: 'Text';
        text: string;
        fontSize: number;
        fontFamily: string;
    };
    Animator: {
        type: 'Animator';
    };
    Script: {
        type: 'Script';
        scriptId: string;
    };
    AudioSource: {
        type: 'AudioSource';
        soundId: string;
        playing: boolean;
    };
    ParticleEmitter: {
        type: 'ParticleEmitter';
        rate: number;
        maxParticles: number;
    };
    CameraTarget: {
        type: 'CameraTarget';
        priority: number;
    };
}
/** Any concrete built-in component (discriminated union). */
export type AnyBuiltInComponent = ComponentTypeMap[BuiltInComponentType] & Component;
export declare function isVec2(value: unknown): value is Vec2;
export declare function isVec3(value: unknown): value is Vec3;
export declare function isRect(value: unknown): value is Rect;
export declare function isColor(value: unknown): value is Color;
export declare function isComponent(value: unknown): value is Component;
export declare function isEntityId(value: unknown): value is EntityId;
/** Narrow component to a specific built-in type. */
export declare function isComponentOfType<T extends BuiltInComponentType>(component: Component, type: T): component is ComponentTypeMap[T] & Component;
/**
 * Get a component with type-safe narrowing instead of `as` cast.
 * Returns undefined if entity doesn't have that component.
 */
export declare function getTypedComponent<T extends BuiltInComponentType>(components: Component[], type: T): (ComponentTypeMap[T] & Component) | undefined;
/**
 * Require a component — throws if not found (use only when guaranteed).
 */
export declare function requireComponent<T extends BuiltInComponentType>(components: Component[], type: T, entityId: EntityId): ComponentTypeMap[T] & Component;
/**
 * Standard event name pattern: `namespace:action`
 * This type restricts event names to the correct format.
 */
export type EngineEventName = `engine:${string}` | `ecs:${string}` | `physics:${string}` | `input:${string}` | `audio:${string}` | `scene:${string}` | `render:${string}` | `network:${string}` | `editor:${string}` | `tutorial:${string}` | `plugin:${string}` | `collision:${string}` | `entity:${string}` | `sound:${string}` | `music:${string}` | `ui:${string}` | `game:${string}`;
/** Known engine events with typed payloads. */
export interface EngineEventMap {
    'engine:start': void;
    'engine:stop': void;
    'engine:pause': void;
    'engine:resume': void;
    'ecs:entity-created': {
        entityId: EntityId;
    };
    'ecs:entity-destroyed': {
        entityId: EntityId;
    };
    'ecs:component-added': {
        entityId: EntityId;
        type: ComponentType;
    };
    'ecs:component-removed': {
        entityId: EntityId;
        type: ComponentType;
    };
    'physics:collision-enter': {
        entityA: EntityId;
        entityB: EntityId;
    };
    'physics:collision-exit': {
        entityA: EntityId;
        entityB: EntityId;
    };
    'input:gamepad-connected': {
        index: number;
    };
    'input:gamepad-disconnected': {
        index: number;
    };
    'audio:sound-play': {
        id: string;
        soundId: number;
    };
    'audio:music-play': {
        id: string;
    };
    'scene:load': {
        sceneId: string;
    };
    'scene:unload': {
        sceneId: string;
    };
}
/**
 * Standard time parameter type.
 * Use `dt` everywhere for delta time (seconds).
 */
export interface TimeDelta {
    /** Delta time in seconds since last frame. */
    readonly dt: number;
    /** Fixed delta time in seconds (for physics). */
    readonly fixedDt: number;
    /** Total elapsed time in seconds. */
    readonly elapsed: number;
    /** Frame count since start. */
    readonly frame: number;
}
/** Generic record type (replaces `Record<string, any>`). */
export type StrictRecord<V = unknown> = Record<string, V>;
/** JSON-serializable value (replaces `any` in serialization). */
export type JsonValue = string | number | boolean | null | JsonValue[] | {
    [key: string]: JsonValue;
};
/** Callback with optional data (replaces `(...args: any[]) => void`). */
export type EventCallback<T = unknown> = (data: T) => void;
/**
 * Mark properties as strictly typed — no implicit `any` allowed.
 * Use instead of `Partial<T>` where undefined is meaningful.
 */
export type StrictPartial<T> = {
    [K in keyof T]?: T[K] | undefined;
};
/**
 * Ensure at least one property is defined (replaces loose optionals).
 */
export type AtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
    [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
}[Keys];
/**
 * Use in `default` of switch to ensure all cases are handled.
 * Compile-time error if a new case is added but not handled.
 */
export declare function assertNever(value: never, message?: string): never;
