Skip to content

Macros

Calendaria supports macro automation through Trigger Configuration and Event-Attached Macros.


Configure macros to execute automatically when calendar events occur. Access via Settings Panel > Macros tab (GM only).

TriggerDescription
DawnFires at sunrise
DuskFires at sunset
MiddayFires at noon
MidnightFires at midnight
New DayFires when the day changes

Execute macros when seasons change:

  • Specific season: Fires when entering that season
  • All Seasons: Fires on any season change

Execute macros when moon phases change:

  • Moon: Specific moon or “All Moons”
  • Phase: Specific phase or “All Phases”

Calendar notes can have an attached macro that executes when the event triggers.

  • Event’s start time is reached
  • Multi-day events fire daily with progress data

Notes with the Silent flag will not trigger macros or notifications.

When Calendaria triggers a macro, it passes context data through Foundry’s scope parameter. This is a standard Foundry feature. When macros are executed programmatically (rather than manually clicked), the caller can provide a scope object containing relevant data.

Inside your macro, access this data by destructuring from scope:

const { event, trigger } = scope;

The scope variable is automatically available in your macro code. You don’t need to define or import it.

// Event trigger context
const { event } = scope;
console.log(event.id); // Note page ID
console.log(event.name); // Note name
console.log(event.flagData); // Full note data (startDate, endDate, categories, etc.)
// Multi-day progress context (if applicable)
const { trigger, progress } = scope;
if (trigger === 'multiDayProgress') {
console.log(progress.currentDay); // Current day number
console.log(progress.totalDays); // Total event duration
console.log(progress.percentage); // Completion percentage
console.log(progress.isFirstDay); // boolean
console.log(progress.isLastDay); // boolean
}

Macros executed via global triggers receive context data:

Time Threshold Triggers (dawn, dusk, midday, midnight)

Section titled “Time Threshold Triggers (dawn, dusk, midday, midnight)”
const { trigger, worldTime, components, calendar } = scope;
console.log(trigger); // "sunrise", "sunset", "midday", "midnight"
console.log(worldTime); // Current world time in seconds
console.log(components); // { year, month, dayOfMonth, hour, minute, ... }
const { trigger, previous, current, calendar } = scope;
console.log(trigger); // "newDay"
console.log(previous.year); // Previous date components
console.log(current.year); // Current date components
console.log(calendar); // Active calendar object
const { trigger, previous, current, previousSeason, currentSeason, calendar } = scope;
console.log(trigger); // "seasonChange"
console.log(previous); // Previous date components
console.log(current); // Current date components
console.log(previousSeason); // Previous season object { name, ... }
console.log(currentSeason); // Current season object { name, ... }
console.log(calendar); // Active calendar object
const { trigger, moon } = scope;
console.log(trigger); // "moonPhaseChange"
console.log(moon.moonIndex); // Moon index
console.log(moon.moonName); // Moon name
console.log(moon.previousPhaseIndex);
console.log(moon.previousPhaseName);
console.log(moon.currentPhaseIndex);
console.log(moon.currentPhaseName);

// Advance 1 hour
await CALENDARIA.api.advanceTime({ hour: 1 });
// Advance 8 hours (long rest)
await CALENDARIA.api.advanceTime({ hour: 8 });
// Advance 1 day
await CALENDARIA.api.advanceTime({ day: 1 });
// Jump to specific date
await CALENDARIA.api.jumpToDate({ year: 1492, month: 5, day: 15 });
// Advance to next sunrise
await CALENDARIA.api.advanceTimeToPreset('sunrise');
// Advance to next sunset
await CALENDARIA.api.advanceTimeToPreset('sunset');
// Force the cinematic overlay when advancing
await CALENDARIA.api.advanceTime({ day: 7 }, { cinematic: true });
await CALENDARIA.api.jumpToDate({ year: 1492, month: 5, day: 15 }, { cinematic: true });
// Toggle the real-time clock on/off
CALENDARIA.api.toggleClock();
// Start the clock (if not already running)
if (!CALENDARIA.api.isClockRunning()) CALENDARIA.api.startClock();
// Stop the clock
CALENDARIA.api.stopClock();
// Check current clock speed (game seconds per real second)
const speed = CALENDARIA.api.getClockSpeed();
ui.notifications.info(`Clock speed: ${speed}x`);
// Show current date/time
const now = CALENDARIA.api.getCurrentDateTime();
const formatted = CALENDARIA.api.formatDate(now, 'datetime24');
ChatMessage.create({ content: `<b>Current Time:</b> ${formatted}` });
// Show weather
const weather = CALENDARIA.api.getCurrentWeather();
ChatMessage.create({
content: `<b>Weather:</b> ${weather.label}, ${weather.temperature}`
});
// Show moon phase
const phase = CALENDARIA.api.getMoonPhase(0);
ChatMessage.create({ content: `<b>Moon:</b> ${phase.name}` });
// Show season
const season = CALENDARIA.api.getCurrentSeason();
ChatMessage.create({ content: `<b>Season:</b> ${season.name}` });
// Is it night?
const isNight = CALENDARIA.api.isNighttime();
ui.notifications.info(isNight ? 'It is nighttime' : 'It is daytime');
// Is it a rest day?
if (CALENDARIA.api.isRestDay()) {
ui.notifications.info('Today is a rest day');
}
// Is it a festival?
if (CALENDARIA.api.isFestivalDay()) {
const festival = CALENDARIA.api.getCurrentFestival();
ui.notifications.info(`Today is ${festival.name}!`);
}
// Create a quick note
const now = CALENDARIA.api.getCurrentDateTime();
await CALENDARIA.api.createNote({
name: 'Session Note',
content: '<p>Something important happened here.</p>',
startDate: { year: now.year, month: now.month, day: now.dayOfMonth },
allDay: true
});
// Get today's events
const notes = CALENDARIA.api.getNotesForDate(now.year, now.month, now.dayOfMonth);
if (notes.length > 0) {
const list = notes.map((n) => n.name).join(', ');
ui.notifications.info(`Today: ${list}`);
}
// Set specific weather
await CALENDARIA.api.setWeather('thunderstorm', { temperature: 55 });
// Override wind and precipitation on top of a preset (morning period only)
await CALENDARIA.api.setWeather('cloudy', {
period: 'morning',
temperature: 11,
wind: { speed: 2, direction: 'SW', forced: false }, // speed 0-5; direction: compass string ('SW') or degrees (225)
precipitation: { type: null, intensity: 0 } // type: null|drizzle|rain|snow|sleet|hail
});
// Generate weather from climate zone
await CALENDARIA.api.generateWeather();
// Get forecast
const forecast = await CALENDARIA.api.getWeatherForecast({ days: 7 });
// Clear all weather history
await CALENDARIA.api.clearWeatherHistory({ all: true });
// Clear future history only
await CALENDARIA.api.clearWeatherHistory({ future: true });

See API Reference and Hooks.