Skip to main content

HasSaveSlots

Functions

ObserveActiveSlotStoreBrio

HasSaveSlots.ObserveActiveSlotStoreBrio(selfHasSaveSlots) → Observable.Observable<Brio.Brio<DataStoreStage.DataStoreStage>>

Observes the DataStoreStage for the active slot as a Brio

PromiseActiveSlotStore

HasSaveSlots.PromiseActiveSlotStore(selfHasSaveSlots) → Promise.Promise<DataStoreStage.DataStoreStage?>

Returns the DataStoreStage for the active slot

PromiseSlotsLoaded

HasSaveSlots.PromiseSlotsLoaded(selfHasSaveSlots) → Promise.Promise<any>

Promises that all slots have loaded

PromiseHasSlot

HasSaveSlots.PromiseHasSlot(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId?
) → Promise.Promise<boolean>

Returns whether the slot with the given ID exists

PromiseSelectSlot

HasSaveSlots.PromiseSelectSlot(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId
) → Promise.Promise<any>

Selects the slot with the given ID

PromiseDeselectSlot

HasSaveSlots.PromiseDeselectSlot(selfHasSaveSlots) → Promise.Promise<()>

Clears the active slot selection, returning the player to a no-slot state -- the counterpart to HasSaveSlots.PromiseSelectSlot, backing a "back to menu" affordance. The active slot's progress is flushed first (mirroring the save PromiseSelectSlot runs when switching away), and the last-active slot is remembered, so HasSaveSlots.PromiseSelectLastSaveSlot can resume it later. A no-op when no slot is active.

PromiseCreateSlot

HasSaveSlots.PromiseCreateSlot(
selfHasSaveSlots,
slotIndexnumber,
metadataSaveSlotCreateMetadata?
) → Promise.Promise<SaveSlotData.SlotId>

Creates a slot at the given index

PromiseExportSlot

HasSaveSlots.PromiseExportSlot(
selfHasSaveSlots,
slotIdSlotId,
allowMainSlotboolean?--

defaults to false

) → Promise<SaveSlotExportUtils.SaveSlotExport>

Exports a slot's saved data into a plain, serializable SaveSlotExportUtils.SaveSlotExport. Rejects the main/default slot by default: its store is the player's shared root datastore, so exporting it would leak the SaveSlots system data and universe-scoped global data living alongside it. Only isolated non-main slot substores are exportable.

allowMainSlot opts out of that refusal for trusted admin tooling (see SaveSlotCmdrService). The SaveSlots system data is always stripped from the result, so the export never carries the slot roster or the other slots' saved data. Universe-scoped global data sharing the root store is indistinguishable from the main slot's own data and is still carried, which is why this is not exposed through SaveSlotService.

PromiseImportSlot

HasSaveSlots.PromiseImportSlot(
selfHasSaveSlots,
exportSaveSlotExportUtils.SaveSlotExport
) → Promise<SlotId>

Imports an exported slot into a fresh slot at the lowest free non-main index, seeding the new slot's store with the exported data. Never uses the main/default index -- importing onto the shared root store would wipe the player's global data. Resolves to the new slot's id. Rejects a malformed export, or when no non-main index is free.

PromiseSaveSlotToSharedDataStore

HasSaveSlots.PromiseSaveSlotToSharedDataStore(
selfHasSaveSlots,
slotIdSlotId,
keystring,
allowMainSlotboolean?--

defaults to false, see HasSaveSlots.PromiseExportSlot

) → Promise<boolean>

Exports a non-main slot (see HasSaveSlots.PromiseExportSlot) and writes it to the shared save slot store under the given key.

PromiseImportSlotFromSharedDataStore

HasSaveSlots.PromiseImportSlotFromSharedDataStore(
selfHasSaveSlots,
keystring
) → Promise<SlotId>

Reads an export from the shared save slot store and imports it into a fresh non-main slot (see HasSaveSlots.PromiseImportSlot). Rejects when no export is stored under the key.

PromiseSelectTransferableEphemeralSlot

HasSaveSlots.PromiseSelectTransferableEphemeralSlot(
selfHasSaveSlots,
keystring
) → Promise<SlotId>

