/**
 * ARCHITECTURE: LiveWorldState
 *
 * Client-side world model that maintains chunk data received from the server.
 * This is the browser's "copy" of the nearby world — chunks are loaded/unloaded
 * as the server sends LevelChunkPackets and NetworkChunkPublisherUpdatePackets.
 *
 * DATA FLOW:
 *   Server → proxy (decodes Bedrock protocol) → WebSocket → LiveWorldState
 *   LiveWorldState marks chunks dirty → WorldRenderer reads dirty chunks →
 *   ChunkMeshBuilder converts to Babylon.js meshes
 *
 * BLOCK ACCESS:
 *   getBlock(x, y, z) → { runtimeId, name } or undefined
 *   setBlock(x, y, z, runtimeId) → marks chunk dirty
 *   getBlockName(runtimeId) → block identifier string via palette lookup
 *
 * CHUNK STORAGE:
 *   Chunks keyed by "chunkX,chunkZ" string in a Map.
 *   Each chunk has up to 24 subchunks (y = -64 to 319 in overworld).
 *   Each subchunk is 16×16×16 blocks stored as a flat Int32Array of runtime IDs.
 *   Storage order is XZY: index = x*256 + z*16 + y (Bedrock SubChunk format).
 *
 * BLOCK PALETTE:
 *   Maps runtime IDs (32-bit hashes) → block names (e.g., "minecraft:stone").
 *   Populated from StartGamePacket.block_palette and block_palette events.
 *   CRITICAL: Chunks loaded before the palette arrives will have zero rendered
 *   blocks. When the palette arrives, all pre-loaded chunks are marked dirty
 *   so they get rebuilt with correct block names.
 *
 * DIRTY TRACKING:
 *   _dirtyChunks tracks which chunk keys need mesh rebuilds.
 *   Chunks are dirtied when: new chunk data arrives, blocks are modified,
 *   palette arrives (mass re-dirty), or adjacent chunks load (face-culling
 *   recalculation at chunk boundaries).
 *
 * CLEAR ZONE:
 *   Optional filter that replaces non-whitelisted blocks above a Y threshold
 *   with air. Used to clear terrain for building or to isolate structures.
 *   Applied to incoming chunk data as it arrives.
 *
 * COORDINATE SYSTEMS:
 *   - World coords: (x, y, z) — absolute block position
 *   - Chunk coords: (chunkX, chunkZ) = (x >> 4, z >> 4)
 *   - Local coords: (x & 15, y & 15, z & 15) within a subchunk
 *   - Subchunk index: (y - minY) >> 4
 *
 * PACKET HANDLERS:
 *   Each handle*() method processes a specific Bedrock protocol packet type.
 *   Packet interfaces are defined at the top of this file. The proxy pre-parses
 *   binary protocol data into JSON objects before sending via WebSocket.
 *
 * RELATED FILES:
 *   - WorldRenderer.ts — reads dirty chunks and builds scene meshes
 *   - ChunkMeshBuilder.ts — converts chunk data to Babylon.js meshes
 *   - EntityManager.ts — tracks entity state (separate from world blocks)
 *   - WorldChunk.ts — existing chunk model (used for file-based worlds)
 *   - BlockPalette.ts — block runtime ID → type mapping
 */
