Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7af690205c | ||
|
|
d22421efbd | ||
|
|
b4990533a8 | ||
|
|
075be5c1de |
@@ -2154,5 +2154,6 @@
|
|||||||
"lingering": "stayed in one place longer than it takes to search it",
|
"lingering": "stayed in one place longer than it takes to search it",
|
||||||
"disturbed": "struck or moved something that had not moved in centuries"
|
"disturbed": "struck or moved something that had not moved in centuries"
|
||||||
},
|
},
|
||||||
"_globalPoolsNote": "decisions/temptations/features below are FALLBACKS ONLY. Real content is motif-scoped under motifs.<id>."
|
"_globalPoolsNote": "decisions/temptations/features below are FALLBACKS ONLY. Real content is motif-scoped under motifs.<id>.",
|
||||||
|
"placeNameStyle": "claimant"
|
||||||
}
|
}
|
||||||
@@ -1169,5 +1169,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"placeNameStyle": "claimant"
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,90 @@
|
|||||||
"label": "Castle",
|
"label": "Castle",
|
||||||
"geometry": "barrow",
|
"geometry": "barrow",
|
||||||
"motifs": 4
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cave",
|
||||||
|
"label": "Cave",
|
||||||
|
"geometry": "cave",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "church",
|
||||||
|
"label": "Church",
|
||||||
|
"geometry": "barrow",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "city",
|
||||||
|
"label": "City",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "forest",
|
||||||
|
"label": "Forest",
|
||||||
|
"geometry": "forest",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "lake",
|
||||||
|
"label": "Lake",
|
||||||
|
"geometry": "fen",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "market",
|
||||||
|
"label": "Market",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mountain",
|
||||||
|
"label": "Mountain",
|
||||||
|
"geometry": "cave",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "palace",
|
||||||
|
"label": "Palace",
|
||||||
|
"geometry": "barrow",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "port",
|
||||||
|
"label": "Port",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "river",
|
||||||
|
"label": "River",
|
||||||
|
"geometry": "fen",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "temple",
|
||||||
|
"label": "Temple",
|
||||||
|
"geometry": "barrow",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "town",
|
||||||
|
"label": "Town",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "valley",
|
||||||
|
"label": "Valley",
|
||||||
|
"geometry": "forest",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "village",
|
||||||
|
"label": "Village",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+15
-5
@@ -22,7 +22,13 @@
|
|||||||
import { arcRole } from './director.mjs';
|
import { arcRole } from './director.mjs';
|
||||||
|
|
||||||
/** Fills {conscript}-style slots. */
|
/** Fills {conscript}-style slots. */
|
||||||
const fill = (tpl, vars) => tpl.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? `{${k}}`);
|
const fill = (tpl, vars) => tpl.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? `{${k}}`)
|
||||||
|
// Conscripts are plural noun phrases ("the climbers"), so a template's `{conscript}'s`
|
||||||
|
// renders "the climbers's". English takes a bare apostrophe on a plural already ending in s.
|
||||||
|
.replace(/s's\b/g, "s'");
|
||||||
|
|
||||||
|
/** Claimants may already carry their own article — "The Grey" must not become "The The Grey". */
|
||||||
|
const named = c => (/^(the|a|an) /i.test(c) ? c : `The ${c}`);
|
||||||
|
|
||||||
/** Facet order used when a facet is exhausted — borrow from a neighbour before repeating. */
|
/** Facet order used when a facet is exhausted — borrow from a neighbour before repeating. */
|
||||||
const FACET_ORDER = ['institution', 'ritual', 'demand', 'wound', 'anchor'];
|
const FACET_ORDER = ['institution', 'ritual', 'demand', 'wound', 'anchor'];
|
||||||
@@ -62,11 +68,12 @@ export function generateSkeleton({ pack, areas = 6, ending = 'authored', rng })
|
|||||||
const prize = { kind: appetite.prize, ...(pack.prizes?.[appetite.prize] ?? {}) };
|
const prize = { kind: appetite.prize, ...(pack.prizes?.[appetite.prize] ?? {}) };
|
||||||
|
|
||||||
const transgression =
|
const transgression =
|
||||||
`The ${claimant} ${fill(accommodation.text, { conscript: appetite.conscript })}, ` +
|
`${named(claimant)} ${fill(accommodation.text, { conscript: appetite.conscript })}, ` +
|
||||||
`so that ${appetite.purpose}.`;
|
`so that ${appetite.purpose}.`;
|
||||||
|
// The bottom problem is the claimant itself — a person in a tomb, an office in a town.
|
||||||
|
|
||||||
const bottomProblem = {
|
const bottomProblem = {
|
||||||
label: `The ${claimant}`,
|
label: named(claimant),
|
||||||
wantNow: appetite.want,
|
wantNow: appetite.want,
|
||||||
failureState: `is ${appetite.lack} now, and cannot bear it`,
|
failureState: `is ${appetite.lack} now, and cannot bear it`,
|
||||||
handledBy: 'giving them what they want, at a price',
|
handledBy: 'giving them what they want, at a price',
|
||||||
@@ -79,8 +86,11 @@ export function generateSkeleton({ pack, areas = 6, ending = 'authored', rng })
|
|||||||
};
|
};
|
||||||
const secondary = r.derive('faction2').pick(pack.factions.filter(f => f.id !== primary.id));
|
const secondary = r.derive('faction2').pick(pack.factions.filter(f => f.id !== primary.id));
|
||||||
|
|
||||||
// Named for its occupant. Drawing the name separately produced tombs named after strangers.
|
// A barrow or keep is named for its occupant — drawing that separately produced tombs named
|
||||||
const placeName = `${r.derive('place').pick(pack.placeNames.first)} ${claimant}`;
|
// after strangers. A settlement is not: it has its own name and the claimant merely runs it.
|
||||||
|
const placeName = pack.placeNameStyle === 'own'
|
||||||
|
? `${r.derive('place1').pick(pack.placeNames.first)} ${r.derive('place2').pick(pack.placeNames.second)}`
|
||||||
|
: `${r.derive('place').pick(pack.placeNames.first)} ${claimant}`;
|
||||||
|
|
||||||
// ---- the foreshadow chain ----------------------------------------------
|
// ---- the foreshadow chain ----------------------------------------------
|
||||||
const progression = pack.facetProgression ?? {};
|
const progression = pack.facetProgression ?? {};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"id": "vanity-delve",
|
"id": "vanity-delve",
|
||||||
"title": "DELVE — a dungeon layer for VANITY",
|
"title": "DELVE — a dungeon layer for VANITY",
|
||||||
"description": "Generates a coherent delve and sequences VANITY's Forge to stage it, one area at a time.",
|
"description": "Generates a coherent delve and sequences VANITY's Forge to stage it, one area at a time.",
|
||||||
"version": "0.2.0",
|
"version": "0.6.0",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "13",
|
"minimum": "13",
|
||||||
"verified": "14.365"
|
"verified": "14.365"
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"How do I look?\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "remembered",
|
"id": "remembered",
|
||||||
@@ -47,7 +48,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"Say my name.\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "obeyed",
|
"id": "obeyed",
|
||||||
@@ -69,7 +71,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"Do as you are told.\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "young",
|
"id": "young",
|
||||||
@@ -91,7 +94,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"Tell me I have not changed.\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "envied",
|
"id": "envied",
|
||||||
@@ -113,7 +117,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"What did you bring me?\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "attended",
|
"id": "attended",
|
||||||
@@ -135,7 +140,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"You are not leaving.\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "forgiven",
|
"id": "forgiven",
|
||||||
@@ -157,7 +163,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"Tell me it was not a sin.\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "first",
|
"id": "first",
|
||||||
@@ -179,7 +186,8 @@
|
|||||||
"bane": 1
|
"bane": 1
|
||||||
},
|
},
|
||||||
"repeatable": true
|
"repeatable": true
|
||||||
}
|
},
|
||||||
|
"asks": "\"Who goes first?\""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"accommodations": [
|
"accommodations": [
|
||||||
@@ -2146,5 +2154,6 @@
|
|||||||
"lingering": "stayed in one place longer than it takes to search it",
|
"lingering": "stayed in one place longer than it takes to search it",
|
||||||
"disturbed": "struck or moved something that had not moved in centuries"
|
"disturbed": "struck or moved something that had not moved in centuries"
|
||||||
},
|
},
|
||||||
"_globalPoolsNote": "decisions/temptations/features below are FALLBACKS ONLY. Real content is motif-scoped under motifs.<id>."
|
"_globalPoolsNote": "decisions/temptations/features below are FALLBACKS ONLY. Real content is motif-scoped under motifs.<id>.",
|
||||||
|
"placeNameStyle": "claimant"
|
||||||
}
|
}
|
||||||
@@ -1169,5 +1169,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"placeNameStyle": "claimant"
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,90 @@
|
|||||||
"label": "Castle",
|
"label": "Castle",
|
||||||
"geometry": "barrow",
|
"geometry": "barrow",
|
||||||
"motifs": 4
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cave",
|
||||||
|
"label": "Cave",
|
||||||
|
"geometry": "cave",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "church",
|
||||||
|
"label": "Church",
|
||||||
|
"geometry": "barrow",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "city",
|
||||||
|
"label": "City",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "forest",
|
||||||
|
"label": "Forest",
|
||||||
|
"geometry": "forest",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "lake",
|
||||||
|
"label": "Lake",
|
||||||
|
"geometry": "fen",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "market",
|
||||||
|
"label": "Market",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mountain",
|
||||||
|
"label": "Mountain",
|
||||||
|
"geometry": "cave",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "palace",
|
||||||
|
"label": "Palace",
|
||||||
|
"geometry": "barrow",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "port",
|
||||||
|
"label": "Port",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "river",
|
||||||
|
"label": "River",
|
||||||
|
"geometry": "fen",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "temple",
|
||||||
|
"label": "Temple",
|
||||||
|
"geometry": "barrow",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "town",
|
||||||
|
"label": "Town",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "valley",
|
||||||
|
"label": "Valley",
|
||||||
|
"geometry": "forest",
|
||||||
|
"motifs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "village",
|
||||||
|
"label": "Village",
|
||||||
|
"geometry": "village",
|
||||||
|
"motifs": 4
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,13 @@
|
|||||||
import { arcRole } from './director.mjs';
|
import { arcRole } from './director.mjs';
|
||||||
|
|
||||||
/** Fills {conscript}-style slots. */
|
/** Fills {conscript}-style slots. */
|
||||||
const fill = (tpl, vars) => tpl.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? `{${k}}`);
|
const fill = (tpl, vars) => tpl.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? `{${k}}`)
|
||||||
|
// Conscripts are plural noun phrases ("the climbers"), so a template's `{conscript}'s`
|
||||||
|
// renders "the climbers's". English takes a bare apostrophe on a plural already ending in s.
|
||||||
|
.replace(/s's\b/g, "s'");
|
||||||
|
|
||||||
|
/** Claimants may already carry their own article — "The Grey" must not become "The The Grey". */
|
||||||
|
const named = c => (/^(the|a|an) /i.test(c) ? c : `The ${c}`);
|
||||||
|
|
||||||
/** Facet order used when a facet is exhausted — borrow from a neighbour before repeating. */
|
/** Facet order used when a facet is exhausted — borrow from a neighbour before repeating. */
|
||||||
const FACET_ORDER = ['institution', 'ritual', 'demand', 'wound', 'anchor'];
|
const FACET_ORDER = ['institution', 'ritual', 'demand', 'wound', 'anchor'];
|
||||||
@@ -62,11 +68,12 @@ export function generateSkeleton({ pack, areas = 6, ending = 'authored', rng })
|
|||||||
const prize = { kind: appetite.prize, ...(pack.prizes?.[appetite.prize] ?? {}) };
|
const prize = { kind: appetite.prize, ...(pack.prizes?.[appetite.prize] ?? {}) };
|
||||||
|
|
||||||
const transgression =
|
const transgression =
|
||||||
`The ${claimant} ${fill(accommodation.text, { conscript: appetite.conscript })}, ` +
|
`${named(claimant)} ${fill(accommodation.text, { conscript: appetite.conscript })}, ` +
|
||||||
`so that ${appetite.purpose}.`;
|
`so that ${appetite.purpose}.`;
|
||||||
|
// The bottom problem is the claimant itself — a person in a tomb, an office in a town.
|
||||||
|
|
||||||
const bottomProblem = {
|
const bottomProblem = {
|
||||||
label: `The ${claimant}`,
|
label: named(claimant),
|
||||||
wantNow: appetite.want,
|
wantNow: appetite.want,
|
||||||
failureState: `is ${appetite.lack} now, and cannot bear it`,
|
failureState: `is ${appetite.lack} now, and cannot bear it`,
|
||||||
handledBy: 'giving them what they want, at a price',
|
handledBy: 'giving them what they want, at a price',
|
||||||
@@ -79,8 +86,11 @@ export function generateSkeleton({ pack, areas = 6, ending = 'authored', rng })
|
|||||||
};
|
};
|
||||||
const secondary = r.derive('faction2').pick(pack.factions.filter(f => f.id !== primary.id));
|
const secondary = r.derive('faction2').pick(pack.factions.filter(f => f.id !== primary.id));
|
||||||
|
|
||||||
// Named for its occupant. Drawing the name separately produced tombs named after strangers.
|
// A barrow or keep is named for its occupant — drawing that separately produced tombs named
|
||||||
const placeName = `${r.derive('place').pick(pack.placeNames.first)} ${claimant}`;
|
// after strangers. A settlement is not: it has its own name and the claimant merely runs it.
|
||||||
|
const placeName = pack.placeNameStyle === 'own'
|
||||||
|
? `${r.derive('place1').pick(pack.placeNames.first)} ${r.derive('place2').pick(pack.placeNames.second)}`
|
||||||
|
: `${r.derive('place').pick(pack.placeNames.first)} ${claimant}`;
|
||||||
|
|
||||||
// ---- the foreshadow chain ----------------------------------------------
|
// ---- the foreshadow chain ----------------------------------------------
|
||||||
const progression = pack.facetProgression ?? {};
|
const progression = pack.facetProgression ?? {};
|
||||||
|
|||||||
Reference in New Issue
Block a user