Version control for your Godot game projects

minapecheux

Mina Pêcheux

Posted on July 26, 2023

Version control for your Godot game projects

Any game developer knows that versioning the code and the assets of a game project is no piece of cake - whereas web apps are mostly big bundles of text files, games require both text and complex binary files. So you need to have a tool that does both version control and asset management!

However, even to this day, the game dev community is fairly sceptical when it comes to using the usual SCM tools for keeping track of the project’s history, and collaborating with the other teammates.

We’ve already talked about these issues for versioning a Unity project with Git, the standard SCM solution; but, of course, the same questions arise for other game engines, such as Godot.

So, today, let’s put on our Godot DevOps hat, and see how we can version a Godot project, what are the differences from a Unity one, and what issues still remain no matter what.

Godot: a VCS-friendly game engine...

Compared to Unity or Unreal Engine, Godot is a somewhat new and small game engine - the real first out-of-beta version dates back to only 2014, and it began as the brainchild of two developers: Juan Linietsky and Ariel Manzur.

However, it does stand out from its competitors with its community-first philosophy, and the fact that it’s been open-source since the very start. This idea of bringing in the community on the development has allowed the engine to grow quite rapidly, in particular thanks to various plugins that can extend the tool in various ways.

And, among all those features, there are some specifically meant to help with versioning and SCM...

Enabling version control for a Godot project

Although there is no SCM tool built-in Godot directly, any Godot project offers an easy way to integrate versioning, just by going to the Project | Version Control menu:

godot-vcs-menu

Except that if you click on that button... you’ll probably get an error popup telling you that you don’t have any VCS plugins enabled:

godot-no-vcs-plugins

That’s because, parallel to enabling version control for your project, you also have to make sure Godot actually has a tool to use to do this versioning!

Now, from what I’ve seen, at the moment, the only plugins that are available in Godot’s asset library for versioning are Git integrations. In fact, the Godot team has even released an official Git versioning plugin to directly connect your Godot project to a Git SCM.

Ok, I know: there are dozens of SCM tools, so you may be thinking that Godot is just limiting our options here, and that this quick VCS setup is just a joke that nobody should use. But, in this specific case, there are actually a few reasons why Git is a nice choice, and may be the right fit:

  • First of all, Git is open-source. And given Godot’s whole “sharing to the community” mindset, it makes sense to stick with open-source software for versioning.
  • Git is also among the most popular SCM tools, so many developers are familiar with it and use it “by default” (as a survey we’ve conducted has shown).
  • Github and Gitlab are also extremely popular, and they provide another set of tools for automation, and CI/CD.
  • A lot of files in a Godot project are text-based (we’ll talk more about this in a second), so they are totally “understandable” and usable by Git.

So, in truth, going for a Godot-Git combo is not that unreasonable :)

Note: By the way, if you’re curious, some of the most famous versioning tools for game development and their specificities are discussed in more detail in this article ;)

Anyway - if you follow the install instructions of this plugin and add it to your Godot project, you’ll then be able to click the Set Up Version Control item of the menu and get this new popup, where you can enter your various Git-related credentials and info:

godot-git-setup

Once it’s configured, you’ll be able to examine your Git repo from inside your Godot project editor, and benefit from various tools like:

  • File differences (in unified or split view):

godot-git-diff-unified

godot-git-diff-split

  • Direct staging/unstaging:

godot-git-staging

  • Direct commit, and a list of all the current commits in the repo:

godot-git-commit

godot-git-log

  • And even more tools for branch management, remote repository configuration, etc.

Ok, that’s great - thanks to this little add-on, we can very easily handle all of our project’s versioning inside the editor, and we have all the basic Git options we need right at our fingertips. So we should be able to version all of our codebase directly, without even needing an external shell.

But this does beg the question: what about our complex project files? You know, all the project settings and resource assets like shader graphs, material properties or even entire scenes?

Godot’s text-based settings file

To me, that’s where Godot really shines!

