Network Sync Demo
This is an interactive demo showcasing @esengine/network network synchronization tools.
Left side is the client view (the player you control), right side is the server authoritative state. Switch between different modes to observe the effects of various synchronization strategies.
Controls:
- Keyboard: WASD or arrow keys to move
- Touch/Mouse: Virtual joystick in the bottom-left corner
Four Sync Mode Comparison
Section titled “Four Sync Mode Comparison”1. No Sync
Section titled “1. No Sync”Client directly responds to input without considering server state.
Problem: Client and server states gradually diverge, red warning ring shows divergence distance.
2. Interpolation
Section titled “2. Interpolation”Client waits for server state, uses SnapshotBuffer for interpolation display.
Problem: Noticeable input delay (feels “sluggish”) because it waits for server confirmation.
3. Client Prediction
Section titled “3. Client Prediction”Uses framework ClientPrediction API for immediate response, corrects when receiving server state.
Feature: Green dashed circle shows server’s actual position, may have slight position snapping.
4. Full Solution
Section titled “4. Full Solution”Combines prediction + HermiteTransformInterpolator + smoothDamp smooth correction.
Features:
- Green dashed line: Server’s actual position
- Red arrow: Correction vector (from predicted to server position)
- Remote players use Hermite curve interpolation for smoother movement
- AI player follows a fixed figure-8 path for easier observation of sync effects
Framework APIs Used
Section titled “Framework APIs Used”1. SnapshotBuffer - Snapshot Buffer
Section titled “1. SnapshotBuffer - Snapshot Buffer”import { createSnapshotBuffer } from '@esengine/network';
// Create snapshot bufferconst buffer = createSnapshotBuffer<PlayerState>( 30, // maxSize: Maximum snapshot count 100 // interpolationDelay: Interpolation delay (ms));
// Store server state when receivedbuffer.push({ timestamp: serverTimestamp, state: playerState});
// Get snapshots for interpolationconst renderTime = Date.now() - 100;const result = buffer.getInterpolationSnapshots(renderTime);
if (result) { const [prevSnapshot, nextSnapshot, t] = result; // t is the interpolation factor between 0~1}2. ClientPrediction - Client Prediction
Section titled “2. ClientPrediction - Client Prediction”import { createClientPrediction } from '@esengine/network';
// Define predictorconst predictor = { predict(state, input, deltaTime) { return { x: state.x + input.dx * SPEED * deltaTime, y: state.y + input.dy * SPEED * deltaTime, vx: input.dx * SPEED, vy: input.dy * SPEED }; }};
// Create prediction managerconst prediction = createClientPrediction(predictor, { maxUnacknowledgedInputs: 60, reconciliationThreshold: 0.5, reconciliationSpeed: 10});
// Each frame: record input and predictconst predictedState = prediction.recordInput(input, currentState, deltaTime);
// When receiving server state: reconcileconst reconciledState = prediction.reconcile( serverState, acknowledgedSequence, state => ({ x: state.x, y: state.y }), deltaTime);3. HermiteTransformInterpolator - Hermite Curve Interpolation
Section titled “3. HermiteTransformInterpolator - Hermite Curve Interpolation”import { createHermiteTransformInterpolator } from '@esengine/network';
// Create Hermite interpolator (smoother than linear interpolation)const hermiteInterpolator = createHermiteTransformInterpolator();
// Use velocity information for smooth interpolationconst result = hermiteInterpolator.interpolate( { x: 0, y: 0, rotation: 0, velocityX: 10, velocityY: 0, angularVelocity: 0 }, { x: 100, y: 50, rotation: 0, velocityX: 5, velocityY: 5, angularVelocity: 0 }, 0.5 // t = 0.5);4. smoothDamp - Smooth Damping
Section titled “4. smoothDamp - Smooth Damping”import { smoothDamp } from '@esengine/network';
// Smoothly transition to target value (used for correction offset)const [newValue, newVelocity] = smoothDamp( currentValue, // Current value targetValue, // Target value velocity, // Current velocity (will be updated) smoothTime, // Smooth time deltaTime, // Frame time maxSpeed // Maximum speed (optional));Network Sync Best Practices
Section titled “Network Sync Best Practices”1. Server Authority
Section titled “1. Server Authority”Server is the single "source of truth"Client only "predicts" and "displays"Server can detect any cheating attempts2. Interpolation Delay
Section titled “2. Interpolation Delay”renderTime = currentTime - interpolationDelay
Higher delay → Smoother, but more latencyLower delay → More responsive, but may stutterRecommended: 100-150ms (adjustable via parameter panel)3. Prediction and Correction
Section titled “3. Prediction and Correction”Prediction: Respond immediately, better feelCorrection: Smooth fix when receiving server stateKey: Use smoothDamp to avoid "jumping"4. Hermite vs Linear Interpolation
Section titled “4. Hermite vs Linear Interpolation”Linear: Simple, but not smooth when turningHermite: Uses velocity info, more natural curvesRecommended: Use Hermite for remote playersRelated Documentation
Section titled “Related Documentation”- Network Module API - Complete API documentation
- Lockstep Guide - Lockstep implementation
- State Sync Guide - State synchronization details