Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/twhl-community/halflife-unified-sdk/llms.txt

Use this file to discover all available pages before exploring further.

Packager is a .NET tool that bundles your mod installation into a distributable ZIP archive. It reads a package manifest to determine which files to include or exclude, names the resulting archive with a UTC timestamp, and automatically removes any previously generated archives on successful completion. The tool is included in the hlu/tools directory of every Unified SDK release.
Packager is a .NET tool. On Windows you can run it as Packager.exe [options] or dotnet Packager.dll [options]. On Linux use dotnet Packager.dll [options].

Command line usage

Usage:
  Packager [options]

Options:
  --mod-directory <mod-directory> (REQUIRED)        Path to the mod directory
  --package-manifest <package-manifest> (REQUIRED)  Path to the package manifest file
  --package-name <package-name> (REQUIRED)          Base name of the package
  --verbose                                         Log additional information [default: False]
  --list-omitted                                    List files that were omitted from the package [default: False]
  --version                                         Show version information
  -?, -h, --help                                    Show help and usage information

Options

--mod-directory should point to your local copy of the mod installation — for example the hlu folder inside your Half-Life game directory. --package-manifest should point to the PackageManifest.json file in the game installation. This file defines which files are included in and excluded from the archive. --package-name is the prefix used when naming the output file. The archive is created with the format PackageName-yyyy-MM-dd-HH-mm-ss.zip. Timestamps use UTC time, not local time. For example, a package name of HalfLifeUnified-Game might produce HalfLifeUnified-Game-2022-05-17-09-28-18.zip. --verbose enables additional log output showing which files are being added or renamed inside the archive. --list-omitted prints the names of files that were found but excluded by the manifest rules.

Running Packager

Packager.exe ^
    --mod-directory "hlu" ^
    --package-manifest "hlu/installer/PackageManifest.json" ^
    --package-name "HalfLifeUnified-Game" ^
    --verbose

Using a script

It is recommended to save the command in a script placed in the directory that contains the game installation (typically the Half-Life folder).
dotnet "path/to/Packager.dll"^
    --mod-directory "hlu"^
    --package-manifest "hlu/installer/PackageManifest.json"^
    --package-name "HalfLifeUnified-Game"^
    --verbose

pause
The pause at the end keeps the window open so you can read the output before it closes.

Error reporting

If any errors occur, Packager logs the details to the console and stops execution. Old packages are only removed if the run completes successfully, so an interrupted or failed run will not delete your previous archive.

PackageManifest.json format

The package manifest controls which files are included in or excluded from the archive. It is a JSON file containing an array of pattern groups.

Top-level structure

{
    "PatternGroups": [
        {
            "Paths": [
                {
                    "Path": "relative/path",
                    "Required": false
                }
            ],
            "IncludePatterns": [],
            "ExcludePatterns": []
        }
    ]
}
PatternGroups is an array of objects, each describing one set of paths and patterns. Paths is an array of path objects. Each Path value is a relative path starting in the Half-Life game directory (for example hlu). If Required is true (the default when omitted), Packager will stop if the path does not exist. IncludePatterns is an array of glob patterns for files to add to the archive. ExcludePatterns is an array of glob patterns for files to exclude. Exclusions take precedence — a file matching both an include and an exclude pattern will not be included. Pattern syntax follows the .NET Matcher class glob format.
Any occurrence of %ModDirectory% in Path, IncludePatterns, or ExcludePatterns is substituted with the mod directory name provided by --mod-directory.
Files whose names end with .install are automatically renamed when added to the archive — the .install extension is stripped. This lets you store install-only variants of files alongside the regular versions.

Example manifest

// See the MSDN documentation on the Matcher class for more information on what patterns are supported:
// https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.filesystemglobbing.matcher
{
    "PatternGroups": [
        {
            // The OpenAL library must be in the game directory so the OS can find it when loaded.
            "Paths": [
                {
                    "Path": "."
                }
            ],
            "IncludePatterns": [
                "openal-%ModDirectory%.dll"
            ]
        },
        {
            "Paths": [
                {
                    "Path": "%ModDirectory%"
                },
                {
                    "Path": "%ModDirectory%_hd",
                    "Required": false
                },
                {
                    "Path": "%ModDirectory%_lv",
                    "Required": false
                }
            ],

            // Files and directories to include in the archive.
            // Files ending in ".install" will have that extension stripped when added.
            "IncludePatterns": [
                "cl_dlls/client.dll",
                "dlls/server.dll",
                "delta.lst",
                "halflife-unified.fgd",
                "liblist.gam",
                "server.cfg",
                "settings.scr.install",
                "user.scr.install",
                "titles.txt",
                "*.wad",
                "cfg/**",
                "events/*.sc",
                "installer/**",
                "maps/*.bsp",
                "maps/graphs/*",
                "models/**",
                "redist/VC_redist.x86.exe",
                "resource/**",
                "scripts/**",
                "sound/**",
                "sprites/**",
                "tools/**"
            ],

            // Files and directories to exclude from the archive.
            "ExcludePatterns": [
                // Generated by game; contains player spray.
                "tempdecal.wad",
                // Exclude player model image (autogenerated by game).
                "models/player/remapped.bmp",
                // Exclude NuGet configuration file used only for dev packages.
                "**/nuget.config",
                // Exclude the VS Code directory.
                "**/.vscode/**",
                // Exclude OmniSharp configuration files.
                "**/omnisharp.json"
            ]
        }
    ]
}

Build docs developers (and LLMs) love