Using Source Control with the Source SDK: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Nesciuse moved page Using Source Control with the Source SDK/en to Using Source Control with the Source SDK without leaving a redirect: Move en subpage to basepage)
 
(31 intermediate revisions by 18 users not shown)
Line 1: Line 1:
{{LanguageBar}}
{{toc-right}}
{{toc-right}}
This article describes how to use [[Wikipedia:Revision control|source control]] with the Source SDK. You will want to use source control even if you're working alone, as it largely automates the process of merging code updates released on Steam – without it, you'll be in a world of hurt every time!


This article describes how to use [[Wikipedia:Revision control|source control]] with the Source SDK. You will want to use source control even if you’re working alone, as it largely automates the process of merging code updates released on Steam – without it, you’ll be in a world of hurt every time!
This document discusses [https://www.perforce.com/ Perforce], the source control system used internally by Valve. It's free for up to 20 users. Other alternatives include [[Wikipedia: Subversion (software)|Subversion]] or [[Wikipedia:Concurrent Versions System|CVS]]. Since all version control systems work with the same high-level processes, this article should still be useful. (Nevertheless, there are specific articles for [[Using Subversion for Source Control with the Source SDK|Subversion]] and [[Using Git for Source Control with the Source SDK|Git]].)
 
This document discusses [[Wikipedia:Perforce|Perforce]], the source control system used internally by Valve. It’s free for up to two users. Larger teams can use free alternatives like [[Wikipedia: Subversion (software)|Subversion]] which use the same high-level processes.


== Before you begin ==
== Before you begin ==
Line 9: Line 10:
If you have started programming without source control, '''STOP!''' Source control needs to be set up at the earliest opportunity, especially since every time a Steam update is released older versions of the base SDK code are lost.
If you have started programming without source control, '''STOP!''' Source control needs to be set up at the earliest opportunity, especially since every time a Steam update is released older versions of the base SDK code are lost.


If you’re reading this as you try to apply an update that’s already out to your unversioned code, you’re screwed and will just have to merge the changes the hard way. Tools like [http://www.scootersoftware.com Beyond Compare] can make this process easier, and if you follow this tutorial after finishing it should be the last time you ever have to endure it.
If you're reading this as you try to apply an update that's already out to your unversioned code, it is too late, and you must merge the changes the hard way. Tools like [https://www.scootersoftware.com Beyond Compare] can make this process easier, and if you follow this tutorial after finishing it should be the last time you ever have to endure it.


=== Get Perforce ===
=== Get Perforce ===


With that out of the way, you’re going to need to download Perforce. [http://www.perforce.com/perforce/downloads/ntx86_64.html Get the first two downloads from this page]:
With that out of the way, [https://www.perforce.com/perforce/downloads/ it's time to get Perforce]. You want both the '''visual client''' (which includes the command-line client anyway) and the '''server'''. Take care when installing to leave the network server configuration alone unless you are actually going to connect somewhere remote.
 
*'''Perforce Server Windows Installer'''
*'''P4V Installer'''


Ignore the ‘P4Win Installer’ further down the page, it’s legacy software now. Take care when installing to leave the network server configuration alone unless you are actually connecting over a LAN or the internet.
If you are using Visual Studio (as opposed to Visual C++ Express) you should also consider downloading the [https://www.perforce.com/perforce/products/p4scc.html SCC plugin], which integrates Perforce into the IDE.


[http://www.perforce.com/perforce/technical.html Perforce provide documentation of their own] which you may want to consult before using or instead of this article. It isn’t as specific as this page, however.
{{tip|[https://www.perforce.com/perforce/technical.html Perforce provide documentation of their own] which you may want to consult. It isn't as specific as this guide, however.}}


{{tip|If you make a mistake and need to reset Perforce’s database, execute this from the command prompt: <code>p4 obliterate –y //depot/...</code>. DON’T do this on a database that's already up and running!}}
{{tip|If you make a mistake while following this tutorial and need to reset Perforce's database, execute this from the command prompt: <code>p4 obliterate –y //depot/...</code>. DON'T do this on a database that's already up and running!}}


== Overview ==
== Overview ==


We will install a fresh instance of the SDK code with the [[Create a Mod]] wizard and submit it to Perforce, which will file it away. We will then ‘branch’ the submitted code to a second instance at another location.
We will make a fresh install of Valve's SDK code and submit it to the Perforce server. We will then 'branch' that submitted code to a second location, which allows you to work with the code as you see fit while retaining the ability to easily 'integrate' future SDK updates from Valve into your project.


It is this branched code with which you will create your mod, occasionally updating Perforce’s filed copy when you need to make a backup. The first instance will remain untouched until a code update is released, at which point you will install the updated code to it before ‘integrating’ it into your branched mod code. Because Perforce knows when the two codelines separated, it will be of great assistance during this process.
This means that you will have two 'codelines' on your Perforce server. Valve's, which will only change with SDK updates, and your own, which will change both whenever you decide to submit your work to it, and whenever you decide to integrate SDK updates from Valve.


== Setting up source control ==
== Setting up source control ==


Valve’s base SDK code will form the ‘trunk’ of your codebase, from which your mod code will ‘branch’. Create it with the [[Create a Mod]] wizard. Your user folder is the best place to store it, especially if you’re using Windows Vista, but put it in a subfolder especially for the base SDK code - the one specifically for your mod's code will be created later.
Valve's base SDK code will form the 'trunk' of your codebase, from which your mod code will 'branch'. Get Valve's code with the [[Create a Mod]] wizard, choosing the "source code only" option and installing to a location in your user dir like <code>C:\Users\You\Mods\valvesrc</code>. Making a <code>\Mods</code> folder is important, as you will discover later.
 
{{tip|Since you won’t be spending much time with the trunk code, it’s a good idea to archive it. You can use it’s folder’s Properties dialogue to disable indexing and enable compression. Or better still, once you’re done with this tutorial zip its contents up into an archive file.}}


=== Create the workspace ===
{{tip|If you're using Windows Vista or later it's a good idea to remove the \Mods folder from the search index. Use the Indexing Options tool, which is in the start menu, to do this. You'll need admin privileges.}}


Now we’ll start using Perforce. Start P4V, the visual client. You will be greeted by the “Open Connection” dialogue.
=== Create a workspace ===


[[Image:P4 openconnection.png|center|Perforce open connection dialogue]]
Now we'll start using Perforce. Start P4V, the visual client. You will be greeted by the "Open Connection" dialogue.


Unless you are actually connecting to a network server you can ignore all of the options it gives you except step 3, which defines the ‘workspace’ you’ll connect to. Click ‘new’, to the right, and name the workspace <code>valvesrc</code>, or words to that effect.
[[File:P4 openconnection.png|center|Perforce open connection dialogue]]


Workspaces are local copies of files on the Perforce server. You’ll have one for Valve’s trunk code and one for your branch code by the time you’re finished, and anyone else working with you will have their own workspace on their machine as well.
Unless you are actually connecting to a network server you can ignore all of the options it gives you except Workspace. Click 'new', to the right, and name the workspace 'mods' (or whatever you please - but the rest of this guide assumes it's called mods).


Most of the fields in the workspace dialogue should be self-explanatory, and you only need to worry about two anyway: Root and View. Root should point to the folder to which you just installed the unmodified SDK code, while View is the location at which the code will be stored on the Perforce server (the ‘depot’).
Workspaces link folders containing your files with the location(s) on the Perforce server where they are archived. Earlier versions of this guide suggested that one workspace be created per codeline, but this is unnecessary. We're going to create just one that will encompass all of the SDK projects on your computer, which is why creating a \Mods folder was recommended above.


There’s a special syntax for Views. The section before the space defines the virtual drive that the workspace will be linked to, while the section after it defines a subfolder on that drive. In this way you can create workspaces with files that are either independent or pooled together.
Most of the fields in the New Workspace dialogue should be self-explanatory, and you only need to worry about two anyway:


For our purposes, we want one that’s independent. Use the following value for View:
* '''Root''' should point to your Source projects folder - <code>C:\Users\You\Mods\</code> if you followed the instructions above precisely.
* '''View''' contains two locations, separated by whitespace:
*# A location on the Perforce server
*# The location that it should correspond to in the workspace


//depot/valvesrc/... //valvesrc/...
Unless you've deviated from this tutorial, the running Perforce server is called 'depot' and your workspace is called 'mods'. We aren't doing anything complex, so View should tie the depot root to the workspace root:


{{todo|Wouldn’t it be entirely feasible to just use <code>//depot/...</code> and then a subfolder?}}
//depot/sourcemods/... //mods/...


Then click OK.
The <code>/sourcemods</code> subfolder will keep your mod projects separate from any other workspaces you create in the future. If you're absolutely sure that this server will only be used with one workspace you can use the root <code>//depot/...</code> path instead.


=== Submit the trunk source code ===
=== Submit the trunk source code ===


We now have a workspace filled with Valve’s base SDK code, but the Perforce server is still empty. We need to get our files up there. To do that we’ll be using the main P4V interface, which should currently be in front of you.
We now have a workspace filled with Valve's base SDK code, but the Perforce server is still empty. We need to get our files up there. To do that we'll be using the main P4V interface, which having created a workspace should currently be in front of you.


[[Image:P4 interfaceoverview.png|center|P4V interface overview]]
<div style="padding:1em; background-color: #2B2B2B;border:1px solid #000;">[[File:P4 interfaceoverview.png|center|P4V interface overview]]


{{tip|You can also get an overview of the interface from <code>Help > Getting Started with P4V</code>.}}
{{tip|You can also get an overview of the interface from <code>Help > Getting Started with P4V</code>.}}


# ''Workspace/depot view (left pane).'' Click on the tabs at the bottom to change between the two. Workspace is your local copy, depot is the server’s master copy.
# ''Workspace/depot view (left pane).'' Click on the tabs at the bottom to change between the two. Workspace is your local copy, depot is the server's master copy.
# ''Task tabs (right pane).'' The tabs along the bottom of this pane allow you to carry out every operation you’ll ever need to with the Perforce client. We will be using Pending, Workspaces and Branches.
# ''Task tabs (right pane).'' The tabs along the bottom of this pane allow you to switch between different tasks. They are opened as needed from the main menu buttons. We will be using Pending, Workspaces and Branches.
# ''Log.'' Errors will appear in bold text.
# ''Log.'' Errors will appear in bold text.
# ''Main menu.'' Most of the options here are available elsewhere in the interface, but it’s useful to have them in one place too.
# ''Main menu.'' Most of the options here are available elsewhere in the interface, but it's useful to have them in one place too.</div>


Bring up the workspace view and we’ll see about uploading the source code. It’s a two-step process:
Bring up the workspace view and we'll submit the code. It's a two-step process:


# Mark the files for addition. We want to add everything, so select the workspace root, right at the top, the click ‘Mark for Add’. You can find it on the main menu or on the context menu; it’s the file icon with a plus over it. There are a lot of files in the SDK, so it might take a while for the operation to complete. When it’s finished, all of the files in the workspace view will have changed appearance to reflect that they are now being version controlled.
# Mark the files for addition. We want to add everything, so select the whole \valvesrc folder and click 'Mark for Add'. You can find the Add button on the main menu or in the context menu; it's the file icon with a plus over it. There are a lot of files in the SDK, so it might take a while for the operation to complete. When it's finished, all of the files in the workspace view will have changed appearance to reflect that they are now being version controlled.
# Submit the changelist. Move to the ‘Pending’ tab (the red, upwards arrow) and you’ll see that there’s an item called ‘default’ that contains all of the files you just added. Submit it with a double-click (or {{key|Ctrl+S}}). You’ll need to enter a brief description of what the changes are.
# Submit the changelist. Move to the 'Pending' tab (the red, upwards arrow) and you'll see that there's an item called 'default' that contains all of the files you just added. Submit it with a double-click (or {{key|Ctrl+S}}). You'll need to enter a brief description of what the changes are.


Once the process has finished, you’ll be able to browse to the newly-populated depot view. Congratulations!  
Once the process has finished, you'll be able to browse to the newly-populated depot view. Congratulations! You can now safely delete the <code>\valvesrc</code> folder.


=== Create and execute the branch ===
=== Create and execute the branch ===


The branched workspace is what you will be working from. It starts of as any other workspace, but this time you can call it after your mod and point its Root to the place where you’d like to store the files as you work on them. The View should be on its own virtual server, so use something like this:
{{note|You can't properly branch to a location that's already populated. If you've already made changes to the code that you want to keep, back the files you've changed up somewhere before deleting the rest of the old source folder. You'll have to manually add everything back later.}}
 
Choose ''File > New > Branch Specification...'' to create a new 'branch'. A branch operation tells Perforce to copy code to a separate location while remembering where it came from, and when &mdash; vital information when it comes to integrating SDK updates.
 
The view field of a branch is slightly different to that of a workspace: ''both'' halves refer to locations on the server. Yours should read something like this:


  //depot/mymod/... //mymod/...
  //depot/valvesrc/... //depot/mymod/...


If you’ve already made some changes that you want to keep, and don’t want to change folders, move your existing code somewhere else until the branch operating is complete. You can’t properly create a workspace in a folder that’s already populated.
Although we've just specified a destination on the server, the new branch will actually be created in the workspace. This is so that you can examine how the integration turned out before committing to anything: polite behaviour that isn't terribly useful at this point, since we are "integrating" with an empty folder!


Choose <code>File > New > Branch Specification...</code> and you’ll create a new branch. Give it a suitable name, like <code>valve_to_<mymod></code>, then configure View to read:
{{note|To see the newly created branch in the workspace, use the Branch Mappings tab. You can Enable it by way of ''View > Branch Mappings...'' or {{key|Ctrl+3}}}}


//depot/valvesrc/... //depot/mymod/...
{{tip|The confusing error "No target file(s) in both client and branch view" means that one or both paths in the View are pointing to the wrong location. Don't forget to include any subfolders you made.}}


Hit OK and it will be created: now we just need to execute it. Active to your mod’s workspace (use the drop-down list just above the left pane, which will currently read valvesrc), and with its root selected go to the Branches task tab and choose the ‘Integrate Using’ context menu option from your new branch. Either uncheck ‘Limit integration to’ option or change the View it’s using to be the ‘target’, then click Integrate.
A good name for the branch is <code>valve_to_mymod</code>. Hit OK and it will be created: now we just need to execute it. Right-click on your new branch and select the 'Integrate Using' option. You should be able to start the process without changing anything.


[[Image:P4 integrate.png|center|Integrating trunk code in Perforce]]
[[File:P4 integrate.png|center|Preparing to execute a branch in Perforce]]


We have now created a branch of <code>//depot/valvesrc/</code> in the mod workspace. It still needs submitting it to the Perforce server, remember! Do it in the same way as we did the trunk code earlier.
You now have the 'mymod' branch of valvesrc registered on the server, and its files sitting in your workspace. Submit them in the same way as you did the trunk code.


=== Check out ===
=== Check out ===


This is a complication that is only useful when you’re working with a team of programmers. Unfortunately you’re going to have to put up with it even if you’re alone! The logic is this: all version-controlled files are locked (i.e. read-only) unless they are ‘checked out’ of the server. This stops people from unintentionally working on the same code at the same time, since that usually leads to duplicated work and confusion.
All version-controlled files in your workspace are read-only unless you have them 'checked out' of the server. This is useful when you're working with a team of programmers, as it makes developers aware of which files they are each working on, but can still help to keep things organised when you are working alone.
 
To check a file or folder out, select it and hit {{key|Ctrl+E}} or use the context menu.


Luckily, it’s easy to check out. If you’re working on your own you can head up to the very top level of your mod workspace and check out the whole workspace in one go. You perform the command from the main menu (left of Add, with a tick), from the context menu, or with {{key|Ctrl+E}}.
If you are working alone you might think it logical to check out the entire workspace, and this is a perfectly valid option. However, it will help you keep track of your changes between submissions if you only check out those files that you need to modify.


If you’re working with a team you’ll need to agree on what code you each check out, or else prepare to face the consequences...
{{warning|Resist the temptation to manually remove the read-only flag from your versioned files. This desynchronizes Perforce and may confuse it (and you) later on.}}


{{warning|Resist the temptation to manually remove the read-only flag from your source files. This desynchronizes Perforce and may confuse you later on (though Perforce won’t care).}}
== Integrating SDK updates ==


== Using source control to integrate SDK updates ==
We've now got source control up and running for your mod. It might have seemed complex, but the steps above only need to be performed once and this stuff will soon become grist for the mill anyway.


We’ve now got source control up and running for your mod. It might have seemed complex, but this stuff will soon become grist for the mill. You can use source control as an ongoing backup, to compare code with what came before or after it, to revert changes, share code with others and contribute collaboratively, and, of course, to integrate trunk updates, which is what we'll be doing in this section.
You can use source control as an ongoing backup, to compare code with what came before or after it, to revert changes, share code with others and contribute collaboratively, and, of course, to integrate trunk updates, which is what we'll be doing in this section.


=== Submit pending branch changes ===
=== Submit pending branch changes ===


This process only changes from our previous submits in that you will need to add any new files created since them to the depot. If you know precisely what's been created you can find each file manually and mark them for addition, but if you’ve got loads or aren’t sure (both will be the case if you’re importing the existing code you moved out earlier back into the workspace) it’s best to add the whole workspace.
You already know how to submit, but this is an appropriate time to remind you that newly-created files aren't automatically added to version control.
 
P4V only supports adding files individually, which is fiddly, or by folder, which will pick up all the huge binary files generated by Visual Studio that you definitely don't want on the server. To add files with a wildcard search, we must turn to the [[command line]].
 
Open CMD and execute these commands ('client' is another word for workspace):
 
set p4client mods
p4 add //mods/game/....cpp
p4 add //mods/game/....h
 
Of course, if you've added files outside the <code>\game</code> folder and/or that aren't .cpp or .h, you'll need to perform extra commands to pick them up.


You’ll need to do two extra things if you add the entire workspace:
Right-click on your branch root and hit the "Revert Unchanged Files" option, then submit the changelist and we'll move on.


# Right-click on the new pending changelist and select the “Revert Unchanged Files” option, for obvious reasons.
{{tip|If you do end up with VS's binary files in the depot, you can delete them from the database with these console commands (which are given without the confirming <code>-y</code> switch):
# Find and revert <code>bin/</code>, <code>release_hl2/</code> and <code>debug_hl2/</code> folders from <code>game/server/</code> and <code>game/client/</code>, then do the same for any <code>.ncb</code> files (you can use {{key|Ctrl+F}}). These all contain very large amounts of auto-generated binary data that you don’t need or want version controlled.


Submit the changelist and we’ll move on.
p4 obliterate //....ncb
p4 obliterate //....sdf
p4 obliterate //....ipch
p4 obliterate //....obj
p4 obliterate //....pdb
p4 obliterate //....pch
}}


=== Submit trunk update ===
=== Submit trunk update ===


The trunk code is that stuff that Valve’s update applies to. Before you open the SDK Launcher and install the new release however, remember that you need to check out the files to make them writeable. Just go to the workspace’s root and hit {{key|Ctrl+E}}.
The 'trunk' contains Valve's unmodified SDK code, which now needs updating too. Delete any workspace files from your \valvesrc folder then [[Create a Mod|install the new code]] there with the Create a Mod wizard's 'Source code only' option.


Now you can [[Create a Mod|install the new code]]; use the wizard's ‘Source code only’ option. After the installation mark all files in the valvesrc workspace for add to pick up anything new, then revert all unchanged files. Deleted files will have to be removed manually (if you think you’ve still got some lying around, search the valvesrc/ folder for files older than those from the SDK launcher install you just performed). Once that’s done submit, and we can move on to the fun part.
Now switch to workspace view in P4V and right-click on the \valvesrc folder. Choose 'Reconcile Offline Work', which is in the same section as Submit and Revert. Leave all the checkboxes in the window that opens active and click 'Reconcile'. Then submit the changes.


=== Integrate ===
=== Integrate ===


We’ve now got fully updated code in both depots, so it’s time to integrate. You do this in the same manner as you populated the branch workspace: go to its root, then integrate with your <code>valve_to_mymod</code> branch.
We've got the latest code for both projects in the depot, so it's time to integrate them. To do this, execute your <code>valve_to_mymod</code> branch again.
 
The difference this time is that you'll need to resolve files that have changed between the versions. Since Perforce knows the point at which your mod code branched it can make a very good guess as to what version of a file should take precedence in most cases. You'll only have to manually inspect changes if there's a conflict that can't be resolved automatically.


The difference here is that you’ll need to resolve files that have changed between the versions. Since Perforce knows the point at which your mod code branched it can make a very good guess as to what version of a file should take precedence in most cases. You’ll usually only have to manually inspect the differences if you’ve made extensive changes to something, or if there’s a conflict that can’t be resolved automatically.
Remember that a) you don't have to submit the integrated code until you're happy and b) you can always revert to the earlier, unmerged version of a file if the process later turns out to have gone wrong.


Otherwise you can accept the automatic result. Remember that you can always revert to the earlier, unmerged version of a file if the process later turns out to have gone wrong.
For more details on merging, open P4Merge's help tool.


{{tip|If Perforce queries a .lib file, always accept Valve's.}}
{{tip|If Perforce queries a .lib file, always accept Valve's.}}
==== Manual merges ====
{{todo|Link to documentation on P4's merge tool.}}


=== Test the new code ===
=== Test the new code ===
Line 147: Line 165:
And you're done!
And you're done!


== Conclustion ==
== Conclusion ==


Working with a source control introduces some concepts that take getting used to, but it pays dividends. It saves time, helps teams work together on the same product, and provides access to the whole history of a project.  
Working with a source control introduces some concepts that take getting used to, but it pays dividends. It saves time, helps teams work together on the same product, and provides access to the whole history of a project.  


Keep in mind that, while this document has a lot of steps, this stuff is all trivial once you're familiar with Perforce. Once you know how this all works, all these integrations and merges can be done in a matter of minutes. We recommend that you jump back to the "overview" section of this document to review the high-level process that is involved, and see how all the detailed steps fit into that simple high-level process.
Keep in mind that, while this document has a lot of steps, this stuff is all trivial once you're familiar with Perforce. Once you know how this all works, all these integrations and merges can be done in a matter of minutes. Valve recommend that you jump back to the "overview" section of this document to review the high-level process that is involved, and see how all the detailed steps fit into that simple high-level process.


Internally, Valve uses source control in a similar fashion to that described in this document. The main difference is that ALL files for Valve games go in Perforce, including content source .TGA artwork, .VMT files, executables, scripts, documents, etc. We recommend doing this while developing a mod as well, bandwidth limits and disc space allowing, because you can instantly restore any version of the mod that ever existed.
Internally, Valve uses source control in a similar fashion to that described in this document. The main difference is that ALL files for Valve games go in Perforce, including content source .TGA artwork, .VMT files, executables, scripts, documents, etc. They recommend doing this while developing a mod as well, bandwidth limits and disc space allowing, because you can instantly restore any version of the mod that ever existed.


Valve also uses a multitude of codelines (whereas there are just two in this document). For example, we have a main codeline that about 20 programmers submit code into. Often programmers need to stay sheltered from other people's changes (which may happen as many as 19 times per day!), so each programmer has their own set of personal codelines that are branched off the main codeline. This way, they can choose when they want to integrate all the changes from other programmers into their personal codeline (just like you now have the choice about when you want to integrate Valve's source code into your mod's source code).
Valve also uses a multitude of codelines (whereas there are just two in this document). For example, they have a main codeline that about 20 programmers submit code into. Often programmers need to stay sheltered from other people's changes (which may happen as many as 19 times per day!), so each programmer has their own set of personal codelines that are branched off the main codeline. This way, the programmers can choose when they want to integrate their colleague's changes into their personal codeline (just like you now have the choice about when you want to integrate Valve's SDK updates into your own codeline).


== See also ==
== See also ==


* [http://www.perforce.com/perforce/technical.html Official Perforce documentation]
* [[Using Subversion for Source Control with the Source SDK]]
* [http://public.perforce.com/public/perforce/faq/beginner.html Perforce Beginner's FAQ]
* [https://www.perforce.com/perforce/technical.html Official Perforce documentation]
* [http://www.perforce.com/perforce/technotes/note064.html Integrating Perforce with Visual Studio]
* [https://public.perforce.com/public/perforce/faq/beginner.html Perforce Beginner's FAQ]
* [https://www.perforce.com/perforce/technotes/note064.html Integrating Perforce with Visual Studio] (Visual C++ Express does not support this)
* [https://www.perforce.com/perforce/doc.092/manuals/p4sag/02_backup.html Backing up and restoring your server]


[[Category:Programming]]
[[Category:Programming]]
[[Category:Tutorials]]
[[Category:Tutorials]]

Latest revision as of 11:52, 12 July 2024

English (en)Español (es)Русский (ru)中文 (zh)Translate (Translate)

This article describes how to use source control with the Source SDK. You will want to use source control even if you're working alone, as it largely automates the process of merging code updates released on Steam – without it, you'll be in a world of hurt every time!

This document discusses Perforce, the source control system used internally by Valve. It's free for up to 20 users. Other alternatives include Subversion or CVS. Since all version control systems work with the same high-level processes, this article should still be useful. (Nevertheless, there are specific articles for Subversion and Git.)

Before you begin

If you have started programming without source control, STOP! Source control needs to be set up at the earliest opportunity, especially since every time a Steam update is released older versions of the base SDK code are lost.

If you're reading this as you try to apply an update that's already out to your unversioned code, it is too late, and you must merge the changes the hard way. Tools like Beyond Compare can make this process easier, and if you follow this tutorial after finishing it should be the last time you ever have to endure it.

Get Perforce

With that out of the way, it's time to get Perforce. You want both the visual client (which includes the command-line client anyway) and the server. Take care when installing to leave the network server configuration alone unless you are actually going to connect somewhere remote.

If you are using Visual Studio (as opposed to Visual C++ Express) you should also consider downloading the SCC plugin, which integrates Perforce into the IDE.

Tip.pngTip:Perforce provide documentation of their own which you may want to consult. It isn't as specific as this guide, however.
Tip.pngTip:If you make a mistake while following this tutorial and need to reset Perforce's database, execute this from the command prompt: p4 obliterate –y //depot/.... DON'T do this on a database that's already up and running!

Overview

We will make a fresh install of Valve's SDK code and submit it to the Perforce server. We will then 'branch' that submitted code to a second location, which allows you to work with the code as you see fit while retaining the ability to easily 'integrate' future SDK updates from Valve into your project.

This means that you will have two 'codelines' on your Perforce server. Valve's, which will only change with SDK updates, and your own, which will change both whenever you decide to submit your work to it, and whenever you decide to integrate SDK updates from Valve.

Setting up source control

Valve's base SDK code will form the 'trunk' of your codebase, from which your mod code will 'branch'. Get Valve's code with the Create a Mod wizard, choosing the "source code only" option and installing to a location in your user dir like C:\Users\You\Mods\valvesrc. Making a \Mods folder is important, as you will discover later.

Tip.pngTip:If you're using Windows Vista or later it's a good idea to remove the \Mods folder from the search index. Use the Indexing Options tool, which is in the start menu, to do this. You'll need admin privileges.

Create a workspace

Now we'll start using Perforce. Start P4V, the visual client. You will be greeted by the "Open Connection" dialogue.

Perforce open connection dialogue

Unless you are actually connecting to a network server you can ignore all of the options it gives you except Workspace. Click 'new', to the right, and name the workspace 'mods' (or whatever you please - but the rest of this guide assumes it's called mods).

Workspaces link folders containing your files with the location(s) on the Perforce server where they are archived. Earlier versions of this guide suggested that one workspace be created per codeline, but this is unnecessary. We're going to create just one that will encompass all of the SDK projects on your computer, which is why creating a \Mods folder was recommended above.

Most of the fields in the New Workspace dialogue should be self-explanatory, and you only need to worry about two anyway:

  • Root should point to your Source projects folder - C:\Users\You\Mods\ if you followed the instructions above precisely.
  • View contains two locations, separated by whitespace:
    1. A location on the Perforce server
    2. The location that it should correspond to in the workspace

Unless you've deviated from this tutorial, the running Perforce server is called 'depot' and your workspace is called 'mods'. We aren't doing anything complex, so View should tie the depot root to the workspace root:

//depot/sourcemods/... //mods/...

The /sourcemods subfolder will keep your mod projects separate from any other workspaces you create in the future. If you're absolutely sure that this server will only be used with one workspace you can use the root //depot/... path instead.

Submit the trunk source code

We now have a workspace filled with Valve's base SDK code, but the Perforce server is still empty. We need to get our files up there. To do that we'll be using the main P4V interface, which having created a workspace should currently be in front of you.

P4V interface overview
Tip.pngTip:You can also get an overview of the interface from Help > Getting Started with P4V.
  1. Workspace/depot view (left pane). Click on the tabs at the bottom to change between the two. Workspace is your local copy, depot is the server's master copy.
  2. Task tabs (right pane). The tabs along the bottom of this pane allow you to switch between different tasks. They are opened as needed from the main menu buttons. We will be using Pending, Workspaces and Branches.
  3. Log. Errors will appear in bold text.
  4. Main menu. Most of the options here are available elsewhere in the interface, but it's useful to have them in one place too.

Bring up the workspace view and we'll submit the code. It's a two-step process:

  1. Mark the files for addition. We want to add everything, so select the whole \valvesrc folder and click 'Mark for Add'. You can find the Add button on the main menu or in the context menu; it's the file icon with a plus over it. There are a lot of files in the SDK, so it might take a while for the operation to complete. When it's finished, all of the files in the workspace view will have changed appearance to reflect that they are now being version controlled.
  2. Submit the changelist. Move to the 'Pending' tab (the red, upwards arrow) and you'll see that there's an item called 'default' that contains all of the files you just added. Submit it with a double-click (or Ctrl+S). You'll need to enter a brief description of what the changes are.

Once the process has finished, you'll be able to browse to the newly-populated depot view. Congratulations! You can now safely delete the \valvesrc folder.

Create and execute the branch

Note.pngNote:You can't properly branch to a location that's already populated. If you've already made changes to the code that you want to keep, back the files you've changed up somewhere before deleting the rest of the old source folder. You'll have to manually add everything back later.

Choose File > New > Branch Specification... to create a new 'branch'. A branch operation tells Perforce to copy code to a separate location while remembering where it came from, and when — vital information when it comes to integrating SDK updates.

The view field of a branch is slightly different to that of a workspace: both halves refer to locations on the server. Yours should read something like this:

//depot/valvesrc/... //depot/mymod/...

Although we've just specified a destination on the server, the new branch will actually be created in the workspace. This is so that you can examine how the integration turned out before committing to anything: polite behaviour that isn't terribly useful at this point, since we are "integrating" with an empty folder!

Note.pngNote:To see the newly created branch in the workspace, use the Branch Mappings tab. You can Enable it by way of View > Branch Mappings... or Ctrl+3
Tip.pngTip:The confusing error "No target file(s) in both client and branch view" means that one or both paths in the View are pointing to the wrong location. Don't forget to include any subfolders you made.

A good name for the branch is valve_to_mymod. Hit OK and it will be created: now we just need to execute it. Right-click on your new branch and select the 'Integrate Using' option. You should be able to start the process without changing anything.

Preparing to execute a branch in Perforce

You now have the 'mymod' branch of valvesrc registered on the server, and its files sitting in your workspace. Submit them in the same way as you did the trunk code.

Check out

All version-controlled files in your workspace are read-only unless you have them 'checked out' of the server. This is useful when you're working with a team of programmers, as it makes developers aware of which files they are each working on, but can still help to keep things organised when you are working alone.

To check a file or folder out, select it and hit Ctrl+E or use the context menu.

If you are working alone you might think it logical to check out the entire workspace, and this is a perfectly valid option. However, it will help you keep track of your changes between submissions if you only check out those files that you need to modify.

Warning.pngWarning:Resist the temptation to manually remove the read-only flag from your versioned files. This desynchronizes Perforce and may confuse it (and you) later on.

Integrating SDK updates

We've now got source control up and running for your mod. It might have seemed complex, but the steps above only need to be performed once and this stuff will soon become grist for the mill anyway.

You can use source control as an ongoing backup, to compare code with what came before or after it, to revert changes, share code with others and contribute collaboratively, and, of course, to integrate trunk updates, which is what we'll be doing in this section.

Submit pending branch changes

You already know how to submit, but this is an appropriate time to remind you that newly-created files aren't automatically added to version control.

P4V only supports adding files individually, which is fiddly, or by folder, which will pick up all the huge binary files generated by Visual Studio that you definitely don't want on the server. To add files with a wildcard search, we must turn to the command line.

Open CMD and execute these commands ('client' is another word for workspace):

set p4client mods
p4 add //mods/game/....cpp
p4 add //mods/game/....h

Of course, if you've added files outside the \game folder and/or that aren't .cpp or .h, you'll need to perform extra commands to pick them up.

Right-click on your branch root and hit the "Revert Unchanged Files" option, then submit the changelist and we'll move on.

Tip.pngTip:If you do end up with VS's binary files in the depot, you can delete them from the database with these console commands (which are given without the confirming -y switch):
p4 obliterate //....ncb
p4 obliterate //....sdf
p4 obliterate //....ipch
p4 obliterate //....obj
p4 obliterate //....pdb
p4 obliterate //....pch

Submit trunk update

The 'trunk' contains Valve's unmodified SDK code, which now needs updating too. Delete any workspace files from your \valvesrc folder then install the new code there with the Create a Mod wizard's 'Source code only' option.

Now switch to workspace view in P4V and right-click on the \valvesrc folder. Choose 'Reconcile Offline Work', which is in the same section as Submit and Revert. Leave all the checkboxes in the window that opens active and click 'Reconcile'. Then submit the changes.

Integrate

We've got the latest code for both projects in the depot, so it's time to integrate them. To do this, execute your valve_to_mymod branch again.

The difference this time is that you'll need to resolve files that have changed between the versions. Since Perforce knows the point at which your mod code branched it can make a very good guess as to what version of a file should take precedence in most cases. You'll only have to manually inspect changes if there's a conflict that can't be resolved automatically.

Remember that a) you don't have to submit the integrated code until you're happy and b) you can always revert to the earlier, unmerged version of a file if the process later turns out to have gone wrong.

For more details on merging, open P4Merge's help tool.

Tip.pngTip:If Perforce queries a .lib file, always accept Valve's.

Test the new code

At this point, you should do a pass of the code to fix any compile errors that may have been introduced by the code merge. You could also do this pass before submitting the merged code changelist, but it tends to be easier to make changes starting with an empty changelist rather than one full of code merges.

And you're done!

Conclusion

Working with a source control introduces some concepts that take getting used to, but it pays dividends. It saves time, helps teams work together on the same product, and provides access to the whole history of a project.

Keep in mind that, while this document has a lot of steps, this stuff is all trivial once you're familiar with Perforce. Once you know how this all works, all these integrations and merges can be done in a matter of minutes. Valve recommend that you jump back to the "overview" section of this document to review the high-level process that is involved, and see how all the detailed steps fit into that simple high-level process.

Internally, Valve uses source control in a similar fashion to that described in this document. The main difference is that ALL files for Valve games go in Perforce, including content source .TGA artwork, .VMT files, executables, scripts, documents, etc. They recommend doing this while developing a mod as well, bandwidth limits and disc space allowing, because you can instantly restore any version of the mod that ever existed.

Valve also uses a multitude of codelines (whereas there are just two in this document). For example, they have a main codeline that about 20 programmers submit code into. Often programmers need to stay sheltered from other people's changes (which may happen as many as 19 times per day!), so each programmer has their own set of personal codelines that are branched off the main codeline. This way, the programmers can choose when they want to integrate their colleague's changes into their personal codeline (just like you now have the choice about when you want to integrate Valve's SDK updates into your own codeline).

See also