Live Sync
Live Sync connects Godot to the StoryFlow Editor via WebSocket, letting you edit your project and see changes reflected in the engine in real time - no manual re-export and re-import after every change.
Overview
Live Sync establishes a WebSocket connection between the Godot Editor and the StoryFlow Editor running on the same machine. When you save changes in the StoryFlow Editor, those changes are automatically pushed to Godot and re-imported, keeping your in-engine project data up to date without any manual steps.
- Real-time synchronization - edit in StoryFlow, see results in Godot immediately
- WebSocket-based communication using
ws://localhost:9000by default - Automatic re-import of the full project when changes are detected
- Built-in editor dock UI for connecting, disconnecting, and configuring the port
Editor-Only Feature
Live Sync is provided by the editor dock and StoryFlowWebSocketSync class, which lives in the editor/ folder of the plugin. It is only available in the Godot Editor and is not included in exported builds. This is intentional - Live Sync is a development workflow tool, not a runtime feature.
Architecture
Live Sync is built from two components that work together to manage the connection and synchronization lifecycle:
- Editor Dock - The UI panel added to the Godot Editor when the plugin is enabled. It provides connect/disconnect buttons, host and port configuration fields, and a status label showing the current connection state. The dock uses a timer to call
poll()at a 0.1-second interval to process incoming WebSocket messages. - StoryFlowWebSocketSync - The GDScript class that handles the low-level WebSocket connection, reconnection logic, message parsing, and project re-import. It receives incoming project update messages from the StoryFlow Editor and coordinates the re-import process through
StoryFlowImporter.
Setup
Getting Live Sync running takes just a few steps. Make sure both the StoryFlow Editor and Godot Editor are open on the same machine.
Step 1: Open your project in the StoryFlow Editor
The StoryFlow Editor runs a sync server that listens for incoming WebSocket connections. Open the project you want to synchronize - the server starts automatically.
Step 2: Connect from Godot using the editor dock
In the Godot Editor, look for the StoryFlow dock panel. It shows a port field (default: 9000) and a Connect button. Click Connect to establish the WebSocket connection to the StoryFlow Editor running on the same machine.
Step 3: Edit and iterate
From this point on, any changes you save in the StoryFlow Editor are automatically pushed to Godot. The dock's status label updates to show when a sync is in progress or complete. You do not need to manually re-export or re-import - it happens automatically.
First Sync
On initial connection, the editor dock can request a full sync to pull the complete project from the StoryFlow Editor. This ensures your Godot project matches the current state of your story, even if you made changes before connecting.
Connection Controls
The editor dock provides the following controls:
- Port field - The port number for the WebSocket connection. Defaults to
9000. Must match the port configured in the StoryFlow Editor. - Connect button - Establishes the WebSocket connection to the StoryFlow Editor's sync server.
- Disconnect button - Closes the active WebSocket connection and stops any reconnection attempts.
- Sync button - Manually triggers a full re-sync of the project while connected.
- Status label - Shows the current connection state: disconnected, connecting, connected, or syncing.
You can also interact with StoryFlowWebSocketSync directly from GDScript if you need programmatic control:
# Programmatic access to WebSocket sync
var sync: StoryFlowWebSocketSync = StoryFlowWebSocketSync.new()
# Connect with default port (9000)
sync.connect_to_editor()
# Connect with custom port
sync.connect_to_editor(9000)
# Check connection status
if sync.is_connected_to_editor():
print("Connected to StoryFlow Editor")
# Request a full project sync
sync.request_sync()
# Set the output directory for imported files
sync.set_output_dir("res://storyflow_data/")
# Disconnect
sync.disconnect_from_editor() Signals
StoryFlowWebSocketSync exposes three signals you can connect to for responding to connection and sync events:
-
connected()- Fires when the WebSocket connection to the StoryFlow Editor is successfully established. -
disconnected()- Fires when the connection is lost, whether due to the editor closing, a network issue, or an explicitdisconnect_from_editor()call. -
sync_complete(project: StoryFlowProject)- Fires when a full project sync finishes. The parameter is the newly imported project resource, ready to be used by yourStoryFlowComponentinstances.
# Connecting to Live Sync signals
func _ready() -> void:
var sync: StoryFlowWebSocketSync = get_sync_instance()
sync.connected.connect(_on_sync_connected)
sync.disconnected.connect(_on_sync_disconnected)
sync.sync_complete.connect(_on_sync_complete)
func _on_sync_connected() -> void:
print("StoryFlow Live Sync connected")
func _on_sync_disconnected() -> void:
print("StoryFlow Live Sync disconnected")
func _on_sync_complete(project: StoryFlowProject) -> void:
print("StoryFlow project synced: ", project.title) How It Works Internally
Understanding the internal flow helps when debugging sync issues or extending the system:
- Connection -
StoryFlowWebSocketSyncestablishes a WebSocket connection to the StoryFlow Editor's sync server at the specified host and port. - Polling - The editor dock runs a timer at a 0.1-second interval that calls
poll()on the sync instance. This processes any incoming WebSocket messages. - Change detection - When you save changes in the StoryFlow Editor, it pushes the updated project data over the WebSocket. The sync class handles
"project-updated"messages (push from editor) and"pong"keep-alive responses. - Re-import - When project data arrives,
StoryFlowWebSocketSyncpasses the JSON data to theStoryFlowImporter, which processes all project files (scripts, characters, assets) and creates or updates the corresponding Godot resources. - Completion - The
sync_completesignal fires with the newStoryFlowProject, notifying any listeners that the project has been updated. - Component update - Active
StoryFlowComponentinstances automatically pick up the updated project through the manager, so running dialogues can reflect the latest changes.
Reconnection
If the WebSocket connection drops unexpectedly - for example, if the StoryFlow Editor is restarted or the connection is interrupted - the sync class automatically attempts to reconnect.
- Up to 5 reconnection attempts are made automatically, one per poll cycle
- Connection state changes are broadcast through the
connected()anddisconnected()signals - If all reconnection attempts fail, the
disconnected()signal fires and you will need to click Connect again in the dock (or callconnect_to_editor()) manually
Monitoring Connection Status
Use is_connected_to_editor() to check the current connection state at any time. The editor dock's status label also updates automatically, so you always know whether Live Sync is active without writing any code.
Limitations
There are a few limitations to be aware of when using Live Sync:
- Editor-only - Live Sync lives in the
editor/folder of the plugin and is not available in exported builds. It is strictly a development workflow tool. - Local only - The connection always targets
localhost, which requires the StoryFlow Editor to be running on the same machine as the Godot Editor. - Full re-import - Each sync performs a complete re-import of the entire project rather than incremental updates. For very large projects, this may take a moment, but for most projects the import is near-instant.