Loads the export stored under the given shared-store key into a fresh ephemeral slot and selects it, remembering the key so a teleport can carry the slot forward (see the transferable-ephemeral teleport provider in SaveSlotService). Like every ephemeral slot it is never persisted, stays out of the slot list, and is torn down on deselect. Rejects when no valid export is stored under the key.

PromiseBuildEphemeralTransferSlice

HasSaveSlots.PromiseBuildEphemeralTransferSlice(selfHasSaveSlots) → Promise<{[string]any}?>

Builds this player's teleport slice for a transferable ephemeral slot: re-saves the active slot's current live data to the shared store under its key and returns a slice carrying that key. Resolves nil when the active slot is not a transferable ephemeral slot. A failed re-save degrades to nil so a teleport is never blocked (the destination then re-loads the last saved state). Asynchronous -- it is consumed through TeleportDataService.PromiseBuildTeleportData.

PromiseLoadTransferableEphemeralSlotFromTeleport

HasSaveSlots.PromiseLoadTransferableEphemeralSlotFromTeleport(selfHasSaveSlots) → Promise<SlotId?>

Selects the transferable ephemeral slot the player teleported in with, from the shared-store key in their arrived data. Reads the unified band (not trusted-only) so a client-initiated teleport -- the common case, e.g. a menu resume hop -- carries it too; a server-initiated teleport still works via the trusted band. Resolves to the slot id, or nil when none arrived.

Because the client band is honored, a client can present any key it knows. The key resolves to a server-side shared-store entry and only ever seeds a throwaway (never-persisted) slot, so the exposure is read-only visibility of a snapshot whose code you already have -- acceptable for the dev/Cmdr tooling this backs. Harden (longer code entropy / ownership) before exposing it to a player-facing surface.

SetCodeGenerator

HasSaveSlots.SetCodeGenerator(
selfHasSaveSlots,
generatorCodeGenerator
) → ()

Overrides the share-code generator for this player's exports (see SaveSlotCodeUtils.CodeGenerator). Games inject a custom format; the default is SaveSlotCodeUtils.generateDefaultCode. Usually set game-wide via SaveSlotService.SetCodeGenerator rather than per player.

PromiseExportSaveSlotToCode

HasSaveSlots.PromiseExportSaveSlotToCode(
selfHasSaveSlots,
slotIdSlotId?,--

defaults to the active slot

allowMainSlotboolean?--

defaults to false, see HasSaveSlots.PromiseExportSlot

) → Promise<string>

Exports a slot to the shared store under a fresh generated code and resolves to that code. The code is a shareable handle other sessions load with HasSaveSlots.PromiseImportEphemeralSaveSlotFromCode. Defaults to the active slot. Refuses the main slot unless allowMainSlot is set (see HasSaveSlots.PromiseExportSlot). The code format comes from the configured generator (see HasSaveSlots.SetCodeGenerator).

PromiseImportEphemeralSaveSlotFromCode

HasSaveSlots.PromiseImportEphemeralSaveSlotFromCode(
selfHasSaveSlots,
codestring
) → Promise<SlotId>

Loads the slot stored under the given code into a fresh transferable ephemeral slot and selects it (see HasSaveSlots.PromiseSelectTransferableEphemeralSlot). Resolves to the new slot id.

PromiseExportSaveSlotToJson

HasSaveSlots.PromiseExportSaveSlotToJson(
selfHasSaveSlots,
slotIdSlotId?,--

defaults to the active slot

allowMainSlotboolean?--

defaults to false, see HasSaveSlots.PromiseExportSlot

) → Promise<string>

Exports a slot as a raw JSON string (no shared store), for direct inspection or attaching to a bug report. Defaults to the active slot. Refuses the main slot unless allowMainSlot is set (see HasSaveSlots.PromiseExportSlot).

PromiseDuplicateSlot

HasSaveSlots.PromiseDuplicateSlot(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId
) → Promise.Promise<SaveSlotData.SlotId>

