Try it out!
Click or scan the QR code above to launch a new CodePen instance of this session. Compare the two sessions - you’ll see that the animated simulations are identical. The balls all move and bounce exactly the same way.Interactive Elements
Click any ball to stop/start it - changes sync to all users
Non-interactive Elements
The rounded rectangle bounces but ignores user actions
What You’ll Learn
1. Simulation Model
How to create a model that runs physics simulations
2. Interactive View
Building views that respond to user interactions
3. Safe Communication
Properly communicating between Model and View
Architecture Overview
This application uses two Multisynq Model subclasses:MyModel
and BallModel
. Both classes must be registered with Multisynq for proper synchronization.
Using Multisynq Constants
The app usesMultisynq.Constants
to ensure all users share the same configuration values:
Models must not use global variables, but global constants are fine.
Multisynq.Constants
is recursively frozen once a session starts to prevent accidental modification.Simple Animation Model
MyModel - Root Model
MyModel
is the root model passed to Multisynq.Session.join()
. It creates and stores the BallModel
objects in the MyModel.children
array.
BallModel - Individual Ball Logic
EachBallModel
represents a shaped, colored, bouncing ball. The model stores only the data needed for synchronization:
- Shape: String (
'circle'
or'roundRect'
) - Color: Random color value
- Position: Current x,y coordinates
- Speed: Velocity vector
Event Subscription
BallModel
subscribes to the 'touch-me'
event using its own ID as scope. This ensures that only the specific ball responds to touch events intended for it.
Simulation Loop
BallModel
schedules its first step()
method invocation. This creates a continuous simulation loop:
25 balls ticking at 30Hz generates 750 messages per second, but future messages are very efficient with minimal overhead.
Movement and Bouncing
moveBounce()
method updates ball position and handles wall collisions. When a ball hits a wall, it gets a new random speed vector.
Deterministic Random Speed
This uses Multisynq’s replicated random number generator. Every session instance computes the same sequence of random numbers, ensuring identical bouncing behavior across all users.
Simple Animation View
The View comprises two classes:MyView
and BallView
.
MyView - Container View
MyView
is called when a session instance starts, receiving the MyModel
object as an argument. It builds the visual representation and container for all balls.
Creating Child Views
MyView
accesses the model’s children collection and creates a BallView
for each BallModel
.
It’s fine for views to read from models directly, but views MUST NOT modify models in any way.
Responsive Scaling
MyView
listens for browser “resize” events and adjusts the view scale accordingly. This ensures all users see the same scene regardless of their window size.
Cleanup on Detach
BallView - Individual Ball Display
EachBallView
tracks its associated BallModel
and handles visual representation and user interaction.
Position Updates
BallView
subscribes to 'pos-changed'
events from its specific model. The "oncePerFrame"
handling ensures efficient rendering even with multiple position updates per frame.
Touch/Click Handling
BallView
sets up touch/click handlers that publish 'touch-me'
events. The corresponding BallModel
subscribes to these events and toggles ball motion on and off.
Key Concepts Demonstrated
Model-View Separation
Model-View Separation
- Models handle all logic and state
- Views handle display and user input
- Communication happens only through events
Deterministic Simulation
Deterministic Simulation
- All instances run identical physics calculations
- Synchronized random number generation
- Consistent timing across all users
Efficient Event Handling
Efficient Event Handling
- Scoped events using object IDs
- Frame-rate limited updates
- Minimal overhead for future scheduling
Interactive Synchronization
Interactive Synchronization
- User actions sync across all sessions
- Individual object state management
- Immediate feedback with global updates
Next Steps
Now that you understand basic animation and interaction patterns, you can explore:Multi-user Chat
Learn to handle user input and message synchronization
View Smoothing
Create smoother animations with interpolation techniques
Best Practices
Use Constants
Store shared configuration in
Multisynq.Constants
Scope Events
Use object IDs to scope events to specific instances
Efficient Updates
Use
"oncePerFrame"
handling for frequent updatesClean Resources
Implement proper cleanup in
detach()
methods