‘Cause, as we said before, many Godot project files are text-based. Basically, as stated in the game engine’s official docs: “Godot aims to be VCS friendly and generate mostly readable and mergeable files”. So the creators have made their best to use human-readable and easy-to-version files for the project configuration and the resource metadata, by writing those files in a TOML-like format.

This makes those project files way easier to version and track than Unity’s - actually, let’s do a quick comparison to better understand the difference ;)

In Unity, even if you force the editor to serialise the assets as text files to help with Git versioning, you still end up with pretty cryptic config files, filled with a long list of mysterious properties:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!129 &1
PlayerSettings:
  m_ObjectHideFlags: 0
  serializedVersion: 23
  productGUID: 969ea8fe4c8a54236a202247833a2b06
  AndroidProfiler: 0
  AndroidFilterTouchesWhenObscured: 0
  AndroidEnableSustainedPerformanceMode: 0
  defaultScreenOrientation: 4
  targetDevice: 2
  useOnDemandResources: 0
  accelerometerFrequency: 60
  companyName: DefaultCompany
  productName: Tutorials
  defaultCursor: {fileID: 0}
Enter fullscreen mode Exit fullscreen mode

On the other hand, here’s the beginning of a project.godot file, which contains the project’s global settings:

; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
;   [section] ; section goes between []
;   param=value ; assign values to parameters
config_version=4
[MonoCustomResourceRegistry]
ClassPrefix=""
SearchType=0
ResourceScriptDirectories=[ "res://" ]
[application]
config/name="Tutorials"
run/main_scene="res://05-MouseFollow/scenes/05-MouseFollow.tscn"
config/icon="res://icon.png"
[display]
window/size/width=1920
window/size/height=1080
[editor_plugins]
enabled=PoolStringArray( "res://addons/MonoCustomResourceRegistry/plugin.cfg" )
Enter fullscreen mode Exit fullscreen mode

And similarly, any Godot resource is stored in this TOML format. So, for example, you can just open and read through your scene hierarchies in any text editor (here’s the top of a .tscn asset in one of my Godot projects):

[gd_scene load_steps=6 format=2]

[ext_resource path="res://04-RTSUnitNavigation/scripts/Unit.cs" type="Script" id=2]
[ext_resource path="res://04-RTSUnitNavigation/art/models/craft_speederA.fbx" type="PackedScene" id=3]

[sub_resource type="BoxShape" id=1]
extents = Vector3( 0.5, 0.55, 0.35 )

[node name="Unit" type="KinematicBody"]
script = ExtResource( 2 )

[node name="Model" parent="." instance=ExtResource( 3 )]
transform = Transform( -0.5, 0, -4.37114e-08, 0, 0.5, 0, 4.37114e-08, 0, -0.5, -1, 0.2, -0.7 )

[node name="CollisionShape" type="CollisionShape" parent="."]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.35, 0.05 )
shape = SubResource( 1 )
Enter fullscreen mode Exit fullscreen mode

What’s great is that a file like this:

  • allows us to quickly peek at our scenes and remember what nodes we’ve put in them, plus all the components and linked resources they use
  • is fully compatible with a Git versioning since it’s just text
  • can be explored and compared throughout the commits history easily
  • is way easier to merge in case of conflicts than an incomprehensible soup of properties like in Unity’s scene description

Actually, to a certain extent, an artist that is a bit curious about coding could probably read those files and get the overall gist, or even help fix merge conflicts!

All of this means that Godot offers a quick tool for integrating Git, and relies on text-files that are totally human-readable, and that Git can handle without any issues. Perfect, right? :)

Well, sadly, not quite.

Because there is still one type of files that poses a problem - it’s those heavy images, movies, audio clips or 3D models that your Github has trouble displaying, and that always ends up as an unreadable mess of binary characters.

... but not for large asset files!

Yep - large binary files are always the problem when versioning a game project, especially when you’re using a tool like Git, that was primarily designed to handle text files.

Your SCM will try its best to help, but if you ask a Git repo to show you the diff on an image or a movie clip, you won’t get very far. All those “special multimedia files” that are crucial to a game project - the images, movies, 3D models, audio files... - are just not meant to be tracked with Git.

