From Code to Data
Traditionally, level editing is done using some kind of standalone tool that is not part of the game engine. The level designer loads the level, makes changes to it, and exports it to see how it plays in the game.
This level-editing tool might be a commercial product, such as 3ds Max, or it might be an engine-specific tool that comes with a third-party engine, or it might even be a custom in-house tool.
Level editors can be integrated with the game engine, allowing the designer to view and play the level as it's being edited. This is ideal from the point of view of rapid feedback, but the problems of edit conflicts and bottlenecks still remain. If two level designers want to edit the same part of the level, they usually will have to check out the entire level from the VCS.
With code, multiple checkouts of the same file are less problematic because it's relatively easy to merge text files automatically, as the changes are usually on well separated lines. Conflicts that cannot be resolved automatically are usually taken care of very easily manually, as the nature of the conflicting changes is readily apparent to the programmer who makes the merge.
Unfortunately, this solution does not work with level data, which is often stored in a binary format that's impossible to merge, especially if the level editing tool is some thing like 3ds Max.
Even if the level is stored in a text-based format, such as XML, it's much harder to merge as there are many internal dependencies and automatically generated data that create a broader mesh of changes that are difficult for a human to read. What we get are more conflicts, which then are much harder to resolve without breaking something.
Splitting Data
The difficulty in merging changes in level or world files would inevitably lead to bottlenecks if no steps were taken to mitigate it. Various solutions have arisen to handle the problem. The simplest is to break the level down into the smallest chunks possible, so that individual level designers can check out only the sections of the level they need.
Using small chunks improves matters by reducing edit bottlenecks, but adds complication in how the level is split up and subsequently pieced together. Implementing high-level changes to large sections of a level also becomes difficult.
Though bottlenecks are reduced, they're not eliminated, as there will still be merge work needed at the borders of the areas assigned to individual level designers. Edits here must still be manually coordinated. The large number of individual parts that make up the divided level now places an undue organizational burden on the level designer.
Sometimes more ad-hoc solutions are used. A level might still be stored in one large file, but when two people need to work on it at the same time, it is manually split into two sections. The work is done (with some discussion to avoid conflicts), and then the two sections are visually merged back together.
Sometimes, special merge tools are written just for this purpose. This technique is fraught with problems, as the merging process is rarely simple, and can take some time.
|
Building a real-time collaborative game asset editor will take time, especially if you consider the computing, storage, and bandwidth problems that would be encountered in the process. In the meantime, it would be more practical to reduce the amount of edit conflicts by reducing the dependencies and increasing the orthogonality of modules (as fine grained module division is usually not enough), and by improving the communication between team members.
When you think about it, VCSs shouldn't take the blame for most of the problems in version control (unless, of course, we're talking about VSS :P ).
Consider two *entwined* editing sessions, then ask yourself how you are going to "undo" some changes. Do you undo your own edits? The other guy's? The other guy's that happen to touch the objects you touched?
I'm betting these hard questions would result in the same solutions we have today. Keep out of my backyard.
I understand that in Hero, the recommendation is to put up yellow police-tape around the area you are working in so these collaborative-conflicts don't happen.
Thanks for the thoughtful and balanced analysis of this problem. I'm trying to keep an open mind about it, but there is a lot of disagreement about where it lands on the usefullness scale. And what size team it makes sense for, what genre of game...
@Eric Slick and others, The article was actually written for Game Developer a few years ago, this is a reprint, so HeroEngine was not so well known back then. But it does sound just like what I was suggesting.
Different granularity comes with tradeoffs, as the article describes; with low granularity, conflicts are hard(people problem), and with high granularity, scalability is hard(computer problem). Note that DVCS mostly arises of the "people problem," and horizontal-scaling, non-relational databases arise from the "computer problem." Most of the obvious ground seems to have been covered by a VCS or database system in some form, so unless there's a radical improvement in our concepts, probably the best working practice is to go for the maximum level of granularity and then work out ways to optimize it, given that computers are cheaper than people.
I politely disagree. On the last page, you stress that "We are in the latest version. We don't need to check things in or out, as we simply start editing them, and they get locked."
That is in my eyes a very simple source control paradigm. Subversion-like systems perform better than that, and the concepts behind distributed systems such as Git are even more flexible.
Granted, those systems lend themselves better to code control. Merging changes to binary data is all but impossible in most cases, so in game development, the criteria are mostly different from many other software projects.