Repository navigation
Collaborative Editing
SparkEngine's collaborative editing system enables multiple editor instances to work on the same scene simultaneously, inspired by HeroEngine's live collaborative editing. The system provides real-time peer presence awareness, node-level locking, edit broadcasting, and optional live push to running game servers.
Release boundary: Collaboration and its broker/client/service paths are experimental development implementations outside the blocked and uncertified
stable-v1service-free profile. This page is implementation guidance, not a production or deployment-support claim.
[Editor A] ── local IPC ──► [SparkCollabServer] ◄── local IPC ── [Editor B]
│ presence / locks / edits │
└──────── CollaborativeEditSession editor API ─────────────────┘
│
LiveEditBridge (optional)
│
[AreaServer]
SparkCollabServer is the development reference authority. The editor's existing
CollaborativeEditSession API translates selection, camera presence, node
locks, and serialized EditMessage objects through
StandaloneCollaborationClient, so hierarchy and viewport callers do not need
a second collaboration API. The older direct TCP peer-hosted mode remains
available as an explicit fallback for ad-hoc sessions.
| Layer | System | Purpose |
|---|---|---|
| Editor Collaboration |
CollaborativeEditSession + StandaloneCollaborationClient
|
Editor API backed by the standalone broker (or explicit peer fallback) |
| Collaboration Authority | SparkCollabServer |
Capability-authenticated presence, locks, ordered edit history, and snapshots |
| Editor ↔ Engine IPC | EngineInterface |
Named pipe communication with local engine process |
| Live Push | LiveEditBridge |
Forward edits to a running AreaServer for live game updates |
These are intentionally separate systems. Editor collaboration uses TCP for reliable ordered delivery of edits. Game networking uses UDP for low-latency gameplay. The LiveEditBridge connects the two when live editing of a running game world is desired.
The current development path keeps collaborative editing logic in the editor-side integration, so the examples do not require game-module code. Coverage and release integration remain unverified:
- Hosting/joining: Use the Collaboration panel (View > Collaboration) to host or join sessions
- Locking: The editor automatically acquires/releases locks when you select and edit nodes
- Edit broadcasting: Property changes in the Inspector and object operations in the Hierarchy are automatically broadcast to all connected editors
- Presence: Other editors' selections and viewport positions are shown automatically in the Scene View
The C++ code examples below are internal API reference showing how the editor's subsystems work under the hood. They are provided for engine developers extending the collaborative editing system, not for game developers using it.
- Start
SparkCollabServer --socket spark-collab-project-a(the Service Topology panel can start it). - Open the Collaboration panel from View > Collaboration.
- Leave Use standalone SparkCollabServer enabled and enter the matching endpoint and a project session ID.
- One editor clicks Create Broker Session; other editors click Join Broker Session.
- Edit the scene normally — locking, broadcasting, and presence are automatic.
- Disconnecting an editor releases its capabilities and locks without stopping the broker.
The following C++ examples show the editor's internal implementation. You do not need to write this code — it runs automatically when you use the Collaboration panel.
SparkEditor::CollaborativeEditSession session;
session.Host(27030, "Alice"); // Opens TCP listener on port 27030session.Connect("192.168.1.100", 27030, "Bob"); // TCP connect with 5s timeoutThe editor automatically locks nodes when you select them for editing:
if (session.RequestLock("Entity_42"))
{
// Lock acquired — safe to edit
SparkEditor::EditMessage msg;
msg.type = SparkEditor::EditMessageType::NodeModified;
msg.sourceEditor = session.GetLocalPeerID();
msg.nodeId = "Entity_42";
msg.propertyName = "position";
msg.newValue = "10.0, 5.0, 3.0";
session.BroadcastEdit(msg);
session.ReleaseLock("Entity_42");
}
else
{
auto owner = session.GetLockOwner("Entity_42");
auto* peer = session.GetPeer(owner);
// Display: "Locked by Bob"
}The editor broadcasts selection and camera state automatically:
// These are called internally by HierarchyPanel and SceneViewPanel
session.SetLocalSelection("Entity_42");
session.SetLocalViewportCamera(cameraPos, cameraDir);
// Called each frame by EditorUI::Update()
session.Update(deltaTime);
// SceneViewPanel renders peer overlays automatically
auto peers = session.GetConnectedPeers();
for (const auto& peer : peers)
{
// Draw peer's name tag with color and selection info
}These are wired automatically by EditorUI::WireCallbacks():
session.SetPeerConnectedCallback([](const SparkEditor::EditorPeer& peer) {
LOG("Editor '%s' joined", peer.userName.c_str());
});
session.SetEditReceivedCallback([](const SparkEditor::EditMessage& msg) {
// Apply the edit locally
});
session.SetLockChangedCallback([](const std::string& nodeId, SparkEditor::PeerID owner) {
// Update lock indicators in the UI
});Run the isolated development broker without a GUI:
SparkCollabServer --socket spark-collab-project-aThis mode:
- Uses an owner-local Windows named pipe or POSIX Unix-domain socket
- Authenticates each peer with an expiring capability token
- Arbitrates node locks and retains bounded, ordered edit history
- Serves canonical peer/lock/edit snapshots to every connected editor
- Supports graceful shutdown through the shared control protocol
The Collaboration panel defaults to this path. Uncheck Use standalone SparkCollabServer only when you intentionally want the legacy peer-hosted TCP mode.
The LiveEditBridge enables HeroEngine-style live editing where changes made by editors appear in the running game world in real-time. This is also handled within the editor — no game module code is needed. The editor's Collaboration panel will include a "Connect to AreaServer" option when an AreaServer is running.
Editor → CollaborativeEditSession → LiveEditBridge → AreaServer → Game Clients
// Created and managed by EditorUI — not user code
SparkEditor::LiveEditBridge bridge;
bridge.Connect("192.168.1.200", 27031, "EditorAlice"); // AreaServer inter-server port
// Edits are forwarded automatically when HierarchyPanel operations occur
bridge.PushEdit(editMessage);
// Called each frame by EditorUI::Update()
bridge.Update();The bridge uses UserDefined message types (starting at 1000) to avoid collision with game messages:
| Type | Value | Description |
|---|---|---|
SceneEdit |
1000 | A scene edit (node/component change) |
LockNotify |
1001 | Lock state change notification |
EditorJoin |
1002 | Editor connecting as privileged client |
EditorLeave |
1003 | Editor disconnecting |
The Collaboration panel (View → Collaboration) provides:
- Connection controls: Host or join a session with username and port
- Peer list: Shows all connected editors with their colors and current selections
- Lock list: Active locks with owner names, durations, and release buttons
- Edit log: Recent edit activity across all peers
- Session stats: Peer count, lock count, edit counts, session duration
When a collaborative session is active, the Scene View panel shows:
- Name tags: Each remote peer's username displayed in their assigned color
- Selection info: What node each peer is currently editing
- Tags appear in the top-right corner of the viewport
| Type | Description |
|---|---|
NodeAdded |
A new node was added to the scene |
NodeRemoved |
A node was removed from the scene |
NodeModified |
A node's properties were changed |
NodeMoved |
A node's transform was changed |
NodeRenamed |
A node was renamed |
ComponentAdded |
A component was added to an entity |
ComponentRemoved |
A component was removed from an entity |
ComponentModified |
A component's properties were changed |
- Locks are pessimistic — only one editor can lock a node at a time
- Locks auto-expire after 5 minutes (configurable via
NodeLock::maxDurationSeconds) - When an editor disconnects, all their locks are released automatically
- Lock ownership is tracked with editor name for UI display
- Double-locking the same node by the same peer is idempotent (succeeds)
Messages are sent as length-prefixed TCP frames:
[4 bytes: message length N] [N bytes: serialized InternalMessage]
The serialization uses big-endian integers and length-prefixed strings. Maximum message size is 16 MB.
-
CollaborativeEditSessionuses one network thread for socket I/O plus per-client handler threads on the host - Message queues (
m_incomingMessages,m_outgoingMessages) are mutex-protected -
m_connectedandm_shuttingDownusestd::atomic<bool>with appropriate memory ordering - Peer map and lock map have separate mutexes (
m_peerMutex,m_lockMutex) - The main thread drains queues and fires callbacks — callbacks always run on the main thread
auto stats = session.GetStats();
// stats.peerCount, stats.activeLocks, stats.editsBroadcast, stats.editsReceived, stats.sessionDuration- Pessimistic locking over CRDTs/OT for simplicity and predictability in small teams (2-10 editors)
- Node-level granularity (not property-level) reduces lock contention while keeping the protocol simple
- Auto-expiry prevents forgotten locks from blocking other editors
- TCP for editor collaboration (reliable, ordered) vs UDP for game networking (low-latency)
- Separate networking stacks — editor collab and game networking serve fundamentally different needs
- Peer-hosted by default — no infrastructure required; dedicated server mode available for larger teams
| File | Description |
|---|---|
SparkEditor/Source/Communication/CollaborativeEditSession.h |
Editor-facing session API and broker/peer mode ownership |
SparkEditor/Source/Communication/CollaborativeEditSession.cpp |
Editor translation, snapshots, callbacks, and legacy TCP fallback |
SparkEditor/Source/Communication/StandaloneCollaborationClient.* |
Typed development client for the broker protocol |
SparkDaemon/src/CollaborationProtocol.h |
Bounded versioned collaboration wire DTOs and codecs |
SparkDaemon/src/CollaborationService.* |
Authoritative presence, lock, and edit-history service |
SparkDaemon/src/CollabServerMain.cpp |
Standalone process entry point |
SparkEditor/Source/Communication/LiveEditBridge.h |
Live push bridge to AreaServer |
SparkEditor/Source/Communication/LiveEditBridge.cpp |
Bridge implementation |
SparkEditor/Source/Panels/CollaborationPanel.h |
Collaboration UI panel |
SparkEditor/Source/Panels/CollaborationPanel.cpp |
Panel implementation |
SparkEditor/Source/main.cpp |
--collab-server CLI mode |
Tests/TestCollaborativeEditing.cpp |
Unit tests |
SparkDaemon/tests/CollabProcessSmoke.cpp |
Black-box process/client startup, operation, and shutdown smoke test |
- SparkEditor — Editor overview
- Networking — Base networking system (game networking)
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers