export enum TileType { DEEP_WATER = 0, SHALLOW_WATER = 1, SAND = 2, GRASS = 3, DARK_GRASS = 4, FOREST = 5, ROCK = 6, FLOOR = 7, WALL = 8, TILLED_SOIL = 9, WATERED_SOIL = 10, } export const IMPASSABLE = new Set([ TileType.DEEP_WATER, TileType.SHALLOW_WATER, TileType.FOREST, TileType.ROCK, TileType.WALL, ]) export type ItemId = 'wood' | 'stone' | 'wheat_seed' | 'carrot_seed' | 'wheat' | 'carrot' export type BuildingType = 'floor' | 'wall' | 'chest' | 'bed' | 'stockpile_zone' export type CropKind = 'wheat' | 'carrot' export type JobType = 'chop' | 'mine' | 'farm' export type AIState = 'idle' | 'walking' | 'working' | 'sleeping' export interface JobPriorities { chop: number // 0 = disabled, 1 = highest, 4 = lowest mine: number farm: number } export interface VillagerJob { type: JobType targetId: string tileX: number tileY: number carrying: Partial> } export interface VillagerState { id: string name: string x: number y: number bedId: string | null job: VillagerJob | null priorities: JobPriorities energy: number aiState: AIState } export interface ResourceNodeState { id: string tileX: number tileY: number kind: 'tree' | 'rock' hp: number } export interface BuildingState { id: string tileX: number tileY: number kind: BuildingType ownerId: string } export interface CropState { id: string tileX: number tileY: number kind: CropKind stage: number maxStage: number stageTimerMs: number watered: boolean } export interface PlayerState { id: string x: number y: number inventory: Partial> } export interface WorldState { seed: number tiles: number[] resources: Record buildings: Record crops: Record villagers: Record stockpile: Partial> } export interface GameStateData { version: number world: WorldState player: PlayerState } export type GameAction = | { type: 'PLAYER_MOVE'; x: number; y: number } | { type: 'HARVEST_RESOURCE'; resourceId: string; rewards: Partial> } | { type: 'CHANGE_TILE'; tileX: number; tileY: number; tile: TileType } | { type: 'PLACE_BUILDING'; building: BuildingState; costs: Partial> } | { type: 'REMOVE_BUILDING'; buildingId: string } | { type: 'ADD_ITEMS'; items: Partial> } | { type: 'PLANT_CROP'; crop: CropState; seedItem: ItemId } | { type: 'WATER_CROP'; cropId: string } | { type: 'HARVEST_CROP'; cropId: string; rewards: Partial> } | { type: 'SPAWN_VILLAGER'; villager: VillagerState } | { type: 'VILLAGER_SET_JOB'; villagerId: string; job: VillagerJob | null } | { type: 'VILLAGER_SET_AI'; villagerId: string; aiState: AIState } | { type: 'VILLAGER_HARVEST_RESOURCE'; villagerId: string; resourceId: string } | { type: 'VILLAGER_HARVEST_CROP'; villagerId: string; cropId: string } | { type: 'VILLAGER_DEPOSIT'; villagerId: string } | { type: 'UPDATE_PRIORITIES'; villagerId: string; priorities: JobPriorities }