Globalsync

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