/** One authored stop in a day: where the agent belongs, and when it wants to get there. */ export interface RoutineStopSpec { /** Opaque place id the agent occupies; the caller owns what a place means and where it stands. */ readonly place: string; /** Authored arrival time in game-seconds into the cycle (0 .. `cycleSeconds`). */ readonly arriveAt: number; /** Opaque activity label the stop is for ("work", "meal", "sleep"); never interpreted here. */ readonly activity?: string; /** Seconds spent walking here from the previous stop; overrides `RoutineConfig.travelSeconds`. */ readonly travelSeconds?: number; /** Need refills applied on arrival — a meal restores hunger while the agent stands there. */ readonly refill?: Readonly>; } /** Everything needed to resolve a routine: its authored stops, its cycle, and how far apart places are. */ export interface RoutineConfig { readonly stops: readonly RoutineStopSpec[]; /** Cycle length in game-seconds; default one game day (`SECONDS_PER_GAME_DAY`). */ readonly cycleSeconds?: number; /** * Injected travel time between two places, used when a stop does not author `travelSeconds`. * Default `0`, so a routine of places that are all the same spot needs no travel at all. */ readonly travelSeconds?: (from: string, to: string) => number; } /** One stop after travel is accounted for: the authored time and the time the agent really gets there. */ export interface RoutineStop { readonly index: number; readonly place: string; readonly activity: string | null; /** The authored arrival time, in cycle seconds. */ readonly plannedArriveAt: number; /** Real arrival — later than planned when the previous stop's walk ran into this one. */ readonly arriveAt: number; /** When the agent must leave to reach the next stop on time; never before `arriveAt`. */ readonly departAt: number; readonly refill: Readonly> | null; } /** Where a routine puts its agent at one instant. */ export interface RoutinePhase { /** Index of the stop held here, or the stop being walked away from. */ readonly stop: number; /** Place the agent is at, or the place it is walking from. */ readonly place: string; /** Place it is walking to; `null` while holding. */ readonly nextPlace: string | null; readonly activity: string | null; readonly travelling: boolean; /** 0 at departure to 1 on arrival; `0` while holding. */ readonly progress: number; /** Absolute game-second this phase began. */ readonly since: number; /** Absolute game-second the next phase begins. */ readonly until: number; } /** * An authored day resolved against time: arrival times after walking, departures early enough to * make the next stop, and a phase for any instant. Pure — there is no state to tick, so a far agent * and a loaded save read the same day from the same clock. */ export interface RoutineTimeline { /** Seconds in one cycle. */ readonly cycleSeconds: number; /** Stops in order, with real arrival and departure times. */ readonly stops: readonly RoutineStop[]; /** Where the routine puts the agent at absolute game-second `time`; wraps every cycle. */ phaseAt(time: number): RoutinePhase; /** Absolute game-second of the next arrival or departure strictly after `time`. */ nextChangeAfter(time: number): number; } /** * Resolve an authored routine into a timeline driven by the world clock. * * Travel is what makes arrival times real: each stop departs early enough to walk there on time, * and when the previous stop ran long the arrival slips instead of the agent teleporting. A day * whose walks cannot fit its cycle throws rather than silently putting the agent in two places. * * @capability routine-timeline authored daily routines (home, work, meal) resolved against the world clock */ export declare function resolveRoutine(config: RoutineConfig): RoutineTimeline;