@maka/maka-cli 5.66.0 → 5.68.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/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/_index.d.ts +1 -0
- package/bundle/typescript/src/commands/game/_index.js +1 -0
- package/bundle/typescript/src/commands/game/_index.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +6 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/ar.js +4 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/ar.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.d.ts +103 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js +423 -25
- package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +15 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +61 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.d.ts +39 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js +85 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.d.ts +37 -17
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js +53 -115
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.d.ts +55 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.js +203 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +23 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +42 -7
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +27 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +28 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js +69 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/register.d.ts +15 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/register.js +32 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/register.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/review.d.ts +39 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/review.js +48 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/review.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sprites.d.ts +35 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sprites.js +108 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sprites.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.d.ts +27 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.js +7 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/unravel.d.ts +57 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/unravel.js +162 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/unravel.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +31 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.d.ts +87 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js +320 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +32 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +8 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +98 -11
- package/bundle/typescript/src/commands/game/sideQuest/game.js +239 -35
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.d.ts +24 -0
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js +63 -0
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +57 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +62 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +10 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/resonance-actions.d.ts +108 -0
- package/bundle/typescript/src/commands/game/sideQuest/resonance-actions.js +186 -0
- package/bundle/typescript/src/commands/game/sideQuest/resonance-actions.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/sprite-powers.d.ts +88 -0
- package/bundle/typescript/src/commands/game/sideQuest/sprite-powers.js +137 -0
- package/bundle/typescript/src/commands/game/sideQuest/sprite-powers.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.d.ts +106 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.js +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +32 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.d.ts +17 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js +250 -36
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.d.ts +30 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js +58 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.d.ts +85 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.js +100 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.d.ts +45 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js +45 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.d.ts +13 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.js +22 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.d.ts +13 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js +36 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.d.ts +42 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.js +57 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.d.ts +68 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.js +147 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +39 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js +46 -0
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.d.ts +3 -1
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +352 -42
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/tools/log/log.class.d.ts +17 -0
- package/bundle/typescript/src/tools/log/log.class.js +30 -1
- package/bundle/typescript/src/tools/log/log.class.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SR5e RESONANCE ACTIONS (core p.250) -- the technomancer's own action
|
|
3
|
+
* list, and the Resonance-side counterpart to the Matrix actions every
|
|
4
|
+
* other decker shares.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS IS A TABLE AND NOT SEVEN STRINGS IN SEVEN FILES.
|
|
7
|
+
*
|
|
8
|
+
* Backlog item SoopwuTFBwayCGhM9 ("check page 250 for resonance
|
|
9
|
+
* actions, right now we have several missing") could only be ANSWERED
|
|
10
|
+
* by laying the book's list beside the game's verbs -- and once that
|
|
11
|
+
* comparison exists, leaving it in a commit message means the next
|
|
12
|
+
* person re-derives it. So the comparison lives here, in the `verb`
|
|
13
|
+
* field, where it is machine-checkable rather than remembered.
|
|
14
|
+
*
|
|
15
|
+
* The audit that produced it, in one line each:
|
|
16
|
+
* present -- Compile, Decompile, Register, Thread (already built)
|
|
17
|
+
* present -- COMMAND SPRITE, via the generic `order` verb. This one
|
|
18
|
+
* nearly got filed as missing: order.ts picks out of
|
|
19
|
+
* `game.companions` with no kind filter, so it has always
|
|
20
|
+
* reached sprites. A "missing" feature that already
|
|
21
|
+
* exists gets built twice and the second one wins quietly.
|
|
22
|
+
* built -- KILL COMPLEX FORM, added as `unravel` against this
|
|
23
|
+
* audit (see unravel.ts).
|
|
24
|
+
* built -- CALL/DISMISS SPRITE, added on `recall` by the
|
|
25
|
+
* sprite-lifecycle work, which imports `name` and
|
|
26
|
+
* `actionType` from here rather than restating them.
|
|
27
|
+
*
|
|
28
|
+
* ALL SEVEN NOW HAVE VERBS, so the audit's missing set is empty. That
|
|
29
|
+
* is the finished state, not an absent check -- see the note in
|
|
30
|
+
* resonance-actions.test.ts about what the tripwire proves once it
|
|
31
|
+
* empties, because an empty expectation is indistinguishable from one
|
|
32
|
+
* that never asserted anything.
|
|
33
|
+
*
|
|
34
|
+
* `verb` IS THE AUDIT, AND IT IS CHECKED: resonance-actions.test.ts
|
|
35
|
+
* asserts that every verb named here is really registered in game.ts.
|
|
36
|
+
* Write a verb that does not exist and the suite fails.
|
|
37
|
+
*
|
|
38
|
+
* WHAT IT DOES NOT CATCH, stated plainly because a comment claiming a
|
|
39
|
+
* guarantee the test does not give is worse than no comment: nothing
|
|
40
|
+
* detects "somebody implemented Kill Complex Form and forgot to fill in
|
|
41
|
+
* its verb". No property of a command's NAME proves which canon action
|
|
42
|
+
* it implements -- an early version of the test tried to guess one from
|
|
43
|
+
* the other and immediately produced a false positive (`call` is
|
|
44
|
+
* registered, as the PHONE command, nothing to do with sprites). What
|
|
45
|
+
* the suite does instead is pin the missing set exactly, so changing it
|
|
46
|
+
* is a conscious edit rather than a silent drift.
|
|
47
|
+
*
|
|
48
|
+
* CITATIONS ARE FIRST-CLASS. Every action type and Test line below was
|
|
49
|
+
* pinned individually against the rulebooks rather than read off one
|
|
50
|
+
* contents-page retrieval, because the failure mode this table exists
|
|
51
|
+
* to prevent is a plausible-sounding invented mechanic. Where canon
|
|
52
|
+
* could not be confirmed the field is LEFT EMPTY -- see `actionType`.
|
|
53
|
+
*/
|
|
54
|
+
/** Which verb, if any, reaches this action in the game today.
|
|
55
|
+
*
|
|
56
|
+
* `undefined` means NOT IMPLEMENTED, and is asserted as such. When a
|
|
57
|
+
* missing action is built, filling this in is the one edit needed --
|
|
58
|
+
* and the suite will demand it, because an unimplemented entry whose
|
|
59
|
+
* verb suddenly resolves is a table that has gone stale. */
|
|
60
|
+
export type ResonanceVerb = string | undefined;
|
|
61
|
+
export interface IResonanceAction {
|
|
62
|
+
key: string;
|
|
63
|
+
/** The book's own name for the action, verbatim from p.250. This is
|
|
64
|
+
* the string every surface must render -- imported, never retyped
|
|
65
|
+
* (backlog-session-2 imports it for the Call/Dismiss verb). */
|
|
66
|
+
name: string;
|
|
67
|
+
/**
|
|
68
|
+
* SR5e action type, verbatim.
|
|
69
|
+
*
|
|
70
|
+
* OPTIONAL ON PURPOSE, and the reason is worth keeping: this field
|
|
71
|
+
* was very nearly shipped `undefined` for Register Sprite on the
|
|
72
|
+
* strength of one retrieval that did not happen to include it. A
|
|
73
|
+
* targeted second query returned "Register Sprite (Complex Action)"
|
|
74
|
+
* from the section heading itself. All seven are confirmed today --
|
|
75
|
+
* but the field stays optional so that the NEXT action added here can
|
|
76
|
+
* be honest about a gap instead of guessing, which is the same rule
|
|
77
|
+
* the sprite powers follow.
|
|
78
|
+
*/
|
|
79
|
+
actionType?: 'Simple' | 'Complex';
|
|
80
|
+
/** The book's Test line, verbatim. `undefined` where the book itself
|
|
81
|
+
* gives none -- the two Simple actions genuinely print "Test: n/a",
|
|
82
|
+
* which is canon saying "no roll", not canon being unavailable. */
|
|
83
|
+
test?: string;
|
|
84
|
+
/** What it does, in one line, for a player reading a list. */
|
|
85
|
+
effect: string;
|
|
86
|
+
/** See ResonanceVerb. */
|
|
87
|
+
verb: ResonanceVerb;
|
|
88
|
+
/** SR5e core page. */
|
|
89
|
+
page: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* All seven, in the book's own alphabetical order (p.250).
|
|
93
|
+
*
|
|
94
|
+
* Kept in canon order rather than "implemented first" order so that
|
|
95
|
+
* comparing this against the page is a straight read down the column --
|
|
96
|
+
* which is exactly the check the backlog item asked for, and a check
|
|
97
|
+
* nobody will run again if it needs re-sorting first.
|
|
98
|
+
*/
|
|
99
|
+
export declare const RESONANCE_ACTIONS: IResonanceAction[];
|
|
100
|
+
/** The book's list, for a caller that wants the canon side alone. */
|
|
101
|
+
export declare const RESONANCE_ACTION_NAMES: string[];
|
|
102
|
+
/** Look one up by key. Used by the surfaces that render a single
|
|
103
|
+
* action's name and type rather than the whole table. */
|
|
104
|
+
export declare function resonanceAction(key: string): IResonanceAction | undefined;
|
|
105
|
+
/** The canon actions this game does NOT yet reach with any verb.
|
|
106
|
+
*
|
|
107
|
+
* The backlog item's actual question, answerable in code. */
|
|
108
|
+
export declare function unimplementedResonanceActions(): IResonanceAction[];
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SR5e RESONANCE ACTIONS (core p.250) -- the technomancer's own action
|
|
3
|
+
* list, and the Resonance-side counterpart to the Matrix actions every
|
|
4
|
+
* other decker shares.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS IS A TABLE AND NOT SEVEN STRINGS IN SEVEN FILES.
|
|
7
|
+
*
|
|
8
|
+
* Backlog item SoopwuTFBwayCGhM9 ("check page 250 for resonance
|
|
9
|
+
* actions, right now we have several missing") could only be ANSWERED
|
|
10
|
+
* by laying the book's list beside the game's verbs -- and once that
|
|
11
|
+
* comparison exists, leaving it in a commit message means the next
|
|
12
|
+
* person re-derives it. So the comparison lives here, in the `verb`
|
|
13
|
+
* field, where it is machine-checkable rather than remembered.
|
|
14
|
+
*
|
|
15
|
+
* The audit that produced it, in one line each:
|
|
16
|
+
* present -- Compile, Decompile, Register, Thread (already built)
|
|
17
|
+
* present -- COMMAND SPRITE, via the generic `order` verb. This one
|
|
18
|
+
* nearly got filed as missing: order.ts picks out of
|
|
19
|
+
* `game.companions` with no kind filter, so it has always
|
|
20
|
+
* reached sprites. A "missing" feature that already
|
|
21
|
+
* exists gets built twice and the second one wins quietly.
|
|
22
|
+
* built -- KILL COMPLEX FORM, added as `unravel` against this
|
|
23
|
+
* audit (see unravel.ts).
|
|
24
|
+
* built -- CALL/DISMISS SPRITE, added on `recall` by the
|
|
25
|
+
* sprite-lifecycle work, which imports `name` and
|
|
26
|
+
* `actionType` from here rather than restating them.
|
|
27
|
+
*
|
|
28
|
+
* ALL SEVEN NOW HAVE VERBS, so the audit's missing set is empty. That
|
|
29
|
+
* is the finished state, not an absent check -- see the note in
|
|
30
|
+
* resonance-actions.test.ts about what the tripwire proves once it
|
|
31
|
+
* empties, because an empty expectation is indistinguishable from one
|
|
32
|
+
* that never asserted anything.
|
|
33
|
+
*
|
|
34
|
+
* `verb` IS THE AUDIT, AND IT IS CHECKED: resonance-actions.test.ts
|
|
35
|
+
* asserts that every verb named here is really registered in game.ts.
|
|
36
|
+
* Write a verb that does not exist and the suite fails.
|
|
37
|
+
*
|
|
38
|
+
* WHAT IT DOES NOT CATCH, stated plainly because a comment claiming a
|
|
39
|
+
* guarantee the test does not give is worse than no comment: nothing
|
|
40
|
+
* detects "somebody implemented Kill Complex Form and forgot to fill in
|
|
41
|
+
* its verb". No property of a command's NAME proves which canon action
|
|
42
|
+
* it implements -- an early version of the test tried to guess one from
|
|
43
|
+
* the other and immediately produced a false positive (`call` is
|
|
44
|
+
* registered, as the PHONE command, nothing to do with sprites). What
|
|
45
|
+
* the suite does instead is pin the missing set exactly, so changing it
|
|
46
|
+
* is a conscious edit rather than a silent drift.
|
|
47
|
+
*
|
|
48
|
+
* CITATIONS ARE FIRST-CLASS. Every action type and Test line below was
|
|
49
|
+
* pinned individually against the rulebooks rather than read off one
|
|
50
|
+
* contents-page retrieval, because the failure mode this table exists
|
|
51
|
+
* to prevent is a plausible-sounding invented mechanic. Where canon
|
|
52
|
+
* could not be confirmed the field is LEFT EMPTY -- see `actionType`.
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* All seven, in the book's own alphabetical order (p.250).
|
|
56
|
+
*
|
|
57
|
+
* Kept in canon order rather than "implemented first" order so that
|
|
58
|
+
* comparing this against the page is a straight read down the column --
|
|
59
|
+
* which is exactly the check the backlog item asked for, and a check
|
|
60
|
+
* nobody will run again if it needs re-sorting first.
|
|
61
|
+
*/
|
|
62
|
+
export const RESONANCE_ACTIONS = [
|
|
63
|
+
{
|
|
64
|
+
key: 'call-dismiss-sprite',
|
|
65
|
+
name: 'Call/Dismiss Sprite',
|
|
66
|
+
actionType: 'Simple',
|
|
67
|
+
// Canon prints "Test: n/a" -- no roll, and no Fading either. That
|
|
68
|
+
// is what makes it a state transition rather than a gamble, and it
|
|
69
|
+
// is why the verb belongs with the registered-sprite store.
|
|
70
|
+
test: undefined,
|
|
71
|
+
effect: 'Call a registered sprite waiting in the Resonance (it arrives at the start of the next Combat Turn), or send one back -- releasing any tasks it still owes you.',
|
|
72
|
+
// OWNED BY backlog-session-2 (sprite lifecycle). Coordinator split
|
|
73
|
+
// this action deliberately: the verb and its state are theirs, the
|
|
74
|
+
// catalogue entry is this table's. They import `name` and
|
|
75
|
+
// `actionType` from here rather than writing a second copy that
|
|
76
|
+
// agrees today and drifts on the first edit.
|
|
77
|
+
//
|
|
78
|
+
// IMPLEMENTED on `recall`, not `call`: `call` is CallCommand, the
|
|
79
|
+
// phone, so claiming it would have cost a technomancer the ability
|
|
80
|
+
// to ring their fixer. `recall` already meant "bring my thing home
|
|
81
|
+
// to me" for drones and agents, and it was also LYING to
|
|
82
|
+
// technomancers -- "Nothing of yours is in the air" with a sprite
|
|
83
|
+
// standing there -- so one verb fixed the falsehood and the missing
|
|
84
|
+
// action together. Bare "recall" only CALLS; dismissing has to be
|
|
85
|
+
// asked for by name, because p.250 releases every task owed.
|
|
86
|
+
verb: 'recall',
|
|
87
|
+
page: 'p.250',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
key: 'command-sprite',
|
|
91
|
+
name: 'Command Sprite',
|
|
92
|
+
actionType: 'Simple',
|
|
93
|
+
test: undefined,
|
|
94
|
+
effect: 'Tell a sprite to do something for you, spending one of its tasks.',
|
|
95
|
+
// ALREADY IMPLEMENTED, and the reason this table has a `verb`
|
|
96
|
+
// column at all. `order <sprite> <command>` has always worked:
|
|
97
|
+
// OrderCommand selects from game.companions with no kind filter,
|
|
98
|
+
// and a sprite is a companion of kind 'sprite' (game.ts). Verified
|
|
99
|
+
// by test, not by reading.
|
|
100
|
+
verb: 'order',
|
|
101
|
+
page: 'p.250',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
key: 'compile-sprite',
|
|
105
|
+
name: 'Compile Sprite',
|
|
106
|
+
actionType: 'Complex',
|
|
107
|
+
test: 'Compiling + Resonance [Level] v. Sprite Level',
|
|
108
|
+
effect: 'Thread a sprite out of raw Resonance. Net hits become its tasks; Fading follows.',
|
|
109
|
+
verb: 'compile',
|
|
110
|
+
page: 'p.250',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: 'decompile-sprite',
|
|
114
|
+
name: 'Decompile Sprite',
|
|
115
|
+
actionType: 'Complex',
|
|
116
|
+
// DECOMPILING, a separate skill from Compiling (p.143). Recorded
|
|
117
|
+
// verbatim because the distinction is load-bearing and was being
|
|
118
|
+
// lost: the game rolled `compiling` for decompiling in one place,
|
|
119
|
+
// which backlog-session-2 is fixing against this citation.
|
|
120
|
+
test: 'Decompiling + Resonance [Level] v. Sprite Rating (+ compiler\'s Resonance)',
|
|
121
|
+
effect: 'Unravel a sprite thread by thread -- your own, or a hostile construct on the grid.',
|
|
122
|
+
verb: 'decompile',
|
|
123
|
+
page: 'p.250',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
key: 'kill-complex-form',
|
|
127
|
+
name: 'Kill Complex Form',
|
|
128
|
+
actionType: 'Complex',
|
|
129
|
+
test: 'Software + Resonance [Level] v. Complex Form Level + Resonance',
|
|
130
|
+
effect: 'End a complex form another technomancer is sustaining, without asking. Net hits eat the original threading hits; reach zero and it collapses. You resist Fading as though you had threaded it yourself.',
|
|
131
|
+
// BUILT (unravel.ts). The game already knew this hole was here:
|
|
132
|
+
// dispel.ts refuses counterspelling against Resonance with a
|
|
133
|
+
// deliberate, correct line ("What's woven around X isn't mana --
|
|
134
|
+
// it's RESONANCE"), naming a gap it had no route to fill. That
|
|
135
|
+
// refusal now points at a real verb.
|
|
136
|
+
//
|
|
137
|
+
// Reaches nothing in a SOLO game today -- not because the route is
|
|
138
|
+
// closed but because it is GATED. An NPC can reach ThreadCommand
|
|
139
|
+
// via `order` (NPC.runCommand parses the same registry), and is
|
|
140
|
+
// refused by its isTechnomancer() check. No NPC is a technomancer
|
|
141
|
+
// today, so none holds a form and a solo runner meets no weave to
|
|
142
|
+
// cut. Live on shared runs, and implemented against any form-holder
|
|
143
|
+
// so it comes alive through the existing path the day one exists.
|
|
144
|
+
// Recorded here because a verb whose target class is thin should
|
|
145
|
+
// say so somewhere durable -- and because "impossible" and "gated"
|
|
146
|
+
// imply very different costs for that feature. See unravel.ts for
|
|
147
|
+
// the full writer set, and for why a name-grep misses one of them.
|
|
148
|
+
verb: 'unravel',
|
|
149
|
+
page: 'p.250',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
key: 'register-sprite',
|
|
153
|
+
name: 'Register Sprite',
|
|
154
|
+
actionType: 'Complex',
|
|
155
|
+
test: 'Registering + Resonance [Level] v. Sprite Level x 2',
|
|
156
|
+
effect: 'Bind a compiled sprite permanently: it gains tasks, survives travel, and rides your save.',
|
|
157
|
+
verb: 'register',
|
|
158
|
+
page: 'p.250',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
key: 'thread-complex-form',
|
|
162
|
+
name: 'Thread Complex Form',
|
|
163
|
+
actionType: 'Complex',
|
|
164
|
+
// "v. special" is the book's own wording -- the opposition depends
|
|
165
|
+
// on the form being threaded. Left verbatim rather than expanded,
|
|
166
|
+
// because expanding it here would be inventing a number.
|
|
167
|
+
test: 'Software + Resonance [Level] v. special',
|
|
168
|
+
effect: 'Weave a complex form out of the Resonance, instant or sustained.',
|
|
169
|
+
verb: 'thread',
|
|
170
|
+
page: 'p.250',
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
/** The book's list, for a caller that wants the canon side alone. */
|
|
174
|
+
export const RESONANCE_ACTION_NAMES = RESONANCE_ACTIONS.map(a => a.name);
|
|
175
|
+
/** Look one up by key. Used by the surfaces that render a single
|
|
176
|
+
* action's name and type rather than the whole table. */
|
|
177
|
+
export function resonanceAction(key) {
|
|
178
|
+
return RESONANCE_ACTIONS.find(a => a.key === key);
|
|
179
|
+
}
|
|
180
|
+
/** The canon actions this game does NOT yet reach with any verb.
|
|
181
|
+
*
|
|
182
|
+
* The backlog item's actual question, answerable in code. */
|
|
183
|
+
export function unimplementedResonanceActions() {
|
|
184
|
+
return RESONANCE_ACTIONS.filter(a => !a.verb);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=resonance-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resonance-actions.js","sourceRoot":"","sources":["../../../../../../src/commands/game/sideQuest/resonance-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SR5e SPRITE POWERS (core p.256-257) and the sprite database's power
|
|
3
|
+
* assignments (p.259).
|
|
4
|
+
*
|
|
5
|
+
* Backlog item Sz7EmXnyRYK4RYqxt, in the reporter's words: "sprite
|
|
6
|
+
* actions should be listed some how, found on pages 256, 257 and 258,
|
|
7
|
+
* sprites have abilities unique to them that not even technomancers
|
|
8
|
+
* have." That last clause is the whole point of the feature -- a
|
|
9
|
+
* technomancer's own surface (`thread`, complex forms) says nothing
|
|
10
|
+
* about what the thing standing next to them can do, so the abilities
|
|
11
|
+
* that make each sprite type worth compiling are invisible at the exact
|
|
12
|
+
* moment you choose one.
|
|
13
|
+
*
|
|
14
|
+
* WHY A SEPARATE MODULE FROM compile.ts's SPRITE_TYPES. The obvious
|
|
15
|
+
* home is a `powers` field on ISpriteType, and it is the wrong one
|
|
16
|
+
* right now: compile.ts is the sprite LIFECYCLE surface, owned by
|
|
17
|
+
* another session mid-repair. Powers are catalogue. Keying this table
|
|
18
|
+
* by the same five keys costs one join and keeps the two edits from
|
|
19
|
+
* landing in one file. If the lifecycle work settles and someone wants
|
|
20
|
+
* them merged later, the join is the seam to delete.
|
|
21
|
+
*
|
|
22
|
+
* ALL NINE POWERS ARE CANON-CONFIRMED, each pinned by its own targeted
|
|
23
|
+
* query rather than read off a contents page -- the standing rule for
|
|
24
|
+
* this work being that a wrong power on a sprite is worse than a
|
|
25
|
+
* missing one. Nothing here is inferred, and nothing was left out for
|
|
26
|
+
* lack of a citation. Every one of the nine is assigned to at least one
|
|
27
|
+
* sprite type, and the five types' assignments account for all nine
|
|
28
|
+
* exactly once -- the book's own list closes.
|
|
29
|
+
*
|
|
30
|
+
* WHAT THIS IS NOT. These are REFERENCE, not mechanics: no power below
|
|
31
|
+
* is wired to a die roll in this engine yet, and `sprites.ts` says so
|
|
32
|
+
* on the panel rather than implying otherwise. Listing an ability the
|
|
33
|
+
* game cannot actually perform, without saying so, is the same defect
|
|
34
|
+
* as a refusal naming a route that does not exist -- the game has paid
|
|
35
|
+
* for that shape more than once. The listing answers "what is this
|
|
36
|
+
* thing FOR", which is what was asked; it does not promise a verb.
|
|
37
|
+
*/
|
|
38
|
+
export interface ISpritePower {
|
|
39
|
+
key: string;
|
|
40
|
+
/** The book's own name. */
|
|
41
|
+
name: string;
|
|
42
|
+
/** What it does, close to the book's wording but readable at a
|
|
43
|
+
* terminal -- this is a player-facing panel, not a rules quote. */
|
|
44
|
+
effect: string;
|
|
45
|
+
/** The book's Test line, where the power has one. `undefined` is
|
|
46
|
+
* canon saying "no roll" (Camouflage, Hash, Stability, Watermark are
|
|
47
|
+
* states the sprite maintains, not attacks it makes) -- NOT canon
|
|
48
|
+
* being unavailable. */
|
|
49
|
+
test?: string;
|
|
50
|
+
/** SR5e core page. */
|
|
51
|
+
page: string;
|
|
52
|
+
}
|
|
53
|
+
/** All nine, alphabetical as the book lists them (p.256). */
|
|
54
|
+
export declare const SPRITE_POWERS: ISpritePower[];
|
|
55
|
+
/**
|
|
56
|
+
* The sprite database's assignments (p.259), keyed to compile.ts's
|
|
57
|
+
* SPRITE_TYPES so the two join on the same five keys.
|
|
58
|
+
*
|
|
59
|
+
* Skills are the book's, listed because they explain the powers: a
|
|
60
|
+
* machine sprite has Hardware, which is what Diagnostics and Gremlins
|
|
61
|
+
* both roll. The pairing is the answer to "why would I compile this
|
|
62
|
+
* one", which is the question the item is really about.
|
|
63
|
+
*/
|
|
64
|
+
export interface ISpritePowerSet {
|
|
65
|
+
/** Matches a key in compile.ts's SPRITE_TYPES. */
|
|
66
|
+
spriteKey: string;
|
|
67
|
+
/** Keys into SPRITE_POWERS. */
|
|
68
|
+
powers: string[];
|
|
69
|
+
/** The book's skill list for the type. */
|
|
70
|
+
skills: string[];
|
|
71
|
+
page: string;
|
|
72
|
+
}
|
|
73
|
+
export declare const SPRITE_POWER_SETS: ISpritePowerSet[];
|
|
74
|
+
/** One power by key. */
|
|
75
|
+
export declare function spritePower(key: string): ISpritePower | undefined;
|
|
76
|
+
/** The powers a given sprite type has, resolved. Unknown type -> []. */
|
|
77
|
+
export declare function powersForSprite(spriteKey: string): ISpritePower[];
|
|
78
|
+
/** The skills the book gives a sprite type. Unknown type -> []. */
|
|
79
|
+
export declare function skillsForSprite(spriteKey: string): string[];
|
|
80
|
+
/**
|
|
81
|
+
* A single use of a sprite power costs one TASK (p.254). Sustaining one
|
|
82
|
+
* it has already started does not cost more -- unless you change it,
|
|
83
|
+
* such as switching targets.
|
|
84
|
+
*
|
|
85
|
+
* Lives here as the one line every surface that mentions a power needs
|
|
86
|
+
* beside it, so the cost is not re-stated (and re-worded) per panel.
|
|
87
|
+
*/
|
|
88
|
+
export declare const SPRITE_POWER_TASK_RULE = "Using a power costs one task. Sustaining one already running is free -- until you change it, such as switching targets (p.254).";
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SR5e SPRITE POWERS (core p.256-257) and the sprite database's power
|
|
3
|
+
* assignments (p.259).
|
|
4
|
+
*
|
|
5
|
+
* Backlog item Sz7EmXnyRYK4RYqxt, in the reporter's words: "sprite
|
|
6
|
+
* actions should be listed some how, found on pages 256, 257 and 258,
|
|
7
|
+
* sprites have abilities unique to them that not even technomancers
|
|
8
|
+
* have." That last clause is the whole point of the feature -- a
|
|
9
|
+
* technomancer's own surface (`thread`, complex forms) says nothing
|
|
10
|
+
* about what the thing standing next to them can do, so the abilities
|
|
11
|
+
* that make each sprite type worth compiling are invisible at the exact
|
|
12
|
+
* moment you choose one.
|
|
13
|
+
*
|
|
14
|
+
* WHY A SEPARATE MODULE FROM compile.ts's SPRITE_TYPES. The obvious
|
|
15
|
+
* home is a `powers` field on ISpriteType, and it is the wrong one
|
|
16
|
+
* right now: compile.ts is the sprite LIFECYCLE surface, owned by
|
|
17
|
+
* another session mid-repair. Powers are catalogue. Keying this table
|
|
18
|
+
* by the same five keys costs one join and keeps the two edits from
|
|
19
|
+
* landing in one file. If the lifecycle work settles and someone wants
|
|
20
|
+
* them merged later, the join is the seam to delete.
|
|
21
|
+
*
|
|
22
|
+
* ALL NINE POWERS ARE CANON-CONFIRMED, each pinned by its own targeted
|
|
23
|
+
* query rather than read off a contents page -- the standing rule for
|
|
24
|
+
* this work being that a wrong power on a sprite is worse than a
|
|
25
|
+
* missing one. Nothing here is inferred, and nothing was left out for
|
|
26
|
+
* lack of a citation. Every one of the nine is assigned to at least one
|
|
27
|
+
* sprite type, and the five types' assignments account for all nine
|
|
28
|
+
* exactly once -- the book's own list closes.
|
|
29
|
+
*
|
|
30
|
+
* WHAT THIS IS NOT. These are REFERENCE, not mechanics: no power below
|
|
31
|
+
* is wired to a die roll in this engine yet, and `sprites.ts` says so
|
|
32
|
+
* on the panel rather than implying otherwise. Listing an ability the
|
|
33
|
+
* game cannot actually perform, without saying so, is the same defect
|
|
34
|
+
* as a refusal naming a route that does not exist -- the game has paid
|
|
35
|
+
* for that shape more than once. The listing answers "what is this
|
|
36
|
+
* thing FOR", which is what was asked; it does not promise a verb.
|
|
37
|
+
*/
|
|
38
|
+
/** All nine, alphabetical as the book lists them (p.256). */
|
|
39
|
+
export const SPRITE_POWERS = [
|
|
40
|
+
{
|
|
41
|
+
key: 'camouflage',
|
|
42
|
+
name: 'Camouflage',
|
|
43
|
+
effect: 'Hides a file inside another file, invisible to Matrix searches. Only a Matrix Perception Test specifically hunting the hidden file will turn it up -- and the sprite has to make that test too, to get its own file back out.',
|
|
44
|
+
test: undefined,
|
|
45
|
+
page: 'p.256',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
key: 'cookie',
|
|
49
|
+
name: 'Cookie',
|
|
50
|
+
effect: 'Tags a persona with a silent tracking file rated at the sprite\'s Level. It logs every host entered, every program used, and who was talked to and when (not what was said). Net hits set the depth: one hit is a bare outline, four or more a detailed report. At a time set when it was placed the file ships itself back to the sprite -- and deletes itself instead if the sprite has left the Matrix. A Matrix Perception Test on the carrier finds it; unprotecting it and deleting it removes it.',
|
|
51
|
+
test: 'Hacking + Resonance [Sleaze] v. Intuition + Firewall',
|
|
52
|
+
page: 'p.256-257',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
key: 'diagnostics',
|
|
56
|
+
name: 'Diagnostics',
|
|
57
|
+
effect: 'Reads a device down to its seams and helps somebody use or repair it, as a Teamwork Test. Any hits give +1 limit, and each hit adds a die to their pool. It takes the sprite\'s whole attention -- the bonus lasts until it drops the power or does anything else.',
|
|
58
|
+
test: 'Simple Hardware + Level [Data Processing]',
|
|
59
|
+
page: 'p.257',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
key: 'electron-storm',
|
|
63
|
+
name: 'Electron Storm',
|
|
64
|
+
effect: 'Engulfs a persona in a sustained barrage of corrupting datastreams. On the first hit and on every action the sprite spends sustaining it, the target takes (Resonance) DV Matrix damage, resisted as normal, plus 2 points of noise. If the sprite takes any Matrix damage of its own, every storm it is sustaining ends at once.',
|
|
65
|
+
test: 'Cybercombat + Resonance [Attack] v. Intuition + Firewall',
|
|
66
|
+
page: 'p.257',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
key: 'gremlins',
|
|
70
|
+
name: 'Gremlins',
|
|
71
|
+
effect: 'Makes a device misbehave -- a jammed control, a looped signal, a faulty reading. Success is a glitch; four or more net hits is a critical one, and the device crashes, burns out, or bites its user.',
|
|
72
|
+
test: 'Hardware + Level [Attack] v. Device Rating + Firewall',
|
|
73
|
+
page: 'p.257',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: 'hash',
|
|
77
|
+
name: 'Hash',
|
|
78
|
+
effect: 'Seals a file with a Resonance algorithm only that sprite can undo, for up to (Level x 10) Combat Turns. Put the file down and it reverts to normal. Destroy the sprite while it still carries the file and the file is corrupted for good.',
|
|
79
|
+
test: undefined,
|
|
80
|
+
page: 'p.257',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
key: 'stability',
|
|
84
|
+
name: 'Stability',
|
|
85
|
+
effect: 'Steadies any persona or device the sprite holds a mark on: standard glitches are ignored outright and critical glitches drop to standard. It stops induced accidents too, Gremlins included -- which is why a machine sprite can both cause and prevent them.',
|
|
86
|
+
test: undefined,
|
|
87
|
+
page: 'p.257',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
key: 'suppression',
|
|
91
|
+
name: 'Suppression',
|
|
92
|
+
effect: 'Baffles a host into hesitating. A sprite using this inside a host delays any IC it launches by (Level / 2) Combat Turns, and delayed IC can neither act nor be targeted.',
|
|
93
|
+
test: undefined,
|
|
94
|
+
page: 'p.257',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: 'watermark',
|
|
98
|
+
name: 'Watermark',
|
|
99
|
+
effect: 'Marks an icon invisibly, readable only by Resonance-driven things -- a way to leave messages on Matrix objects that nobody else can see. A new watermark overwrites an old one, and it lasts as long as the icon does unless somebody erases the Matrix signature.',
|
|
100
|
+
test: undefined,
|
|
101
|
+
page: 'p.257',
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
export const SPRITE_POWER_SETS = [
|
|
105
|
+
{ spriteKey: 'courier', powers: ['cookie', 'hash'], skills: ['Computer', 'Hacking'], page: 'p.259' },
|
|
106
|
+
{ spriteKey: 'crack', powers: ['suppression'], skills: ['Computer', 'Electronic Warfare', 'Hacking'], page: 'p.259' },
|
|
107
|
+
{ spriteKey: 'data', powers: ['camouflage', 'watermark'], skills: ['Computer', 'Electronic Warfare'], page: 'p.259' },
|
|
108
|
+
{ spriteKey: 'fault', powers: ['electron-storm'], skills: ['Computer', 'Cybercombat', 'Hacking'], page: 'p.259' },
|
|
109
|
+
{ spriteKey: 'machine', powers: ['diagnostics', 'gremlins', 'stability'], skills: ['Computer', 'Electronic Warfare', 'Hardware'], page: 'p.259' },
|
|
110
|
+
];
|
|
111
|
+
/** One power by key. */
|
|
112
|
+
export function spritePower(key) {
|
|
113
|
+
return SPRITE_POWERS.find(p => p.key === key);
|
|
114
|
+
}
|
|
115
|
+
/** The powers a given sprite type has, resolved. Unknown type -> []. */
|
|
116
|
+
export function powersForSprite(spriteKey) {
|
|
117
|
+
const set = SPRITE_POWER_SETS.find(s => s.spriteKey === spriteKey);
|
|
118
|
+
if (!set)
|
|
119
|
+
return [];
|
|
120
|
+
// Resolved through spritePower() rather than trusted: a key naming no
|
|
121
|
+
// power would otherwise render as a silent gap in the panel.
|
|
122
|
+
return set.powers.map(k => spritePower(k)).filter((p) => !!p);
|
|
123
|
+
}
|
|
124
|
+
/** The skills the book gives a sprite type. Unknown type -> []. */
|
|
125
|
+
export function skillsForSprite(spriteKey) {
|
|
126
|
+
return SPRITE_POWER_SETS.find(s => s.spriteKey === spriteKey)?.skills ?? [];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A single use of a sprite power costs one TASK (p.254). Sustaining one
|
|
130
|
+
* it has already started does not cost more -- unless you change it,
|
|
131
|
+
* such as switching targets.
|
|
132
|
+
*
|
|
133
|
+
* Lives here as the one line every surface that mentions a power needs
|
|
134
|
+
* beside it, so the cost is not re-stated (and re-worded) per panel.
|
|
135
|
+
*/
|
|
136
|
+
export const SPRITE_POWER_TASK_RULE = 'Using a power costs one task. Sustaining one already running is free -- until you change it, such as switching targets (p.254).';
|
|
137
|
+
//# sourceMappingURL=sprite-powers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sprite-powers.js","sourceRoot":"","sources":["../../../../../../src/commands/game/sideQuest/sprite-powers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Direction } from './shared/direction-enum.js';
|
|
2
|
+
import { DeviceSeedKind } from './seed/device-seed.js';
|
|
3
|
+
/**
|
|
4
|
+
* A REPRO FIXTURE -- the bench a review item ships with itself.
|
|
5
|
+
*
|
|
6
|
+
* The problem this exists for, in the reporter's words: "Many backlog
|
|
7
|
+
* items are found during a run, so reproducing them for testing is
|
|
8
|
+
* difficult... I'm trying to review the item fixed by commit 359ad1fe.
|
|
9
|
+
* But I can't get to a barrier like a lock or ward."
|
|
10
|
+
*
|
|
11
|
+
* That is exactly true, and not a discoverability problem -- the static
|
|
12
|
+
* scenes carry no devices at all, so there is nowhere in the shipped
|
|
13
|
+
* game to go and stand in front of a maglock. Every fix that touches a
|
|
14
|
+
* barrier has been unconfirmable for the same reason.
|
|
15
|
+
*
|
|
16
|
+
* WHY A SPEC AND NOT A SCENE. The obvious answer is to grow one scene a
|
|
17
|
+
* fixture per item, and the reporter rejected it: the fixtures pile up
|
|
18
|
+
* forever, in a scene that doubles as the generation-failure fallback
|
|
19
|
+
* for ordinary players, inside the shipped binary and in git for good.
|
|
20
|
+
* So each item carries a ~20-line spec instead, and the client builds a
|
|
21
|
+
* two-room bench from it on demand. Nothing accumulates anywhere.
|
|
22
|
+
*
|
|
23
|
+
* WHY INTENT AND NOT STRUCTURE. Everything here says what the bench is
|
|
24
|
+
* FOR, never how to wire it. `atDoorway: true` is a statement about the
|
|
25
|
+
* fiction; deriving the spot name it implies is the builder's job, and
|
|
26
|
+
* that division is the whole design (see factories/repro-scene.ts).
|
|
27
|
+
* Hand-authored seed JSON can be subtly wrong in the way this codebase
|
|
28
|
+
* keeps shipping -- a check whose two sides fail together cannot see
|
|
29
|
+
* the failure -- and a repro that quietly proves the opposite of what
|
|
30
|
+
* it claims is worse than no repro at all.
|
|
31
|
+
*/
|
|
32
|
+
/** Which side of the sealed door something stands on. The BARRIER side
|
|
33
|
+
* is the room the device is in and the room that declares the exit it
|
|
34
|
+
* seals; the FAR side is through the door. */
|
|
35
|
+
export type ReproSide = 'barrier' | 'far';
|
|
36
|
+
export interface IReproBarrier {
|
|
37
|
+
kind: DeviceSeedKind;
|
|
38
|
+
/** Defaults per kind -- Maglock, Keypad, Chalk Ward. */
|
|
39
|
+
name?: string;
|
|
40
|
+
/** The credential it answers to. PANEL ONLY, and the builder refuses
|
|
41
|
+
* it elsewhere rather than dropping it: "if it's a _mechanical_ lock,
|
|
42
|
+
* it has a key or can be picked. You can't talk at a _mechanical_
|
|
43
|
+
* lock." A code that silently does nothing is a repro that proves
|
|
44
|
+
* nothing. */
|
|
45
|
+
code?: string;
|
|
46
|
+
/** An item that opens it outright. Placed on the runner's own side. */
|
|
47
|
+
keyItem?: string;
|
|
48
|
+
/** Start it ALREADY OPEN. Not a curiosity -- an NPC's brief has to be
|
|
49
|
+
* right about an opened barrier too, and getting that wrong is a
|
|
50
|
+
* live item on the board. */
|
|
51
|
+
open?: boolean;
|
|
52
|
+
/** The exit it seals. Defaults to north. */
|
|
53
|
+
sealsExit?: Direction;
|
|
54
|
+
}
|
|
55
|
+
export interface IReproNpc {
|
|
56
|
+
name: string;
|
|
57
|
+
/** What they are, in a sentence. Becomes the description AND the AI
|
|
58
|
+
* brief, so an NPC in a repro is briefed the way a real one is --
|
|
59
|
+
* which matters, because half these items are about what an NPC
|
|
60
|
+
* believes about a door. */
|
|
61
|
+
concept: string;
|
|
62
|
+
side?: ReproSide;
|
|
63
|
+
/** Standing IN the sealed doorway. */
|
|
64
|
+
atDoorway?: boolean;
|
|
65
|
+
/** Holding it shut: a doorman, a picket. Implies atDoorway, because a
|
|
66
|
+
* guard who is not in the doorway guards nothing. */
|
|
67
|
+
guarding?: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface IReproItem {
|
|
70
|
+
name: string;
|
|
71
|
+
description: string;
|
|
72
|
+
/** The long read, for a clue that carries a code. */
|
|
73
|
+
details?: string;
|
|
74
|
+
side?: ReproSide;
|
|
75
|
+
}
|
|
76
|
+
export interface IReproFixture {
|
|
77
|
+
/** Plain-English framing, printed above the steps. */
|
|
78
|
+
premise?: string;
|
|
79
|
+
/** Names an ARCHETYPES entry and decides the pregen. Defaults to
|
|
80
|
+
* Covert Ops, which carries the Lockpick Set and locksmith 5 -- so a
|
|
81
|
+
* lock repro works without anyone having to think about it. */
|
|
82
|
+
archetype?: string;
|
|
83
|
+
/** Omitted for a repro that needs a scene and no obstacle. */
|
|
84
|
+
barrier?: IReproBarrier;
|
|
85
|
+
npcs?: IReproNpc[];
|
|
86
|
+
items?: IReproItem[];
|
|
87
|
+
/** Which side the runner starts on. Defaults to the barrier side. */
|
|
88
|
+
start?: ReproSide;
|
|
89
|
+
}
|
|
90
|
+
export interface IRepro {
|
|
91
|
+
fixture?: IReproFixture;
|
|
92
|
+
/** Framing for the READER, printed above the steps.
|
|
93
|
+
*
|
|
94
|
+
* Lives here and not only on the fixture because a repro can have no
|
|
95
|
+
* fixture at all -- some items are about a verb or a menu -- and the
|
|
96
|
+
* one line explaining what you are looking at should not depend on
|
|
97
|
+
* there being a scene. When a fixture has none of its own, this
|
|
98
|
+
* becomes the bench's story too. */
|
|
99
|
+
premise?: string;
|
|
100
|
+
/** The literal commands to type, in order -- and the same strings the
|
|
101
|
+
* walkthrough test replays. Steps that only a human can read are
|
|
102
|
+
* steps that rot. */
|
|
103
|
+
steps: string[];
|
|
104
|
+
/** What passing looks like. */
|
|
105
|
+
expect?: string;
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repro.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/types/repro.ts"],"names":[],"mappings":""}
|