@maka/maka-cli 5.9.0 → 5.10.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/sideQuest/commands/rest.js +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +23 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.js +160 -3
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +17 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +32 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +208 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.js +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +48 -4
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.d.ts +50 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.js +232 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.d.ts +71 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +447 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +174 -18
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 2.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 2.x applications using React.",
|
|
@@ -102,6 +102,11 @@ export class RestCommand extends Command {
|
|
|
102
102
|
: hint(` (Rest again to keep recovering.)`));
|
|
103
103
|
this.actor.performAction('rests', '');
|
|
104
104
|
this.scene.updateStatus();
|
|
105
|
+
// A rest is a safe beat -- autosave (player ruling). requestSave's
|
|
106
|
+
// own guards keep mid-run and NPC rests from writing anything.
|
|
107
|
+
if (this.game && this.actor === this.scene.getPlayer()) {
|
|
108
|
+
this.game.requestSave('rest');
|
|
109
|
+
}
|
|
105
110
|
return lines.join('\n');
|
|
106
111
|
}
|
|
107
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/rest.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/rest.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import blessed from 'blessed';
|
|
|
2
2
|
import { ISceneSeedJson } from './types/seed/scene-seed.js';
|
|
3
3
|
import { Item } from './models/item.js';
|
|
4
4
|
import { Player, Inventory, Room, Scene } from './models/_index.js';
|
|
5
|
+
import { ISaveFileV1, SaveReason } from './types/save-file.js';
|
|
5
6
|
import { ILifestyleTier } from './utilities/commerce.js';
|
|
6
7
|
import { NPC } from './models/npc.js';
|
|
7
8
|
import { AutoFight } from './utilities/auto-fight.js';
|
|
@@ -60,6 +61,10 @@ export default class Game {
|
|
|
60
61
|
boundDevice?: Item;
|
|
61
62
|
}[];
|
|
62
63
|
private _pendingRedeploys;
|
|
64
|
+
private _saveFilePath?;
|
|
65
|
+
private _dead;
|
|
66
|
+
private _resume?;
|
|
67
|
+
private _hubSeed?;
|
|
63
68
|
/**
|
|
64
69
|
* The one correct runtime NPC spawn (mirrors scene-factory's seed
|
|
65
70
|
* path): construct with a scene-bound registry, add to the scene
|
|
@@ -230,6 +235,23 @@ export default class Game {
|
|
|
230
235
|
get metaBox(): blessed.Widgets.BoxElement;
|
|
231
236
|
get inputBox(): blessed.Widgets.TextboxElement;
|
|
232
237
|
init(options: IMainGameConfig, screen: blessed.Widgets.Screen): Promise<string>;
|
|
238
|
+
/**
|
|
239
|
+
* Everything a save restores beyond the seed synthesis: the player,
|
|
240
|
+
* the hub world overlay, and the Game-level ledgers. Ordering inside
|
|
241
|
+
* matters less than its POSITION in init(): after seedHomeTurfContacts
|
|
242
|
+
* and snapshotVendorStock (both deliberately pre-overlay).
|
|
243
|
+
*/
|
|
244
|
+
private applyResumeState;
|
|
245
|
+
/**
|
|
246
|
+
* THE single save routine -- every safe beat funnels here. Guards make
|
|
247
|
+
* it a silent no-op anywhere a save would lie: mid-run (the "runs are
|
|
248
|
+
* disposable" ruling lives in the scene === _hubScene check), downed
|
|
249
|
+
* or KO'd, mid-exchange, dead, or before init finishes. Synchronous by
|
|
250
|
+
* design so the process-exit quit hook can use it; failures log and
|
|
251
|
+
* never crash a turn.
|
|
252
|
+
*/
|
|
253
|
+
requestSave(reason: SaveReason): void;
|
|
254
|
+
private buildSaveFile;
|
|
233
255
|
/**
|
|
234
256
|
* Synchronous readiness check for continueToNextScene() -- lets callers
|
|
235
257
|
* give instant feedback for the "not ready yet" cases (job not done, no
|
|
@@ -352,7 +374,7 @@ export default class Game {
|
|
|
352
374
|
updateEquipment(_playerEquipment: PlayerEquipment): void;
|
|
353
375
|
updateExits(_room: Room): void;
|
|
354
376
|
updateInventory(_playerInventory: Inventory, _currencyName?: string): void;
|
|
355
|
-
static getInstance(player: Player, sceneSeed: ISceneSeedJson): Promise<Game>;
|
|
377
|
+
static getInstance(player: Player, sceneSeed: ISceneSeedJson, resume?: ISaveFileV1): Promise<Game>;
|
|
356
378
|
handleInput(input: string): Promise<string | null>;
|
|
357
379
|
/**
|
|
358
380
|
* The help taxonomy: every entry is [primary, ...aliases], grouped the
|
|
@@ -4,6 +4,9 @@ import { Category } from './types/shared/item-enum.js';
|
|
|
4
4
|
import { Item } from './models/item.js';
|
|
5
5
|
import { Room } from './models/_index.js';
|
|
6
6
|
import { Door } from './models/door.js';
|
|
7
|
+
import { SAVE_VERSION } from './types/save-file.js';
|
|
8
|
+
import { serializePlayer, restorePlayer, captureHubOverlay, applyHubOverlay, writeSaveAtomic, deleteSave, } from './utilities/persistence.js';
|
|
9
|
+
import { pushSave, burnCloudSaveFor } from './utilities/cloud-saves.js';
|
|
7
10
|
import { isFence, LIFESTYLE_TIERS } from './utilities/commerce.js';
|
|
8
11
|
import { rollPool, formatRoll } from './utilities/dice.js';
|
|
9
12
|
import { Direction } from './types/shared/direction-enum.js';
|
|
@@ -198,6 +201,13 @@ export default class Game {
|
|
|
198
201
|
// Drones deployed at travel time re-shell on arrival ("the rotors spin
|
|
199
202
|
// back up at the curb") -- tracked as their items across the swap.
|
|
200
203
|
_pendingRedeploys = [];
|
|
204
|
+
// ---------------- PERSISTENCE (see utilities/persistence.ts) ----------
|
|
205
|
+
// Character + hub world survive the process (player rulings): autosave
|
|
206
|
+
// at safe beats only, one slot per character, PERMADEATH on real death.
|
|
207
|
+
_saveFilePath; // from options.saveFilePath; unset = never save
|
|
208
|
+
_dead = false; // set in close(); suppresses any later save
|
|
209
|
+
_resume; // present when this session continues a save
|
|
210
|
+
_hubSeed; // the seed embedded into every save
|
|
201
211
|
/**
|
|
202
212
|
* The one correct runtime NPC spawn (mirrors scene-factory's seed
|
|
203
213
|
* path): construct with a scene-bound registry, add to the scene
|
|
@@ -849,6 +859,7 @@ export default class Game {
|
|
|
849
859
|
async init(options, screen) {
|
|
850
860
|
this._useAi = options.useAi;
|
|
851
861
|
this._logFilePath = options.logFilePath;
|
|
862
|
+
this._saveFilePath = options.saveFilePath;
|
|
852
863
|
this.initInputBox(screen);
|
|
853
864
|
this.initLogBox(screen);
|
|
854
865
|
this.initMetaBox(screen);
|
|
@@ -891,16 +902,24 @@ export default class Game {
|
|
|
891
902
|
if (this.scene.isHub) {
|
|
892
903
|
this._hubScene = this.scene;
|
|
893
904
|
this._hubName = this.sceneSeed?.name ?? 'home';
|
|
905
|
+
// Every save embeds this seed -- resume never depends on the
|
|
906
|
+
// original scene file still existing or matching.
|
|
907
|
+
this._hubSeed = this.sceneSeed;
|
|
894
908
|
// The street starts talking from minute one.
|
|
895
909
|
this._rumorPool = this.sceneSeed?.rumors ?? [];
|
|
896
910
|
this.advanceRumor();
|
|
897
911
|
// The economy wakes up with it: shelf blueprints for restocking,
|
|
898
912
|
// the first odd job on offer, and the lifestyle's edge perk.
|
|
913
|
+
// snapshotVendorStock deliberately runs BEFORE any resume overlay:
|
|
914
|
+
// the restock blueprint is the seed's PRISTINE shelves (config
|
|
915
|
+
// copies), and restockVendorShelves only refills what the overlay
|
|
916
|
+
// leaves empty.
|
|
899
917
|
this.snapshotVendorStock();
|
|
900
918
|
this._gigPool = this.sceneSeed?.gigs ?? [];
|
|
901
919
|
this.advanceGig();
|
|
902
920
|
this.player.lifestyleEdgeBonus = this.lifestyle.edgeBonus;
|
|
903
|
-
// Home turf knows its own (see seedHomeTurfContacts).
|
|
921
|
+
// Home turf knows its own (see seedHomeTurfContacts). On resume the
|
|
922
|
+
// saved contacts overwrite these loyalty-1 seeds a few lines down.
|
|
904
923
|
this.seedHomeTurfContacts();
|
|
905
924
|
// The next run starts cooking the moment you're home (player
|
|
906
925
|
// request): generation takes 20-40s, and waiting for the player
|
|
@@ -908,7 +927,9 @@ export default class Game {
|
|
|
908
927
|
// Mr. Johnson's "1 new message" ping lands mid-session, and the
|
|
909
928
|
// call finds work already waiting. The gate keeps this a no-op
|
|
910
929
|
// with AI off or a draft/pending seed somehow already in flight.
|
|
911
|
-
|
|
930
|
+
// GATED on resume: a restored pendingRun must not be clobbered by
|
|
931
|
+
// a fresh background draft landing 20-40s into the session.
|
|
932
|
+
if (!this._resume && this.canDraftNextScene().allowed) {
|
|
912
933
|
this.draftNextSceneInBackground();
|
|
913
934
|
}
|
|
914
935
|
}
|
|
@@ -922,7 +943,20 @@ export default class Game {
|
|
|
922
943
|
// The banner learns where we are only after the hub/scene bookkeeping
|
|
923
944
|
// above settles.
|
|
924
945
|
this.refreshLogLabel();
|
|
946
|
+
// RESUME (see utilities/persistence.ts): lay the save over the
|
|
947
|
+
// freshly-synthesized hub -- player sheet/gear, hub world diffs,
|
|
948
|
+
// and the Game-level ledgers -- AFTER all the fresh-start seeding
|
|
949
|
+
// above, so the save is authoritative everywhere they overlap.
|
|
950
|
+
if (this._resume && this._hubScene) {
|
|
951
|
+
this.applyResumeState(this._resume);
|
|
952
|
+
}
|
|
925
953
|
this.initialized = true;
|
|
954
|
+
if (this._resume) {
|
|
955
|
+
const pendingNote = this._pendingRunSeed
|
|
956
|
+
? hint(`\n\n${FIXER_NAME}'s job is still on offer: "${this._pendingRunSeed.name}". "call taxi" when you're ready, or "call ${FIXER_NAME}" to hear it again.`)
|
|
957
|
+
: '';
|
|
958
|
+
return `Welcome back, ${this.player.name}. The cot remembers your shape.\n ${this.scene.story}${pendingNote}`;
|
|
959
|
+
}
|
|
926
960
|
// Nudge the player toward "call" up front -- the fixer convention means
|
|
927
961
|
// the story deliberately doesn't narrate a completed briefing, so
|
|
928
962
|
// without this hint there'd be no in-game indication that "call" is how
|
|
@@ -933,6 +967,106 @@ export default class Game {
|
|
|
933
967
|
: '';
|
|
934
968
|
return `Welcome, ${this.player.name}\n ${this.scene.story}${callHint}`;
|
|
935
969
|
}
|
|
970
|
+
/**
|
|
971
|
+
* Everything a save restores beyond the seed synthesis: the player,
|
|
972
|
+
* the hub world overlay, and the Game-level ledgers. Ordering inside
|
|
973
|
+
* matters less than its POSITION in init(): after seedHomeTurfContacts
|
|
974
|
+
* and snapshotVendorStock (both deliberately pre-overlay).
|
|
975
|
+
*/
|
|
976
|
+
applyResumeState(save) {
|
|
977
|
+
restorePlayer(this.player, save.player);
|
|
978
|
+
applyHubOverlay(this.scene, save.hub, this.player, this._homeRoom);
|
|
979
|
+
this.lifestyleTier = save.game.lifestyleTier;
|
|
980
|
+
this.rentDebt = save.game.rentDebt;
|
|
981
|
+
this.syncHomeToLifestyle();
|
|
982
|
+
this.player.lifestyleEdgeBonus = this.lifestyle.edgeBonus;
|
|
983
|
+
this._tier = save.game.tier;
|
|
984
|
+
this.contacts = new Map(save.game.contacts);
|
|
985
|
+
this.fencedCategories = new Set(save.game.fencedCategories);
|
|
986
|
+
this._rumorIndex = save.game.rumorIndex;
|
|
987
|
+
this.activeRumor = save.game.activeRumor;
|
|
988
|
+
this._gigPool = [...save.game.gigPool];
|
|
989
|
+
this._gigIndex = save.game.gigIndex;
|
|
990
|
+
this.gigAvailable = save.game.gigAvailable;
|
|
991
|
+
this.activeGig = save.game.activeGig;
|
|
992
|
+
if (save.game.pendingRun) {
|
|
993
|
+
this._pendingRunSeed = save.game.pendingRun.seed;
|
|
994
|
+
this._pendingRunTier = save.game.pendingRun.tier;
|
|
995
|
+
this._pendingRide = save.game.pendingRun.ride;
|
|
996
|
+
}
|
|
997
|
+
this.player.currentLocation = this._homeRoom;
|
|
998
|
+
this.updateEquipment(this.player.equipment);
|
|
999
|
+
this.updateInventory(this.player.inventory, capitalCase(this.scene.getCurrencyType()));
|
|
1000
|
+
this.updateExits(this.player.currentLocation);
|
|
1001
|
+
this.updateStatus();
|
|
1002
|
+
this.refreshLogLabel();
|
|
1003
|
+
Logger.getInstance().write(`Resumed save for ${save.playerName} (saved ${save.savedAt}, reason ${save.reason}).`);
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* THE single save routine -- every safe beat funnels here. Guards make
|
|
1007
|
+
* it a silent no-op anywhere a save would lie: mid-run (the "runs are
|
|
1008
|
+
* disposable" ruling lives in the scene === _hubScene check), downed
|
|
1009
|
+
* or KO'd, mid-exchange, dead, or before init finishes. Synchronous by
|
|
1010
|
+
* design so the process-exit quit hook can use it; failures log and
|
|
1011
|
+
* never crash a turn.
|
|
1012
|
+
*/
|
|
1013
|
+
requestSave(reason) {
|
|
1014
|
+
const logger = Logger.getInstance();
|
|
1015
|
+
if (!this.initialized || this._dead || !this._saveFilePath)
|
|
1016
|
+
return;
|
|
1017
|
+
if (!this.hasHub || this.scene !== this._hubScene || !this._hubSeed)
|
|
1018
|
+
return;
|
|
1019
|
+
if (this.player.isDown() || this.player.isUnconscious())
|
|
1020
|
+
return;
|
|
1021
|
+
if (this.scene.isPlayerExchangeActive())
|
|
1022
|
+
return;
|
|
1023
|
+
try {
|
|
1024
|
+
const save = this.buildSaveFile(reason);
|
|
1025
|
+
writeSaveAtomic(this._saveFilePath, save);
|
|
1026
|
+
logger.write(`Saved (${reason}) -> ${this._saveFilePath}`);
|
|
1027
|
+
// Local-first: the beat is DONE the moment the file lands. The
|
|
1028
|
+
// cloud mirror rides behind, fire-and-forget (see cloud-saves.ts
|
|
1029
|
+
// -- logged-out/offline/expired all degrade to a silent no-op).
|
|
1030
|
+
void pushSave(this._saveFilePath, save);
|
|
1031
|
+
}
|
|
1032
|
+
catch (err) {
|
|
1033
|
+
logger.error(`requestSave(${reason}) failed: ${err}`);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
buildSaveFile(reason) {
|
|
1037
|
+
return {
|
|
1038
|
+
version: SAVE_VERSION,
|
|
1039
|
+
savedAt: new Date().toISOString(),
|
|
1040
|
+
reason,
|
|
1041
|
+
playerName: this.player.name,
|
|
1042
|
+
summary: {
|
|
1043
|
+
archetypeName: this.player.archetypeName,
|
|
1044
|
+
karma: this.player.karma,
|
|
1045
|
+
currency: this.player.currency,
|
|
1046
|
+
lifestyleTier: this.lifestyleTier,
|
|
1047
|
+
hubName: this._hubName,
|
|
1048
|
+
},
|
|
1049
|
+
hubSeed: this._hubSeed,
|
|
1050
|
+
player: serializePlayer(this.player),
|
|
1051
|
+
game: {
|
|
1052
|
+
lifestyleTier: this.lifestyleTier,
|
|
1053
|
+
rentDebt: this.rentDebt,
|
|
1054
|
+
tier: this._tier,
|
|
1055
|
+
contacts: [...this.contacts.entries()],
|
|
1056
|
+
fencedCategories: [...this.fencedCategories],
|
|
1057
|
+
rumorIndex: this._rumorIndex,
|
|
1058
|
+
activeRumor: this.activeRumor,
|
|
1059
|
+
gigPool: [...this._gigPool],
|
|
1060
|
+
gigIndex: this._gigIndex,
|
|
1061
|
+
gigAvailable: this.gigAvailable,
|
|
1062
|
+
activeGig: this.activeGig,
|
|
1063
|
+
pendingRun: this._pendingRunSeed && this._pendingRunTier !== undefined
|
|
1064
|
+
? { seed: this._pendingRunSeed, tier: this._pendingRunTier, ride: this._pendingRide }
|
|
1065
|
+
: undefined,
|
|
1066
|
+
},
|
|
1067
|
+
hub: captureHubOverlay(this._hubScene, this._hubSeed, this.player, this._homeRoom),
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
936
1070
|
/**
|
|
937
1071
|
* Synchronous readiness check for continueToNextScene() -- lets callers
|
|
938
1072
|
* give instant feedback for the "not ready yet" cases (job not done, no
|
|
@@ -1096,6 +1230,10 @@ export default class Game {
|
|
|
1096
1230
|
// Drones spin back up beside the cot.
|
|
1097
1231
|
const companionArrivalLines = this.unfoldCompanionsOnArrival();
|
|
1098
1232
|
const companionBlock = [...companionFoldLines, ...companionArrivalLines];
|
|
1233
|
+
// The homecoming save: everything above (payout, rent, restock,
|
|
1234
|
+
// contacts reset) settled first, so the save reflects the hub as
|
|
1235
|
+
// the player will find it.
|
|
1236
|
+
this.requestSave('homecoming');
|
|
1099
1237
|
const fateLine = wrappedRun
|
|
1100
1238
|
? `The run's wrapped and the street swallows you back up.`
|
|
1101
1239
|
: `The run's behind you -- unfinished, unpaid, already someone else's problem. The street doesn't ask.`;
|
|
@@ -1282,6 +1420,9 @@ export default class Game {
|
|
|
1282
1420
|
if (!seed || tier === undefined) {
|
|
1283
1421
|
return `There's no job waiting. "call ${FIXER_NAME}" to drum one up.`;
|
|
1284
1422
|
}
|
|
1423
|
+
// The departure save: hub state with the job still on offer -- what
|
|
1424
|
+
// a mid-run quit resumes to (the "runs are disposable" ruling).
|
|
1425
|
+
this.requestSave('job-accept');
|
|
1285
1426
|
const haggledAtOffer = this.player.haggledThisJob;
|
|
1286
1427
|
try {
|
|
1287
1428
|
const banner = await this.activateRunScene(seed, tier, { startInHideout: false });
|
|
@@ -1300,6 +1441,21 @@ export default class Game {
|
|
|
1300
1441
|
}
|
|
1301
1442
|
}
|
|
1302
1443
|
async close() {
|
|
1444
|
+
// PERMADEATH (player ruling): close() is reachable ONLY via
|
|
1445
|
+
// Scene.endGame(), and endGame fires ONLY on real death (combat
|
|
1446
|
+
// resolveDeath, street-decides knockout, drain burnout, ward
|
|
1447
|
+
// backlash, stim crash) -- so this IS the one death choke point.
|
|
1448
|
+
// The save burns with the body; _dead also suppresses the quit
|
|
1449
|
+
// hook's save on the way out. Keep that invariant: any future
|
|
1450
|
+
// non-death caller of close() must set a flag before this line.
|
|
1451
|
+
this._dead = true;
|
|
1452
|
+
if (this._saveFilePath) {
|
|
1453
|
+
deleteSave(this._saveFilePath);
|
|
1454
|
+
// The cloud copy burns too -- tombstone-first, so an offline death
|
|
1455
|
+
// can't be resurrected from the mirror (see cloud-saves.ts).
|
|
1456
|
+
burnCloudSaveFor(this._saveFilePath, this.player.name);
|
|
1457
|
+
Logger.getInstance().write(`Permadeath: save deleted (${this._saveFilePath}).`);
|
|
1458
|
+
}
|
|
1303
1459
|
this.stopPursuitHeartbeat();
|
|
1304
1460
|
this._inputBox.removeAllListeners(); // removes all event listeners
|
|
1305
1461
|
this._inputBox.cancel(); // cancels any active input session
|
|
@@ -1691,9 +1847,10 @@ export default class Game {
|
|
|
1691
1847
|
this.updateStatus();
|
|
1692
1848
|
}
|
|
1693
1849
|
// Public method to get the instance of the Game class
|
|
1694
|
-
static async getInstance(player, sceneSeed) {
|
|
1850
|
+
static async getInstance(player, sceneSeed, resume) {
|
|
1695
1851
|
if (!Game.instance) {
|
|
1696
1852
|
Game.instance = new Game(player, sceneSeed);
|
|
1853
|
+
Game.instance._resume = resume;
|
|
1697
1854
|
}
|
|
1698
1855
|
return Game.instance;
|
|
1699
1856
|
}
|