@dsh-agentic-roleplay/state 0.3.1 → 0.3.3
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/lib/index.d.ts +200 -2
- package/lib/index.js +564 -8
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { DatabaseSync } from "node:sqlite";
|
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { Service } from "@deepseek-ai/cordis";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
|
-
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { randomInt, randomUUID } from "node:crypto";
|
|
7
7
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, renameSync, rmSync } from "node:fs";
|
|
8
8
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
9
9
|
//#region ../dsh-roleplay-model/src/character.ts
|
|
@@ -367,6 +367,31 @@ const TRIGGER_NOTE_KINDS = ["beat", "cue"];
|
|
|
367
367
|
/** At most this many triggers in a story. */
|
|
368
368
|
const MAX_TRIGGERS = 200;
|
|
369
369
|
//#endregion
|
|
370
|
+
//#region ../dsh-roleplay-model/src/dice.ts
|
|
371
|
+
/** What a band of a check makes of an attempt; the same three results a round's outcome has. */
|
|
372
|
+
const DICE_RESULTS = [
|
|
373
|
+
"succeeded",
|
|
374
|
+
"partial",
|
|
375
|
+
"failed"
|
|
376
|
+
];
|
|
377
|
+
/** How a roll is read: by its total, or by how many of the dice came up high enough. */
|
|
378
|
+
const DICE_READINGS = ["total", "successes"];
|
|
379
|
+
/**
|
|
380
|
+
* What the value is compared with: `absolute` reads the value itself, `over` the amount by which it beats the target
|
|
381
|
+
* (a difficulty to meet or exceed), `under` the amount by which it stays below the target (a skill to roll under).
|
|
382
|
+
*/
|
|
383
|
+
const DICE_COMPARISONS = [
|
|
384
|
+
"absolute",
|
|
385
|
+
"over",
|
|
386
|
+
"under"
|
|
387
|
+
];
|
|
388
|
+
/** Rolls and checks are limited so that a story cannot grow without bound. */
|
|
389
|
+
const MAX_DICE_CHECKS = 40;
|
|
390
|
+
const MAX_DICE_BANDS = 20;
|
|
391
|
+
const MAX_DICE_PER_ROLL = 100;
|
|
392
|
+
const MAX_DICE_SIDES = 1e3;
|
|
393
|
+
const MAX_DICE_TERMS = 8;
|
|
394
|
+
//#endregion
|
|
370
395
|
//#region ../dsh-roleplay-model/src/visual.ts
|
|
371
396
|
const VISUAL_SUBJECT_KINDS = [
|
|
372
397
|
"character",
|
|
@@ -445,6 +470,16 @@ const ZH = {
|
|
|
445
470
|
"age: {value}": "年龄:{value}",
|
|
446
471
|
"gender: {value}": "性别:{value}",
|
|
447
472
|
"pronouns: {value}": "代词:{value}",
|
|
473
|
+
"- {key} ({name}): {use}": "- {key}({name}):{use}",
|
|
474
|
+
"Rolls {dice}.": "掷 {dice}。",
|
|
475
|
+
"Give a target: the difficulty, the number to meet or beat; set it by how hard the attempt is.": "需给出 target:难度,即要达到或超过的数字;按这次尝试的难易来定。",
|
|
476
|
+
"Give a target: the number to stay under; set it by how hard the attempt is.": "需给出 target:要低于的数字;按这次尝试的难易来定。",
|
|
477
|
+
"It adds the character's {variable}.": "它会加上该角色的 {variable}。",
|
|
478
|
+
"Counts the dice that show {hit} or more.": "统计显示 {hit} 或更高的骰子数。",
|
|
479
|
+
"the player's roll": "玩家的掷骰",
|
|
480
|
+
"The player rolled {dice} ({reason}) and got {total}: dice {faces}. This is a fact, decided by the dice: take it into account when you judge the attempt and decide what happens.": "玩家掷了 {dice}({reason}),得到 {total}:骰面 {faces}。这是由骰子决定的事实:在你判断这次尝试、决定发生什么时把它考虑进去。",
|
|
481
|
+
"The checks of this story:": "本故事的检定:",
|
|
482
|
+
"No checks are defined: use roll_dice only.": "没有定义检定:只用 roll_dice。",
|
|
448
483
|
"Situation:": "当前情形:",
|
|
449
484
|
"Now: {time}.": "现在是:{time}。",
|
|
450
485
|
"Where you are:": "你所在之处:",
|
|
@@ -538,11 +573,23 @@ const ZH = {
|
|
|
538
573
|
"{where}: one passing moment is not yet a belief; rest it on things from at least two different turns, or on one event that turned the story": "{where}:一个转瞬即逝的瞬间还不是看法;请以至少两个不同回合的经历为依据,或以一件扭转了故事的事件为依据",
|
|
539
574
|
"{where}: to be sure of something it must rest on things from at least two different turns": "{where}:要对某事确信,必须以至少两个不同回合的经历为依据",
|
|
540
575
|
"{where}: \"{name}\" is not a character; name them as they are named": "{where}:“{name}”不是角色;请使用他们的名字",
|
|
576
|
+
"say in a sentence what the belief claims and what the things say, before the verdict": "先用一句话说明这个看法主张什么、这些内容说了什么,再给出判断",
|
|
577
|
+
"the verdict is consistent or contradicted": "判断是 consistent 或 contradicted",
|
|
578
|
+
"a belief that can be true together with all of them names none of them": "与它们全都可以同时成立的看法,不应列出其中任何一条",
|
|
579
|
+
"name the things that cannot be true together with the belief": "写出与这个看法不可能同时成立的内容",
|
|
580
|
+
"there is no thing listed numbered {id}": "列出的内容里没有编号为 {id} 的",
|
|
581
|
+
"thing {id} came before the belief was formed": "内容 {id} 出现在这个看法形成之前",
|
|
582
|
+
"A belief held by {name}: {text}": "{name} 持有的一个看法:{text}",
|
|
583
|
+
"What they took in since that bears on it:": "此后他们接收到的、与之有关的内容:",
|
|
584
|
+
"Can the belief and each of these be true together? Name the ones that cannot be.": "这个看法与其中每一件事能否同时成立?指出不能同时成立的。",
|
|
585
|
+
"{names} could not be sorted this time and will be tried again: {reason}": "{names} 这一次没能整理,下次会再试:{reason}",
|
|
541
586
|
"{where}: belief {id} is already changed in this pass": "{where}:看法 {id} 在这一轮中已经修改过",
|
|
542
587
|
"{where}: say what it took in since that bears on it": "{where}:请写出此后与之相关的经历",
|
|
543
588
|
"{where}: thing {id} came before the belief was formed; cite what came after": "{where}:经历 {id} 发生在看法形成之前;请引用之后发生的事",
|
|
544
589
|
"{where}: say what changes": "{where}:请写出有何改变",
|
|
545
|
-
"{where}: the text must be there and at most {max} characters": "{where}
|
|
590
|
+
"{where}: the text must be there and at most {max} characters; leave it out to keep the belief as it is": "{where}:文字不能为空,且最多 {max} 个字符;想保持信念原样就不要写这一项",
|
|
591
|
+
"{where}: the confidence, the importance and the numbers are fields of their own, not part of the text": "{where}:把握程度、重要性和编号是各自独立的字段,不属于文字",
|
|
592
|
+
"{where}: name what speaks against the belief in contradicted_by": "{where}:在 contradicted_by 里写出与该信念相悖的内容的编号",
|
|
546
593
|
"{where}: a belief that something contradicts must be doubted: lower its confidence": "{where}:被事实相悖的看法必须存疑:请降低其 confidence",
|
|
547
594
|
"{where}: to doubt a belief, name what contradicts it in contradicted_by": "{where}:要对看法存疑,请在 contradicted_by 中写明与之相悖的经历",
|
|
548
595
|
"{where}: merge into a belief that stays": "{where}:请合并到保留的看法中",
|
|
@@ -595,7 +642,10 @@ const ZH = {
|
|
|
595
642
|
"The time you had for \"{goal}\" has passed ({when}; it is {now} now)": "你为“{goal}”预留的时间已过({when};现在是{now})",
|
|
596
643
|
"You are not with the player's character and nothing of this happens in front of anyone: decide what you do about it.": "你不和玩家的角色在一起,这件事也不会发生在任何人面前:决定你要怎么处理。",
|
|
597
644
|
"{names} noticed: {text}": "{names}注意到:{text}",
|
|
598
|
-
"{name} went to {place}.": "{name}去了{place}。"
|
|
645
|
+
"{name} went to {place}.": "{name}去了{place}。",
|
|
646
|
+
"## MCP resource servers\n\nUse {tools} with the server argument naming an MCP server.": "## MCP 资源服务器\n\n使用 {tools},server 参数填 MCP 服务器的名称。",
|
|
647
|
+
"## MCP resource servers\n\nUse {tools} with one of these names as the server argument: {servers}.": "## MCP 资源服务器\n\n使用 {tools},server 参数填下列名称之一:{servers}。",
|
|
648
|
+
"{where}: the text is longer than {max} characters. A belief is not rewritten to hold what speaks against it: leave the text out and list the belief under doubt with the numbers of what speaks against it, and put what was learned as a new belief of its own": "{where}:文字超过 {max} 个字符。不要通过改写信念来容纳与之相悖的事:不要写文字,把这条信念列入 doubt 并给出与之相悖的编号;新了解到的内容另写成一条新信念"
|
|
599
649
|
};
|
|
600
650
|
//#endregion
|
|
601
651
|
//#region ../dsh-roleplay-model/src/messages.ts
|
|
@@ -1084,7 +1134,7 @@ function seasonOf(day, hemisphere = "north") {
|
|
|
1084
1134
|
return north === "winter" ? "summer" : north === "summer" ? "winter" : north === "spring" ? "autumn" : "spring";
|
|
1085
1135
|
}
|
|
1086
1136
|
const key = (month, day) => month * 100 + day;
|
|
1087
|
-
function within(day, from, to) {
|
|
1137
|
+
function within$1(day, from, to) {
|
|
1088
1138
|
if (from.year !== void 0 && to.year !== void 0) {
|
|
1089
1139
|
const at = day.year * 1e4 + key(day.month, day.day);
|
|
1090
1140
|
return at >= from.year * 1e4 + key(from.month, from.day) && at <= to.year * 1e4 + key(to.month, to.day);
|
|
@@ -1099,7 +1149,7 @@ function matches(token, day, calendar) {
|
|
|
1099
1149
|
case "weekday": return day.weekday === token.weekday;
|
|
1100
1150
|
case "month": return day.month === token.month;
|
|
1101
1151
|
case "date": return day.month === token.month && day.day === token.day && (token.year === void 0 || day.year === token.year);
|
|
1102
|
-
case "span": return within(day, token.from, token.to);
|
|
1152
|
+
case "span": return within$1(day, token.from, token.to);
|
|
1103
1153
|
case "dom": return token.day === "last" ? day.day === daysIn(day.year, day.month) : day.day === token.day;
|
|
1104
1154
|
case "nth": return day.weekday === token.weekday && (token.n === "last" ? day.day + 7 > daysIn(day.year, day.month) : Math.ceil(day.day / 7) === token.n);
|
|
1105
1155
|
case "season": return seasonOf(day, calendar.hemisphere) === token.season;
|
|
@@ -7538,6 +7588,108 @@ var SqliteTriggerRepository = class {
|
|
|
7538
7588
|
}
|
|
7539
7589
|
};
|
|
7540
7590
|
//#endregion
|
|
7591
|
+
//#region src/sqlite/dice-repository.ts
|
|
7592
|
+
const MAX_ROLLS_LISTED = 200;
|
|
7593
|
+
function parseDefinition(text) {
|
|
7594
|
+
try {
|
|
7595
|
+
return JSON.parse(text);
|
|
7596
|
+
} catch (error) {
|
|
7597
|
+
throw new CorruptDataError("a dice check's definition is not valid JSON", { cause: error });
|
|
7598
|
+
}
|
|
7599
|
+
}
|
|
7600
|
+
var SqliteDiceRepository = class {
|
|
7601
|
+
db;
|
|
7602
|
+
clock;
|
|
7603
|
+
constructor(db, clock) {
|
|
7604
|
+
this.db = db;
|
|
7605
|
+
this.clock = clock;
|
|
7606
|
+
}
|
|
7607
|
+
define(definition) {
|
|
7608
|
+
if ((this.db.get("SELECT count(*) AS count FROM dice_checks")?.count ?? 0) >= 40) throw new InvalidValueError(`a story has at most 40 dice checks`);
|
|
7609
|
+
const { key, name, use, ...rest } = definition;
|
|
7610
|
+
return guard(() => {
|
|
7611
|
+
const { lastInsertRowid } = this.db.run("INSERT INTO dice_checks (key, name, use_text, definition) VALUES (?, ?, ?, ?)", [
|
|
7612
|
+
key,
|
|
7613
|
+
name,
|
|
7614
|
+
use,
|
|
7615
|
+
toJson(rest)
|
|
7616
|
+
]);
|
|
7617
|
+
return this.require(Number(lastInsertRowid));
|
|
7618
|
+
});
|
|
7619
|
+
}
|
|
7620
|
+
checks() {
|
|
7621
|
+
return this.db.all("SELECT * FROM dice_checks ORDER BY id").map((row) => this.toCheck(row));
|
|
7622
|
+
}
|
|
7623
|
+
check(key) {
|
|
7624
|
+
const row = this.db.get("SELECT * FROM dice_checks WHERE key = ?", [key]);
|
|
7625
|
+
return row === void 0 ? void 0 : this.toCheck(row);
|
|
7626
|
+
}
|
|
7627
|
+
removeCheck(key) {
|
|
7628
|
+
if (this.db.run("DELETE FROM dice_checks WHERE key = ?", [key]).changes === 0) throw new NotFoundError(`there is no dice check "${key}"`);
|
|
7629
|
+
}
|
|
7630
|
+
record(roll) {
|
|
7631
|
+
const at = this.clock().toISOString();
|
|
7632
|
+
const { lastInsertRowid } = this.db.run("INSERT INTO dice_rolls (turn, check_key, expression, faces, kept, modifier, target, total, value, readout, reason, character, by, at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
|
7633
|
+
roll.turn,
|
|
7634
|
+
roll.check ?? null,
|
|
7635
|
+
roll.expression,
|
|
7636
|
+
toJson(roll.faces),
|
|
7637
|
+
toJson(roll.kept),
|
|
7638
|
+
roll.modifier,
|
|
7639
|
+
roll.target ?? null,
|
|
7640
|
+
roll.total,
|
|
7641
|
+
roll.value,
|
|
7642
|
+
roll.readout === void 0 ? null : toJson(roll.readout),
|
|
7643
|
+
roll.reason,
|
|
7644
|
+
roll.character ?? null,
|
|
7645
|
+
roll.by,
|
|
7646
|
+
at
|
|
7647
|
+
]);
|
|
7648
|
+
return {
|
|
7649
|
+
...roll,
|
|
7650
|
+
id: Number(lastInsertRowid),
|
|
7651
|
+
at
|
|
7652
|
+
};
|
|
7653
|
+
}
|
|
7654
|
+
rolls(filter = {}) {
|
|
7655
|
+
const limit = Math.min(filter.limit ?? MAX_ROLLS_LISTED, MAX_ROLLS_LISTED);
|
|
7656
|
+
return (filter.turn === void 0 ? this.db.all("SELECT * FROM (SELECT * FROM dice_rolls ORDER BY id DESC LIMIT ?) ORDER BY id", [limit]) : this.db.all("SELECT * FROM dice_rolls WHERE turn = ? ORDER BY id LIMIT ?", [filter.turn, limit])).map((row) => this.toRoll(row));
|
|
7657
|
+
}
|
|
7658
|
+
require(id) {
|
|
7659
|
+
const row = this.db.get("SELECT * FROM dice_checks WHERE id = ?", [id]);
|
|
7660
|
+
if (row === void 0) throw new NotFoundError(`there is no dice check ${id}`);
|
|
7661
|
+
return this.toCheck(row);
|
|
7662
|
+
}
|
|
7663
|
+
toCheck(row) {
|
|
7664
|
+
return {
|
|
7665
|
+
id: row.id,
|
|
7666
|
+
key: row.key,
|
|
7667
|
+
name: row.name,
|
|
7668
|
+
use: row.use_text,
|
|
7669
|
+
...parseDefinition(row.definition)
|
|
7670
|
+
};
|
|
7671
|
+
}
|
|
7672
|
+
toRoll(row) {
|
|
7673
|
+
return {
|
|
7674
|
+
id: row.id,
|
|
7675
|
+
turn: row.turn,
|
|
7676
|
+
expression: row.expression,
|
|
7677
|
+
faces: parseNumberList(row.faces, "dice_rolls.faces"),
|
|
7678
|
+
kept: parseNumberList(row.kept, "dice_rolls.kept"),
|
|
7679
|
+
modifier: row.modifier,
|
|
7680
|
+
total: row.total,
|
|
7681
|
+
value: row.value,
|
|
7682
|
+
reason: row.reason,
|
|
7683
|
+
by: row.by,
|
|
7684
|
+
at: row.at,
|
|
7685
|
+
...row.check_key === null ? {} : { check: row.check_key },
|
|
7686
|
+
...row.target === null ? {} : { target: row.target },
|
|
7687
|
+
...row.readout === null ? {} : { readout: JSON.parse(row.readout) },
|
|
7688
|
+
...row.character === null ? {} : { character: row.character }
|
|
7689
|
+
};
|
|
7690
|
+
}
|
|
7691
|
+
};
|
|
7692
|
+
//#endregion
|
|
7541
7693
|
//#region src/sqlite/clock-repository.ts
|
|
7542
7694
|
const toChange = (row) => ({
|
|
7543
7695
|
id: row.id,
|
|
@@ -8681,7 +8833,7 @@ var SqliteMetadataRepository = class {
|
|
|
8681
8833
|
//#region src/sqlite/schema.ts
|
|
8682
8834
|
/**
|
|
8683
8835
|
* Migrations are applied in order and never edited once released (0.1.0 released
|
|
8684
|
-
* versions 1 to 6; tests/sqlite/migrate.spec.ts pins
|
|
8836
|
+
* versions 1 to 6; tests/sqlite/migrate.spec.ts pins the released ones): a change to the schema
|
|
8685
8837
|
* is a new entry. Enumerations are spelled out so that a later change to the model
|
|
8686
8838
|
* cannot alter what an old migration did.
|
|
8687
8839
|
*/
|
|
@@ -9260,6 +9412,36 @@ const MIGRATIONS = [
|
|
|
9260
9412
|
) STRICT;
|
|
9261
9413
|
CREATE INDEX memory_evidence_perception ON memory_evidence (perception_id);
|
|
9262
9414
|
ALTER TABLE routine_windows ADD COLUMN filters TEXT NOT NULL DEFAULT '[]';
|
|
9415
|
+
`
|
|
9416
|
+
},
|
|
9417
|
+
{
|
|
9418
|
+
version: 8,
|
|
9419
|
+
sql: `
|
|
9420
|
+
CREATE TABLE dice_checks (
|
|
9421
|
+
id INTEGER PRIMARY KEY,
|
|
9422
|
+
key TEXT NOT NULL UNIQUE,
|
|
9423
|
+
name TEXT NOT NULL,
|
|
9424
|
+
use_text TEXT NOT NULL,
|
|
9425
|
+
definition TEXT NOT NULL
|
|
9426
|
+
) STRICT;
|
|
9427
|
+
CREATE TABLE dice_rolls (
|
|
9428
|
+
id INTEGER PRIMARY KEY,
|
|
9429
|
+
turn INTEGER NOT NULL,
|
|
9430
|
+
check_key TEXT,
|
|
9431
|
+
expression TEXT NOT NULL,
|
|
9432
|
+
faces TEXT NOT NULL,
|
|
9433
|
+
kept TEXT NOT NULL,
|
|
9434
|
+
modifier INTEGER NOT NULL,
|
|
9435
|
+
target INTEGER,
|
|
9436
|
+
total INTEGER NOT NULL,
|
|
9437
|
+
value INTEGER NOT NULL,
|
|
9438
|
+
readout TEXT,
|
|
9439
|
+
reason TEXT NOT NULL,
|
|
9440
|
+
character TEXT,
|
|
9441
|
+
by TEXT NOT NULL CHECK (by IN ('agent', 'player')),
|
|
9442
|
+
at TEXT NOT NULL
|
|
9443
|
+
) STRICT;
|
|
9444
|
+
CREATE INDEX dice_rolls_turn ON dice_rolls (turn, id);
|
|
9263
9445
|
`
|
|
9264
9446
|
}
|
|
9265
9447
|
];
|
|
@@ -10008,6 +10190,7 @@ var SqliteSessionStore = class {
|
|
|
10008
10190
|
routines;
|
|
10009
10191
|
engagements;
|
|
10010
10192
|
triggers;
|
|
10193
|
+
dice;
|
|
10011
10194
|
recallIndex;
|
|
10012
10195
|
eventRepository;
|
|
10013
10196
|
constructor(db, clock, vectors) {
|
|
@@ -10038,6 +10221,7 @@ var SqliteSessionStore = class {
|
|
|
10038
10221
|
this.routines = new SqliteRoutineRepository(db);
|
|
10039
10222
|
this.engagements = new SqliteEngagementRepository(db);
|
|
10040
10223
|
this.triggers = new SqliteTriggerRepository(db);
|
|
10224
|
+
this.dice = new SqliteDiceRepository(db, clock);
|
|
10041
10225
|
this.eventRepository = new SqliteEventRepository(db, clock, this.recallIndex, (id) => this.locations.get(id)?.name, (id) => this.items.get(id)?.name);
|
|
10042
10226
|
this.events = this.eventRepository;
|
|
10043
10227
|
this.memories = new SqliteMemoryRepository(db, clock, this.recallIndex);
|
|
@@ -10444,6 +10628,375 @@ function identityOf(database, storeOptions) {
|
|
|
10444
10628
|
}
|
|
10445
10629
|
}
|
|
10446
10630
|
//#endregion
|
|
10631
|
+
//#region src/records/dice.ts
|
|
10632
|
+
const systemRoller = (sides) => randomInt(1, sides + 1);
|
|
10633
|
+
const TERM = /^(?:(\d*)d(\d+|%)(?:(kh|kl|dh|dl)(\d*))?|(\d+))$/;
|
|
10634
|
+
/** Reads dice notation: `2d6+1`, `d20`, `4d6kh3`, `d%`, `1d8+1d4-1`. @throws {InvalidValueError} with what is wrong. */
|
|
10635
|
+
function parseNotation(input) {
|
|
10636
|
+
const source = input.toLowerCase().replace(/\s+/g, "");
|
|
10637
|
+
if (source === "") throw new InvalidValueError("dice notation is empty: write it like 2d6+1");
|
|
10638
|
+
const parts = source.split(/(?=[+-])/);
|
|
10639
|
+
if (parts.length > 8) throw new InvalidValueError(`dice notation has more than 8 terms`);
|
|
10640
|
+
const terms = parts.map((part, index) => {
|
|
10641
|
+
const sign = part.startsWith("-") ? -1 : 1;
|
|
10642
|
+
const body = part.replace(/^[+-]/, "");
|
|
10643
|
+
if (index > 0 && !/^[+-]/.test(part)) throw new InvalidValueError(`"${input}" is not dice notation: write it like 2d6+1`);
|
|
10644
|
+
const match = TERM.exec(body);
|
|
10645
|
+
if (match === null) throw new InvalidValueError(`"${part}" is not dice notation: write it like 2d6+1, 4d6kh3 or d100`);
|
|
10646
|
+
if (match[5] !== void 0) return {
|
|
10647
|
+
sign,
|
|
10648
|
+
constant: Number(match[5])
|
|
10649
|
+
};
|
|
10650
|
+
const count = match[1] === "" || match[1] === void 0 ? 1 : Number(match[1]);
|
|
10651
|
+
const sides = match[2] === "%" ? 100 : Number(match[2]);
|
|
10652
|
+
if (count < 1 || count > 100) throw new InvalidValueError(`"${part}": roll from 1 to 100 dice at a time`);
|
|
10653
|
+
if (sides < 2 || sides > 1e3) throw new InvalidValueError(`"${part}": a die has from 2 to ${MAX_DICE_SIDES} sides`);
|
|
10654
|
+
const mode = match[3];
|
|
10655
|
+
if (mode === void 0) return {
|
|
10656
|
+
sign,
|
|
10657
|
+
count,
|
|
10658
|
+
sides
|
|
10659
|
+
};
|
|
10660
|
+
const n = match[4] === "" || match[4] === void 0 ? 1 : Number(match[4]);
|
|
10661
|
+
if (n < 1 || n >= count) throw new InvalidValueError(`"${part}": ${mode.startsWith("k") ? "keep" : "drop"} at least 1 and fewer than the ${count} dice`);
|
|
10662
|
+
return {
|
|
10663
|
+
sign,
|
|
10664
|
+
count,
|
|
10665
|
+
sides,
|
|
10666
|
+
keep: {
|
|
10667
|
+
mode,
|
|
10668
|
+
n
|
|
10669
|
+
}
|
|
10670
|
+
};
|
|
10671
|
+
});
|
|
10672
|
+
if (!terms.some((term) => "sides" in term)) throw new InvalidValueError(`"${input}" has no dice: write it like 2d6+1`);
|
|
10673
|
+
return {
|
|
10674
|
+
text: source,
|
|
10675
|
+
terms
|
|
10676
|
+
};
|
|
10677
|
+
}
|
|
10678
|
+
/** The lowest and highest total the dice and constants can give. */
|
|
10679
|
+
function notationRange(notation) {
|
|
10680
|
+
let min = 0;
|
|
10681
|
+
let max = 0;
|
|
10682
|
+
for (const term of notation.terms) {
|
|
10683
|
+
if ("constant" in term) {
|
|
10684
|
+
min += term.sign * term.constant;
|
|
10685
|
+
max += term.sign * term.constant;
|
|
10686
|
+
continue;
|
|
10687
|
+
}
|
|
10688
|
+
const kept = term.keep === void 0 ? term.count : term.keep.mode.startsWith("k") ? term.keep.n : term.count - term.keep.n;
|
|
10689
|
+
const low = kept;
|
|
10690
|
+
const high = kept * term.sides;
|
|
10691
|
+
min += term.sign === 1 ? low : -high;
|
|
10692
|
+
max += term.sign === 1 ? high : -low;
|
|
10693
|
+
}
|
|
10694
|
+
return {
|
|
10695
|
+
min,
|
|
10696
|
+
max
|
|
10697
|
+
};
|
|
10698
|
+
}
|
|
10699
|
+
function keepOf(faces, keep) {
|
|
10700
|
+
const ordered = faces.map((face, index) => ({
|
|
10701
|
+
face,
|
|
10702
|
+
index
|
|
10703
|
+
})).sort((a, b) => a.face - b.face || a.index - b.index);
|
|
10704
|
+
const count = keep.mode.startsWith("k") ? keep.n : faces.length - keep.n;
|
|
10705
|
+
return (keep.mode === "kh" || keep.mode === "dl" ? ordered.slice(ordered.length - count) : ordered.slice(0, count)).sort((a, b) => a.index - b.index).map((entry) => entry.face);
|
|
10706
|
+
}
|
|
10707
|
+
function rollNotation(notation, roll = systemRoller) {
|
|
10708
|
+
const faces = [];
|
|
10709
|
+
const kept = [];
|
|
10710
|
+
let constant = 0;
|
|
10711
|
+
let total = 0;
|
|
10712
|
+
for (const term of notation.terms) {
|
|
10713
|
+
if ("constant" in term) {
|
|
10714
|
+
constant += term.sign * term.constant;
|
|
10715
|
+
total += term.sign * term.constant;
|
|
10716
|
+
continue;
|
|
10717
|
+
}
|
|
10718
|
+
const thrown = Array.from({ length: term.count }, () => roll(term.sides));
|
|
10719
|
+
const counted = term.keep === void 0 ? thrown : keepOf(thrown, term.keep);
|
|
10720
|
+
faces.push(...thrown);
|
|
10721
|
+
kept.push(...counted);
|
|
10722
|
+
total += term.sign * counted.reduce((sum, face) => sum + face, 0);
|
|
10723
|
+
}
|
|
10724
|
+
return {
|
|
10725
|
+
faces,
|
|
10726
|
+
kept,
|
|
10727
|
+
constant,
|
|
10728
|
+
total
|
|
10729
|
+
};
|
|
10730
|
+
}
|
|
10731
|
+
const within = (band, value) => (band.min === void 0 || value >= band.min) && (band.max === void 0 || value <= band.max);
|
|
10732
|
+
/** What the bands of a check make of a value. @throws {InvalidValueError} when no band holds it. */
|
|
10733
|
+
function readBands(bands, value) {
|
|
10734
|
+
const band = bands.find((candidate) => within(candidate, value));
|
|
10735
|
+
if (band === void 0) throw new InvalidValueError(`no band of this check holds ${value}: the check's bands leave a gap`);
|
|
10736
|
+
return {
|
|
10737
|
+
label: band.label,
|
|
10738
|
+
result: band.result,
|
|
10739
|
+
critical: band.critical === true
|
|
10740
|
+
};
|
|
10741
|
+
}
|
|
10742
|
+
/**
|
|
10743
|
+
* Rolls a check: the dice, the character's modifier and any bonus added, then the value read against the bands. With the reading
|
|
10744
|
+
* `successes` the total is the number of dice that hit. A check read against a target needs one.
|
|
10745
|
+
* @throws {InvalidValueError} for a target a check needs and is not given, or bands that leave the value unread.
|
|
10746
|
+
*/
|
|
10747
|
+
function rollCheck(check, input, roll = systemRoller) {
|
|
10748
|
+
const rolled = rollNotation(parseNotation(check.dice), roll);
|
|
10749
|
+
const comparison = check.compare ?? "absolute";
|
|
10750
|
+
if (comparison !== "absolute" && input.target === void 0) throw new InvalidValueError(`the check "${check.key}" is read against a target (${comparison === "over" ? "the number to meet or beat" : "the number to stay under"}): give one`);
|
|
10751
|
+
const added = (input.modifier ?? 0) + (input.bonus ?? 0);
|
|
10752
|
+
const total = check.reading === "successes" ? rolled.kept.filter((face) => face >= (check.hit ?? 0)).length + (input.bonus ?? 0) : rolled.total + added;
|
|
10753
|
+
const value = comparison === "over" ? total - (input.target ?? 0) : comparison === "under" ? (input.target ?? 0) - total : total;
|
|
10754
|
+
return {
|
|
10755
|
+
faces: rolled.faces,
|
|
10756
|
+
kept: rolled.kept,
|
|
10757
|
+
modifier: check.reading === "successes" ? input.bonus ?? 0 : rolled.constant + added,
|
|
10758
|
+
...input.target === void 0 ? {} : { target: input.target },
|
|
10759
|
+
total,
|
|
10760
|
+
value,
|
|
10761
|
+
readout: readBands(check.bands, value)
|
|
10762
|
+
};
|
|
10763
|
+
}
|
|
10764
|
+
/** What is wrong with a check as a world defines it; nothing when it is sound. */
|
|
10765
|
+
function checkProblems(check) {
|
|
10766
|
+
const problems = [];
|
|
10767
|
+
if (!/^[a-z][a-z0-9_-]{0,39}$/.test(check.key)) problems.push(`the key "${check.key}" must be lower-case letters, digits, - or _, starting with a letter`);
|
|
10768
|
+
if (check.name.trim() === "") problems.push("it needs a name");
|
|
10769
|
+
if (check.use.trim() === "") problems.push("it needs a \"use\": when the game master rolls it");
|
|
10770
|
+
if (check.compare !== void 0 && !DICE_COMPARISONS.includes(check.compare)) problems.push(`"compare" must be one of: ${DICE_COMPARISONS.join(", ")}`);
|
|
10771
|
+
if (check.reading !== void 0 && !DICE_READINGS.includes(check.reading)) problems.push(`"reading" must be one of: ${DICE_READINGS.join(", ")}`);
|
|
10772
|
+
let notation;
|
|
10773
|
+
try {
|
|
10774
|
+
notation = parseNotation(check.dice);
|
|
10775
|
+
} catch (error) {
|
|
10776
|
+
problems.push(`"dice": ${error instanceof Error ? error.message : String(error)}`);
|
|
10777
|
+
}
|
|
10778
|
+
if (check.bands.length === 0) problems.push("it needs at least one band");
|
|
10779
|
+
if (check.bands.length > 20) problems.push(`it has more than 20 bands`);
|
|
10780
|
+
check.bands.forEach((band, index) => {
|
|
10781
|
+
if (band.label.trim() === "") problems.push(`band ${index + 1} needs a label`);
|
|
10782
|
+
if (!DICE_RESULTS.includes(band.result)) problems.push(`band ${index + 1}: "result" must be one of: ${DICE_RESULTS.join(", ")}`);
|
|
10783
|
+
if (band.min !== void 0 && band.max !== void 0 && band.min > band.max) problems.push(`band ${index + 1}: min is above max`);
|
|
10784
|
+
});
|
|
10785
|
+
if (check.reading === "successes") {
|
|
10786
|
+
const sides = notation?.terms.flatMap((term) => "sides" in term ? [term.sides] : []) ?? [];
|
|
10787
|
+
if (check.hit === void 0 || !Number.isInteger(check.hit) || check.hit < 1 || sides.length > 0 && check.hit > Math.max(...sides)) problems.push("the reading \"successes\" needs \"hit\": the lowest face that counts");
|
|
10788
|
+
}
|
|
10789
|
+
if (notation !== void 0 && problems.length === 0 && (check.compare ?? "absolute") === "absolute" && check.modifier === void 0) {
|
|
10790
|
+
const { min, max } = check.reading === "successes" ? {
|
|
10791
|
+
min: 0,
|
|
10792
|
+
max: notation.terms.reduce((sum, term) => sum + ("count" in term ? term.count : 0), 0)
|
|
10793
|
+
} : notationRange(notation);
|
|
10794
|
+
for (let value = min; value <= max; value += 1) if (!check.bands.some((band) => within(band, value))) {
|
|
10795
|
+
problems.push(`no band holds ${value}, which the dice can give`);
|
|
10796
|
+
break;
|
|
10797
|
+
}
|
|
10798
|
+
}
|
|
10799
|
+
return problems;
|
|
10800
|
+
}
|
|
10801
|
+
function rollPlain(expression, roll = systemRoller) {
|
|
10802
|
+
const notation = parseNotation(expression);
|
|
10803
|
+
const rolled = rollNotation(notation, roll);
|
|
10804
|
+
return {
|
|
10805
|
+
expression: notation.text,
|
|
10806
|
+
faces: rolled.faces,
|
|
10807
|
+
kept: rolled.kept,
|
|
10808
|
+
modifier: rolled.constant,
|
|
10809
|
+
total: rolled.total
|
|
10810
|
+
};
|
|
10811
|
+
}
|
|
10812
|
+
//#endregion
|
|
10813
|
+
//#region src/tools/dice.ts
|
|
10814
|
+
const ROLL_DICE_TOOL = "roll_dice";
|
|
10815
|
+
const ROLL_CHECK_TOOL = "roll_check";
|
|
10816
|
+
const LIST_CHECKS_TOOL = "list_checks";
|
|
10817
|
+
const sign = (value) => value >= 0 ? `+${value}` : String(value);
|
|
10818
|
+
/** How a roll reads to the agent that asked for it: what fell, what it adds up to, and what the world's check makes of it. */
|
|
10819
|
+
function describeRoll(roll, check) {
|
|
10820
|
+
const dice = `[${roll.faces.join(", ")}]${roll.kept.length < roll.faces.length ? ` keeping [${roll.kept.join(", ")}]` : ""}`;
|
|
10821
|
+
const lines = [`Roll ${roll.id}: ${roll.expression}${check === void 0 ? "" : ` for the check "${check.name}"`}${roll.character === void 0 ? "" : ` (${roll.character})`} - ${dice}${roll.modifier === 0 ? "" : ` ${sign(roll.modifier)}`} = ${roll.total}${check?.reading === "successes" ? " successes" : ""}.`];
|
|
10822
|
+
if (roll.target !== void 0) lines.push(`Against ${roll.target}: ${roll.value >= 0 ? "+" : ""}${roll.value}.`);
|
|
10823
|
+
if (roll.readout !== void 0) lines.push(`That is: ${roll.readout.label}${roll.readout.critical ? " (critical)" : ""}; the result is ${roll.readout.result}. This is decided by the dice: do not change it, narrate it.${check === void 0 || roll.character === void 0 ? "" : ` In resolve_round give ${roll.character}'s outcome this result and cite the roll: roll ${roll.id}.`}`);
|
|
10824
|
+
return lines.join(" ");
|
|
10825
|
+
}
|
|
10826
|
+
const rolled = (_args, value) => [{
|
|
10827
|
+
type: "text",
|
|
10828
|
+
text: value.text
|
|
10829
|
+
}];
|
|
10830
|
+
/**
|
|
10831
|
+
* Tools that roll dice for an agent, so that numbers are not made up. `roll_check` rolls a check the story defines and reads
|
|
10832
|
+
* the result with the check's own bands; `roll_dice` rolls plain notation for what has no check. The roller is the system's
|
|
10833
|
+
* source of randomness unless one is given.
|
|
10834
|
+
*/
|
|
10835
|
+
function createDiceTools(resolve, options = {}) {
|
|
10836
|
+
const roller = options.roller ?? systemRoller;
|
|
10837
|
+
const linkOf = (agent) => {
|
|
10838
|
+
const found = agent === void 0 ? void 0 : resolve(agent.session.id);
|
|
10839
|
+
if (found === void 0) throw new NotFoundError("this agent is not working in a roleplay session, so there are no dice to roll");
|
|
10840
|
+
return found;
|
|
10841
|
+
};
|
|
10842
|
+
return [
|
|
10843
|
+
defineTool({
|
|
10844
|
+
name: LIST_CHECKS_TOOL,
|
|
10845
|
+
description: "List the checks this story defines for settling uncertain attempts: when each is used, the dice it rolls and how its result is read.",
|
|
10846
|
+
parameters: {},
|
|
10847
|
+
output: {
|
|
10848
|
+
schema: { type: "json" },
|
|
10849
|
+
render: (_args, value) => [{
|
|
10850
|
+
type: "text",
|
|
10851
|
+
text: JSON.stringify(value, null, 2)
|
|
10852
|
+
}]
|
|
10853
|
+
},
|
|
10854
|
+
isConcurrencySafe: () => true,
|
|
10855
|
+
execute(_args, exec) {
|
|
10856
|
+
const { session } = linkOf(exec.agent);
|
|
10857
|
+
return Promise.resolve(session.dice.checks().map((check) => ({
|
|
10858
|
+
key: check.key,
|
|
10859
|
+
name: check.name,
|
|
10860
|
+
use: check.use,
|
|
10861
|
+
dice: check.dice,
|
|
10862
|
+
compare: check.compare ?? "absolute",
|
|
10863
|
+
...check.modifier === void 0 ? {} : { modifier: `the character's ${check.modifier}` },
|
|
10864
|
+
bands: check.bands.map((band) => ({
|
|
10865
|
+
...band.min === void 0 ? {} : { from: band.min },
|
|
10866
|
+
...band.max === void 0 ? {} : { to: band.max },
|
|
10867
|
+
label: band.label,
|
|
10868
|
+
result: band.result
|
|
10869
|
+
}))
|
|
10870
|
+
})));
|
|
10871
|
+
}
|
|
10872
|
+
}),
|
|
10873
|
+
defineTool({
|
|
10874
|
+
name: ROLL_CHECK_TOOL,
|
|
10875
|
+
description: "Roll one of the story's checks for an attempt whose outcome is uncertain and matters: the dice are rolled for you and the result is read with the check's own bands, so you never choose or make up a number. Use the check whose \"use\" fits (list_checks shows them). Roll once per attempt, before you decide what happens, and let the result stand: a failed roll is a failure, whatever the story would like.",
|
|
10876
|
+
parameters: {
|
|
10877
|
+
check: {
|
|
10878
|
+
type: "string",
|
|
10879
|
+
required: true,
|
|
10880
|
+
description: "The key of the check, as list_checks gives it."
|
|
10881
|
+
},
|
|
10882
|
+
reason: {
|
|
10883
|
+
type: "string",
|
|
10884
|
+
required: true,
|
|
10885
|
+
description: "What is attempted, by whom, in a sentence."
|
|
10886
|
+
},
|
|
10887
|
+
character: {
|
|
10888
|
+
type: "string",
|
|
10889
|
+
required: true,
|
|
10890
|
+
description: "The key of the character the attempt is for (the player's character included): the roll is theirs, and their outcome in resolve_round takes its result from it."
|
|
10891
|
+
},
|
|
10892
|
+
target: {
|
|
10893
|
+
type: "integer",
|
|
10894
|
+
description: "When the check is read against a target (list_checks says compare over or under): the difficulty, the number the total must meet or beat (or stay under). Set it by how hard the attempt is, using what the check's \"use\" says about difficulty; never 0 to make it easy."
|
|
10895
|
+
},
|
|
10896
|
+
bonus: {
|
|
10897
|
+
type: "integer",
|
|
10898
|
+
description: "What the circumstances add to or take from the roll, from -10 to 10; leave out for none."
|
|
10899
|
+
}
|
|
10900
|
+
},
|
|
10901
|
+
output: {
|
|
10902
|
+
schema: { type: "json" },
|
|
10903
|
+
render: rolled
|
|
10904
|
+
},
|
|
10905
|
+
isConcurrencySafe: () => false,
|
|
10906
|
+
execute(args, exec) {
|
|
10907
|
+
const { session, turn } = linkOf(exec.agent);
|
|
10908
|
+
const check = session.dice.check(args.check);
|
|
10909
|
+
if (check === void 0) throw new NotFoundError(`there is no check "${args.check}"; list_checks shows the story's checks`);
|
|
10910
|
+
if (session.characters.list().every((entry) => characterKey(entry) !== args.character)) throw new NotFoundError(`there is no character "${args.character}"; list_characters shows the keys`);
|
|
10911
|
+
let modifier;
|
|
10912
|
+
if (check.modifier !== void 0) {
|
|
10913
|
+
const who = session.characters.list().find((entry) => characterKey(entry) === args.character);
|
|
10914
|
+
if (who === void 0) throw new NotFoundError(`there is no character "${args.character}"; list_characters shows the keys`);
|
|
10915
|
+
const value = session.variables.value(check.modifier, "character", who.id);
|
|
10916
|
+
if (typeof value !== "number") throw new NotFoundError(`the character's ${check.modifier} is not a number, so the check cannot add it`);
|
|
10917
|
+
modifier = value;
|
|
10918
|
+
}
|
|
10919
|
+
const bonus = Math.max(-10, Math.min(10, args.bonus ?? 0));
|
|
10920
|
+
const made = rollCheck(check, {
|
|
10921
|
+
...modifier === void 0 ? {} : { modifier },
|
|
10922
|
+
bonus,
|
|
10923
|
+
...args.target === void 0 ? {} : { target: args.target }
|
|
10924
|
+
}, roller);
|
|
10925
|
+
const roll = session.dice.record({
|
|
10926
|
+
turn,
|
|
10927
|
+
check: check.key,
|
|
10928
|
+
expression: check.dice,
|
|
10929
|
+
faces: made.faces,
|
|
10930
|
+
kept: made.kept,
|
|
10931
|
+
modifier: made.modifier,
|
|
10932
|
+
...made.target === void 0 ? {} : { target: made.target },
|
|
10933
|
+
total: made.total,
|
|
10934
|
+
value: made.value,
|
|
10935
|
+
readout: made.readout,
|
|
10936
|
+
reason: args.reason,
|
|
10937
|
+
character: args.character,
|
|
10938
|
+
by: options.by ?? "agent"
|
|
10939
|
+
});
|
|
10940
|
+
return Promise.resolve({
|
|
10941
|
+
roll: roll.id,
|
|
10942
|
+
check: check.key,
|
|
10943
|
+
total: roll.total,
|
|
10944
|
+
result: made.readout.result,
|
|
10945
|
+
label: made.readout.label,
|
|
10946
|
+
critical: made.readout.critical,
|
|
10947
|
+
text: describeRoll(roll, check)
|
|
10948
|
+
});
|
|
10949
|
+
}
|
|
10950
|
+
}),
|
|
10951
|
+
defineTool({
|
|
10952
|
+
name: ROLL_DICE_TOOL,
|
|
10953
|
+
description: "Roll dice for something the story has no check for (damage, a random pick, who goes first, a rumour table): the dice are rolled for you, so you never make up a number. Write the notation like 1d6, 2d4+1, 4d6kh3 (keep the highest 3) or d100. What the number means is for you to decide from the rules you were given; when a check fits the attempt, use roll_check instead.",
|
|
10954
|
+
parameters: {
|
|
10955
|
+
expression: {
|
|
10956
|
+
type: "string",
|
|
10957
|
+
required: true,
|
|
10958
|
+
description: "Dice notation, for example 2d6+1."
|
|
10959
|
+
},
|
|
10960
|
+
reason: {
|
|
10961
|
+
type: "string",
|
|
10962
|
+
required: true,
|
|
10963
|
+
description: "What the roll is for, in a sentence."
|
|
10964
|
+
},
|
|
10965
|
+
character: {
|
|
10966
|
+
type: "string",
|
|
10967
|
+
description: "The key of the character it is for, when it is for one."
|
|
10968
|
+
}
|
|
10969
|
+
},
|
|
10970
|
+
output: {
|
|
10971
|
+
schema: { type: "json" },
|
|
10972
|
+
render: rolled
|
|
10973
|
+
},
|
|
10974
|
+
isConcurrencySafe: () => false,
|
|
10975
|
+
execute(args, exec) {
|
|
10976
|
+
const { session, turn } = linkOf(exec.agent);
|
|
10977
|
+
const made = rollPlain(args.expression, roller);
|
|
10978
|
+
const roll = session.dice.record({
|
|
10979
|
+
turn,
|
|
10980
|
+
expression: made.expression,
|
|
10981
|
+
faces: made.faces,
|
|
10982
|
+
kept: made.kept,
|
|
10983
|
+
modifier: made.modifier,
|
|
10984
|
+
total: made.total,
|
|
10985
|
+
value: made.total,
|
|
10986
|
+
reason: args.reason,
|
|
10987
|
+
...args.character === void 0 ? {} : { character: args.character },
|
|
10988
|
+
by: options.by ?? "agent"
|
|
10989
|
+
});
|
|
10990
|
+
return Promise.resolve({
|
|
10991
|
+
roll: roll.id,
|
|
10992
|
+
total: roll.total,
|
|
10993
|
+
text: describeRoll(roll)
|
|
10994
|
+
});
|
|
10995
|
+
}
|
|
10996
|
+
})
|
|
10997
|
+
];
|
|
10998
|
+
}
|
|
10999
|
+
//#endregion
|
|
10447
11000
|
//#region src/records/lint.ts
|
|
10448
11001
|
/**
|
|
10449
11002
|
* What is inconsistent or unfinished in the world's graph of places and characters. Things made up in
|
|
@@ -12031,7 +12584,8 @@ function createTools(resolve, options) {
|
|
|
12031
12584
|
//#region src/plugin.ts
|
|
12032
12585
|
const Config = z.object({
|
|
12033
12586
|
journalMode: z.union(["delete", "wal"]).default("delete"),
|
|
12034
|
-
writeTools: z.boolean().default(false)
|
|
12587
|
+
writeTools: z.boolean().default(false),
|
|
12588
|
+
diceTools: z.boolean().default(false)
|
|
12035
12589
|
});
|
|
12036
12590
|
/**
|
|
12037
12591
|
* Roleplay session state for other plugins. It creates and opens sessions
|
|
@@ -12057,6 +12611,7 @@ var RoleplayState = class extends Service {
|
|
|
12057
12611
|
};
|
|
12058
12612
|
ctx.inject(["tools"], (scope) => {
|
|
12059
12613
|
for (const tool of createTools(resolve, { write: config.writeTools ?? false })) scope.tools.register(tool);
|
|
12614
|
+
if (config.diceTools === true) for (const tool of createDiceTools(resolve)) scope.tools.register(tool);
|
|
12060
12615
|
});
|
|
12061
12616
|
}
|
|
12062
12617
|
/**
|
|
@@ -12192,6 +12747,7 @@ var RoleplayState = class extends Service {
|
|
|
12192
12747
|
routines: store.routines,
|
|
12193
12748
|
engagements: store.engagements,
|
|
12194
12749
|
triggers: store.triggers,
|
|
12750
|
+
dice: store.dice,
|
|
12195
12751
|
planMove: (characterId, move) => store.planMove(characterId, move),
|
|
12196
12752
|
planKnownMove: (characterId, move) => store.planKnownMove(characterId, move),
|
|
12197
12753
|
move: (characterId, move) => store.move(characterId, move),
|
|
@@ -12461,6 +13017,6 @@ function createCharacterTools(link, characterId) {
|
|
|
12461
13017
|
];
|
|
12462
13018
|
}
|
|
12463
13019
|
//#endregion
|
|
12464
|
-
export { ACCURACIES, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Config, ConflictError, CorruptDataError, DAY, DAY_PARTS, DEFAULT_CONFIDENCE, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EVIDENCE_RELATIONS, EXIT_STATES, HOUR, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, InvalidEditError, InvalidMoveError, InvalidValueError, KNOWLEDGE_KINDS, LANGUAGES, LORE_KINDS, LORE_SUBJECT_KINDS, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_CONFIDENCES, MEMORY_KINDS, MIGRATION_BACKUP_FOLDER, MINUTE, MONTH_NAMES, NO_CALENDAR, NotFoundError, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, RECALL_ITEM_KINDS, RoleplayState, LATEST_VERSION as SCHEMA_VERSION, SEASONS, SECOND, SELF, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, StateError, TEMPLATE_KINDS, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, UnwritableError, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, WEEKDAY_NAMES, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayMatches, dayPart, dayTokenProblems, deleteSession, deliverNotes, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, holidaysOn, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, languageOf, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, migrationBackupPath, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseDayToken, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, placeholdersOf, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readCalendar, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, renderWords, retention, runTriggers, seasonOf, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, translated, translation, translator, triggerReferenceProblems, valueIssue, writeCalendar, zonedInstant };
|
|
13020
|
+
export { ACCURACIES, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Config, ConflictError, CorruptDataError, DAY, DAY_PARTS, DEFAULT_CONFIDENCE, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, DICE_COMPARISONS, DICE_READINGS, DICE_RESULTS, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EVIDENCE_RELATIONS, EXIT_STATES, HOUR, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, InvalidEditError, InvalidMoveError, InvalidValueError, KNOWLEDGE_KINDS, LANGUAGES, LIST_CHECKS_TOOL, LORE_KINDS, LORE_SUBJECT_KINDS, MAX_DICE_BANDS, MAX_DICE_CHECKS, MAX_DICE_PER_ROLL, MAX_DICE_SIDES, MAX_DICE_TERMS, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_CONFIDENCES, MEMORY_KINDS, MIGRATION_BACKUP_FOLDER, MINUTE, MONTH_NAMES, NO_CALENDAR, NotFoundError, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, RECALL_ITEM_KINDS, ROLL_CHECK_TOOL, ROLL_DICE_TOOL, RoleplayState, LATEST_VERSION as SCHEMA_VERSION, SEASONS, SECOND, SELF, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, StateError, TEMPLATE_KINDS, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, UnwritableError, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, WEEKDAY_NAMES, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, checkProblems, clarityAt, clockTime, conditionHolds, createCharacterTools, createDiceTools, createSession, createSessionStore, createTools, dayMatches, dayPart, dayTokenProblems, deleteSession, deliverNotes, denseScore, describeDuration, describeHolder, describeInstant, describeRoll, describeValue, finishRecall, fuseScores, holidaysOn, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, languageOf, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, migrationBackupPath, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, notationRange, occurrenceAt, openSession, openSessionStore, overlap, parseDayToken, parseInstant, parseNotation, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, placeholdersOf, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readBands, readCalendar, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, renderWords, retention, rollCheck, rollNotation, rollPlain, runTriggers, seasonOf, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemRoller, systemTimeZone, tokens, translated, translation, translator, triggerReferenceProblems, valueIssue, writeCalendar, zonedInstant };
|
|
12465
13021
|
|
|
12466
13022
|
//# sourceMappingURL=index.js.map
|