Merging is a fact of life for most of us. Eventually two users touch the same files and a conflict must be resolved. For programmers merging is a daily activity, but what about the content creators?
If two artists touch the same level, have your tools programmers made enough of an effort to make merging possible and if possible as painless as can be?
Here’s a handy checklist,
1 – Use XML/JSON (or some other text based file format)
It’s slower, it’s bigger but it’s going to make merging possible. If your level files are binary blobs merging without a custom tool just isn’t going to be possible. Using XML or JSON are the simplest text based alternatives because there are already many libraries for reading and writing them.
2 – For XML – Give Each Attribute a Line
If you’re using XML, you should make sure to write out the files such that every element and every attribute receives its own line. If you don’t do this it will make conflicts a lot more likely if two users touch the same object.
If you’re using JSON, having each attribute on its own line is the norm unless the library is attempting to keep the text compact.
Here’s a quick example, note that after separating the attributes the merge tool handles the conflict correctly while it fails to do so when they are on the same line.
Figure 1 – Attributes all on the same line
Figure 2 – Attributes on different lines
If you’re using .Net this can be achieved very easily by changing the default XmlWriterSettings with the NewLineOnAttribute property set to true.
3 – Maintain Order
Always write out the order of the data the same. This one is pretty easy, the only real pitfall is to make sure your data structure and undo/redo system are working correctly. For example, if you happen to store your objects in a list and someone removes and object at the front, but when it’s undone it’s inserted at the end of the list (Even if the UI doesn’t reflect this) this could affect your output order.
4 – Don’t Add New Objects At The End
When you go to save the entities don’t write them out in the order they were created. This will definitely result in a merge conflict. Because it ensures that if two users edit the file and both add an entity they’ll both show up in the same location and confuse the merge tool.
One thing you could do is to sort them based on a GUID that is stored as part of the objects data. Sorting based on GUID ensures a lower probability of collisions occurring when two users both add objects.
Alternatively a sorting based on a string containing the machine name of the original creator of the object is another idea. It would ensure every user touching the file would be inserting to their own section of the file instead of everyone inserting to the tail.