Chronology
A custom dating system is part of a world's identity — "22 Halimath, 1401 SR" reads nothing like "the Third Age, 3019". GMTales lets you define your world's own Calendars, date events against them in plain prose, and see every event laid out on one shared timeline — without ever leaking an event a player isn't meant to know about yet.
The pieces fit together like this: you define one or more Calendars in Settings, date Events inside your articles' Markdown, optionally set the campaign's Current Date, and browse it all in the Calendar — its own section in the campaign navigation bar.
Calendars
A Calendar is an in-world dating system — its months, an optional weekday cycle, and one or more eras. It is campaign configuration, edited in a GUI, not written as Markdown (see Packages for why config travels separately from content). Open it from Settings → Manage Calendars. Defining and editing Calendars is restricted to Game Masters and the campaign Creator.
Each Calendar has:
Months — a name and a fixed length in days for each. There are no leap rules.
Weekday cycle — optional named weekdays.
Eras — each with a
key(e.g.SR), a display name, an anchor, and a direction. A Forward era's year numbers grow later in time (Shire Reckoning); a Backward era's grow earlier (a "Before Reckoning" count).Date format template — a single template with placeholders that drives both how dates are read and how they are shown.
A typical Shire Reckoning calendar uses twelve 30-day months (Afteryule, Solmath, Rethe, Astron, Thrimidge, Forelithe, Afterlithe, Wedmath, Halimath, Winterfilth, Blotmath, Foreyule), one forward era SR, and the template:
The format template and the precision ladder
The template lists placeholders in significance order. The available placeholders are {era}, {year}, {month} (the month name), {monthn} (the month number), and {day}. You write one full template; partial dates work automatically, because the parser drops the least-significant parts and takes the longest match. With the template above, all of these are valid and parse at decreasing precision:
This means a date's precision is whatever you chose to write — and it is preserved everywhere. A year-precision event is never shown with a made-up day.
Primary calendar and offsets
Exactly one Calendar per campaign is the primary. It fixes the shared zero-point of the campaign's timeline. Every other Calendar declares an offset in days that aligns its own epoch to the primary, so events authored against different Calendars still land in the right order on one axis. The primary's offset is always 0. Your first Calendar is made primary automatically; single-calendar campaigns never touch offsets.
Dating Events
An Event is a dated point attached to the article segment it sits in. It inherits that segment's visibility, and its description auto-links to any articles it names.
An Event is calendar data, not article prose — the temporal counterpart of an image marker. You author it inside an article, but it does not render in the article body; it surfaces only in the Calendar. The surrounding prose stays, and the auto-link to any article the description names still forms. There are two ways to write one.
A one-liner, inline in your prose:
A block, when the event needs a fuller description:
The date is written in the chosen Calendar's own format, at whatever precision you like.
Which Calendar an Event uses
The Calendar for an Event is resolved in this order:
An explicit
calendar:argument on aneventortimelineblock.The article's default, set once at the top:
<!-- calendar: shire -->.The campaign's primary Calendar.
Calendar-bound timelines
A timeline block is free-text and presentational by default. Add a calendar: argument and each of its entries becomes a real, dated Event that joins the chronology. A calendar-bound timeline also renders like the chronology, inline where you wrote it: its entries are resolved against the Calendar, sorted, and grouped into Era/year bands — the same component and look as the Calendar:
A timeline with no calendar: argument is unchanged — free text, no Events, rendered as a plain inline timeline.
The Current Date
A campaign has an optional in-world "now", set by a Game Master from Settings → Manage Calendars. Pick a Calendar and choose an era, year, month, and day; GMTales records the moment on the shared axis. The Current Date marks where the story stands and defines which Events count as upcoming. You can clear it at any time.
The Calendar
The Calendar is its own section in the campaign navigation bar, alongside Articles and Gallery. It shows the chronology two ways:
A timeline of Era/year bands, each listing its Events in order. Click a band to drill into it.
A month grid for the chosen year, placing each Event on its month — and, at day precision, its day.
The Current Date appears as a "you are here" marker, and a per-viewer Upcoming panel lists the Events still ahead of it. If the campaign has more than one Calendar, a selector switches which one the dates are displayed in — the same shared timeline, re-read through a different culture's reckoning.
Spoiler-safety by construction
Because every date is a self-contained absolute point — no relative dates ("three days after the fall of Isengard"), no ranges — a date-keyed view simply omits the Events a viewer may not see, leaving no gap, anchor, or placeholder to infer hidden content from. Every aggregate the view shows — the bands, the counts, the upcoming list, the current date — is computed over the viewer-visible set only. A player browsing the chronology can never deduce that a secret event exists between two they can see.