export interface IBlockState {
    runtimeId: number;
    name?: string;
}
export interface ISubChunk {
    blocks: Int32Array | number[];
    dirty: boolean;
}
export interface IChunkColumn {
    x: number;
    z: number;
    subchunks: (ISubChunk | undefined)[];
    dirty: boolean;
    meshGenerated: boolean;
}
export interface IBlockPaletteEntry {
    name: string;
    states?: Record<string, unknown>;
}
/** Shared 3D coordinate shape. */
interface IBlockPosition {
    x?: number;
    y?: number;
    z?: number;
    X?: number;
    Y?: number;
    Z?: number;
}
/** Pre-parsed subchunk data attached to a level_chunk packet by the proxy. */
interface IParsedSubChunkEntry {
    y?: number;
    blocks?: number[] | Int32Array;
}
export interface ILevelChunkPacket {
    x: number;
    z: number;
    sub_chunk_count?: number;
    /** Pre-parsed subchunk block arrays (provided by the proxy). */
    subchunks?: IParsedSubChunkEntry[];
    /** Raw payload buffer (legacy path). */
    payload?: ArrayBuffer | Uint8Array;
}
/** A single entry inside a SubChunk response. */
interface ISubChunkResponseEntry {
    result?: string;
    blocks?: number[] | Int32Array;
    dx?: number;
    dy?: number;
    dz?: number;
    yIndex?: number;
}
export interface ISubChunkPacket {
    origin?: {
        x?: number;
        z?: number;
    };
    entries?: ISubChunkResponseEntry[];
}
export interface IUpdateBlockPacket {
    position?: IBlockPosition;
    block_position?: IBlockPosition;
    block_runtime_id?: number;
    runtime_id?: number;
}
/** Individual block update within an update_subchunk_blocks batch. */
interface ISubChunkBlockUpdate {
    block_position?: IBlockPosition;
    position?: IBlockPosition;
    block_runtime_id?: number;
    runtime_id?: number;
}
export interface IUpdateSubChunkBlocksPacket {
    blocks?: ISubChunkBlockUpdate[];
    standard_blocks?: ISubChunkBlockUpdate[];
    extra_blocks?: ISubChunkBlockUpdate[];
}
export interface IChunkPublisherUpdatePacket {
    position?: IBlockPosition;
    radius?: number;
}
export interface IStartGameData {
    player_gamemode?: number;
    gamemode?: number;
    world_name?: string;
    difficulty?: number;
    dimension?: number;
    world_spawn?: {
        x?: number;
        y?: number;
        z?: number;
    };
    itemstates?: unknown[];
    block_palette?: Array<{
        runtime_id?: number;
        name?: string;
        states?: Record<string, unknown>;
    }>;
}
export default class LiveWorldState {
    private _chunks;
    private _blockPalette;
    private _dirtyChunks;
    private _worldName;
    private _gameMode;
    private _spawnPosition;
    private _worldTime;
    private _minY;
    private _maxY;
    private _dimensionId;
    private _difficulty;
    private _clearZone?;
    private _loadedChunkCount;
    get worldName(): string;
    get gameMode(): number;
    get spawnPosition(): {
        x: number;
        y: number;
        z: number;
    };
    get worldTime(): number;
    set worldTime(t: number);
    get dimensionId(): number;
    get minY(): number;
    get loadedChunkCount(): number;
    get dirtyChunkCount(): number;
    /**
     * Return the center position (in world coordinates) of all loaded chunks.
     * Falls back to spawnPosition if no chunks are loaded.
     */
    getChunkCenter(): {
        x: number;
        y: number;
        z: number;
    };
    /**
     * Set a clear zone that automatically filters incoming SubChunk data.
     * Any block above clearAboveY is replaced with air UNLESS it's in keepNames
     * AND at or below maxKeepY. This prevents SubChunk data races from restoring
     * natural terrain that was previously cleared.
     */
    setClearZone(clearAboveY: number, maxKeepY: number, keepNames: Set<string>): void;
    clearClearZone(): void;
    /**
     * Initialize from StartGamePacket data.
     */
    initFromStartGame(data: IStartGameData): void;
    /**
     * Get a block at world coordinates.
     */
    getBlock(x: number, y: number, z: number): IBlockState | undefined;
    /**
     * Set a block at world coordinates (for client-side prediction).
     */
    setBlock(x: number, y: number, z: number, runtimeId: number): void;
    /**
     * Check if the chunk containing this position has been loaded.
     */
    isChunkLoaded(x: number, z: number): boolean;
    /**
     * Check if a block position is solid (for collision detection).
     */
    isSolid(x: number, y: number, z: number): boolean;
    /**
     * Handle block_palette event from the proxy.
     * This provides the mapping of runtime IDs to block names.
     */
    handleBlockPalette(entries: {
        rid: number;
        name: string;
    }[]): void;
    /**
     * Handle a level_chunk packet from the server.
     * The proxy may have pre-parsed subchunk data for us.
     */
    private _levelChunkLogCount;
    private _subchunkLogCount;
    handleLevelChunk(packet: ILevelChunkPacket): void;
    /**
     * Handle a subchunk packet (from the proxy's parsed SubChunk response).
     * The proxy resolves PalettedBlockStorage and sends pre-parsed block arrays.
     * Origin is in sub-chunk coordinates (chunkX, subchunkY, chunkZ) — already
     * in chunk coordinate space. Do NOT right-shift by 4 (that would be double-shifting).
     */
    handleSubChunk(packet: ISubChunkPacket): void;
    /**
     * Handle update_block packet.
     */
    handleUpdateBlock(packet: IUpdateBlockPacket): void;
    /**
     * Handle update_subchunk_blocks — batch block updates within a subchunk.
     */
    handleUpdateSubChunkBlocks(packet: IUpdateSubChunkBlocksPacket): void;
    /**
     * Handle network_chunk_publisher_update — defines which chunks should be loaded.
     */
    handleChunkPublisherUpdate(packet: IChunkPublisherUpdatePacket): void;
    /**
     * Get chunk at chunk coordinates.
     */
    getChunk(chunkX: number, chunkZ: number): IChunkColumn | undefined;
    /**
     * Get all dirty chunks and clear dirty flags.
     */
    consumeDirtyChunks(): IChunkColumn[];
    /**
     * Mark a chunk as dirty so it will be rebuilt on next consumeDirtyChunks call.
     */
    markChunkDirty(chunk: IChunkColumn): void;
    /**
     * Get all loaded chunks.
     */
    getAllChunks(): IChunkColumn[];
    /**
     * Read-only access to the chunks map for iteration.
     * Used by WorldRenderer.ensureNearbyChunkMeshes() to scan for chunks
     * within render distance that need mesh generation.
     */
    get chunks(): ReadonlyMap<string, IChunkColumn>;
    /**
     * Get a chunk by its key string ("chunkX,chunkZ").
     */
    getChunkByKey(key: string): IChunkColumn | undefined;
    /**
     * Add or replace a chunk column directly.
     * Used by WorldViewer to feed pre-built chunk data from file-based MCWorld.
     */
    setChunkColumn(chunk: IChunkColumn): void;
    /**
     * Mark ALL loaded chunks as dirty, forcing a complete mesh rebuild.
     * Useful after fill commands or other bulk world modifications.
     */
    markAllChunksDirty(): void;
    /**
     * Get block palette entry by runtime ID.
     */
    private _lookupLogCount;
    private _lookupMissCount;
    private _lookupHitCount;
    getBlockName(runtimeId: number): string;
    /**
     * Unload all chunks (e.g., on dimension change).
     */
    clear(): void;
    /**
     * Parse a level_chunk payload into subchunk data.
     * The payload format depends on the network protocol version, but decoded
     * packets typically give us the raw subchunk data as a Buffer.
     */
    private _parseLevelChunkPayload;
    /**
     * Parse raw subchunk data into an ISubChunk.
     * Bedrock uses PalettedBlockStorage format per subchunk.
     */
    private _parseSubChunkData;
    /**
     * Apply the clear zone filter to a subchunk's block data.
     * Replaces non-whitelisted blocks above clearAboveY with air (runtime ID 0).
     */
    private _applyClearZoneToSubchunk;
}
export {};
