GlobalSync - Real-time Multiplayer
GlobalSync is Globio's real-time multiplayer service. Build FPS games, battle royales, card games, and any multiplayer experience with low-latency networking.
🚀 Quick Start
import { GlobalSync } from '@stanlink/globio/gaming'
const sync = new GlobalSync({
apiKey: 'your-api-key',
projectId: 'your-project-id'
})
// Join a multiplayer room
const room = sync.room('battle-royale-1')
await room.join('player123', { name: 'John', level: 5 })
// Send game events
room.broadcast('player-move', { x: 100, y: 200, z: 50 })
// Listen for events
room.on('player-move', (data, fromPlayer) => {
updatePlayerPosition(fromPlayer, data)
})🎮 Room Management
Creating Rooms
// Create a room with configuration
const roomConfig = {
maxPlayers: 4,
gameMode: 'team-deathmatch',
map: 'desert-storm',
private: false,
password: null
}
const room = await sync.createRoom(roomConfig)
console.log('Room created:', room.id)Joining Rooms
// Join specific room
const room = sync.room('room-123')
await room.join('player456', {
name: 'Alice',
character: 'warrior',
team: 'blue'
})
// Auto-join available room
const room = await sync.findAndJoinRoom({
gameMode: 'battle-royale',
region: 'us-east',
skillLevel: 1500
})Room States
// Get room information
const roomInfo = await room.getInfo()
console.log('Players:', roomInfo.players.length)
console.log('Game state:', roomInfo.gameState)
console.log('Started at:', roomInfo.startTime)
// Listen for room updates
room.on('room-updated', (roomInfo) => {
updateLobbyUI(roomInfo)
})
// Listen for players joining/leaving
room.on('player-joined', (playerId, playerData) => {
console.log(`${playerData.name} joined the game`)
addPlayerToGame(playerId, playerData)
})
room.on('player-left', (playerId) => {
console.log(`Player ${playerId} left the game`)
removePlayerFromGame(playerId)
})🎯 Game Types
FPS/Action Games
// High-frequency position updates
setInterval(() => {
room.broadcast('player-position', {
x: player.position.x,
y: player.position.y,
z: player.position.z,
rotation: player.rotation,
timestamp: Date.now()
})
}, 50) // 20 FPS
// Weapon firing
room.broadcast('weapon-fire', {
weapon: 'assault-rifle',
origin: player.position,
direction: player.aimDirection,
timestamp: Date.now()
})
// Hit detection
room.on('weapon-fire', (data, fromPlayer) => {
if (isPlayerHit(data.origin, data.direction, localPlayer.position)) {
room.sendTo(fromPlayer, 'hit-confirmed', {
target: localPlayer.id,
damage: calculateDamage(data.weapon)
})
}
})Turn-Based Games
// Card game example
room.on('game-started', () => {
if (isMyTurn()) {
enableCardSelection()
}
})
// Play a card
function playCard(cardId) {
room.broadcast('card-played', {
playerId: localPlayer.id,
cardId: cardId,
turnNumber: currentTurn
})
endTurn()
}
// Handle opponent's move
room.on('card-played', (data, fromPlayer) => {
if (fromPlayer !== localPlayer.id) {
animateOpponentCard(data.cardId)
processGameLogic(data)
}
})Battle Royale
// Zone management
room.on('zone-update', (zoneData) => {
updateSafeZone(zoneData.center, zoneData.radius)
showZoneTimer(zoneData.nextShrinkTime)
})
// Player elimination
room.broadcast('player-eliminated', {
eliminatedPlayer: 'player123',
eliminatedBy: 'player456',
playersRemaining: 23,
placement: 24
})
// Loot spawning
room.on('loot-spawned', (lootData) => {
spawnLootItems(lootData.items, lootData.locations)
})🔄 State Synchronization
Authoritative Server
// Server-side game state (in GlobalCode function)
export default async function gameStateUpdate(data, context) {
const { roomId, playerId, action } = data
// Get current game state
const gameState = await getGameState(roomId)
// Validate and process action
if (isValidAction(action, playerId, gameState)) {
const newState = processAction(action, gameState)
// Save updated state
await saveGameState(roomId, newState)
// Broadcast to all players
await broadcastToRoom(roomId, 'state-update', newState)
return { success: true, newState }
}
return { success: false, error: 'Invalid action' }
}Client-Side Prediction
// Predict movement locally for smooth gameplay
function movePlayer(direction) {
// Apply movement immediately (prediction)
const predictedPosition = calculateNewPosition(player.position, direction)
player.position = predictedPosition
updatePlayerVisual()
// Send to server for validation
room.broadcast('move-request', {
direction,
timestamp: Date.now(),
predictedPosition
})
}
// Handle server correction
room.on('position-correction', (data) => {
if (data.playerId === localPlayer.id) {
// Server disagreed with prediction, correct position
player.position = data.correctedPosition
updatePlayerVisual()
}
})Lag Compensation
// Timestamp-based lag compensation
room.on('player-action', (data, fromPlayer) => {
const latency = Date.now() - data.timestamp
const compensatedTime = data.timestamp + (latency / 2)
// Rewind game state to when action was performed
const historicalState = getGameStateAtTime(compensatedTime)
// Process action with historical context
processActionWithState(data.action, historicalState)
})📱 Platform Examples
Unity C#
// Unity multiplayer
public class MultiplayerManager : MonoBehaviour {
private GlobalSync sync;
private Room currentRoom;
async void Start() {
sync = new GlobalSync("your-api-key");
// Join room
currentRoom = sync.Room("game-room-1");
await currentRoom.Join("player123", new {
name = "Player",
character = "warrior"
});
// Listen for events
currentRoom.On("player-move", OnPlayerMove);
currentRoom.On("player-attack", OnPlayerAttack);
}
void Update() {
// Send position updates
if (playerMoved) {
currentRoom.Broadcast("player-move", new {
x = transform.position.x,
y = transform.position.y,
z = transform.position.z
});
}
}
void OnPlayerMove(object data, string fromPlayer) {
// Update other player's position
var moveData = JsonUtility.FromJson<MoveData>(data.ToString());
UpdatePlayerPosition(fromPlayer, moveData);
}
}Flutter/Dart
// Flutter multiplayer
class MultiplayerService {
late GlobalSync _sync;
Room? _currentRoom;
Future<void> initialize() async {
_sync = GlobalSync(apiKey: 'your-api-key');
}
Future<void> joinRoom(String roomId, String playerId) async {
_currentRoom = _sync.room(roomId);
await _currentRoom!.join(playerId, {
'name': 'Player',
'avatar': 'knight'
});
// Listen for game events
_currentRoom!.on('game-update', _onGameUpdate);
_currentRoom!.on('player-joined', _onPlayerJoined);
}
void sendGameAction(String action, Map<String, dynamic> data) {
_currentRoom?.broadcast(action, data);
}
void _onGameUpdate(dynamic data, String fromPlayer) {
// Update game state
GameState.instance.updateFromNetwork(data);
}
}🔧 Advanced Features
Room Persistence
// Save room state to database
await room.saveState({
gameMode: 'survival',
wave: 15,
playersAlive: 2,
timeElapsed: 1800000, // 30 minutes
worldState: compressedWorldData
})
// Restore room state
const savedState = await room.loadState()
if (savedState) {
restoreGameFromState(savedState)
}Spectator Mode
// Join as spectator
await room.joinAsSpectator('spectator123')
// Spectators receive all game events but can't send actions
room.on('*', (eventType, data, fromPlayer) => {
updateSpectatorView(eventType, data, fromPlayer)
})
// Switch spectator target
room.sendSpectatorCommand('follow-player', { targetPlayer: 'player456' })Anti-Cheat Integration
// Validate actions server-side
room.on('player-action', async (data, fromPlayer) => {
// Check if action is possible given current game state
const isValid = await validateAction(data, fromPlayer, currentGameState)
if (!isValid) {
// Flag potential cheating
await flagSuspiciousActivity(fromPlayer, data)
// Don't broadcast invalid action
return
}
// Broadcast valid action to other players
room.broadcastToOthers('validated-action', data, fromPlayer)
})💡 Best Practices
Network Optimization
// Batch multiple updates
const updateBatch = []
updateBatch.push({ type: 'position', data: positionData })
updateBatch.push({ type: 'animation', data: animationData })
updateBatch.push({ type: 'health', data: healthData })
room.broadcast('batch-update', updateBatch)
// Use delta compression for large states
const deltaState = calculateDelta(previousState, currentState)
room.broadcast('state-delta', deltaState)Error Handling
// Handle connection issues
room.on('connection-lost', () => {
showReconnectingMessage()
pauseGame()
})
room.on('connection-restored', () => {
hideReconnectingMessage()
resumeGame()
// Request state sync
room.requestStateSync()
})
// Handle room errors
room.on('error', (error) => {
console.error('Room error:', error)
switch (error.code) {
case 'ROOM_FULL':
showMessage('Room is full')
break
case 'ROOM_NOT_FOUND':
showMessage('Room no longer exists')
break
case 'KICKED':
showMessage('You were kicked from the room')
break
}
})Next: Learn about GlobalBrain AI →