Solution Configuration setup
Part 1: Introduction
The main purpose of this tutorial is to serve as a helper or more as an introduction on how to enhance configuration proprety / file and folder management.
This tutorial convers the use of additional header directories and preprocessor directions in order to manage code modification and management easier. Occasionally, there would be needs or requirements to modify original source files that were written by either Valve or one other person from the team who is sharing the same solution. Very often, programmers do tend to leave comments with names and indications of what was modified at this point. However, when working in the main engine stucture or several other files related to proper stability, despite comments, readability can still become insufficient in certain cases. This is mainly where preprocessor directives come in handy when it comes to efficiently separate pieces of original code with the new modifided one. Another advantage of preprocessors is the fact that the sections of code they do bear can be disabled by undefinition, thus completely disabling every code shared by those.
As for the additional directories of headers, which will be the first part of this tutorial, this habit consists of creating and moving all new source files to a particuliar folder in which, becomes easier and more efficient when removing / deleting user created source code is required. Of course, since filters can be present in the main solution, they do procure a good and intuitive way of keeping track of new user created content / files. As such, when regrouping or distributing a portion of source code for an upgrade or sharing, process is usually much quicker and easier, since searching new files through the entire source code is not as long as it would be since they are all stocked in one user created folder for distinction.
Part 2: Path creation
Go to your main Src folder in the mod directory where you specified the source dump. e.g. C:\mymod\src\... From this spot, several folders named such as 'Common', 'Public', 'Game' can be seen. Depending on the branch of the engine you are using, you might require to proceed to different paths. If your modification is based on the 2006 version of Valve's Source Engine, then, you should find three folders name respectfully 'cl_dlls', 'dlls', 'shared'. Otherwise, if you are using newer versions of Source SDK, you should proceed to the 'Game' folder and you will be presented to threed folders named 'Client', 'Server', 'Shared'. Assuming each folder has been found, add a folder in each of these and rename it accordinly to your mod convention e.g. Mod name: mymod, folder name: mymod. Mod name: testmod, folder name: testmod. Once this is completed, proceed to your solution located in the main root of the Src folder: C:/mymod/src/Game_Episodic-2005.sln. Open it and wait while symbols and header files are being parsed.
Part 3: Configuration of directories
You should open up the main solution and follow the process on how to correct mistakes if any. Depending of the version of Visual Studio you are currently using, you might have several extra steps to follow. Once the solution is fixed, Right click on 'Client' project in the solution explorer and click on 'Propreties'. Once the main proprety pages windows is opened, scroll down and find a section named C/C++. In this section, several fields are related to file directories and references.
Before proceeding to changes and proper configuration, you should change the Configuration setup to 'All Configurations'. it is quite important to understand that depending on which configuration you are currently using, you will be able to modify parameters for only this configuration type. But if you revert to debug or other setup you are using, you will have to configure them again on the other side. e.g. If you are currently in 'Debug' mode and configuring, then you will need to switch to release and do the same.
Assuming the configuration setup is changed to 'All Configurations', you should go in the sub category, 'General' and find a field named 'Additional Include Directories'. Click in the main field and an arrow should appear on the far right of the tab. Click on it and select <edit...>. As soon as this is completed, a menu will show up and list you all the solution paths where headers can be found. Scroll down the menu until you notice a blank space. You should double click on this space and you will be prompted to enter the path of your additional header files. Assuming that the custom folders were named e.g. mymod; Enter this following text without quotes in the blank space: ".\mymod" Press enter and once again scroll down and select the next blank space. Enter this text without quotes: "..\..\game\shared\mymod" If you are using the 2006 branch version of Valve's Source Engine, you should enter those lines: "..\..\cl_dlls\mymod", "..\..\shared\mymod"
These declarations will allow path search to new user defined header files and thus, should avoid having to type '..\..\...' each time a new file needs to be included. Now that this is done with the 'Client' project, repeat the same process for the 'Server' project. If you are using the 2006 version of Source SDK, instead of ..\..\cl_dlls\mymod, add this line: "..\..\dlls\mymod".
Part 4: Preprocessors directives
Open up the 'Client' project if it is not already done again and find the 'C/C++' label in the proprety pages. Indeed, this is the place where we wnt in order to configure Headers' search paths. However, this time do find a label named 'Preprocessor' in the 'C/C++' tab. You should come across the first proprety named 'Preprocessor Definitions'. You should make sure to change your Configuration setup to 'All Configurations' before proceeding. As with the previous step, click on the field and an arrow should appear on the far right. Click on it and a drop down menu will appear. Since you are in 'All Configurations' mode, the only word that will be present in the menu is: <different options>. If you are not in this mode, simply scroll down until you find a blank space. Once a blank space is located, simply double click on it and you will be prompted to write a text.
This text you are about to write is the name of the preprocessor which defines itself as a section delimiter. If an undefined preprocessor is referenced through the code, every source code section it bears will become disabled until redefined. Your preprocessor naming convention should stand for the same name as your modification, but it is not necessary. As suggested, if the name of your modification is e.g. Mymod, then the preprocessor could be named _MYMOD_DLL_ or even MYMOD_DLL. Since this is a 'Client / Server' architecture, it would be wise to name the 'Client' version of your own preprocessor e.g. MYMOD_CLIENT_DLL and on 'Server' side, it could be called 'MYMOD_DLL'. Thus, when working on shared file between both 'Client' and 'Server', the naming convention would make sense even with new code and preprocessors.
In order to use your new preprocessor, simply call it before the code section you wish to delimitate:
#ifdef MYMOD_DLL / #ifndef MYMOD_DLL // Additional source code... #endif // MYMOD_DLL #if defined ( MYMOD_DLL ) / #if !defined ( MYMOD_DLL ) // Additional source code... #endif // MYMOD_DLL
Preprocessors might prove themselves useful and intuitive, specially when working in a part of the code that was previously written by Valve or by another programmer. Despite comments can often take care of these problems, it is strongly recommended to use preprocessors definitions.
Part 5: Solution filters
Once the main preprocessors are in place and folders related to new source file publication are setup, one of the last improvements to cover is use of filters. Filters are easy to use in solution and can make file display and visibility quite flexible. Filters are mainly used not only to separate code display in several sections, but also to control visiblity on a group of code that could fit in a particuliar section. In order to add a new filter, proceed to the solution explorer and expand projects b continualy clicking on arrows next to their names. Upon having opened enough sections, you should come and notice a section named 'HL2 DLL'. This is an example of filter, as it separates the main game's source code from the other files more or less related to the base Source Engine. If you do expand it, you will come across various source files and headers related to Valve's Half-Life 2: npc_kleiner, npc_breen, npc_hunter... Now, you should be familiar with the main use of these filters and see the purpose of their use. It is quite important to keep a relative cleanliness and readability of the Source code you are working on. Whether a standalone work or in a team, communication and comprehension is a must.
To add a new filter, simply right click on the section you are working on e.g. 'Source Files' and in the 'Add' menu, choose and select 'Filter'. By adding a filter to 'Source Files' you can easily understand that you are allowed to add multiple sub filters to others and thus, create a better hierarchy of Header understanding. If you would like to move new files in new folders, you can click hold and drag them onto the new filter. As such, file display and readability is more common and allows a better diversity of file belonging in terms of sections.