@scrthq/runlog 0.0.43 → 0.0.45
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/dist/runlog.js +66 -8
- package/package.json +1 -1
package/dist/runlog.js
CHANGED
|
@@ -26448,13 +26448,15 @@ var Action = external_exports.lazy(
|
|
|
26448
26448
|
do: external_exports.literal("modCounter").describe("Adjust a counter."),
|
|
26449
26449
|
counter: Id.describe("Id of the counter to change."),
|
|
26450
26450
|
by: external_exports.number().int().optional().describe("Amount to add; negative subtracts."),
|
|
26451
|
-
set: external_exports.number().int().optional().describe("Absolute value to set, overriding `by`.")
|
|
26451
|
+
set: external_exports.number().int().optional().describe("Absolute value to set, overriding `by`."),
|
|
26452
|
+
setFrom: external_exports.string().min(1).optional().describe("Set it to a value bound earlier \u2014 a roll's total or a prompt's answer \u2014 by name. Overrides `by` and `set`.")
|
|
26452
26453
|
}).strict().describe("Adjust a counter."),
|
|
26453
26454
|
external_exports.object({
|
|
26454
26455
|
do: external_exports.literal("modResource").describe("Adjust a resource."),
|
|
26455
26456
|
resource: Id.describe("Id of the resource to change."),
|
|
26456
26457
|
by: external_exports.number().int().optional().describe("Amount to add; negative spends."),
|
|
26457
|
-
set: external_exports.number().int().optional().describe("Absolute value to set, overriding `by`.")
|
|
26458
|
+
set: external_exports.number().int().optional().describe("Absolute value to set, overriding `by`."),
|
|
26459
|
+
setFrom: external_exports.string().min(1).optional().describe("Set it to a value bound earlier \u2014 a roll's total or a prompt's answer \u2014 by name. Overrides `by` and `set`.")
|
|
26458
26460
|
}).strict().describe("Adjust a resource, clamped to its declared min and max."),
|
|
26459
26461
|
external_exports.object({
|
|
26460
26462
|
do: external_exports.literal("grantCard").describe("Draw cards into the player's hand."),
|
|
@@ -26523,6 +26525,9 @@ var EntryBase = {
|
|
|
26523
26525
|
tags: external_exports.array(external_exports.string()).optional().describe("Free tags, for cross-referencing and for filtering results out in some modes."),
|
|
26524
26526
|
points: external_exports.number().int().min(0).optional().describe(
|
|
26525
26527
|
"What a contestant earns for completing this result in a moderated mode. A result with points is a challenge the moderator can award; one without is an effect that lands on everyone."
|
|
26528
|
+
),
|
|
26529
|
+
needs: external_exports.array(Id).optional().describe(
|
|
26530
|
+
"Requirements this result depends on, by id from the pack's `requires`. A run that said it lacks one of them draws again instead of landing here \u2014 a barbell movement for someone without a barbell, an oven dish in a kitchen without one."
|
|
26526
26531
|
)
|
|
26527
26532
|
};
|
|
26528
26533
|
var LookupEntry = external_exports.object({
|
|
@@ -26669,7 +26674,10 @@ var StateDef = external_exports.object({
|
|
|
26669
26674
|
short: external_exports.string().max(8).optional().describe(
|
|
26670
26675
|
"Compact form for embedding in the name of the thing itself \u2014 a file, a layer, a DAW track. Keep it very short, e.g. VF."
|
|
26671
26676
|
),
|
|
26672
|
-
scope: external_exports.enum(["subject", "run"]).default("subject").describe(
|
|
26677
|
+
scope: external_exports.enum(["subject", "run", "contestant"]).default("subject").describe(
|
|
26678
|
+
"Whether this attaches to one subject, to the whole run, or \u2014 in moderated play \u2014 to one contestant on the roster, marked by the moderator: spared from a curse, disqualified, and so on."
|
|
26679
|
+
),
|
|
26680
|
+
until: external_exports.enum(["unitEnd"]).optional().describe("When the state lifts by itself. `unitEnd`: it is taken off everything it is on when the unit closes \u2014 a curse for this region, a cure for this region."),
|
|
26673
26681
|
semantics: external_exports.array(
|
|
26674
26682
|
external_exports.enum(["blocksEdit", "makesUntargetable", "excludesFromResult", "locksValue", "removesFromPlay"])
|
|
26675
26683
|
).optional().describe(
|
|
@@ -26710,6 +26718,14 @@ var ResourceDef = external_exports.object({
|
|
|
26710
26718
|
}).strict().describe(
|
|
26711
26719
|
"A numeric track the player fills or spends: a progress clock, a word count, training volume, stock on hand."
|
|
26712
26720
|
);
|
|
26721
|
+
var Requirement = external_exports.object({
|
|
26722
|
+
id: Id.describe("Unique among requirements. Table entries name it in `needs`."),
|
|
26723
|
+
label: external_exports.string().min(1).describe("What it is, in the words a person would use: Rocket League, a potter's wheel, an oven."),
|
|
26724
|
+
kind: external_exports.enum(["game", "platform", "software", "equipment", "supplies", "space", "other"]).default("other").describe("What sort of thing it is, so a catalog can say 'needs a game' or 'needs equipment' at a glance."),
|
|
26725
|
+
optional: external_exports.boolean().default(false).describe("Nice to have rather than needed. A player says at the start whether they have it, and results that `need` it are drawn again when they do not."),
|
|
26726
|
+
note: external_exports.string().optional().describe("A line on where to get it, which version, or what will do instead."),
|
|
26727
|
+
url: external_exports.string().url().optional().describe("Where to find it.")
|
|
26728
|
+
}).strict().describe("A physical or software requirement: the game and the system to play it on, a mod or training pack, a wheel, a kitchen, supplies.");
|
|
26713
26729
|
var ChecklistItem = external_exports.union([
|
|
26714
26730
|
external_exports.string().min(1),
|
|
26715
26731
|
external_exports.object({
|
|
@@ -26939,6 +26955,11 @@ var Pack = external_exports.object({
|
|
|
26939
26955
|
author: external_exports.string().optional().describe("Who wrote the game."),
|
|
26940
26956
|
description: external_exports.string().optional().describe("One or two sentences on what the game is."),
|
|
26941
26957
|
homepage: external_exports.string().url().optional().describe("Where to find out more."),
|
|
26958
|
+
category: external_exports.string().min(1).max(40).optional().describe("What kind of thing this is, in a word or two, for a catalog to group by: everyday, games, craft, fitness, cooking, writing\u2026"),
|
|
26959
|
+
tags: external_exports.array(external_exports.string().min(1).max(40)).max(12).optional().describe("Free tags for a catalog to filter by: the game it is for, the hobby, the shape of play. Short, and in the words a person would search for."),
|
|
26960
|
+
requires: external_exports.array(Requirement).max(20).optional().describe(
|
|
26961
|
+
"What a person needs before playing, shown in the catalog and the rulebook: the game and a system that runs it, mods or training packs, a wheel, a kitchen, supplies. Mark the ones that are nice to have `optional`; results can `need` those and be drawn again for a player who lacks them."
|
|
26962
|
+
),
|
|
26942
26963
|
license: License,
|
|
26943
26964
|
capabilities: external_exports.array(Capability).default([]).describe(
|
|
26944
26965
|
"Engine features this pack needs. Declaring them lets an older app refuse the pack with a clear message instead of misplaying it."
|
|
@@ -27259,6 +27280,7 @@ function lintPack(pack) {
|
|
|
27259
27280
|
let usesResources = resourceIds.size > 0;
|
|
27260
27281
|
let usesTimers = false;
|
|
27261
27282
|
let usesResolveTarget = false;
|
|
27283
|
+
const movedCounters = /* @__PURE__ */ new Set();
|
|
27262
27284
|
for (const site of collectActionSites(pack)) {
|
|
27263
27285
|
walkActions(site.actions, (a) => {
|
|
27264
27286
|
switch (a.do) {
|
|
@@ -27277,6 +27299,7 @@ function lintPack(pack) {
|
|
|
27277
27299
|
if (!counterIds.has(a.counter)) {
|
|
27278
27300
|
d.push(err("ref/unknown-counter", site.path, `references unknown counter ${a.counter}`));
|
|
27279
27301
|
}
|
|
27302
|
+
movedCounters.add(a.counter);
|
|
27280
27303
|
break;
|
|
27281
27304
|
case "modResource":
|
|
27282
27305
|
if (!resourceIds.has(a.resource)) {
|
|
@@ -27313,6 +27336,18 @@ function lintPack(pack) {
|
|
|
27313
27336
|
}
|
|
27314
27337
|
});
|
|
27315
27338
|
}
|
|
27339
|
+
const requirements = new Map((pack.requires ?? []).map((r) => [r.id, r]));
|
|
27340
|
+
for (const [tableId, table] of Object.entries(pack.tables)) {
|
|
27341
|
+
table.entries.forEach((e, i) => {
|
|
27342
|
+
for (const need of e.needs ?? []) {
|
|
27343
|
+
const r = requirements.get(need);
|
|
27344
|
+
if (!r) d.push(err("ref/unknown-requirement", `tables.${tableId}.entries[${i}].needs`, `needs unknown requirement ${need}`));
|
|
27345
|
+
else if (!r.optional) {
|
|
27346
|
+
d.push(warn("requirement/never-lacked", `tables.${tableId}.entries[${i}].needs`, `needs ${need}, which is not optional, so no run can lack it; the entry will never be skipped`));
|
|
27347
|
+
}
|
|
27348
|
+
}
|
|
27349
|
+
});
|
|
27350
|
+
}
|
|
27316
27351
|
const predicateSites = [];
|
|
27317
27352
|
for (const [tableId, table] of Object.entries(pack.tables)) {
|
|
27318
27353
|
table.entries.forEach(
|
|
@@ -27385,6 +27420,7 @@ function lintPack(pack) {
|
|
|
27385
27420
|
if (typeof item !== "string" && item.tally && !counterIds.has(item.tally)) {
|
|
27386
27421
|
d.push(err("ref/unknown-counter", `${path}.${field}[${ii}]`, `tallies unknown counter ${item.tally}`));
|
|
27387
27422
|
}
|
|
27423
|
+
if (typeof item !== "string" && item.tally) movedCounters.add(item.tally);
|
|
27388
27424
|
if (typeof item !== "string" && item.shows && !tableIds.has(item.shows.table)) {
|
|
27389
27425
|
d.push(err("ref/unknown-table", `${path}.${field}[${ii}]`, `shows unknown table ${item.shows.table}`));
|
|
27390
27426
|
}
|
|
@@ -27493,8 +27529,8 @@ function lintPack(pack) {
|
|
|
27493
27529
|
d.push(err("ref/unknown-state", path, `hooks unknown state ${sel.state}`));
|
|
27494
27530
|
}
|
|
27495
27531
|
}
|
|
27496
|
-
if (!counter.incrementOn?.length && !counter.triggers?.length) {
|
|
27497
|
-
d.push(warn("counter/inert", path, "counter has no incrementOn
|
|
27532
|
+
if (!counter.incrementOn?.length && !counter.triggers?.length && !movedCounters.has(counterId)) {
|
|
27533
|
+
d.push(warn("counter/inert", path, "counter has no incrementOn, no triggers, and nothing moves it; it will never change"));
|
|
27498
27534
|
}
|
|
27499
27535
|
}
|
|
27500
27536
|
if (pack.targeting?.strategy === "anchoredOffset") {
|
|
@@ -28264,6 +28300,9 @@ function stepDetail(pack, step) {
|
|
|
28264
28300
|
function whatYouNeed(pack) {
|
|
28265
28301
|
const n = nouns(pack);
|
|
28266
28302
|
const items = [];
|
|
28303
|
+
for (const r of pack.requires ?? []) {
|
|
28304
|
+
items.push(`${cap(r.label)}${r.optional ? " (optional; results that need it are drawn again without it)" : ""}${r.note ? ` \u2014 ${r.note}` : ""}${r.url ? ` (${r.url})` : ""}.`);
|
|
28305
|
+
}
|
|
28267
28306
|
const dice = diceInWords(diceNeeded(pack));
|
|
28268
28307
|
if (dice) items.push(cap(dice) + ".");
|
|
28269
28308
|
for (const deck of Object.values(pack.decks ?? {})) {
|
|
@@ -28341,6 +28380,7 @@ function summaryDoc(pack) {
|
|
|
28341
28380
|
const n = nouns(pack);
|
|
28342
28381
|
const b = new Builder();
|
|
28343
28382
|
b.p(pack.description);
|
|
28383
|
+
b.p([pack.category ? `Category: ${pack.category}` : "", pack.tags?.length ? `Tags: ${pack.tags.join(", ")}` : ""].filter(Boolean).join(" \xB7 "), "muted");
|
|
28344
28384
|
b.p(license(pack), "muted");
|
|
28345
28385
|
b.h(2, "How it plays");
|
|
28346
28386
|
const unitRange = `${pack.unit.min === pack.unit.max ? pack.unit.min : `${pack.unit.min}\u2013${pack.unit.max}`}`;
|
|
@@ -28422,8 +28462,8 @@ function rulebookDoc(pack) {
|
|
|
28422
28462
|
["State", "On", "Means"],
|
|
28423
28463
|
states.map(([, s]) => [
|
|
28424
28464
|
s.short ? `${s.label} (${s.short})` : s.label,
|
|
28425
|
-
s.scope === "run" ? `the ${n.run}` : `a ${n.subject}`,
|
|
28426
|
-
[s.description ?? "", ...(s.semantics ?? []).map(semanticInWords), s.group ? `Replaces any other \u201C${s.group}\u201D state.` : ""].filter(Boolean).join(" ")
|
|
28465
|
+
s.scope === "run" ? `the ${n.run}` : s.scope === "contestant" ? "a contestant" : `a ${n.subject}`,
|
|
28466
|
+
[s.description ?? "", ...(s.semantics ?? []).map(semanticInWords), s.group ? `Replaces any other \u201C${s.group}\u201D state.` : "", s.until === "unitEnd" ? `Lifts when the ${n.unit} closes.` : ""].filter(Boolean).join(" ")
|
|
28427
28467
|
])
|
|
28428
28468
|
);
|
|
28429
28469
|
}
|
|
@@ -28809,6 +28849,7 @@ function initialState(pack, e) {
|
|
|
28809
28849
|
outcomes: [],
|
|
28810
28850
|
obligations: [],
|
|
28811
28851
|
firedOnce: [],
|
|
28852
|
+
lacks: e.lacks ?? [],
|
|
28812
28853
|
contestants: [],
|
|
28813
28854
|
awards: [],
|
|
28814
28855
|
ending: null
|
|
@@ -28985,6 +29026,10 @@ function reduce(pack, log) {
|
|
|
28985
29026
|
for (const subject of state.subjects) {
|
|
28986
29027
|
if (subject.unit === state.unit) subject.finalized = true;
|
|
28987
29028
|
}
|
|
29029
|
+
const lifts = (id) => pack.states?.[id]?.until === "unitEnd";
|
|
29030
|
+
state.runStates = state.runStates.filter((id) => !lifts(id));
|
|
29031
|
+
for (const subject of state.subjects) subject.states = subject.states.filter((id) => !lifts(id));
|
|
29032
|
+
for (const who of state.contestants) who.states = who.states.filter((id) => !lifts(id));
|
|
28988
29033
|
break;
|
|
28989
29034
|
}
|
|
28990
29035
|
case "JournalWritten":
|
|
@@ -29020,12 +29065,25 @@ function reduce(pack, log) {
|
|
|
29020
29065
|
break;
|
|
29021
29066
|
case "ContestantAdded":
|
|
29022
29067
|
if (!state.contestants.some((c) => c.id === event.contestant)) {
|
|
29023
|
-
state.contestants.push({ id: event.contestant, name: event.name });
|
|
29068
|
+
state.contestants.push({ id: event.contestant, name: event.name, states: [] });
|
|
29024
29069
|
}
|
|
29025
29070
|
break;
|
|
29026
29071
|
case "ContestantRemoved":
|
|
29027
29072
|
state.contestants = state.contestants.filter((c) => c.id !== event.contestant);
|
|
29028
29073
|
break;
|
|
29074
|
+
case "ContestantStateApplied": {
|
|
29075
|
+
const who = state.contestants.find((c) => c.id === event.contestant);
|
|
29076
|
+
if (!who) break;
|
|
29077
|
+
const group = pack.states?.[event.state]?.group;
|
|
29078
|
+
if (group) who.states = who.states.filter((s) => s === event.state || pack.states?.[s]?.group !== group);
|
|
29079
|
+
if (!who.states.includes(event.state)) who.states.push(event.state);
|
|
29080
|
+
break;
|
|
29081
|
+
}
|
|
29082
|
+
case "ContestantStateRemoved": {
|
|
29083
|
+
const who = state.contestants.find((c) => c.id === event.contestant);
|
|
29084
|
+
if (who) who.states = who.states.filter((s) => s !== event.state);
|
|
29085
|
+
break;
|
|
29086
|
+
}
|
|
29029
29087
|
case "Awarded":
|
|
29030
29088
|
if (!state.awards.some((a) => a.contestant === event.contestant && a.outcome === event.outcome)) {
|
|
29031
29089
|
state.awards.push({
|