Mosaic synchronisation and z-index
March 15th, 2006 in The Making of TheBroth · By Markus WeichselbaumAs TheBroth is a multiplayer, near real-time application, we need to synchronize players with each other and with the system, so that each player sees the exact same thing in their browser.

The tricky part of this complex issue arises from the z-index. This is a value that defines the order of overlapping elements on a webpage. In the case of TheBroth’s mosaics, the z-index defines which tiles are above or below other tiles.
As human players, what we instinctly expect is that if you grab a tile, it is by definition above all other tiles, and when you drag it somewhere, the dragged tile will end up above all other tiles, ie, it has the highest z-index.
Exploring the z-index
The z-index, technically, is a property of the style of an object. An object’s z-index would be referenced and written to using the following syntax:
Note that if you were to define the z-index of an object using CSS, you write it as “z-index” (with the hyphen):
<style type="text/css">
#mydiv {z-index: 10;}
</style>
When you access this property using JavaScript, the syntax is “zIndex”. The style object itself is a child object of an object.
<script type="text/javascript">
mydiv=document.getElementById('mydiv');
mydiv.style.zIndex=10;
</script>
Whichever object has the highest z-index will appear on top of other objects. The actual value is not important - the elements are rendered by the browser simply in order of each element’s z-index.
The element with the smallest z-index is drawn first and appears “at the bottom”, the object with highest z-index is drawn last and appears on top, above all other objects.
Synchronizing the z-index for all players
Our goal was to ensure that no matter how many players are active, everyone gets to see exactly the same mosaic, with the tiles overlapping in the exact same order.
The trick here is to devise an algorithm that keeps the order in which tiles were moved intact, because this order determines the z-index for each tile - what was moved last, should be on top, even if the tile you move is always on top, from your point of view.
Our algorithm for this is described below.
At thebroth.com, there can be more than one active mosaic, with different tile positions and different players. For each mosaic we keep a move counter that increments whenever a tile is moved. In terms of database structures, we refer to each mosaic as a “set”, thus this move counter is stored in the set table, and we’ll refer to it as a logical entity of “set move counter”.
Writing the new tile position(s) to the server
When a player drags a tile, the new position of the tile is written to the server. All the data of each tile is stored in what we call a “slot” in the slots table. Each slot stores the tile’s x/y position, the move number, the tile color, and the id of the player who last moved the tile.
The server script has to now update the move number for each slot that is to be updated. It is invoked via Ajax, sending a write request to the server that contains the positions of the moved tiles.
It is possible to drag tiles so quickly so that each write request actually updates several slots.
The first of these slots to be updated will get a move number of “set move counter + 1″, the next one will get “set move counter + 2″ and so on.
To achieve this, the script first locks this table with the move counter (the sets table) to avoid that other players change this value at the same time.
Then the current move number is being read, and then updated with the move number of the last slot to be updated. In other words, if we have to update 5 slots, then the update query would perform a “set move number = set move number + 5″.
The table is then unlocked again.
Reading new tile positions for tiles that have moved since the last update
The same server script that performed the write operation also returns to the player’s browser which tiles have moved since the last update.
So how we do know which tiles we have to send to the browser?
From the slot table, the script selects all those tiles that have a move number that is higher then the highest move number from the previous update for this player, and it sends the information to the browser, ascendingly ordered by move number.
Lastly, the server stores the highest move number of all the tile positions that were sent to the browser in the previous update. This “highest move number” is stored separately for each player, in what we call the “room occupants table”.
Client side: Keeping track of the Z-index
When the browser’s Ajax object receives the update information from the server, it will - in the order of the position information returned from the server - do the following for each of these tiles:
- increment the global z-index
- set the tile’s z-index to this value
Now, what about the tile you just moved, isn’t that always on top? Well, yes initially it is. But then, as the position of that tile is sent to the server, it is being ordered in time with all other players’ activities.
Thus, your own tile position is being sent back to your browser as well, neatly in order with all other tiles that were being moved concurrently.
Voila! Everyone sees tiles overlapping in exactly the same way.












