ServerTransferQueue¶
The ServerTransferQueue table manages the pipeline for transferring player characters between servers in a QS-Bridge cluster. Each row represents a transfer request and tracks its progress through a multi-step state machine — from initial request through character snapshot, transit, and completion on the destination server.
Scope¶
🌍 Global — Transfer records are visible to all servers and the admin panel. Both the source and destination servers must be able to read the transfer record to coordinate the handoff.
Schema¶
| Column | Type | Constraints | Description |
|---|---|---|---|
transfer_id |
u64 |
Primary Key, auto-increment | Unique identifier for this transfer request |
player_id |
String |
Indexed | Platform-wide player identifier of the transferring player |
from_server_id |
String |
— | The server_id of the origin server |
to_server_id |
String |
— | The server_id of the destination server |
status |
String |
— | Current transfer state (see state machine below) |
character_snapshot |
String |
— | Serialized character data (JSON format) |
requested_at |
Timestamp |
— | When the transfer was initiated |
completed_at |
Option<Timestamp> |
— | When the transfer reached a terminal state (None if in progress) |
Rust Definition¶
#[spacetimedb::table(public, name = server_transfer_queue)]
pub struct ServerTransferQueue {
#[primary_key]
#[auto_inc]
pub transfer_id: u64,
#[index(btree)]
pub player_id: String,
pub from_server_id: String,
pub to_server_id: String,
pub status: String,
pub character_snapshot: String,
pub requested_at: Timestamp,
pub completed_at: Option<Timestamp>,
}
Transfer State Machine¶
Each transfer progresses through a defined set of states:
graph LR
Pending["pending"] --> InTransit["in_transit"]
InTransit --> Completed["completed"]
Pending --> Failed1["failed"]
InTransit --> Failed2["failed"]
| Status | Description |
|---|---|
pending |
Transfer requested; character snapshot is being captured on the source server |
in_transit |
Snapshot captured; waiting for the destination server to accept and restore |
completed |
Character successfully restored on the destination server |
failed |
Transfer failed at any stage — character data remains on the source server |
State Transitions¶
-
pending— The source server receives the transfer request and begins serializing the player's character data (inventory, stats, position, etc.) into thecharacter_snapshotfield. -
in_transit— The source server has captured the snapshot and disconnected the player. The destination server detects thein_transitrecord (via subscription) and begins restoring the character. -
completed— The destination server has successfully deserialized and applied the character snapshot. The player can now connect to the destination server. -
failed— An error occurred during snapshot capture, transit, or restoration. The player's original data on the source server is preserved.
Usage Patterns¶
Transfer Initiation¶
A transfer is initiated when a player requests to move to another server (or an admin forces a transfer):
// Pseudocode — initiate transfer
fn request_transfer(player_id: &str, from: &str, to: &str) {
ServerTransferQueue::insert(ServerTransferQueue {
transfer_id: 0, // auto-incremented
player_id: player_id.to_string(),
from_server_id: from.to_string(),
to_server_id: to.to_string(),
status: "pending".to_string(),
character_snapshot: String::new(), // Populated during snapshot
requested_at: Timestamp::now(),
completed_at: None,
});
}
Character Snapshot¶
The character_snapshot field stores a JSON-serialized representation of the player's full character state. Like GlobalVault's item_data, this is an opaque payload — the platform does not interpret its contents. The game-specific sub-database defines the snapshot schema.
Example snapshot structure (game-specific):
{
"character_name": "PlayerOne",
"level": 42,
"position": { "x": 100.5, "y": 200.3, "z": 50.0 },
"inventory": [ /* serialized items */ ],
"stats": { "health": 100, "stamina": 80 },
"skills": { /* skill tree data */ },
"equipment": { /* equipped items */ }
}
Coordination with Player Presence¶
During a transfer, the player's PlayerServerPresence row ensures they cannot connect to any server while the transfer is in flight:
- Player is disconnected from the source server → presence row remains (preventing reconnection).
- Transfer reaches
completedstate. - Presence row is updated to reflect the destination
server_id. - Player connects to the destination server.
Failure Recovery¶
If a transfer fails (status = "failed"), the character data remains on the source server. The character_snapshot may still contain the captured data for diagnostic purposes. An administrator can review the failed transfer in the panel and decide whether to retry or cancel.
Related Reducers¶
Transfer operations are primarily managed by game-specific reducers in the sub-database layer, as the snapshot format is game-dependent. Platform-level coordination happens through table subscriptions rather than dedicated platform reducers.
Related Subscriptions¶
| Subscriber | Query | Purpose |
|---|---|---|
| Source Server | SELECT * FROM server_transfer_queue WHERE from_server_id = '{self}' |
Monitor outbound transfers |
| Destination Server | SELECT * FROM server_transfer_queue WHERE to_server_id = '{self}' |
Detect incoming transfers to process |
| Admin Panel | SELECT * FROM server_transfer_queue |
Transfer monitoring, failure review |
For full subscription architecture, see Subscriptions.
Related Pages¶
- GlobalVault — Individual item transfers (vault is lighter-weight than full character transfers)
- PlayerServerPresence — Presence tracking during transfers
- ServerRegistry — Server directory (provides
server_idreferences) - Multi-Server Architecture — Character transfer as a cross-server capability