@maka/maka-cli 5.380.3 → 5.381.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.380.3",
3
+ "version": "5.381.0",
4
4
  "type": "module",
5
5
  "summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
6
6
  "description": "A command line tool for scaffolding Meteor 3.x applications using React.",
@@ -1,5 +1,6 @@
1
1
  import { Command } from './command.js';
2
2
  import { BULLET } from '../utilities/log-style.js';
3
+ import { reputationWarning, NOTORIETY_GAME_OVER, AWARENESS_GAME_OVER } from '../utilities/reputation-ending.js';
3
4
  /**
4
5
  * THE LEDGER BEHIND THE THREE NUMBERS (uEQtkJczFtDE7r3Gn: "I'd like a way
5
6
  * to view the ledger or my 3 stats for cred, notoriety, and awareness").
@@ -49,7 +50,10 @@ export class RepCommand extends Command {
49
50
  static description = 'Your reputation, itemised (SR5 p.368): Street Cred and the career karma behind it, every stain on your Notoriety, and what put your face on the feeds. The same three numbers the sheet shows, with the reasons.';
50
51
  async execute() {
51
52
  const a = this.actor;
52
- return ['REPUTATION (p.368)', ...credSection(a), ...notorietySection(a), ...awarenessSection(a)].join('\n');
53
+ const warning = reputationWarning(a);
54
+ return ['REPUTATION (p.368)', ...credSection(a), ...notorietySection(a), ...awarenessSection(a),
55
+ ` Notoriety ${NOTORIETY_GAME_OVER} or Public Awareness ${AWARENESS_GAME_OVER} ends a career (house rule).`,
56
+ ...(warning ? [` ${warning}`] : [])].join('\n');
53
57
  }
54
58
  }
55
59
  //# sourceMappingURL=rep.js.map
@@ -3290,5 +3290,18 @@
3290
3290
  // the meet (give and upload cargo), the job-item prompt line, give,
3291
3291
  // drop, store, sell, keys (lock/unlock/use), the gig check and climbing
3292
3292
  // gear now see what is held or worn.
3293
- export const ENGINE_VERSION = '1.192.3';
3293
+ // 1.193.0 (2026-10-04): NOTORIETY OR PUBLIC AWARENESS AT 5 IS GAME OVER
3294
+ // (rfJGmF42kdnRw5AMT; user ruling, a HOUSE RULE -- SR5 sets no such
3295
+ // number, p.368 / Run Faster p.202).
3296
+ // - Read after every landed command for every standing human
3297
+ // (Game.settleReputationEndings): permadeath by the astral cord's road
3298
+ // -- the primary's save burns, a rider's goes to onPlayerDeath. No
3299
+ // brink, no DocWagon: neither fixes a name.
3300
+ // - "rep" names the line and warns one step short of it.
3301
+ // - Chargen refuses a build whose qualities start it at Notoriety 5.
3302
+ // - p.368's quality lists are counted whole: Addiction (once, any
3303
+ // severity), Gremlins, Scorched, Uncouth, Uneducated and Weak Immune
3304
+ // System add one, Blandness takes one off. Elf Poser, Ork Poser and
3305
+ // Spirit Bane have no catalog row yet.
3306
+ export const ENGINE_VERSION = '1.193.0';
3294
3307
  //# sourceMappingURL=engine-version.js.map
@@ -18,6 +18,7 @@ import { canonicalLifestyleTier, LIFESTYLE_TIERS, canonicalLifestyleOption, life
18
18
  import { SAVE_VERSION } from '../types/save-file.js';
19
19
  import { hubSeedRefOf } from '../utilities/hub-seed.js';
20
20
  import { DOCWAGON_TIERS, canonicalDocwagonTier, sealWristband, newContract } from '../utilities/docwagon.js';
21
+ import { reputationEnding, NOTORIETY_GAME_OVER } from '../utilities/reputation-ending.js';
21
22
  /**
22
23
  * THE ENGINE-SIDE CHARACTER FACTORY -- one payload in, one bootable save
23
24
  * out, so the maka-cli.com web generator and the CLI cannot produce
@@ -426,6 +427,13 @@ export function buildFromChargen(payload) {
426
427
  }
427
428
  player.addQuality(key, payload.qualityRatings?.[q.key] ?? payload.qualityRatings?.[key]);
428
429
  }
430
+ // BORN ON THE LINE (utilities/reputation-ending.ts): Bad Rep's 3 and
431
+ // p.368's quality stains can reach 5 at creation, and the first landed
432
+ // command would end the career. Refused here, where every build lands,
433
+ // rather than handed a runner who is over before they start.
434
+ if (reputationEnding(player)) {
435
+ throw new ChargenPayloadError(`Those qualities start this runner at Notoriety ${player.notoriety} -- ${NOTORIETY_GAME_OVER} ends a career. Drop a negative one (p.368's list, or Bad Rep).`);
436
+ }
429
437
  // ---- THE PICK, applied (2026-09-04). Without this the whole `choice`
430
438
  // contract stopped at the row: the shape was declared, the resolver
431
439
  // could read it, and nothing on any path ever put an answer in.
@@ -8,6 +8,8 @@ import { hostLabel } from './utilities/grid-names.js';
8
8
  import { marksPlaced, marksOnYou } from './utilities/marks.js';
9
9
  import { settleUnresolvedHarm } from './utilities/harm-settlement.js';
10
10
  import { answerBrink } from './utilities/not-dead-yet.js';
11
+ import { reputationEnding } from './utilities/reputation-ending.js';
12
+ import { announceGameOver } from './utilities/game-over.js';
11
13
  import { settleNanoware } from './utilities/implant-matrix.js';
12
14
  import { hostInteriorPanel } from './utilities/grid-view.js';
13
15
  import { DEFAULT_GRID_PROVIDER, PUBLIC_GRID, globalGrid } from './utilities/grids.js';
@@ -9857,8 +9859,45 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
9857
9859
  // After the command has fully landed, so the game master judges the
9858
9860
  // world the table is actually looking at.
9859
9861
  this.gameMaster?.afterCommand();
9862
+ // A quit (null) has already sealed the save; nothing ends after it.
9863
+ if (res.text !== null)
9864
+ this.settleReputationEndings();
9860
9865
  return res;
9861
9866
  }
9867
+ /**
9868
+ * NOTORIETY OR PUBLIC AWARENESS AT 5 IS GAME OVER (utilities/
9869
+ * reputation-ending.ts, user ruling 2026-10-04). Every standing human
9870
+ * at the table is read after every landed command, so a stain from any
9871
+ * source -- an incident, the tab's debt roll, a quality trade, earned
9872
+ * cred lifting awareness -- ends the career on the beat it lands.
9873
+ * Permadeath, by the same road the astral cord takes (planes.ts): the
9874
+ * primary's death runs Scene.endGame (the save burns, or the host
9875
+ * takes it in a crew space); a rider's goes to onPlayerDeath while
9876
+ * the run goes on. Not a body on the floor, so no brink and no
9877
+ * DocWagon -- neither one fixes a name.
9878
+ */
9879
+ settleReputationEndings() {
9880
+ const scene = this.scene;
9881
+ if (!scene)
9882
+ return;
9883
+ for (const p of scene.getPlayers()) {
9884
+ if (scene.deadPlayers.has(p.name))
9885
+ continue;
9886
+ const line = reputationEnding(p);
9887
+ if (!line)
9888
+ continue;
9889
+ Logger.getInstance().write(`Reputation game over: ${p.name} (Notoriety ${p.notoriety}, Public Awareness ${p.publicAwareness}).`);
9890
+ scene.addWorldEvent(`${p.name}'s reputation ended their career.`);
9891
+ scene.markPlayerDead(p);
9892
+ if (p === scene.getPlayer()) {
9893
+ void scene.endGame(line).then(() => announceGameOver(Logger.getInstance(), line, p.name));
9894
+ }
9895
+ else {
9896
+ this.onPlayerDeath?.(p);
9897
+ announceGameOver(Logger.getInstance(), line, p.name);
9898
+ }
9899
+ }
9900
+ }
9862
9901
  async runInputAs(actorName, input) {
9863
9902
  const actor = this.scene.getPlayerByName(actorName);
9864
9903
  if (!actor) {
@@ -2878,10 +2878,16 @@ export class Player extends AbstractPlayer {
2878
2878
  }
2879
2879
  /** The p.368 quality list, restricted to the qualities this game ships. */
2880
2880
  get qualityNotoriety() {
2881
- const plus = ['bad-luck', 'combat-paralysis', 'sinner-criminal']
2881
+ // p.368's lists, verbatim and whole (2026-10-04: the engine counted
2882
+ // four of thirteen negatives and two of three positives). Elf Poser,
2883
+ // Ork Poser and Spirit Bane are on the book's list but have no
2884
+ // catalog row, so nobody can hold them yet. Addiction is one entry
2885
+ // whatever its severity row -- one point, not one per row.
2886
+ const plus = ['bad-luck', 'combat-paralysis', 'sinner-criminal', 'incompetent', 'gremlins',
2887
+ 'scorched', 'uncouth', 'uneducated', 'weak-immune-system']
2882
2888
  .filter(k => this.qualities.has(k)).length
2883
- + (this.qualities.has('incompetent') ? 1 : 0);
2884
- const minus = ['first-impression', 'lucky'].filter(k => this.qualities.has(k)).length;
2889
+ + ([...this.qualities.keys()].some(k => k.startsWith('addiction')) ? 1 : 0);
2890
+ const minus = ['blandness', 'first-impression', 'lucky'].filter(k => this.qualities.has(k)).length;
2885
2891
  // BAD REP CARRIES ITS OWN NUMBER (p.79): "starts play with 3 points
2886
2892
  // of Notoriety" -- not one entry on p.368's list, which is why it is
2887
2893
  // added here rather than pushed into `plus`. The quality does not
@@ -0,0 +1,39 @@
1
+ /**
2
+ * THE NAME THAT ENDS A CAREER (user ruling 2026-10-04, rfJGmF42kdnRw5AMT:
3
+ * "If either gets to 5, it's game over").
4
+ *
5
+ * A HOUSE RULE, AND SAID SO. SR5 gives no Notoriety or Public Awareness
6
+ * score at which a career ends: p.368 only says high Notoriety makes
7
+ * work "increasingly difficult as contacts and others become less
8
+ * willing to help", and Run Faster p.202 reserves "it's all over for
9
+ * you" for killing a Johnson who paid you -- an act, not a number. The
10
+ * number is the table's ruling; the fiction below borrows the book's
11
+ * two reasons a runner stops being hireable: nobody will work with the
12
+ * name, or everybody knows the face.
13
+ *
14
+ * Read once per landed command (Game.settleReputationEndings), not at
15
+ * each of the places that raise either score -- incidents, the tab's
16
+ * debt roll, quality trades and earned cred all move them, and a check
17
+ * at each would be the family swept one site at a time.
18
+ */
19
+ export const NOTORIETY_GAME_OVER = 5;
20
+ export const AWARENESS_GAME_OVER = 5;
21
+ /** The GAME OVER banner when this runner's reputation has ended them, else undefined. */
22
+ export function reputationEnding(p) {
23
+ if (p.notoriety >= NOTORIETY_GAME_OVER) {
24
+ return `💀 GAME OVER: ${p.name}'s name is poison -- Notoriety ${p.notoriety}. No fixer takes the call and no Johnson sits down across from them. The career is over.`;
25
+ }
26
+ if (p.publicAwareness >= AWARENESS_GAME_OVER) {
27
+ return `💀 GAME OVER: ${p.name}'s face is on every feed -- Public Awareness ${p.publicAwareness}. A runner the whole city knows is no use in the shadows. The career is over.`;
28
+ }
29
+ return undefined;
30
+ }
31
+ /** The line `rep` and the sheet show under a score that is one step from the end. */
32
+ export function reputationWarning(p) {
33
+ if (p.notoriety === NOTORIETY_GAME_OVER - 1)
34
+ return `One more stain and the name is finished (Notoriety ${NOTORIETY_GAME_OVER} ends a career).`;
35
+ if (p.publicAwareness === AWARENESS_GAME_OVER - 1)
36
+ return `One more headline and the face is finished (Public Awareness ${AWARENESS_GAME_OVER} ends a career).`;
37
+ return undefined;
38
+ }
39
+ //# sourceMappingURL=reputation-ending.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.380.3",
3
+ "version": "5.381.0",
4
4
  "type": "module",
5
5
  "summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
6
6
  "description": "A command line tool for scaffolding Meteor 3.x applications using React.",