Common API Calls
This page is the quick copy/paste layer.
Use it after you understand the basic Save Graph idea and need to wire buttons, menus, autosave zones, or debug shortcuts.
If the slot/record model is still fuzzy, read
Player Slots And Records first.
The short version is: keep the player's slot_id stable, then let each API
write the correct record inside that slot.
Save A Scope
Use this when one gameplay domain owns the save/load boundary.
This writes a Scope record under the provided player slot. Keep the slot_id
stable for the playthrough; the Scope and current scene decide which record
inside that slot is written.
@onready var room_scope: SaveFlowScope = $RoomScope
func save_room() -> void:
var metadata := SaveFlowSlotMetadata.new()
metadata.slot_id = "slot_1"
metadata.display_name = "Village Start"
metadata.save_type = "manual"
metadata.chapter_name = "Chapter 1"
metadata.location_name = "Forest Gate"
metadata.playtime_seconds = 960
var result := SaveFlow.save_scope("slot_1", room_scope, metadata)
if not result.ok:
push_warning(result.message)
Load A Scope
The target Scope and its Sources must already exist in the currently loaded scene.
This reads the matching Scope record for the current scene and Scope key under the same player slot.
func load_room() -> void:
var result := SaveFlow.load_scope("slot_1", room_scope)
if not result.ok:
push_warning(result.message)
Use strict: true only when missing Sources should fail the load:
SaveFlow.load_scope("slot_1", room_scope, true)
Save And Load A Scene Graph
Use this when the scene's Sources are discovered from the saveflow group.
Scene graph calls use a scene-qualified record under the player slot.
func save_current_scene() -> void:
var result := SaveFlow.save_scene("slot_1", get_tree().current_scene)
if not result.ok:
push_warning(result.message)
func load_current_scene() -> void:
var result := SaveFlow.load_scene("slot_1", get_tree().current_scene)
if not result.ok:
push_warning(result.message)
Most project-ready workflows should still prefer save_scope() when a domain
boundary is clear.
Use Active Slot Helpers
Use SaveFlowSlotWorkflow when a menu or gameplay session has a selected slot.
var slot_workflow := SaveFlowSlotWorkflow.new()
func select_slot(slot_index: int) -> void:
slot_workflow.select_slot_index(slot_index)
func active_slot_id() -> String:
return slot_workflow.active_slot_id()
Build metadata for the active slot:
func build_metadata(save_type: String) -> SaveFlowSlotMetadata:
return slot_workflow.build_active_slot_metadata(
"",
save_type,
"Chapter 1",
"Forest Gate",
_current_playtime_seconds
)
Manual Save
func manual_save() -> void:
var metadata := build_metadata("manual")
var result := SaveFlow.save_scope(slot_workflow.active_slot_id(), room_scope, metadata)
if not result.ok:
push_warning(result.message)
Autosave
Autosave usually writes the active slot without opening a menu.
func trigger_autosave() -> void:
var metadata := build_metadata("autosave")
var result := SaveFlow.save_scope(slot_workflow.active_slot_id(), room_scope, metadata)
if not result.ok:
push_warning(result.message)
Checkpoint Save
Checkpoint is a gameplay recovery marker. It usually writes the active slot with checkpoint metadata.
func trigger_checkpoint() -> void:
var metadata := build_metadata("checkpoint")
metadata.location_name = "West Room Checkpoint"
var result := SaveFlow.save_scope(slot_workflow.active_slot_id(), room_scope, metadata)
if not result.ok:
push_warning(result.message)
Build Save Cards For UI
Use summaries and cards to draw a save menu without loading every full payload.
func build_save_cards() -> Array:
var summaries := SaveFlow.list_slot_summaries()
if not summaries.ok:
push_warning(summaries.message)
return []
return slot_workflow.build_cards_for_indices(
PackedInt32Array([1, 2, 3]),
summaries.data
)
Each card can drive a UI card:
for card in build_save_cards():
print(card.display_name, " ", card.location_name, " ", card.save_type)
Read One Slot Summary
func print_slot_summary(slot_id: String) -> void:
var result := SaveFlow.read_slot_summary(slot_id)
if not result.ok:
push_warning(result.message)
return
print(result.data)
Delete A Slot
func delete_selected_slot() -> void:
var result := SaveFlow.delete_slot(slot_workflow.active_slot_id())
if not result.ok:
push_warning(result.message)
Check Compatibility Before Loading
func can_load_slot(slot_id: String) -> bool:
var result := SaveFlow.inspect_slot_compatibility(slot_id)
if not result.ok:
push_warning(result.message)
return false
return bool(result.data.get("compatible", false))
Compatibility checks report schema/data-version safety. They do not run Pro migration.
List Records In A Slot
Use this for editor tooling, QA helpers, diagnostics, or migration checks. Most player-facing save menus should still show slot summaries instead.
func print_slot_records(slot_id: String) -> void:
var result := SaveFlow.list_slot_records(slot_id)
if not result.ok:
push_warning(result.message)
return
for record in result.data:
print(record.get("record_key", ""), " ", record.get("record_kind", ""))
Store A Raw Payload
Use save_data() only when your code already owns the whole payload.
func save_settings_payload() -> void:
var payload := {
"volume": 0.8,
"language": "en",
}
SaveFlow.save_data("settings", payload)
For gameplay scene state, use Sources and Scopes instead.
C# Equivalent
In C#, the same Scope workflow is:
var workflow = new SaveFlowSlotWorkflow();
workflow.SelectSlotIndex(1);
var metadata = workflow.BuildActiveSlotMetadata(
displayName: "Village Start",
saveType: "manual",
chapterName: "Chapter 1",
locationName: "Forest Gate",
playtimeSeconds: 960);
var result = SaveFlowClient.SaveScope(workflow.ActiveSlotId(), roomScope, metadata);
if (!result.Ok)
{
GD.PushWarning(result.Message);
}
See the C# page and C# API reference when you need the full wrapper surface.