Where is Poppy
Setting up a GoldSrc Mod
You can find the accompanying PDF here.
The Original Tutorial can be read here.
You can Download the Project Source Code and Releases through Github.
This tutorial will cover the steps required when setting up a mod to run on the GoldSrc engine. The mod will use the latest Half-Life SDK from Github for the source code. This is the first part in a series of tutorials covering the creation of the project "Where is Poppy".
This tutorial uses Perforce for Source control, You should be able to apply what you learn to any Version control system regardless.
It is not required but may be helpful if you watch the following two tutorials I created prior to this one:
Introduction to GoldSrc Programming – Setting up Visual Studio
Introduction to Perforce
What you will need
- Perforce Server & Client (or any Version control system)
Installation & Preparation
Install Visual Studio
for C++ ( you are required to create a free account )
Downloads can be found here
for the free version. You may have to do some digging for the older versions. Note:
I will be using Visual Studio 2013
as it’s the latest version of Visual Studio
you can use that doesn’t require you make changes to the HLSDK
just so that it will compile. If you must use the latest and greatest you can try a fork of the SDK from Malortie
which should compile with Visual Studio 2015.
Download the Half-Life SDK
from Valve’s Github
repository, Hold onto this file as we will be using it later.
If you use Git as version control you can use GitHub Desktop
the official repository.
You could also fork the Where is Poppy
Repository if you want to check its code out instead.
Debug Vs Release
There will be two Mod folders during the life of this Mod, it is not necessary for you to following exactly along these lines but my reasoning for each are as follows: WereIsPoppy_dev:
This is my initial playground, a sandbox for new features, code I am currently working on and developing. I will use this for the tutorials. WhereIsPoppy_rel:
This is a duplication of my Develop
branch. Typically, I would merge the contents or individual features from my Develop
branch here once they are complete and in a stable state. This branch should be relatively bug free and used for testing and release.
This system also doubles as an aid for me when I am creating these tutorials as I typically test a concept first in Develop
and merge to Release
. Then when I start recording the Tutorial I wipe the Develop
branch or return to the previous tutorials state knowing that I have a copy in the Release
branch and use Develop
to teach the lesson. After each tutorial in this series I will commit Release
for those following along.
Using Perforce (Helix) for Version Control (Optional)
You can use whichever version control system you like. For this series of tutorials, I will be using Perforce
. This first tutorial will be the only one to mention Perforce
as I walk you through setting it up for a Goldsrc
mod. Those of you using alternatives or no source control (you really should be) can safely skip over the Perforce
sections or modify them to suit whatever system you are using. Download and install Perforce
You can get the version I am using here
. Otherwise head over to Perforce
to get the latest and greatest. First install the server component "helix-versioning-engine-x64.exe
- Select the components you want to use; the defaults should suffice.
- Under Server configuration set the server to "1666" unless you have a server elsewhere. Set the location where you want your server repository to reside. Typically, this is on a different hard drive to the one your actual project is on so that in the event of hardware failure you have a backup.
- If a repository already exists in the location you select you will be greeted with this screen, It’s up to your own discretion what to do in this situation but if you are like me and moving occasionally from one pc to another I will select "Yes" to use the predefined repository.
- Next up is to set the Server to "1666" (set it elsewhere if you have a server elsewhere on your network but in my case the server is on my work machine.), Set your preferred text editor and then a username you will use for admin on the server.
Install the client component "p4vinst64.exe
Setup the Environment Variables
- Select the features you want; I use all of them.
- Set the Server to "1666" unless you have a separate server elsewhere, set your text editor and the username you want to use.
- Start and complete the installation.
Open command prompt in windows and type the following:
You should see the following:
Issue the following command:
p4 set P4CLIENT=WIP_Development
should be the same name as the name of your workspace in P4V (Perforce GUI)
. We will create it shortly. Note:
You can set any of the listed variables using "p4 set
", This is useful if you need to change the location of the repository etc. P4Admin
The next tool we need to check out is P4Admin
which should have installed with the Perforce visual components.
The Open Connection
dialog should appear.
In my case the user did not exist when I tried to open the connection. So we just create a user.
Click on New
and fill out the new user details.
You will be presented with the following message if you open the connection. Hit yes because you want to be the administrator on this server.
P4Admin lets you create and manage users, groups and set permissions to each. For our use case, it is not necessary.
One thing I would advise you to do would be to require a password for the depot. You can change the password security level through the administration menu entry.
The last thing we can do but is not necessary (unless you want to follow step by step) is to rename the depot in p4admin.
Select the "Depots
Right-Click on "depot
Select "Delete Depot ‘depot’
Select File > New > Depot
to create a new Repository
Give it a name, I called mine "Projects
That is all we have to do in P4 Admin. P4V
P4V (GUI for Perforce) is where you typically would create the connection from your local working files and where you want to place them in the Perforce depot.
Firstly, start up P4V. You should see this:
For now, let us leave workspace blank as we have yet to create it. P4V
looks something like this: (It may seem daunting at first but it is not a difficult program to master, you probably will not need to use the majority of functions Perforce provides.)
Ok let’s create the Workspace
that we will use for our Development
Click on the Workspaces
Tab (If you cannot see it, it is accessible via the View Menu)
Right click in the white space and select "New Workspace
For Workspace Name call it "WIP_Development" (Like we called our P4CLIENT earlier)
Point it to the location on your PC where you will be working from. Mine is:
C:\_Projects\Where is Poppy\WIP_Development
Workspace mappings are used to map folders from the repository to your local workspace.
It also functions much like a ".gitignore
" by settings file types or specific locations you do or don’t want versioned.
My mapping looks like the following:
"-//Projects/WIP_Dev/Source Code/dmc/..." "//WIP_Development/Source Code/dmc/..."
"-//Projects/WIP_Dev/Source Code/ricochet/..." "//WIP_Development/Source Code/ricochet/..."
"-//Projects/WIP_Dev/Source Code/linux/..." "//WIP_Development/Source Code/linux/..."
"-//Projects/WIP_Dev/Source Code/projects/vs2010/Debug/..." "//WIP_Development/Source Code/projects/vs2010/Debug/..."
The first line directs Perforce to include the whole repository and version it under "WIP_Development" which we set above to be:
C:\_Projects\Where is Poppy\WIP_Development
" as a variable that holds the above path. Note:
This is our Project Source Directory which we will be setting up later, for now create an empty directory.
The remaining lines with a preceding minus " -
" are being told to exclude files and directories from being versioned, These include intermediately created files from visual studio that we don’t want to clutter out commits with.
Save your workspace and select it.
If you see the following message, there are files within your selected project folder. This may be because you are moving from one PC to another or you prepared source assets within it already.
In my case I choose "No
If you see the following Screen Ignore it and Cancel
For paths with spaces be sure to use enclosing "quotes
For those interested my Release branch is basically the same setup but in the above workspace mappings "WIP_Dev
" is replaced with "WIP_Rel
" and the Workspace itself is called "Release
" and not "Develop
" I would then have to set "P4CLIENT=Release
" If I ever want to commit files to that repository.
As I won’t be building the code on Release
frequently (I mostly merge to it from the Develop
branch – binaries included) it won’t really be an issue.
Install your level editor of choice, I will be using (J.A.C.K) Jackhammer
in the context of this tutorial. Note:
Be sure in the setup to correctly point Jackhammer
to your Half-Life
under Options > Game Profiles
Be sure to check and update if necessary the paths to the Game
and Build Programs
. I installed Jack
in a location other than its default and some of these paths failed because they hadn’t updated.
Setup the Mod
Prepare the Directory
Create a Mod folder inside the Half-Life
directory. Something along these lines:
You should not have any spaces in the Mod folder name to avoid potential issues. Use Camel Case or underscores if you need to break up words.
Concept: A Modification (Mod)
The general idea behind a Mod is fairly simple and quite ingenious as well. Valve
created a generic engine structure which is abstract enough to lend itself to any number of custom mods. You simply need to create a folder inside the Half-Life
folder and give it the name of your Mod (To avoid potential future issues, keep white spaces out of the folder name i.e. Spaces). The subfolders within your mod folder should be named the same way as the subfolders inside the "valve
" directory within the Half-Life
folder. Why do this you ask?
Well the explanation is simple, you are making a modification of Half-life
, not a whole new game from scratch so you need to follow the engine structure Valve
set-up for Half-Life
. Then all you have to do is place models and textures in their appropriate subfolders. You can make uniquely named assets or you can be lazy and create assets with the exact same name and directory structure as vanilla Half-Life
assets. The engine will look in your mod folder first and use that before looking in the original games folder.
The benefit to this is that you save yourself some work especially if you only want to replace for example the texture of an original Half-Life
model and use the existing mesh. You would only have to place a texture of the exact same name and location in your mod folder so that the engine can find and use it rather than the original texture. This way you also preserve the original Half-life
folder and its assets.
Your mod folder should contain at least some of these folders: Explanation of folder purposes: cl_dlls
- Harbour for the Client side dll files dlls
- Harbour for the main game dll files events
- Contains event placeholders for client playback. Read more
about it. gfx
- Contains graphics for the Half-Life launcher shell and map skies hw
- Contains hardware specific optimization scripts logos
– Contains game logos/Sprays maps
- Location of all the maps and stores the nodegraphs media
- Contains launcher sounds models
- Location of the game models overviews
- Contains the overviews for the maps resource
– UI related contents and resources save
- Stores the saved game files scripts
- scripts folder sound
- Contains any sounds used in the game sprites
- Contains special effect sprites and sprites for the heads-up-display
is a text based file that acts as a descriptor for your mod, if you are familiar with Source engine mods the spiritual equivalent is gameinfo.txt
. It is structured as such:
Liblist.gam’s keys explained:
Key [string] : Value"[string]"
Each line has one Key followed by its Value which Half-Life uses to display and initialize your Mod.
The version Half-Life uses looks like this:
Key Value Description
game "string" Mod Name
icon "string" Name of image used as an Icon in Steam
developer "string" Name of Mod/Game Developer
developer_url "string" Home Website of game
manual "string" Link to the games manual
gamedll "string" Name and relative location of the games main library file [Win(dll)]
gamedll_linux "string" Name and relative location of the games main library [Linux(so)]
gamedll_osx "string" Name and relative location of the games main library file [Mac(dylib)]
secure "boolean" Allow VAC secure server
svonly "boolean" Is it a Server only Mod?
cldll "boolean" Use the client dll in the mod?
type "string" singleplayer or Multiplayer mod
startmap "string" Name of the games starting Map
trainmap "string" Name of the games training Map
mpentity "string" WON, Deprecated. Omit maps with this name in it.
mpfilter "string" Omit maps with this name in it.
fallback_dir "string" set a fallback mod directory
fallback_maps "string" set a fallback map
nomodels "boolean" Don't show models in browser since you don't pick them there.
nohimodels "boolean" Use high or low poly models
detailed_textures "boolean" Use detailed textures in the mod for better quality
// Valve Game Info file
// These are key/value pairs. Certain mods will use different settings.
Your Mods liblist.gam
should be located in the root of your Mod folder. Using this as a base I will create one in the "Where is Poppy"
// Where is Poppy Liblist.gam
// Cathal McNally
game "Where is Poppy"
This may change over time, for now it will suffice. If it does change I will inform you in future tutorials
Next item on the list is to compile your games code.
You should at least have created in your mods folder subfolders named "dlls
" & "maps
It will look something like this:
folder will contain your MODs main code library.
folder will contain the client dll for the MOD.
folder will contain your compiled maps. Important Note:
If you are having issues with the filecopy.bat
relating to access denied make sure you change the security permissions of the whereIsPoppy_dev
Mod folder to allow the current full control over it. Otherwise Windows prevents Visual Studio
from copying the file. Half-Life
will look for your liblist.gam
and read its contents according to how you set them.
Setup a Project Directory
Project Management, Folder Structure & Version Control
I have an overall Projects folder I use for games development where I try to keep everything tidy and organised. Since all projects are different and everyone has their own idea of how best to structure a project I will simply provide mine as an example of what you can do. It looks something like this: Where is Poppy
is the Root Project Folder Assets
is a directory for source maps, textures, models, concept art, documentation etc.. Mod
is a Symlink
to the WhereIsPoppy
folder found in the Steam/Steamapps/common/Halflife
directory (I use a symlink so that I can version everything together with Perforce). To create the symlink I did the following:
- I shift right clicked inside the Where is Poppy project folder and opened a Commandline Window
- I typed the following:
mklink /D Mod "C:\Program Files\steam\steamapps\common\Half-Life\WhereIsPoppy_dev"
is a directory to store the Half-Life SDK code we will be compiling. Extract (or clone if you use Git
) the contents of the Half-Life SDK
you downloaded from Github
" into your Projects Source Code
directory. Mine is located here:
It should look something like this:
So now that you have you an initial state for your Source Project including the Source Code, Assets and the Mod Symlink we can add this to Perforce
Select your WIP_Development
Workspace. You should see something along these lines:
Highlight the folders in the Workspace and select "Mark for Add
" from the Right-Click Menu.
For Select Pending Changelist
: Select "New
" and add a description for your initial commit.
Switch to the Pending
Tab. The files will all be added to the Pending Changelist "1
Right click on the Pending Changelist "1
" and Click "Submit
It will present you with a confirmation dialog, select "Submit
You should see its progress:
Your files will now have been added to the Projects Repository. You can check this by selecting the "Depot
If you want to edit these files in future, you need to put them on a pending changelist
prior to making changes as Perforce
now controls the Read-Only
state of all the files it versions.
Load the Half-Life Source Code into Visual Studio
Open main project and unload unrequired projects
Let’s switch over to Visual Studio
where we can load up the Half-life SDK
. The solution can be found inside the projects/vs2010/
folder and is named projects.sln
Open this with Visual studio
and follow any onscreen prompts that may popup to convert the codebase to work with your version of Visual studio if you are using anything greater than 2010.
You will see something like the following if it loaded correctly: hldll
is the main project to worry about game specific features in your MOD/Game. hl_cdll
is the client dll project and contains important code we will modify in the soon future.
Firstly let’s right click on dmc_cdll, dmcdll, ricochet_cdll, ricochetdll
and unload them since we don’t really need to use them.
Right click on hldll
and set the Configuration
in the top left corner to "All Configurations"
. This means that changes we make to the properties page will propagate through all project configurations in this case both Debug
and Release. Do the same for hl_cdll
Suppress unnecessary warnings
Let’s also suppress the unnecessary warnings Visual Studio spits out.
Right click on hldll
and under Properties
navigate to Configurations Properties -> C/C++ -> Advanced
, (Make sure to set "All Configurations"
so that it affects both Debug Release)
For "Disable Specific Warnings"
add the following:
Do the same for cl_dll
Rename Target Library (Dll name)
RightClick on hldll
and select Properties
. Let’s rename what the output library will be called so we can personalize it for our project. There is no real need to do this to hl_cdll
(Its name cannot be changed in liblist.gam
as far as I am aware unlike hldll
" to "wip
Under Configuration Properties -> General
Set Target Name
to whatever you want your mod to be called. (wip in my case)
Modify Post-Build Event (Filecopy.bat)
Next up we should modify the post build event of both hldll
to suit our requirements. Under Build Events -> Post-Build Event
Set Command Line
to suit your needs.
It originally looked like:
call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\dlls\$(TargetName).dll
call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\dlls\$(TargetName).pdb
Mine looks like the following now for hl_dll
call ..\..\filecopy.bat "$(TargetDir)$(TargetName).dll" "C:\_Projects\Where is Poppy\Develop\Mod\dlls\$(TargetName).dll"
call ..\..\filecopy.bat "$(TargetDir)$(TargetName).pdb" "C:\_Projects\Where is Poppy\Develop\Mod\dlls\$(TargetName).pdb"
Mine looks like the following for hl_cdll
call ..\..\filecopy.bat "$(TargetDir)$(TargetName).dll" "C:\_Projects\Where is Poppy\Develop\Mod\cl_dlls\$(TargetName).dll"
call ..\..\filecopy.bat "$(TargetDir)$(TargetName).pdb" "C:\_Projects\Where is Poppy\Develop\Mod\cl_dlls\$(TargetName).pdb"
Basically what this does is call an external batch file which will copy the file from parameter 1
to parameter 2
. In our case we want to copy the dll
(project debug info) files from the source code location to our mods dlls folder where it can be used.
I have enclosed the paths in quotes so when filecopy.bat
tries to load the given paths it won’t fail with a spacing issue. I changed the first line to specifically copy the game dll and not the whole TargetPath folder Note: $(TargetDir)
are Visual Studio macros used for aiding with keeping paths dynamic incase things such as the project name change etc.
I used a full path in my second parameters as there is no macro set for them. Read here
if you want to create custom macros in VS.
I edited filecopy.bat
to suit my needs a little better. For the sake of comparison it looked like the following before my edits:
rem @echo off
rem echo %~f2
p4 edit %~f2
@copy %1 %~f2
It reads as the following now:
echo "SourcePath : %sourcePath%"
echo "TargetPath : %targetPath%"
p4 edit "%targetPath%"
p4 add "%targetPath%"
@copy "%sourcePath%" "%targetPath%"
It basically carries out the same procedure as before except I created local variables to store the parameters as well as an extra Perforce
command. "p4 add
" which tells perforce to open the file for add if it has not been versioned before (only really necessary on first compile or if you change the dll name)
You can check over in P4V
there should be changelist that includes the dll and pdb files you just compiled.
If you get an error in Visual Studio about file is not under the client
make sure that P4CLIENT
is set to the name of your workspace and that the Symlink
functions i.e. takes you to the WhereIsPoppy_dev
You can edit this file to work for your own version control system such as git, mercurial
or you can completely remove the perforce commands and only use the copy feature.
Now that this is all prepared you can go on ahead and Compile your code in Visual Studio
and hopefully if no errors occur you will see your dll file & pdb files pop up in your mods dll folders.
If you are using Perforce
you should notice (Press F5 to refresh) that the 4 files that were copied to the Mod directory have been added to a default changelist for addtion or edit in the server.
Restart steam. If everything is setup correctly you should see your mod listed on your game list.
How to add a custom game Icon that’s shows up in Steam
To see an icon in steam declare it in your liblist.gam file as:
The icon should be a 32 * 32 sized Targa
image. Do not add the .tga file extension to the name in liblist.gam
Go ahead and launch the Mod, It should launch with a vanilla Half-Life using your custom dlls if you set your parameters correctly in the liblist.gam
Create a Basic Sandbox Level for testing
I am using Jackhammer
, an up to date replacement for Hammer/Worldcraft
This is not really and overly important or necessary step but having a small plain block room to test your code changes can be useful while you develop.
Fire up Jackhammer.
Open Tools -> Options
Double check that under Game Profiles Half-Life
is the selected Configuration.
Under directories change the Source Maps Directory to your mods "map
I would recommend installing JHLMV
for viewing models through Jackhammer. Learn more about JHLMV here
Provide the Directory to your mod under "Mod Directory" and ensure the remaining paths make sense.
Mine looks like the following:
Now click File -> New
In the small dialog that pops up you have some options for creating a default room if you like.
In my case I will go with the default settings and hit OK
This will create a small room with a light, textured floor/walls/ceiling & player start, like this..
For now this is enough for our debugging and testing needs. Click on File -> Run.
If it asks you to, save a map source file (.rmf/.jmf
) into your Mods Source Map folder. Jack will copy the compiled version to the actual Mods Map folder.
In the pre-compile Dialog that pops up make sure to set some console commands for Half-Life to obey.
It should look something like the following: "-game WhereIsPoppy_dev"
: Explicitly set your Mod here "-dev -console"
: start the engine in dev mode with console "-condebug"
: writes everything logged in the console to a text file console.log
For now ignore the remaining options.. Click OK
If Jackhammer asks you to save the map (.MAP
) place it in your Mods "maps
" folder next to the previously saved .rmf/.jmf Note:
During the compilation process the .MAP
file is compressed and compiled into a .BSP
which the engine can read and use. RMF/JMF/MAP
files are text based source files whereas BSP
is the compiled & compressed binary.
Wait for a successful build and watch as it runs half-Life and places you in the map you just created.
To be sure that Half-life is using your custom dll press the console key which should be represented by ~
(tilde) on your keyboard.
Look back through the log until you come across the section displaying this:
This confirms that it loaded both your custom dll & newly created map.
You can go ahead now and add all your new files to Perforce
, revert unchanged files and commit your files with a meaningful description.
I hope this tutorial helps you in some small way :)
If you find any issues or if you know of anything this tutorial should include please feel free to send an E-Mail
onto me concerning it.
The support thread for this tutorial can be found over on the forums