Setting up UnrealGameSync
=========================

UnrealGameSync provides a graphical frontend to sync and build UE4 projects from Perforce, designed to facilitate low overhead and fast iteration 
times between designers, programmers and artists.

* Developers can sync to a changelist as soon as it's submitted, and locally compile the source code matching that change. They can add comments to each 
  change, or flag builds as good or bad for other developers.
* Zipped editor builds compiled by CIS can be synced and decompressed automatically for artists without Visual Studio.
* Engine version files (Version.h and Build.version) are updated to the changelist synced, so programmers can safely make content changes from local builds
  without submitting unversioned assets. Since UnrealGameSync syncs code and content at the same time, it is safe to submit changes containing assets and source code.
* Individual engineers can flag to the rest of the team when they're taking responsibility for the build being broken and working on a fix.
* CIS results can be surfaced directly alongside the list of submitted changelists, along with a link to build logs.
* Custom build steps allow setting up project-specific tools and utilities.


Tools
-----

* UnrealGameSync: Main tool to sync and build from Perforce.
* UnrealGameSyncLauncher: Launcher for UnrealGameSync, which auto-updates the program executables from a path in Perforce. It does not require a clientspec which has the path mapped.
* Installer: MSI installer for UnrealGameSyncLauncher. This is typically used to get the bootstrap launcher onto developer machines, which can then auto-update and 
  run the actual program from Perforce. Requires Wix 3.8 to build.
* PostBadgeStatus: Small utility to poke CIS results into the database that UGS reads from.


Site-specific Configuration
---------------------------

