Master Multisynq’s simulation time and future scheduling system for synchronized time-based behaviors
Understanding Multisynq’s time system is crucial for building applications with animations, timers, and time-dependent behaviors. Unlike real-world time, Multisynq uses simulation time to ensure perfect synchronization across all users.
class GameModel extends Multisynq.Model { init() { console.log("Session started at:", this.now()); // Simulation time this.tick(); } tick() { const currentTime = this.now(); console.log("Simulation time:", currentTime); // All users see identical time values this.future(1000).tick(); // Schedule next tick }}
Simulation time only advances when heartbeat ticks are received from the reflector.
Synchronized, deterministic time used by models
Source: Multisynq reflector heartbeat ticks
Synchronization: Identical across all users
Deterministic: Same time, same results
Access: this.now() in models
Copy
class GameModel extends Multisynq.Model { init() { console.log("Session started at:", this.now()); // Simulation time this.tick(); } tick() { const currentTime = this.now(); console.log("Simulation time:", currentTime); // All users see identical time values this.future(1000).tick(); // Schedule next tick }}
Simulation time only advances when heartbeat ticks are received from the reflector.
Local system time used by views
Source: Local device system clock
Synchronization: Different on each device
Variable: Can drift between devices
Access: Date.now() in views
Copy
class GameView extends Multisynq.View { init() { console.log("View created at:", Date.now()); // Real time this.updateDisplay(); } updateDisplay() { const realTime = Date.now(); const simTime = this.model.now(); console.log("Real time:", realTime); console.log("Sim time:", simTime); // Views can use future() with real time this.future(16).updateDisplay(); // ~60fps }}
Never use Date.now() in models - it breaks synchronization!
class GameView extends Multisynq.View { init() { this.canvas = document.getElementById('canvas'); this.lastFrame = Date.now(); // Start render loop using real time this.renderLoop(); } renderLoop() { const now = Date.now(); const deltaTime = now - this.lastFrame; // Render current frame this.render(deltaTime); this.lastFrame = now; // Schedule next frame (~60fps) this.future(16).renderLoop(); } render(deltaTime) { // Use simulation time for game state const gameTime = this.model.now(); // Use real time for smooth interpolation this.drawGameObjects(gameTime, deltaTime); }}
Views can use future() with real time
Copy
class GameView extends Multisynq.View { init() { this.canvas = document.getElementById('canvas'); this.lastFrame = Date.now(); // Start render loop using real time this.renderLoop(); } renderLoop() { const now = Date.now(); const deltaTime = now - this.lastFrame; // Render current frame this.render(deltaTime); this.lastFrame = now; // Schedule next frame (~60fps) this.future(16).renderLoop(); } render(deltaTime) { // Use simulation time for game state const gameTime = this.model.now(); // Use real time for smooth interpolation this.drawGameObjects(gameTime, deltaTime); }}
Coordinate between sim time and real time
Copy
class SmoothView extends Multisynq.View { init() { this.interpolatedPositions = new Map(); this.renderLoop(); // Listen to model updates this.subscribe("object", "moved", this.onObjectMoved); } onObjectMoved(data) { // Store position with simulation time const interpolation = { startPos: this.interpolatedPositions.get(data.id) || data.position, endPos: data.position, startTime: Date.now(), simTime: this.model.now() }; this.interpolatedPositions.set(data.id, interpolation); } renderLoop() { const realTime = Date.now(); // Smooth interpolation between model updates for (const [id, interp] of this.interpolatedPositions) { const elapsed = realTime - interp.startTime; const progress = Math.min(elapsed / 100, 1); // 100ms interpolation const smoothPos = { x: this.lerp(interp.startPos.x, interp.endPos.x, progress), y: this.lerp(interp.startPos.y, interp.endPos.y, progress) }; this.drawObject(id, smoothPos); } this.future(16).renderLoop(); // ~60fps }}
// ✅ Good: Different rates for different systemsthis.updatePhysics(); // 60fps - needs precisionthis.updateAI(); // 10fps - less criticalthis.updateNetworking(); // 20fps - moderate// ❌ Avoid: Everything at maximum ratethis.future(16).updateEverything(); // Wasteful
Copy
// ✅ Good: Batch related operationsthis.future(100).batchUpdate();batchUpdate() { this.updateMultipleThings(); this.processAllChanges(); this.future(100).batchUpdate();}
🎯 Precision
Use appropriate timing precision
Copy
// ✅ Good: Match timing to needthis.future(1000/60).renderFrame(); // 60fps for smooth animationthis.future(1000/20).checkCollisions();// 20fps for game logicthis.future(5000).saveProgress(); // 5s for persistence// ❌ Avoid: Inappropriate frequenciesthis.future(1).highFrequencySpam(); // Too fastthis.future(10000).criticalGameLogic(); // Too slow
Mastering simulation time and the future() method is essential for creating responsive, synchronized applications. Always use simulation time in models and real time in views to maintain perfect synchronization across all users.
Assistant
Responses are generated using AI and may contain mistakes.