1.1About version control for games

Why the tools built for source code struggle with Unreal projects, and what changes when your files are binary.

Section 1 of 5 in this chapter

Version control is a system that records changes to a set of files over time so you can recall any version later. That definition is old and it has not changed. What has changed is what people put under version control, and a modern Unreal Engine project is not what these systems were designed for.

What source code assumes

Git, and every tool shaped like it, rests on three assumptions. Files are text. Text files can be merged automatically when two people change different parts of them. And the whole history is small enough that every contributor can carry a complete copy of it.

All three hold beautifully for a web application. None of them hold for a game.

A .umap is not text. A .uasset is not text. When two people edit the same level, there is no line-by-line reconciliation to perform — the file is a serialized object graph, and the only two possible outcomes are "keep mine" and "keep theirs". And a single Nanite mesh can be larger than the entire history of a mature codebase, so cloning "the whole history" stops being a sensible default somewhere around your first cinematic.

  TEXT                                BINARY

  MyCharacter.cpp                     MainLevel.umap

  Sarah  ─┐                           Sarah  ─┐
          ├──►  merged, both kept             ├──►  one wins,
  Marcus ─┘                           Marcus ─┘     the other is gone
Figure 1-1. Two people edit a text file and both changes survive. Two people edit a level and one of them loses a day.

The workarounds, and what they cost

The industry has three standard answers, and it is worth knowing what each one actually asks of you.

Git LFS keeps the big files out of the repository and leaves pointer text behind. It works, in the sense that clones stop taking a week. But you have swapped one problem for a quota and a bandwidth bill, your artists still need the Git command line, and One File Per Actor turns a single level into thousands of tiny files that LFS was never tuned for.

Perforce is the honest AAA answer and it is genuinely good at this. It is also a server you run, patch, secure, and back up, with licenses to buy and often a proxy or an edge server per studio location. For a team of four that is a part-time job nobody signed up for.

Cloud storage — a synced folder — is what most small teams actually use, and it is the worst of the three. No history, no commit trail, no locking, and a conflicted copy is the only warning you get that a day has gone missing.

What we do instead

USourceControl starts from the constraint rather than working around it. Binary files cannot merge, so the answer is not a better merge algorithm — it is making sure two people never edit the same file at the same time in the first place. That is what locking is for, and it is why locking is a first-class feature here rather than an add-on.

Large files are normal, not exceptional, so there is no pointer layer, no separate large-file store, and no quota. Storage and bandwidth are unlimited on every plan, including the free one, because metering them would push you back toward the behaviour that loses work — committing less often, keeping things out of source control, working from a folder on your desk.

And the whole history does not live on your machine. You have the current state of your project plus whatever you ask for; everything else is one click away when you need it. That is what makes a hundred-gigabyte project openable on a laptop.

Was this helpful?

Back to top