Several of these tools require site-specific configuration for Perforce paths and database server connection settings. The defaults are left blank, and are defined 
at the top of the Program.cs file in each tool. 

	In UnrealGameSync:

		string SqlConnectionString (Standard C# syntax suitable for constructing a SqlConnection object)

	In UnrealGameSyncLauncher:

		string StableSyncPath (Path to auto-update UnrealGameSync executables from)
		string UnstableSyncPath (Path to update pre-release UnrealGameSync executables from. Hold down the SHIFT key when running UnrealGameSyncLauncher to use pre-release executables).

Epic's settings are in a NotForLicensees/ProgramSettings.cs file under each tool, which are included by the project files if present, but which we do not distribute. In each case, this 
file uses the 'partial class' feature of C# to implement a static constructor for the Program class, which initializes these settings. Licensees may add their own version of these files,
similarly to this:

	using System;
	using System.Data.SqlClient;

	namespace UnrealGameSync
	{
		static partial class Program
		{
			static Program()
			{
				SqlConnectionStringBuilder SqlConnectionStringBuilder = new SqlConnectionStringBuilder();
				SqlConnectionStringBuilder.DataSource = "database.mycompany.com";
				// SqlConnectionStringBuilder.IntegratedSecurity = ...
				// SqlConnectionStringBuilder.UserID = ...
				// SqlConnectionStringBuilder.Password = ...
				SqlConnectionStringBuilder.InitialCatalog = "UnrealGameSync";
				SqlConnectionStringBuilder.ConnectTimeout = 10;

				SqlConnectionString = SqlConnectionStringBuilder.ToString();
			}
		}
	}


Team Deployment
---------------

To allow development on UnrealGameSync out of band with different branches and game projects, Epic distribute UnrealGameSync to internal developers via a self-patching
mechanism that leverages Perforce for distribution.

A rarely-updated launcher application is manually installed on each developers machine (UnrealGameSyncLauncher) via an MSI (the 'Installer' project). Installing this 
creates a start-menu icon, and running it syncs the latest UnrealGameSync executables from a path in Perforce and runs them. That path is monitored, and if new executables
are submitted, the program restarts and re-syncs them.

You may find it more convenient to distribute the UnrealGameSync executable directly in Perforce, or via some other means.	


Zipped Editor Builds
--------------------
	
To allow users to download zipped editor builds instead of compiling locally, you can add a Build\UnrealGameSync.ini file under your project
which references a location in Perforce where zipped binaries are kept for each branch. 

	[//UE4/Main/Samples/StarterContent/StarterContent.uproject]
	ZippedBinariesPath=//depot/ZippedBinaries/StarterContent/Main-Editor.zip

Note that the same restrictions are enforced with zipped editor binaries as local builds - UnrealGameSync will not allow you to sync any changelist,
even a content changelist, *after* a code change unless there are matching binaries for it. It will allow you to sync content-only changes using previously
submitted binaries as long as there are no *.cpp, *.h, *.cs, *.usf files are modified.

This functionality does not require use of a database, but reads the matching corresponding changelist for each submitted zip from the changelist 
description (it should start with the tag "[CL 12345678]"). 

There is an AutomationTool script called BuildForUGS (Engine/Source/Programs/AutomationTool/Scripts/BuildForUGS.Automation.cs) which can be used to create and 
submit editor binaries in the correct format from a build machine. A typical command-line to run it is as follows:

Engine\Build\BatchFiles\RunUAT.bat 
	BuildForUGS 
	-Target="UnrealHeaderTool Win64 Development" 
	-Target="MyGameEditor Win64 Development" 
	-Target="ShaderCompileWorker Win64 Development" 
	-Target="UnrealLightmass Win64 Development" 
	-Target="CrashReportClient Win64 Shipping" 
	-WithUAT 
	-WithUBT 
	-Archive=//depot/ZippedBinaries/StarterContent/Main-Editor.zip

Build System Integration
------------------------

UnrealGameSync can surface build system results (and notifications that a build is in progress) via badges shown in the list of submitted changelists, and will 
also show a toast popup to notify any developers that have submitted changes if the build breaks. Clicking on a badge can open a web browser at an URL containing 
the build log. This information is stored in a database, and entries are poked into it using the PostBadgeStatus utility. 

Command-line syntax:

	PostBadgeStatus.exe
		-Name=Editor 
			(The badge name that will appear in UGS)
		-Change=123456 
			(The changelist being compiled)
		-Project=//UE4/Main/Samples/StarterContent 
			(The project to show the badge for. Note that this is the path to a folder, not the actual .uproject file)
		-Database="Data Source=mydatabase.mycompany.com;Initial Catalog=UnrealGameSync;Integrated Security=True;Connect Timeout=10" 
			(An SQL connection string)
		-Status=Success
			(The status of the build. Valid values are 'Starting', 'Failure', 'Warning' and 'Success').
		-Url=http://link-to-build-log
			(Link to take the user to if they click on the badge)


Branding
--------

You can add a project logo to be displayed in UnrealGameSync by placing an Build\UnrealGameSync.png file in the directory containing 
your project. The image will be scaled to height of 126 pixels. We recommend dimensions of 200x126 or similar.


Other Notes
-----------

* UnrealGameSync does not log in to Perforce, so you'll need an active login ticket while running it. The Perforce server only creates login tickets 
  which are valid only for 12 hours by default; we configure our Perforce server to issue tickets which do not expire.


Database Setup
--------------

UnrealGameSync uses a database to store user feedback, compile results, telemetry, and the results of any external CIS results posted using the PostBadgeStatus utility. While it can run without this
being set up, some of the more powerful features will not be available.

Create scripts for the tables used are below:

	CREATE TABLE [dbo].[CIS] (
		[Id]           INT           IDENTITY (1, 1) NOT NULL,
		[ChangeNumber] INT           NOT NULL,
		[BuildType]    NCHAR (32)    NOT NULL,
		[Result]       NCHAR (10)    NOT NULL,
		[Url]          VARCHAR (512) NOT NULL,
		[Project]      VARCHAR (256) NULL,
		[ArchivePath]  VARCHAR (512) NULL,
		PRIMARY KEY CLUSTERED ([Id] ASC)
	);

	CREATE TABLE [dbo].[Comments] (
		[Id]           INT            IDENTITY (1, 1) NOT NULL,
		[ChangeNumber] INT            NOT NULL,
		[UserName]     VARCHAR (128)  NOT NULL,
		[Text]         VARCHAR (140)  NOT NULL,
		[Project]      NVARCHAR (256) NOT NULL,
		PRIMARY KEY CLUSTERED ([Id] ASC)
	);

	CREATE TABLE [dbo].[Errors] (
		[Id]        INT            IDENTITY (1, 1) NOT NULL,
		[Type]      VARCHAR (50)   NOT NULL,
		[Text]      VARCHAR (1024) NOT NULL,
		[UserName]  NVARCHAR (128) NOT NULL,
		[Project]   VARCHAR (128)  NULL,
		[Timestamp] DATETIME       NOT NULL,
		[Version]   VARCHAR (64)   NOT NULL,
		[IpAddress] VARCHAR (64)   NOT NULL,
		PRIMARY KEY CLUSTERED ([Id] ASC)
	);

	CREATE TABLE [dbo].[Telemetry.v2] (
		[Id]        INT            IDENTITY (1, 1) NOT NULL,
		[Action]    VARCHAR (128)  NOT NULL,
		[Result]    VARCHAR (128)  NOT NULL,
		[UserName]  NVARCHAR (128) NOT NULL,
		[Project]   VARCHAR (128)  NOT NULL,
		[Timestamp] DATETIME       NOT NULL,
		[Duration]  REAL           NOT NULL,
		[Version]   VARCHAR (64)   NULL,
		[IpAddress] VARCHAR (64)   NULL,
		PRIMARY KEY CLUSTERED ([Id] ASC)
	);

	CREATE TABLE [dbo].[UserVotes] (
		[Id]         BIGINT         IDENTITY (1, 1) NOT NULL,
		[Changelist] INT            NOT NULL,
		[UserName]   NVARCHAR (128) NOT NULL,
		[Verdict]    NCHAR (32)     NOT NULL,
		[Project]    NVARCHAR (256) NULL,
		PRIMARY KEY CLUSTERED ([Id] ASC)
	);