In other words, despite Godot’s really nice Git integration, it is still limited by this everlasting versioning issue when working on game projects. So you’ll be able to commit all your metadata files into your Git repository without a hitch, but when the time comes to actually add the file itself, you’ll need to blindly push the binary contents of the asset and hope it works.

As time goes by and you continue to add more resources, pulling back your Git repository will become longer and longer because the tool will have to try and retrieve all of this complex data.

And yes: all of this will be a real nightmare for the (non-dev) artists in your team... who should actually be the ones authoring and keeping track of these final asset files!

This might be fine for small Godot projects. But for big ones, long story short: versioning large asset files is, as it’s always been, a pain - and this time, Godot doesn’t have a ready-made solution.

So, does all that mean we should give up and manage with this less-than-ideal situation? Is Git the doomed-but-only option? Or could we connect Godot with another SCM tool to dodge some of those problems?

An alternative to Git with better asset management?

Because the usual version control solution, Git, has proven somewhat limited for game projects time and time again, many people have turned to other SCM solutions.

Most notably, Perforce and PlasticSCM are two common versioning tools that are used by the game creation community.

Perforce is an interesting solution for big companies, because it handles large assets well and it’s good with code and complex assets. It’s also centralised, which means you won’t have to worry about re-merging local versions... but also that you are completely dependent on the remote server. Plus, compared to Git, Perforce is free for a little bit, but then it quickly adopts the pay-as-you-go strategy. And finally - you have to host and manage the remote server...

PlasticSCM shares many of Perforce’s advantages. However, since it’s been acquired by Unity in 2021, it’s slowly been tuned for this game engine - so it’s now mostly valuable for Unity dev teams that want an all-in-one solution. (And who aren’t too scared by the price, since PlasticSCM is a pay-as-you-go tool as well, but with fairly high prices.)

And then, of course, a few other teams around the world have started to dream of easier game dev versioning tools, too - which is why, today, various new SCM solutions with a special focus on game development are in the works.

For example, Diversion is a cloud-native version control system, still in beta but very promising, that aims at providing a versioning tool that is easy-to-use for everyone (meaning, developers and artists alike) and highly scalable.

Its goal is to facilitate versioning for multimedia projects like games by natively managing small text files and large assets, and by offering a centralised history of everything in your project, trouble-free. Plus, because they have a simple GUI, non-dev members of the team can use it too, and help with the integration and merges :)

The Diversion team is also working on a conflict-prevention feature to notify you whenever you’re updating the same file as somebody else, and you might be creating a conflict (thanks to its continuous sync system of local changes with the remote repository in the cloud).

Combine this with Godot’s easy-to-read text-based configuration files, and you’ll get a pretty neat version system that makes it easy to browse the entire history of your project, and lets you do collaborative work without too many risks of merge conflicts!

Conclusion

Godot is a rising game engine that is attracting more and more followers and that already offers quite a variety of features thanks to its open-source nature and its community-made plugins.

Some of those plugins make it very easy to integrate Git versioning in a Godot project, simply by downloading an add-on and turning on a few options. We then have everything we need to inspect and update our Git repo inside our Godot project editor. Plus, because Godot uses a plain text TOML-like format for all of its settings and metadata files, we can read through the config and version it with Git without the big merge conflict issues we’d have in a similar Unity project, for example.

However, this solution is not perfect, because Git is not meant to handle large asset files, and those are an essential part of many games. For big and complex Godot projects, keeping track of images, 3D models or audio sources alongside the codebase is hard, and taming all the subtleties of Git is often too complex for non-dev members of the team to be brought in on it.

But nowadays, new SCM solutions are popping here and there to serve as alternatives to Git, such as Diversion. This cloud-native versioning tool handles both basic text files and large binary asset files, and it is accessible to developers and artists thanks to its visual interface. A conflict prevention feature is even in development, that could nicely complement Godot’s VCS-friendly configuration files and reduce the frustration of detecting and avoiding potential conflicts :)

If you want to learn more about Diversion, go ahead and check the website!

💖 💪 🙅 🚩
minapecheux
Mina Pêcheux

Posted on July 26, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related