@heroiclands/package-build 22.7.0 → 22.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/docs/api.md +45 -0
- package/docs/configuration.md +2 -2
- package/docs/content-format.md +152 -13
- package/engine/calendar-notes.mjs +805 -0
- package/engine/calendars.mjs +233 -0
- package/engine/content-format-check.mjs +10 -1
- package/engine/draft-notice.mjs +45 -13
- package/engine/frontmatter-lint.mjs +26 -0
- package/engine/index.mjs +9 -0
- package/engine/infobox.mjs +7 -2
- package/engine/note-dates.mjs +350 -0
- package/engine/note-vocabulary.mjs +69 -8
- package/engine/pdf-render.mjs +10 -0
- package/engine/retired-fields.mjs +58 -8
- package/package.json +1 -1
- package/types/engine/calendar-notes.d.mts +173 -0
- package/types/engine/calendars.d.mts +206 -0
- package/types/engine/draft-notice.d.mts +26 -4
- package/types/engine/index.d.mts +3 -0
- package/types/engine/note-dates.d.mts +70 -0
- package/types/engine/retired-fields.d.mts +23 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 22.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
**Calendars are content, not configuration.** The `calendar:` block retires from `package-build.config.yaml`, and a configuration that still declares it is refused by name.
|
|
8
|
+
|
|
9
|
+
**A calendar is a note.** A `lore` note with `subType: calendar` states the months it keeps, the weekdays it names, the seasons it marks and the year-counts kept in it, and a date names one of those by writing `<calendar shortcode>.<era shortcode>`. Days that belong to no month are a short month like any other, sitting in the list where they fall in the year.
|
|
10
|
+
|
|
11
|
+
**The world states its own year.** How long the year is, how the day divides and how the moon moves are written once on the world's own `place` note and on its moon's, so no calendar restates them — and a calendar whose months do not add up to that year is refused, naming the year rather than the arithmetic.
|
|
12
|
+
|
|
13
|
+
**A body is a place.** `place` gains `celestial`, for something observed from a world rather than located on one.
|
|
14
|
+
|
|
15
|
+
**A written day is bounded by the month it names.** A five-day month accepts five days and a thirty-day month accepts thirty, in whatever order a calendar keeps them; a package that names no calendar bounds nothing.
|
|
16
|
+
|
|
17
|
+
## 22.8.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
**A being's dates**
|
|
22
|
+
|
|
23
|
+
- A being says when it was born and when it died: `born:` takes over from `birthday:`, and `died:` sits beside it.
|
|
24
|
+
- Either date may read `unknown` where it was never recorded; an absent `born` says the being was never born, and an absent `died` says it is alive.
|
|
25
|
+
- `age:` is optional, and is an override — write it only where the number should win over the date, and write it `~34` where it is somebody's estimate.
|
|
26
|
+
- A note still writing `birthday:` compiles identically and is told once what to write instead.
|
|
27
|
+
- A profile reads its two dates ahead of the line describing the being's appearance.
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
**Dates**
|
|
32
|
+
|
|
33
|
+
- A package can state how its year is divided — how many months, and how many
|
|
34
|
+
days to a month — and the date it treats as the present.
|
|
35
|
+
- A refused `BF`/`AF` date now states the replacement rule instead of a computed value, which was wrong for `AF`.
|
|
36
|
+
|
|
37
|
+
**The book**
|
|
38
|
+
|
|
39
|
+
- A numbered or bulleted point whose text runs to more than one paragraph now
|
|
40
|
+
sets every paragraph flush under the point, so it reads as one block hanging
|
|
41
|
+
off its number instead of a stray indented paragraph beneath it.
|
|
42
|
+
|
|
43
|
+
**A draft entry's notice**
|
|
44
|
+
|
|
45
|
+
- The sentence sets in italic, with `Draft.` in bold ahead of it, on the page, in a journal entry and on an actor's dossier alike: the entry speaking about its own state rather than about the world.
|
|
46
|
+
- In the book the notice's mark sits in a column of its own, so a sentence that runs to two lines sets both of them clear of it.
|
|
47
|
+
- The mark is a filled disc with the exclamation knocked out of it, in the book's accent.
|
|
48
|
+
- The sentence sets at the size, face and ink of the entry's prose; the rule down its edge and the mark are what set it apart.
|
|
49
|
+
|
|
3
50
|
## 22.7.0
|
|
4
51
|
|
|
5
52
|
### Minor Changes
|
package/docs/api.md
CHANGED
|
@@ -604,6 +604,51 @@ The closed registry of system ids, and the `none` that stands for no system at a
|
|
|
604
604
|
| `assertSystemSegment` | `assertSystemSegment(value, where)` | `string` — the value, unchanged | refusing a value the `<system>` segment may not hold, validating inline |
|
|
605
605
|
| `assertSystemCharset` | `assertSystemCharset(segments, where)` | throws | refusing a registry declaration whose id could not be an address segment |
|
|
606
606
|
|
|
607
|
+
### `engine.calendars`
|
|
608
|
+
|
|
609
|
+
The axis every date normalises onto, the arithmetic over a calendar's month list, and the moon. A reckoning is an **era** declared on the note about the calendar that counts those years, and its epoch is the `start` written on that row — nothing is registered in configuration. The year conversion is piecewise on the sign, because the authored numbering has no year zero while the normalised value does: authored `-1` is `0`, and `-1` and `1` are adjacent. `lunarPhase` takes a floored modulo for the same reason the conversion branches: a truncated one is right on one side of an epoch and wrong on the other.
|
|
610
|
+
|
|
611
|
+
| Export | Signature | Returns | Use it when |
|
|
612
|
+
| ------------------- | ---------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------- |
|
|
613
|
+
| `CANONICAL_EPOCH` | `const CANONICAL_EPOCH` | — | naming where the canonical axis's own year 1 sits |
|
|
614
|
+
| `canonicalYear` | `canonicalYear(year, epoch?)` | `number` — the signed year on the axis | converting a year written in one reckoning to the number everything compares on |
|
|
615
|
+
| `dateSortKey` | `dateSortKey(year, month, day)` | `number` | ordering mixed-precision dates against a single number |
|
|
616
|
+
| `calendarStructure` | `calendarStructure(calendar)` | `{months}` — `null` where unstated | reading the months a calendar keeps, before phrasing a finding |
|
|
617
|
+
| `daysInMonth` | `daysInMonth(calendar, month)` | `number` — `null` where unstated | bounding a written day against the month it names |
|
|
618
|
+
| `daysInYear` | `daysInYear(months)` | `number` | asking what a month list claims the year is |
|
|
619
|
+
| `monthStarts` | `monthStarts(months)` | `number[]` | reading the same sum as a sequence, which is what an ordering error moves |
|
|
620
|
+
| `dayOfYear` | `dayOfYear(months, month, day)` | `number` | placing a written month and day in the year |
|
|
621
|
+
| `lunarPhase` | `lunarPhase(day, epochDay, cycle)` | `number` — `0` to `cycle - 1` | asking how far into its cycle a moon is, on either side of the epoch |
|
|
622
|
+
|
|
623
|
+
### `engine.noteDates`
|
|
624
|
+
|
|
625
|
+
A date on a note is one authored string — `[~][-]YYYY[/MM[/DD]] [<calendar shortcode>.<era shortcode>]` — and every field holding one parses through a single grammar into a single record. Print `text`, order on `sort`, do arithmetic on `canonicalYear`. A bare value sits on the canonical axis and carries `era: null`; one naming an era carries the qualifier and no `canonicalYear` or `sort` keys at all until the era is resolved against the corpus. The literal `unknown` parses to the same record with the year half empty, carrying a null `sort` and a null `canonicalYear`, so nothing can order it to one end of a list.
|
|
626
|
+
|
|
627
|
+
| Export | Signature | Returns | Use it when |
|
|
628
|
+
| ----------------------- | ------------------------------- | -------------------------------------------------- | ------------------------------------------------------------- |
|
|
629
|
+
| `UNKNOWN_DATE` | `const UNKNOWN_DATE` | — | naming the literal that says a date is not recorded |
|
|
630
|
+
| `NOTE_DATE_PATTERN` | `const NOTE_DATE_PATTERN` | — | matching the date grammar directly |
|
|
631
|
+
| `ERA_QUALIFIER_PATTERN` | `const ERA_QUALIFIER_PATTERN` | — | checking that a string is an era qualifier a date could carry |
|
|
632
|
+
| `parseNoteDate` | `parseNoteDate(value, options)` | `{date, findings}` — `date` is `null` when refused | reading a note's authored date, with every finding it earned |
|
|
633
|
+
|
|
634
|
+
### `engine.calendarNotes`
|
|
635
|
+
|
|
636
|
+
A calendar is a `lore` note with `subType: calendar`, declaring the months it keeps, the weekdays it names, the seasons it marks and the eras it counts years in. How long the year is, how the day divides and how the moon moves are facts about the **world**, written on its `place` note and its moon's, and no calendar may restate them — which is why the months summing to the world's year is the only arithmetic a calendar note is held to. One definition is emitted per calendar, in array shape: Foundry core prunes the keys outside its schema, and Calendaria converts the arrays to its own keyed collections.
|
|
637
|
+
|
|
638
|
+
| Export | Signature | Returns | Use it when |
|
|
639
|
+
| -------------------- | ----------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------- |
|
|
640
|
+
| `CALENDAR_SUBTYPE` | `const CALENDAR_SUBTYPE` | — | naming the `lore` subType whose notes are calendars |
|
|
641
|
+
| `INVARIANT_SUBTYPES` | `const INVARIANT_SUBTYPES` | — | naming the `place` subTypes a world fact may be written on |
|
|
642
|
+
| `CALENDAR_FIELDS` | `const CALENDAR_FIELDS` | — | reading the closed list of what a calendar note may declare |
|
|
643
|
+
| `INVARIANT_FIELDS` | `const INVARIANT_FIELDS` | — | reading the closed list of what a body may declare about itself |
|
|
644
|
+
| `checkCalendarNote` | `checkCalendarNote(note, opts)` | `object[]` — findings | holding a `lore` note to the family and to the year the world keeps |
|
|
645
|
+
| `checkWorldFacts` | `checkWorldFacts(note, opts)` | `object[]` — findings | holding a `place` note's world facts to one body, one year and one moon |
|
|
646
|
+
| `worldInvariants` | `worldInvariants(index)` | `{year, present, moon, body, moonName, …}` | reading the year, the present and the moon a package's own notes state |
|
|
647
|
+
| `quarterDays` | `quarterDays(daysPerYear)` | `number[]` — four days of the year | asking which days the year turns on |
|
|
648
|
+
| `compileCalendar` | `compileCalendar({note, invariants, contentPackage})` | `object` — the definition | building the one object both a core consumer and Calendaria read |
|
|
649
|
+
| `compileCalendars` | `compileCalendars(index, opts)` | `{calendars, invariants}` | building every calendar a package declares, or none where it states no year |
|
|
650
|
+
| `calendariaEnvelope` | `calendariaEnvelope(definition, opts)` | `object` — the import envelope | wrapping a definition for a hand import through Calendaria's settings |
|
|
651
|
+
|
|
607
652
|
### `engine.contentAddress`
|
|
608
653
|
|
|
609
654
|
Where a content note publishes on the web. One rule, in one place, because two builds need the same answer: the knowledgebase build renders the page, and the link manifest records the address other packages link to. Stating it twice is how a manifest comes to assert a URL that resolves at build time and 404s for the reader.
|
package/docs/configuration.md
CHANGED
|
@@ -48,7 +48,7 @@ around its own evaluation.
|
|
|
48
48
|
|
|
49
49
|
### Quick reference
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
22 top-level keys. `rootDir` is not one of them — a data configuration never
|
|
52
52
|
writes it — and is documented under [Derived values](#derived-values) instead,
|
|
53
53
|
alongside `foundryPackage`, `homepage`, `author` and `itemBuilders`, whose
|
|
54
54
|
data-configuration behaviour is also derivation rather than ordinary
|
|
@@ -290,7 +290,7 @@ Unlike the first three, authoring `itemBuilders` is not an error — it is
|
|
|
290
290
|
|
|
291
291
|
---
|
|
292
292
|
|
|
293
|
-
## The
|
|
293
|
+
## The 22 keys
|
|
294
294
|
|
|
295
295
|
### `contentPackage`
|
|
296
296
|
|
package/docs/content-format.md
CHANGED
|
@@ -2301,8 +2301,9 @@ Generates a living (or undead, or spirit) being.
|
|
|
2301
2301
|
| `affiliations` | `WikiLink[]` | Affilliations (e.g., arcane/divine traditions, polities, etc) |
|
|
2302
2302
|
| `gender` | `male \| female \| other` | Gender of the character |
|
|
2303
2303
|
| `species` | `WikiLink` | Being's species (lore) |
|
|
2304
|
-
| `
|
|
2305
|
-
| `
|
|
2304
|
+
| `born` | `YYYY/MM/DD \| unknown` | When the being was born; absent, it was never born |
|
|
2305
|
+
| `died` | `YYYY/MM/DD \| unknown` | When the being died; absent, it is alive |
|
|
2306
|
+
| `age` | `34 \| ~34` | Age in years, stated only to override what `born` says; `~` marks an estimate |
|
|
2306
2307
|
| `height` | `number` | Height in meters |
|
|
2307
2308
|
| `weight` | `number` | Weight in kilograms |
|
|
2308
2309
|
| `frame` | `scant \| light \| medium \| large \| massive` | Relative frame size |
|
|
@@ -2312,6 +2313,31 @@ Generates a living (or undead, or spirit) being.
|
|
|
2312
2313
|
| `appearance.complexion` | `string` | Complexion |
|
|
2313
2314
|
| `appearance.extra_features` | `string[]` | Extra features |
|
|
2314
2315
|
|
|
2316
|
+
#### When a being was born, when it died, and how old it is
|
|
2317
|
+
|
|
2318
|
+
**Absence asserts a fact rather than recording a gap**, and that is what these
|
|
2319
|
+
three fields are built around.
|
|
2320
|
+
|
|
2321
|
+
- **`born` absent** says the being was **never born** — a construct, a spirit,
|
|
2322
|
+
an elemental, a thing that was made. **`born: unknown`** says it was born and
|
|
2323
|
+
the date is unrecorded, which is the commonest shape in a tree.
|
|
2324
|
+
- **`died` absent** says the being is **alive**, which is the common case and so
|
|
2325
|
+
takes the cheapest form. **`died: unknown`** says it is dead and the date is
|
|
2326
|
+
unrecorded. Both spellings of `died` mean dead.
|
|
2327
|
+
- **`age` is optional and is an override.** Written, it wins over anything the
|
|
2328
|
+
dates say. Unwritten beside a dated `born`, it is the age that follows from
|
|
2329
|
+
the date. Unwritten beside `born: unknown` or an absent `born`, the age is
|
|
2330
|
+
unknown.
|
|
2331
|
+
|
|
2332
|
+
Most people in a setting do not know their own birth date, so an age beside
|
|
2333
|
+
`born: unknown` is an ordinary complete record and not a note working around the
|
|
2334
|
+
schema. Where the number is somebody's estimate rather than a fact, write it
|
|
2335
|
+
`~34` — the same `~` a date carries.
|
|
2336
|
+
|
|
2337
|
+
`birthday:` is the retired spelling of `born:`. Both are read and `born` wins,
|
|
2338
|
+
so a note compiles identically either way; the old spelling is reported until
|
|
2339
|
+
every tree has moved.
|
|
2340
|
+
|
|
2315
2341
|
#### The lead image
|
|
2316
2342
|
|
|
2317
2343
|
**A being's portrait is the first thing inside its `{#appearance}` section,
|
|
@@ -3191,8 +3217,65 @@ In-world information about people, places, or concepts.
|
|
|
3191
3217
|
tournament is not a matter of time-reckoning at all — and from `culture`, which is a grouping
|
|
3192
3218
|
of people rather than an occasion they attend.
|
|
3193
3219
|
|
|
3194
|
-
| `data` property | Values
|
|
3195
|
-
| --------------- |
|
|
3220
|
+
| `data` property | Values | Description |
|
|
3221
|
+
| --------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
3222
|
+
| `epoch` | `date` | Which in-world day the world's clock reads zero on |
|
|
3223
|
+
| `months` | `{ name, abbreviation?, days }[]` | The months this calendar keeps, in order — the list sums to the world's year |
|
|
3224
|
+
| `weekdays` | `{ name, abbreviation? }[]` | The days of the week it names, in order; a calendar with no week writes none |
|
|
3225
|
+
| `seasons` | `{ name, abbreviation?, monthStart?, monthEnd?, dayStart?, dayEnd? }[]` | The seasons it marks, bounded by month or by day of year |
|
|
3226
|
+
| `eras` | `{ shortcode, name, abbreviation?, proclaimedBy?, start, end? }[]` | The year-counts kept in it, each addressed `<calendar shortcode>.<era shortcode>` |
|
|
3227
|
+
|
|
3228
|
+
#### What a calendar note declares
|
|
3229
|
+
|
|
3230
|
+
**Those five keys belong to `subType: calendar` and to no other genre of
|
|
3231
|
+
`lore`.** A note carrying one under any other subType is refused, and a calendar
|
|
3232
|
+
note that states no `months` and no `epoch` is refused too: a calendar divides
|
|
3233
|
+
the year and says where the count begins, and one that does neither is prose
|
|
3234
|
+
about time rather than a calendar.
|
|
3235
|
+
|
|
3236
|
+
```yaml
|
|
3237
|
+
type: lore
|
|
3238
|
+
subType: calendar
|
|
3239
|
+
shortcode: commoncal
|
|
3240
|
+
name:
|
|
3241
|
+
full: The Common Calendar
|
|
3242
|
+
data:
|
|
3243
|
+
epoch: 720/1/1
|
|
3244
|
+
months:
|
|
3245
|
+
- { name: Floralis, abbreviation: Flor, days: 30 }
|
|
3246
|
+
- { name: Lusenar, abbreviation: Luse, days: 31 }
|
|
3247
|
+
# … ten more, summing to the world's year
|
|
3248
|
+
seasons:
|
|
3249
|
+
- { name: Spring, monthStart: 1, monthEnd: 3 }
|
|
3250
|
+
eras:
|
|
3251
|
+
- shortcode: founding
|
|
3252
|
+
name: After the Founding
|
|
3253
|
+
abbreviation: AF
|
|
3254
|
+
proclaimedBy: vylarinmpr
|
|
3255
|
+
start: 1
|
|
3256
|
+
```
|
|
3257
|
+
|
|
3258
|
+
**Position in the list is position in the year.** Days that belong to no month
|
|
3259
|
+
are a short month like any other: a five-day festival is one entry, and where it
|
|
3260
|
+
sits in the list is where it falls in the year. There is no intercalary
|
|
3261
|
+
mechanism, because there is nothing for one to do.
|
|
3262
|
+
|
|
3263
|
+
**How long the year is, how the day divides and how the moon moves are facts
|
|
3264
|
+
about the world, not about a calendar**, so no calendar note states any of them
|
|
3265
|
+
— they are written once on the world's own `place` note and on its moon's, and
|
|
3266
|
+
every calendar is compiled against them. The one arithmetic check follows from
|
|
3267
|
+
that: `months` must sum to `year.days`, and a list that does not describes a
|
|
3268
|
+
different world rather than a different calendar.
|
|
3269
|
+
|
|
3270
|
+
**An era is a way of counting years within a calendar**, so its rows sit beside
|
|
3271
|
+
the months. Each states its own `shortcode`, unique within the note, and a date
|
|
3272
|
+
names one by writing it after the calendar's address — `3 commoncal.founding`.
|
|
3273
|
+
`proclaimedBy` is optional: a reckoning whose proclaiming body is unknown, or
|
|
3274
|
+
whose body has no note, says so by leaving it out.
|
|
3275
|
+
|
|
3276
|
+
**A calendar with no week writes no `weekdays`.** An empty list and an absent
|
|
3277
|
+
one say the same thing, and nothing downstream shows a weekday for a calendar
|
|
3278
|
+
that names none.
|
|
3196
3279
|
|
|
3197
3280
|
### type: map
|
|
3198
3281
|
|
|
@@ -3344,16 +3427,72 @@ three maps, and none of those maps needs to know it is a keep.
|
|
|
3344
3427
|
- site: A place significant by what was made or done there — ruins, monoliths, henges, works, battlefields.
|
|
3345
3428
|
- structure: A single building or habitation — halls, keeps, temples, inns, towers.
|
|
3346
3429
|
- feature: A place significant by its terrain — forests, rivers, falls, passes, fords.
|
|
3430
|
+
- celestial: A body observed from a world rather than located on one — a sun, a planet, a comet.
|
|
3431
|
+
|
|
3432
|
+
| `data` property | Values | Description |
|
|
3433
|
+
| --------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
3434
|
+
| `demonym` | `string` | What a person from this place is called — a Vylarian |
|
|
3435
|
+
| `lore` | `WikiLink[]` | Lore concerning this place — its peoples, its law, its calendar, its history |
|
|
3436
|
+
| `parents` | `WikiLink[]` | Enclosing places within which this place is located |
|
|
3437
|
+
| `population` | `number` | Approximate population (precision 2 significant digits) |
|
|
3438
|
+
| `market` | `number` | Market class, 1 to 6 — what trade a settlement supports |
|
|
3439
|
+
| `borders` | `{ to, bearing }[]` | Places sharing a frontier with this one, and where each lies from here |
|
|
3440
|
+
| `routes` | `{ to, bearing, mode, days, terrain?, leagues? }[]` | Journeys from this place's centre to another place |
|
|
3441
|
+
| `world.equatorialCircumferenceKm` | `number` | The distance round the body at its equator, in kilometres |
|
|
3442
|
+
| `world.surfaceGravityG` | `number` | Surface gravity, as a multiple of Earth's |
|
|
3443
|
+
| `world.axialTiltDegrees` | `number` | The tilt of the axis, in degrees |
|
|
3444
|
+
| `year.days` | `number` | How many days the body's year holds |
|
|
3445
|
+
| `year.hoursPerDay` | `number` | How many hours the day divides into |
|
|
3446
|
+
| `year.minutesPerHour` | `number` | How many minutes the hour divides into |
|
|
3447
|
+
| `year.secondsPerMinute` | `number` | How many seconds the minute divides into |
|
|
3448
|
+
| `present` | `date` | The day the setting stops and play begins |
|
|
3449
|
+
| `body.diameterKm` | `number` | The body's diameter, in kilometres |
|
|
3450
|
+
| `body.orbitalRadiusKm` | `number` | How far it orbits from the body it circles, in kilometres |
|
|
3451
|
+
| `body.orbit` | `string` | The orbit's shape — `circular` means the cycle never varies |
|
|
3452
|
+
| `body.inclined` | `boolean` | Whether the orbit is inclined to the plane the world orbits in |
|
|
3453
|
+
| `moon.cycle` | `number` | How many days it takes to return to the same phase |
|
|
3454
|
+
| `moon.newOn` | `date` | A day it was new, written in the reference calendar |
|
|
3455
|
+
| `moon.eclipses` | `string` | `never`, `rare`, `occasional` or `frequent` |
|
|
3456
|
+
|
|
3457
|
+
#### What a body states about itself
|
|
3458
|
+
|
|
3459
|
+
**The four groups above are the world's own facts, and they are legal on a
|
|
3460
|
+
`world` or a `celestial` note and nowhere else.** A region, a settlement, a
|
|
3461
|
+
site, a structure or a feature is somewhere _within_ a world and says nothing
|
|
3462
|
+
about the world's year.
|
|
3463
|
+
|
|
3464
|
+
```yaml
|
|
3465
|
+
# the world — type: place, subType: world
|
|
3466
|
+
data:
|
|
3467
|
+
world: { equatorialCircumferenceKm: 40000, surfaceGravityG: 1.0, axialTiltDegrees: 23.5 }
|
|
3468
|
+
year: { days: 365, hoursPerDay: 24, minutesPerHour: 60, secondsPerMinute: 60 }
|
|
3469
|
+
present: 720
|
|
3470
|
+
|
|
3471
|
+
# its moon — a note of its own, because a moon is a body and not a property
|
|
3472
|
+
data:
|
|
3473
|
+
body: { diameterKm: 3800, orbitalRadiusKm: 388600, orbit: circular, inclined: true }
|
|
3474
|
+
moon: { cycle: 30, newOn: 720/1/1, eclipses: rare }
|
|
3475
|
+
```
|
|
3347
3476
|
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3477
|
+
**`year.days` is where the year's length lives, and every calendar in the
|
|
3478
|
+
package is compiled against it.** A package whose notes state no `year` has no
|
|
3479
|
+
calendar mechanism at all: no sum is checked, and nothing is emitted. That is
|
|
3480
|
+
the right answer for a package building a setting whose world facts somebody
|
|
3481
|
+
else wrote down.
|
|
3482
|
+
|
|
3483
|
+
**One year and one moon to a package.** Two years is two settings and nothing
|
|
3484
|
+
can say which one a calendar divides; a `moon` with no `year` anywhere is
|
|
3485
|
+
refused, because a cycle counted in days has no year to be measured against.
|
|
3486
|
+
|
|
3487
|
+
**`present` is the day an age is computed against**, written in the grammar a
|
|
3488
|
+
note's dates are written in, so a setting whose present is best said in an era
|
|
3489
|
+
says it that way.
|
|
3490
|
+
|
|
3491
|
+
**`world.axialTiltDegrees`, the circumference, the gravity, the moon's diameter
|
|
3492
|
+
and its orbital radius are read by nobody.** They are there so a reader knows
|
|
3493
|
+
what kind of world this is. What the build consumes is the year, the day's
|
|
3494
|
+
divisions, the present, the moon's cycle and epoch, and whether its orbit is
|
|
3495
|
+
circular and inclined.
|
|
3357
3496
|
|
|
3358
3497
|
#### What a settlement's market supports
|
|
3359
3498
|
|