Duplicates the slot with the given ID into a new slot at the lowest free index, copying its saved data. Resolves to the new slot's id. The copy is not selected, its metadata (playtime, timestamps) starts fresh, and its name is suffixed with " (Copy)". Rejects when the source slot is missing or every index is in use.

An ephemeral slot may be duplicated: the copy is a real, persisted slot seeded with the ephemeral slot's live in-memory data, which is how a throwaway session is turned into a save. It keeps the source's name unsuffixed (the copy is the first real slot for that session, not a second copy of an existing save) and, like any duplicate, is not selected -- see HasSaveSlots.PromisePersistEphemeralSlot for the version that continues play on the new slot.

PromisePersistEphemeralSlot

HasSaveSlots.PromisePersistEphemeralSlot(
selfHasSaveSlots,
slotIdSlotId?--

defaults to the active slot

) → Promise<SlotId>

Turns an ephemeral slot into a real save: duplicates it into a fresh persisted slot at the lowest free index (see HasSaveSlots.PromiseDuplicateSlot) and selects that slot, so play continues on data that is now being written. Defaults to the active slot, which in practice is the only ephemeral slot there is -- one stops existing the moment it stops being active. Resolves to the new slot's id.

The copy is taken from the ephemeral slot's live in-memory data at the moment this runs, and selecting the new slot retires the ephemeral one, so anything written to the old store between the copy and the selection is dropped. Rejects when no slot is active, the slot is missing, the slot is not ephemeral, or every index is in use.

PromiseDeleteSlot

HasSaveSlots.PromiseDeleteSlot(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId
) → Promise.Promise<any>

Deletes the slot with the given ID. Deleting an ephemeral slot ends that session -- it is deselected and retired along with its in-memory store -- rather than being refused for being the active slot.

PromiseDeleteAllSlots

HasSaveSlots.PromiseDeleteAllSlots(selfHasSaveSlots) → Promise.Promise<any>

Deletes every slot for the player and clears the active/last-active selection, resetting the player to a fresh state. Resolves once all slots are gone.

PromiseResetSlot

HasSaveSlots.PromiseResetSlot(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId
) → Promise.Promise<SaveSlotData.SlotId>

Resets the slot with the given id to a fresh empty one -- equivalent to deleting the slot and creating a new one at the same index. The slot keeps its index and name; its saved data and metadata (timestamps) start fresh. Resolves to the new slot id.

When the reset slot is the active slot, the selection clears and then reselects the fresh slot: everything bound to HasSaveSlots.ObserveActiveSlotStoreBrio tears down as the selection clears and rebuilds against the empty store on reselect, so consumers reset reactively without wiping their own state. A non-active slot is left unselected, and its "Continue" pointer (when it was the last-active slot) is carried across to the fresh id so the reset slot stays resumable. Rejects when the slot is missing.

PromiseResetActiveSlot

HasSaveSlots.PromiseResetActiveSlot(selfHasSaveSlots) → Promise.Promise<SaveSlotData.SlotId?>

Resets the active slot to a fresh empty one -- see HasSaveSlots.PromiseResetSlot. The slot keeps its index and name; its saved data and metadata (timestamps) start fresh, and the fresh slot stays selected. Resolves to the new slot id, or nil when no slot is active.

PromiseSetSlotMetadata

HasSaveSlots.PromiseSetSlotMetadata(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId,
dataSaveSlotData.SaveSlotMetadata
) → Promise.Promise<any>

Sets the metadata for the slot with the given ID

PromiseGetSlotMetadata

HasSaveSlots.PromiseGetSlotMetadata(
selfHasSaveSlots,
slotIdSaveSlotData.SlotId
) → Promise.Promise<SaveSlotData.SaveSlotMetadata?>

Gets the metadata for the slot with the given ID

PromiseSlotIdFromIndex

HasSaveSlots.PromiseSlotIdFromIndex(
selfHasSaveSlots,
slotIndexnumber
) → Promise.Promise<SaveSlotData.SlotId?>

Returns the slot ID from the given index

PromiseLastActiveSlotId

HasSaveSlots.PromiseLastActiveSlotId(selfHasSaveSlots) → Promise.Promise<SaveSlotData.SlotId?>

