As with the chat example, the Peer event group is a little simpler than that of the host. Remember that Sync object creates, moves and destroys objects automatically for peers depending on what happens on the host, so we don't need to worry about that here. The Host group however will have to deal with the logic of how the objects move and interact, which in this case is mostly getting the ball to bounce off paddles, and keeping score.
There is one thing we need to do when creating objects as a peer, though. Sync object will automatically create and destroy objects, but when they are created we need to set their peerid instance variable so we can later know which peer the object represents. When Sync object creates an object, the object's On created event triggers and the Multiplayer.PeerID expression is set to the ID of the peer for whom the object is being created. This allows us to remember who the peer is. Also, as with all objects representing peers, we use the Associate object with peer action to indicate this object represents a connected peer. (This must always be done on both the host and peer sides.)
Next, the peer needs to send its inputs to the host. On client update triggers for peers when the multiplayer engine is about to send inputs to the host, so we should tell the Multiplayer object the latest values. All we need to do is tell the host our paddle's Y co-ordinate. The paddle is placed by our mouse cursor, so we just set the "y" input value (which we added on start of layout) to the mouse Y position.
Finally, the host is in control of the game, and decides when we move from "get ready" to "go!". In order to keep our GameState global variable synchronised with the host, whenever we receive a "gamestate-changed" message we update the global variable.
That's it for the peer-specific events!