Skip to main content

Pipeline Signals

Use SaveFlowPipelineSignals when the user story is:

React to save/load lifecycle events without subclassing every Source.

Pipeline signals are scene-authored event bridges. They are not saved as gameplay data.

SaveFlow pipeline signals flow

The Pipeline Notifications demo shows the intended runtime shape: each Source emits its own feedback first, then the graph emits the final slot-write message.

Pipeline Notifications demo after save, showing source-level messages and final Data Saved feedback

Common Uses​

Use pipeline signals for:

  • "Data Saved!" toast messages
  • analytics or debug logging
  • disabling UI during load
  • refreshing derived UI after load
  • cancelling or warning around unsafe actions

Signal Shape​

SaveFlowPipelineSignals exposes lifecycle signals such as:

  • before_save
  • after_gather
  • before_write
  • after_write
  • before_load
  • after_read
  • before_apply
  • after_load
  • before_gather_source
  • after_gather_source
  • before_apply_source
  • after_apply_source
  • pipeline_error

Each signal receives a SaveFlowPipelineEvent.

Example scene behavior:

func _on_after_write(event: SaveFlowPipelineEvent) -> void:
_show_toast("Data Saved")

func _on_after_gather_source(event: SaveFlowPipelineEvent) -> void:
_show_toast("%s Saved" % event.source_key)

Connect these from the Godot inspector when possible. That keeps the Source script focused on data and lets UI feedback live in UI nodes.

Runtime Entity Placement​

Use the narrowest event that matches the behavior:

  • one field updates its own derived state: use a property setter
  • one entity reacts after all fields owned by one Source were applied: put SaveFlowPipelineSignals under that Source
  • a runtime collection reacts to restored entities: connect SaveFlowEntityCollectionSource.entity_restored
  • a runtime collection reacts once after the batch: connect SaveFlowEntityCollectionSource.collection_restored

For entity-local pipeline behavior, the bridge belongs under the entity's Source:

RuntimeOrb
|- SaveFlowIdentity
|- StateSource (SaveFlowNodeSource)
|- PipelineSignals

Connect after_apply_source when initialization depends on several fields in that Source. The entity still does not need to inherit a SaveFlow class.

Do not place the bridge under SaveFlowEntityFactory. A factory is a runtime adapter used by the collection; it does not emit its own save/load pipeline stages.

For collection-level entity semantics, connect the collection directly:

func _on_entity_restored(entity: Node, descriptor: Dictionary) -> void:
entity.finalize_restored_state()

func _on_collection_restored(report: Dictionary) -> void:
print("Restored %d entities" % report.get("restored_count", 0))

The signal bridge reacts to lifecycle events. It does not save fields and cannot replace StateSource.

Listen Modes​

Use Owner Only when the signal node should observe one Source or Scope.

Use Owner And Descendants when it should observe a nested domain.

Use All Pipeline Events only for global debug or UI feedback nodes.

Why This Exists​

Without signal bridges, users often subclass Sources just to run small side effects.

Signals keep data ownership and presentation behavior separate:

  • Sources own save/load data
  • gameplay nodes respond to save/load events
  • UI can show feedback without becoming part of the saved payload