Gets the last active slot ID

PromiseSelectLastSaveSlot

HasSaveSlots.PromiseSelectLastSaveSlot(selfHasSaveSlots) → Promise.Promise<SaveSlotData.SlotId?>

Selects the player's last active slot if one still exists, resolving to the selected slot id -- or nil when there is no slot to continue on. Backs a "Continue" affordance that every save-slot consumer tends to need.

PromiseSelectNewSaveSlot

HasSaveSlots.PromiseSelectNewSaveSlot(selfHasSaveSlots) → Promise.Promise<SaveSlotData.SlotId?>

Creates a new slot at the lowest free index and selects it, resolving to the new slot id -- or nil when every slot is already in use. Backs a "New Game" affordance.

PromiseSelectEphemeralSlot

HasSaveSlots.PromiseSelectEphemeralSlot(
selfHasSaveSlots,
metadataSaveSlotCreateMetadata?--

optional SlotName/Summary for the in-memory slot

) → Promise<SlotId>

Creates a fresh ephemeral slot and selects it, resolving to its id. An ephemeral slot is selectable and active exactly like a real one -- it drives HasSaveSlots.ObserveActiveSlotStoreBrio, summaries, and playtime the same way, and its metadata replicates to the client like any other slot's, so UI can render the active session's name and summary -- but it is never persisted: no metadata is written, its data store is in-memory, and it is torn down the moment it stops being the active slot. It is also excluded from the save list (SaveSlotDataService.GetSlotList / SaveSlotDataService.ObserveSlotList), so it never shows up as something the player can return to. Selecting it never disturbs the persisted active-slot pointer or the "Continue" target, so the real slot the player came from resumes untouched afterward. Backs a throwaway session (e.g. exploring a lobby) that must leave no trace on save data.

RegisterSummaryProvider

HasSaveSlots.RegisterSummaryProvider(
selfHasSaveSlots,
namestring,
providerSummaryProvider
) → () → ()

Registers a named summary provider. Every registered provider's current value is aggregated into the active slot's Summary, keyed by name (see HasSaveSlots.PromiseGetSlotMetadata). Registering the same name again replaces the previous provider. Returns a function that unregisters the provider (also give it to a [Maid]).

_setupPlaytimeTracking

HasSaveSlots._setupPlaytimeTracking(selfHasSaveSlots) → ()

Accrues per-slot playtime automatically. A "session" spans the time a slot is the active slot: selecting a slot begins one (bumping PlayCount), and deselecting, switching, or unbinding ends it. Elapsed wall time is folded into the slot's TimePlayed from a datastore saving callback, so it persists on exactly the cadence the data is written -- always fresh at save time, with no separate timer -- and again at each session boundary.

