// the day and night cycle. world time counts ticks since 06:00 of day 1, it never wraps around import { TICKS_PER_SECOND } from "./constants.ts"; // 30 minutes of day, 06:00 to 18:00 export const DAY_TICKS = 30 * 60 * TICKS_PER_SECOND; // 10 minutes of night, 18:00 to 06:00 export const NIGHT_TICKS = 10 * 60 * TICKS_PER_SECOND; export const CYCLE_TICKS = DAY_TICKS + NIGHT_TICKS; // dusk right after sunset and dawn right before sunrise, so the whole day is bright export const TWILIGHT_TICKS = 60 * TICKS_PER_SECOND; // in game hours are longer during the day than at night, since both halves are 12 hours const DAY_TICKS_PER_HOUR = DAY_TICKS / 12; const NIGHT_TICKS_PER_HOUR = NIGHT_TICKS / 12; // from midnight to 06:00, to count days from midnight const TICKS_BEFORE_SIX = 6 * NIGHT_TICKS_PER_HOUR; // named times of day, as ticks into the cycle export const TIMES_OF_DAY: Record = { day: 0, noon: 6 * DAY_TICKS_PER_HOUR, sunset: DAY_TICKS, night: DAY_TICKS + TWILIGHT_TICKS, midnight: DAY_TICKS + 6 * NIGHT_TICKS_PER_HOUR, }; // ticks into the current cycle, 0 is 06:00 export function time_of_day(time: number): number { return ((time % CYCLE_TICKS) + CYCLE_TICKS) % CYCLE_TICKS; } export function is_day(time: number): boolean { return time_of_day(time) < DAY_TICKS; } // the day number, starting at 1 and going up at midnight, and the time on a 24 hour clock export function clock(time: number): { day: number; hour: number; minute: number } { const t = time_of_day(time); const hours = t < DAY_TICKS ? 6 + t / DAY_TICKS_PER_HOUR : 18 + (t - DAY_TICKS) / NIGHT_TICKS_PER_HOUR; const total_minutes = Math.floor(hours * 60) % (24 * 60); return { day: Math.floor((time + TICKS_BEFORE_SIX) / CYCLE_TICKS) + 1, hour: Math.floor(total_minutes / 60), minute: total_minutes % 60, }; } // like "Day 3, 14:05" export function format_clock(time: number): string { const { day, hour, minute } = clock(time); return `Day ${day}, ${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`; } // how much daylight there is, 1 all day and 0 in the middle of the night, fading through dusk and dawn. // time can be fractional, for drawing between ticks export function daylight(time: number): number { const t = time_of_day(time); if (t < DAY_TICKS) return 1; const into_night = t - DAY_TICKS; const until_day = CYCLE_TICKS - t; const fade = Math.min(1, into_night / TWILIGHT_TICKS, until_day / TWILIGHT_TICKS); return 1 - smoothstep(fade); } function smoothstep(x: number) { return x * x * (3 - 2 * x); }