From 8dea6b116909dd2e6fa78baa928ce45b877bfc6a Mon Sep 17 00:00:00 2001 From: Liana P <32243840+liana-p@users.noreply.github.com> Date: Fri, 30 Aug 2024 13:29:37 +0100 Subject: [PATCH] feat: new option to not autosave on specific labels --- docs/features/save-and-load.md | 29 +++++++++++++++++++ packages/narrat/src/application/saving.ts | 5 ++++ packages/narrat/src/config/common-config.ts | 2 ++ .../src/examples/default/config/common.yaml | 7 +++++ .../examples/default/scripts/default.narrat | 2 +- .../default/scripts/test_saves.narrat | 7 ++++- packages/narrat/src/stores/vm-store.ts | 10 ++++++- 7 files changed, 59 insertions(+), 3 deletions(-) diff --git a/docs/features/save-and-load.md b/docs/features/save-and-load.md index ac4aca0b..26d5cc00 100644 --- a/docs/features/save-and-load.md +++ b/docs/features/save-and-load.md @@ -83,6 +83,10 @@ saves: mode: manual slots: 10 runOnReload: 'game_reload' + autosaveDisabledOnLabels: + - test_no_autosave + # disabled: true + notifyOnSave: true ``` Then for example in the game code: @@ -134,3 +138,28 @@ saves: Setting the `disabled` option to true in the saves config will remove the continue/load button, and remove the warning about erasing save slots when clicking on new game. The game will still be saving in the background, but the player won't be able to load the save. + +## Save notification + +The game automatically adds a notification on screen when autosaving. This can be disabled in the save config: + +```yaml +saves: + notifyOnSave: false +``` + +## Disabling autosave on specific labels + +There are cases where you might want your game to _not_ autosave on specific labels. For example if there is a choice in your game that might softlock the player, you might want to prevent the player from autosaving after that choice. + +To do that, add the `autosaveDisabledOnLabels` option to the saves config and list all the labels that should _not_ trigger an autosave. + +```yaml +saves: + autosaveDisabledOnLabels: + - no_autosave + - dont_save_this_label + - please_dont_save_me + - this_really_shouldnt_be_saved + - no_dont_save_this_label_senpai_yamete_kudasai +``` diff --git a/packages/narrat/src/application/saving.ts b/packages/narrat/src/application/saving.ts index 846e1feb..056dce6f 100644 --- a/packages/narrat/src/application/saving.ts +++ b/packages/narrat/src/application/saving.ts @@ -10,6 +10,8 @@ import { } from '@/utils/save-helpers'; import { getPlayTime } from '@/utils/time-helpers'; import { error } from '@/utils/error-handling'; +import { useNotifications } from '@/stores/notification-store'; +import { getCommonConfig } from '@/config'; export function autoSaveGame({ slotId, @@ -25,6 +27,9 @@ export function autoSaveGame({ name, extractedSave: extractSaveData(), }); + if (getCommonConfig().saves.notifyOnSave !== false) { + useNotifications().addNotification('Game Saved'); + } } export function setupLoadedData(save: ExtractedSave) { diff --git a/packages/narrat/src/config/common-config.ts b/packages/narrat/src/config/common-config.ts index f3ecac65..b93b42a6 100644 --- a/packages/narrat/src/config/common-config.ts +++ b/packages/narrat/src/config/common-config.ts @@ -129,6 +129,8 @@ export const SavesConfigSchema = Type.Object({ slots: Type.Number(), runOnReload: Type.Optional(Type.String()), disabled: Type.Optional(Type.Boolean()), + autosaveDisabledOnLabels: Type.Optional(Type.Array(Type.String())), + notifyOnSave: Type.Optional(Type.Boolean()), }); export type SavesConfig = Static; diff --git a/packages/narrat/src/examples/default/config/common.yaml b/packages/narrat/src/examples/default/config/common.yaml index e3fc9c9a..fd98fa17 100644 --- a/packages/narrat/src/examples/default/config/common.yaml +++ b/packages/narrat/src/examples/default/config/common.yaml @@ -49,7 +49,14 @@ saves: mode: manual slots: 10 runOnReload: 'test_label_reload' + autosaveDisabledOnLabels: + - test_no_autosave # disabled: true + notifyOnSave: true + +notifications: + timeOnScreen: 2.5 + alsoPrintInDialogue: false hudStats: money: diff --git a/packages/narrat/src/examples/default/scripts/default.narrat b/packages/narrat/src/examples/default/scripts/default.narrat index eb620a1f..63d6d857 100644 --- a/packages/narrat/src/examples/default/scripts/default.narrat +++ b/packages/narrat/src/examples/default/scripts/default.narrat @@ -1,6 +1,6 @@ dev_test: - run test_dialog run test_saves + run test_dialog run test_conditions run test_js run test_arrays diff --git a/packages/narrat/src/examples/default/scripts/test_saves.narrat b/packages/narrat/src/examples/default/scripts/test_saves.narrat index 5c19eece..59af2719 100644 --- a/packages/narrat/src/examples/default/scripts/test_saves.narrat +++ b/packages/narrat/src/examples/default/scripts/test_saves.narrat @@ -1,4 +1,6 @@ test_saves: + "hello saves" + jump test_no_autosave jump test_save_bug "Let's try a save prompt" set data.save_test 1 @@ -36,4 +38,7 @@ test_save_bug_3: jump test_save_bug_4 test_save_bug_4: - "after jump" \ No newline at end of file + "after jump" + +test_no_autosave: + "this label shouldn't autosave" \ No newline at end of file diff --git a/packages/narrat/src/stores/vm-store.ts b/packages/narrat/src/stores/vm-store.ts index b6323d65..85151aca 100644 --- a/packages/narrat/src/stores/vm-store.ts +++ b/packages/narrat/src/stores/vm-store.ts @@ -365,7 +365,15 @@ export const useVM = defineStore('vm', { } this.hasJumped = true; this.setStack(target); - await autoSaveGame({}); + const autoSaveDisabledOnLabels = + getCommonConfig().saves.autosaveDisabledOnLabels; + if ( + !autoSaveDisabledOnLabels || + !autoSaveDisabledOnLabels.includes(target.label) + ) { + // Don't autosave if we're on a label that's not supposed to + await autoSaveGame({}); + } result = await this.runFrame(); } if (result === STOP_SIGNAL) {