Show raw api
{
    "functions": [
        {
            "name": "ObserveActiveSlotStoreBrio",
            "desc": "Observes the [DataStoreStage] for the active slot as a [Brio]",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Observable.Observable<Brio.Brio<DataStoreStage.DataStoreStage>>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 123,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseActiveSlotStore",
            "desc": "Returns the [DataStoreStage] for the active slot",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<DataStoreStage.DataStoreStage?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 144,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSlotsLoaded",
            "desc": "Promises that all slots have loaded",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<any>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 156,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseHasSlot",
            "desc": "Returns whether the slot with the given ID exists",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<boolean>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 163,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSelectSlot",
            "desc": "Selects the slot with the given ID",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<any>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 188,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseDeselectSlot",
            "desc": "Clears the active slot selection, returning the player to a no-slot state --\nthe counterpart to [HasSaveSlots.PromiseSelectSlot], backing a \"back to menu\"\naffordance. The active slot's progress is flushed first (mirroring the save\nPromiseSelectSlot runs when switching away), and the last-active slot is\nremembered, so [HasSaveSlots.PromiseSelectLastSaveSlot] can resume it later.\nA no-op when no slot is active.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<()>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 237,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseCreateSlot",
            "desc": "Creates a slot at the given index",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotIndex",
                    "desc": "",
                    "lua_type": "number"
                },
                {
                    "name": "metadata",
                    "desc": "",
                    "lua_type": "SaveSlotCreateMetadata?\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 258,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseExportSlot",
            "desc": "Exports a slot's saved data into a plain, serializable [SaveSlotExportUtils.SaveSlotExport].\nRejects the main/default slot by default: its store is the player's shared root datastore, so\nexporting it would leak the SaveSlots system data and universe-scoped global data living\nalongside it. Only isolated non-main slot substores are exportable.\n\n`allowMainSlot` opts out of that refusal for trusted admin tooling (see [SaveSlotCmdrService]).\nThe SaveSlots system data is always stripped from the result, so the export never carries the\nslot roster or the other slots' saved data. Universe-scoped global data sharing the root store\nis indistinguishable from the main slot's own data and is still carried, which is why this is\nnot exposed through [SaveSlotService].",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SlotId"
                },
                {
                    "name": "allowMainSlot",
                    "desc": "defaults to false",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SaveSlotExportUtils.SaveSlotExport>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 307,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseImportSlot",
            "desc": "Imports an exported slot into a fresh slot at the lowest free non-main index, seeding the new\nslot's store with the exported data. Never uses the main/default index -- importing onto the\nshared root store would wipe the player's global data. Resolves to the new slot's id. Rejects a\nmalformed export, or when no non-main index is free.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "export",
                    "desc": "",
                    "lua_type": "SaveSlotExportUtils.SaveSlotExport"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 349,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSaveSlotToSharedDataStore",
            "desc": "Exports a non-main slot (see [HasSaveSlots.PromiseExportSlot]) and writes it to the shared save\nslot store under the given key.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SlotId"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "allowMainSlot",
                    "desc": "defaults to false, see [HasSaveSlots.PromiseExportSlot]",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 399,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseImportSlotFromSharedDataStore",
            "desc": "Reads an export from the shared save slot store and imports it into a fresh non-main slot (see\n[HasSaveSlots.PromiseImportSlot]). Rejects when no export is stored under the key.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 417,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSelectTransferableEphemeralSlot",
            "desc": "Loads the export stored under the given shared-store key into a fresh ephemeral slot and selects it,\nremembering the key so a teleport can carry the slot forward (see the transferable-ephemeral teleport\nprovider in [SaveSlotService]). Like every ephemeral slot it is never persisted, stays out of the slot\nlist, and is torn down on deselect. Rejects when no valid export is stored under the key.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 444,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseBuildEphemeralTransferSlice",
            "desc": "Builds this player's teleport slice for a transferable ephemeral slot: re-saves the active slot's\n*current live* data to the shared store under its key and returns a slice carrying that key. Resolves\nnil when the active slot is not a transferable ephemeral slot. A failed re-save degrades to nil so a\nteleport is never blocked (the destination then re-loads the last saved state). Asynchronous -- it is\nconsumed through [TeleportDataService.PromiseBuildTeleportData].",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<{ [string]: any }?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 495,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseLoadTransferableEphemeralSlotFromTeleport",
            "desc": "Selects the transferable ephemeral slot the player teleported in with, from the shared-store key in\ntheir arrived data. Reads the *unified* band (not trusted-only) so a **client-initiated** teleport --\nthe common case, e.g. a menu resume hop -- carries it too; a server-initiated teleport still works via\nthe trusted band. Resolves to the slot id, or nil when none arrived.\n\nBecause the client band is honored, a client can present any key it knows. The key resolves to a\nserver-side shared-store entry and only ever seeds a throwaway (never-persisted) slot, so the exposure\nis read-only visibility of a snapshot whose code you already have -- acceptable for the dev/Cmdr tooling\nthis backs. Harden (longer code entropy / ownership) before exposing it to a player-facing surface.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 532,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "SetCodeGenerator",
            "desc": "Overrides the share-code generator for this player's exports (see [SaveSlotCodeUtils.CodeGenerator]).\nGames inject a custom format; the default is [SaveSlotCodeUtils.generateDefaultCode]. Usually set\ngame-wide via [SaveSlotService.SetCodeGenerator] rather than per player.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "generator",
                    "desc": "",
                    "lua_type": "CodeGenerator"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 552,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseExportSaveSlotToCode",
            "desc": "Exports a slot to the shared store under a fresh generated code and resolves to that code. The code\nis a shareable handle other sessions load with [HasSaveSlots.PromiseImportEphemeralSaveSlotFromCode].\nDefaults to the active slot. Refuses the main slot unless `allowMainSlot` is set (see\n[HasSaveSlots.PromiseExportSlot]). The code format comes from the configured generator (see\n[HasSaveSlots.SetCodeGenerator]).",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "defaults to the active slot",
                    "lua_type": "SlotId?"
                },
                {
                    "name": "allowMainSlot",
                    "desc": "defaults to false, see [HasSaveSlots.PromiseExportSlot]",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<string>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 585,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseImportEphemeralSaveSlotFromCode",
            "desc": "Loads the slot stored under the given code into a fresh transferable ephemeral slot and selects it\n(see [HasSaveSlots.PromiseSelectTransferableEphemeralSlot]). Resolves to the new slot id.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "code",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 610,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseExportSaveSlotToJson",
            "desc": "Exports a slot as a raw JSON string (no shared store), for direct inspection or attaching to a bug\nreport. Defaults to the active slot. Refuses the main slot unless `allowMainSlot` is set (see\n[HasSaveSlots.PromiseExportSlot]).",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "defaults to the active slot",
                    "lua_type": "SlotId?"
                },
                {
                    "name": "allowMainSlot",
                    "desc": "defaults to false, see [HasSaveSlots.PromiseExportSlot]",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<string>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 626,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseDuplicateSlot",
            "desc": "Duplicates the slot with the given ID into a new slot at the lowest free index,\ncopying its saved data. Resolves to the new slot's id. The copy is not selected,\nits metadata (playtime, timestamps) starts fresh, and its name is suffixed with\n\" (Copy)\". Rejects when the source slot is missing or every index is in use.\n\nAn ephemeral slot may be duplicated: the copy is a real, persisted slot seeded with the ephemeral\nslot's live in-memory data, which is how a throwaway session is turned into a save. It keeps the\nsource's name unsuffixed (the copy is the first real slot for that session, not a second copy of an\nexisting save) and, like any duplicate, is not selected -- see\n[HasSaveSlots.PromisePersistEphemeralSlot] for the version that continues play on the new slot.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 655,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromisePersistEphemeralSlot",
            "desc": "Turns an ephemeral slot into a real save: duplicates it into a fresh persisted slot at the lowest free\nindex (see [HasSaveSlots.PromiseDuplicateSlot]) and selects that slot, so play continues on data that\nis now being written. Defaults to the active slot, which in practice is the only ephemeral slot there\nis -- one stops existing the moment it stops being active. Resolves to the new slot's id.\n\nThe copy is taken from the ephemeral slot's live in-memory data at the moment this runs, and selecting\nthe new slot retires the ephemeral one, so anything written to the old store between the copy and the\nselection is dropped. Rejects when no slot is active, the slot is missing, the slot is not ephemeral,\nor every index is in use.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "defaults to the active slot",
                    "lua_type": "SlotId?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 732,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseDeleteSlot",
            "desc": "Deletes the slot with the given ID. Deleting an ephemeral slot ends that session -- it is deselected\nand retired along with its in-memory store -- rather than being refused for being the active slot.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<any>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 762,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseDeleteAllSlots",
            "desc": "Deletes every slot for the player and clears the active/last-active\nselection, resetting the player to a fresh state. Resolves once all slots\nare gone.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<any>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 825,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseResetSlot",
            "desc": "Resets the slot with the given id to a fresh empty one -- equivalent to deleting the slot\nand creating a new one at the same index. The slot keeps its index and name; its saved data\nand metadata (timestamps) start fresh. Resolves to the new slot id.\n\nWhen the reset slot is the active slot, the selection clears and then reselects the fresh\nslot: everything bound to [HasSaveSlots.ObserveActiveSlotStoreBrio] tears down as the\nselection clears and rebuilds against the empty store on reselect, so consumers reset\nreactively without wiping their own state. A non-active slot is left unselected, and its\n\"Continue\" pointer (when it was the last-active slot) is carried across to the fresh id so\nthe reset slot stays resumable. Rejects when the slot is missing.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 860,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseResetActiveSlot",
            "desc": "Resets the active slot to a fresh empty one -- see [HasSaveSlots.PromiseResetSlot]. The slot\nkeeps its index and name; its saved data and metadata (timestamps) start fresh, and the fresh\nslot stays selected. Resolves to the new slot id, or nil when no slot is active.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 915,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSetSlotMetadata",
            "desc": "Sets the metadata for the slot with the given ID",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId"
                },
                {
                    "name": "data",
                    "desc": "",
                    "lua_type": "SaveSlotData.SaveSlotMetadata\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<any>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 929,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseGetSlotMetadata",
            "desc": "Gets the metadata for the slot with the given ID",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotId",
                    "desc": "",
                    "lua_type": "SaveSlotData.SlotId\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SaveSlotMetadata?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 953,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSlotIdFromIndex",
            "desc": "Returns the slot ID from the given index",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "slotIndex",
                    "desc": "",
                    "lua_type": "number\n"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 966,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseLastActiveSlotId",
            "desc": "Gets the last active slot ID",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 986,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSelectLastSaveSlot",
            "desc": "Selects the player's last active slot if one still exists, resolving to the\nselected slot id -- or nil when there is no slot to continue on. Backs a\n\"Continue\" affordance that every save-slot consumer tends to need.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 997,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSelectNewSaveSlot",
            "desc": "Creates a new slot at the lowest free index and selects it, resolving to the\nnew slot id -- or nil when every slot is already in use. Backs a \"New Game\"\naffordance.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise.Promise<SaveSlotData.SlotId?>\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1020,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "PromiseSelectEphemeralSlot",
            "desc": "Creates a fresh ephemeral slot and selects it, resolving to its id. An ephemeral slot is selectable and\nactive exactly like a real one -- it drives [HasSaveSlots.ObserveActiveSlotStoreBrio], summaries, and\nplaytime the same way, and its metadata replicates to the client like any other slot's, so UI can render\nthe active session's name and summary -- but it is never persisted: no metadata is written, its data store\nis in-memory, and it is torn down the moment it stops being the active slot. It is also excluded from the\nsave list ([SaveSlotDataService.GetSlotList] / [SaveSlotDataService.ObserveSlotList]), so it never shows up\nas something the player can return to. Selecting it never disturbs the persisted active-slot pointer or the\n\"Continue\" target, so the real slot the player came from resumes untouched afterward. Backs a throwaway\nsession (e.g. exploring a lobby) that must leave no trace on save data.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "metadata",
                    "desc": "optional SlotName/Summary for the in-memory slot",
                    "lua_type": "SaveSlotCreateMetadata?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<SlotId>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1064,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "RegisterSummaryProvider",
            "desc": "Registers a named summary provider. Every registered provider's current value is aggregated into\nthe active slot's Summary, keyed by `name` (see [HasSaveSlots.PromiseGetSlotMetadata]). Registering\nthe same name again replaces the previous provider. Returns a function that unregisters the provider\n(also give it to a [Maid]).",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "provider",
                    "desc": "",
                    "lua_type": "SummaryProvider"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "() -> ()"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1096,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        },
        {
            "name": "_setupPlaytimeTracking",
            "desc": "Accrues per-slot playtime automatically. A \"session\" spans the time a slot is the active slot:\nselecting a slot begins one (bumping PlayCount), and deselecting, switching, or unbinding ends\nit. Elapsed wall time is folded into the slot's TimePlayed from a datastore saving callback, so\nit persists on exactly the cadence the data is written -- always fresh at save time, with no\nseparate timer -- and again at each session boundary.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "HasSaveSlots"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 1410,
                "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
            }
        }
    ],
    "properties": [],
    "types": [],
    "name": "HasSaveSlots",
    "desc": "",
    "source": {
        "line": 5,
        "path": "src/saveslot/src/Server/Binders/HasSaveSlots.lua"
    }
}