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.

The Half-Life Unified SDK’s replacement map system lets you swap out assets used by the game at runtime — without touching entity definitions or recompiling map files. A replacement map is a JSON file containing a set of key-value pairs where each key is the original asset identifier and each value is the identifier to use instead. Replacements can apply globally to all entities or be scoped to a single entity via a keyvalue. The replacement map system uses the logger named replacementmap.

Configuration File Syntax

Replacement map files are plain JSON objects. Each key is the original identifier (the asset path or sentence name as the game currently uses it), and each value is the replacement identifier to use in its place.
{
    "original/path/to/asset.ext": "replacement/path/to/asset.ext"
}

Model Replacement

Model replacement files swap out models used by entities on the server side.
  • File paths are case-insensitive and are relative to the mod directory.
  • Paths may refer to files in the mod directory or in any game whose content is being used as a base or fallback (for example valve, or the directory specified in liblist.gam’s fallback_dir).
  • Supported asset types: .mdl, .spr

Per-Entity Keyvalue

Add the model_replacement_filename keyvalue to an entity to apply a model replacement file to that entity only.

Example

This file replaces weapon viewmodels with their Opposing Force equivalents:
{
	"models/v_9mmAR.mdl": "models/op4/v_9mmAR.mdl",
	"models/v_9mmhandgun.mdl": "models/op4/v_9mmhandgun.mdl",
	"models/v_357.mdl": "models/op4/v_357.mdl",
	"models/v_chub.mdl": "models/op4/v_chub.mdl",
	"models/v_crossbow.mdl": "models/op4/v_crossbow.mdl",
	"models/v_crowbar.mdl": "models/op4/v_crowbar.mdl",
	"models/v_desert_eagle.mdl": "models/op4/v_desert_eagle.mdl",
	"models/v_displacer.mdl": "models/op4/v_displacer.mdl",
	"models/v_egon.mdl": "models/op4/v_egon.mdl",
	"models/v_grenade.mdl": "models/op4/v_grenade.mdl",
	"models/v_knife.mdl": "models/op4/v_knife.mdl",
	"models/v_m40a1.mdl": "models/op4/v_m40a1.mdl",
	"models/v_penguin.mdl": "models/op4/v_penguin.mdl",
	"models/v_pipe_wrench.mdl": "models/op4/v_pipe_wrench.mdl",
	"models/v_rpg.mdl": "models/op4/v_rpg.mdl",
	"models/v_satchel.mdl": "models/op4/v_satchel.mdl",
	"models/v_satchel_radio.mdl": "models/op4/v_satchel_radio.mdl",
	"models/v_saw.mdl": "models/op4/v_saw.mdl",
	"models/v_shock.mdl": "models/op4/v_shock.mdl",
	"models/v_shotgun.mdl": "models/op4/v_shotgun.mdl",
	"models/v_spore_launcher.mdl": "models/op4/v_spore_launcher.mdl",
	"models/v_squeak.mdl": "models/op4/v_squeak.mdl",
	"models/v_tripmine.mdl": "models/op4/v_tripmine.mdl"
}

Sentence Replacement

Sentence replacement files swap out sentences used by entities on the server side.
  • Both keys and values can be either sentence group names or individual sentence names, but the key and value must be the same type — you cannot map a group name to an individual sentence name.
  • Names are case-sensitive.
Refer to the TWHL wiki article on Sentences.txt for background on sentence groups and sentence names.

Per-Entity Keyvalue

Add the sentence_replacement_filename keyvalue to an entity to apply a sentence replacement file to that entity only.

Example

This file replaces sentences with their Opposing Force equivalents, remapping both individual sentences and sentence groups:
{
	// Human Grunt dialogue. Not used in Op4 since it uses different NPCs with unfiltered dialogue, but custom maps could use this.
	"HG_GREN": "OFHG_GREN",
	"HG_ALERT": "OFHG_ALERT",
	"HG_MONST": "OFHG_MONST",
	"HG_COVER": "OFHG_COVER",
	"HG_THROW": "OFHG_THROW",
	"HG_TAUNT": "OFHG_TAUNT",
	"HG_CHARGE": "OFHG_CHARGE",
	"HG_IDLE": "OFHG_IDLE",
	"HG_QUEST": "OFHG_QUEST",
	"HG_ANSWER": "OFHG_ANSWER",
	"HG_CLEAR": "OFHG_CLEAR",
	"HG_CHECK": "OFHG_CHECK",
	
	// Base computer dialogue. Used in of1a1, can probably just modify the map to use a custom sentence group.
	"C1A0_": "OFC1A0_",
	
	// HEV suit. Replaced with PCV sounds. Most of these use the same replacement so they could be merged to cut down on the number of sentences and groups.
	"HEV_AAx": "PCV_AAx",
	"HEV_A": "PCV_A",
	// Replace these separately because they are played directly.
	"HEV_A0": "PCV_A0",
	"HEV_A1": "PCV_A1"
}

Sound Replacement

Sound replacement files swap out sounds used by entities on the server side and by player movement code on the client side.
  • File paths are case-insensitive and are relative to the mod directory.
  • Paths may refer to files in the mod directory or in any game being used as a base or fallback.
  • Supported asset types: .wav

Per-Entity Keyvalue

Add the sound_replacement_filename keyvalue to an entity to apply a sound replacement file to that entity only.

Example

This file replaces player footstep sounds with their Opposing Force equivalents across several surface types:
{
	"player/pl_organic1.wav": "player/op4/pl_organic1.wav",
	"player/pl_organic2.wav": "player/op4/pl_organic2.wav",
	"player/pl_organic3.wav": "player/op4/pl_organic3.wav",
	"player/pl_organic4.wav": "player/op4/pl_organic4.wav",
	
	"player/pl_snow1.wav": "player/op4/pl_snow1.wav",
	"player/pl_snow2.wav": "player/op4/pl_snow2.wav",
	"player/pl_snow3.wav": "player/op4/pl_snow3.wav",
	"player/pl_snow4.wav": "player/op4/pl_snow4.wav",
	
	"player/pl_step1.wav": "player/op4/pl_step1.wav",
	"player/pl_step2.wav": "player/op4/pl_step2.wav",
	"player/pl_step3.wav": "player/op4/pl_step3.wav",
	"player/pl_step4.wav": "player/op4/pl_step4.wav",
	
	"player/pl_tile1.wav": "player/op4/pl_tile1.wav",
	"player/pl_tile2.wav": "player/op4/pl_tile2.wav",
	"player/pl_tile3.wav": "player/op4/pl_tile3.wav",
	"player/pl_tile4.wav": "player/op4/pl_tile4.wav",
	"player/pl_tile5.wav": "player/op4/pl_tile5.wav",
	
	"player/pl_wood1.wav": "player/op4/pl_wood1.wav",
	"player/pl_wood2.wav": "player/op4/pl_wood2.wav",
	"player/pl_wood3.wav": "player/op4/pl_wood3.wav",
	"player/pl_wood4.wav": "player/op4/pl_wood4.wav"
}

Global Replacements

Replacement files can also be applied globally so that they affect all entities rather than just a single one. Global replacement files are registered through the Game Configuration System in a map configuration file using the appropriate section type:
SectionReplacement Type
GlobalModelReplacementModel replacement applied to all entities
GlobalSentenceReplacementSentence replacement applied to all entities
GlobalSoundReplacementSound replacement applied to all entities
See the Game Configuration System documentation for the full syntax for registering these files in a map configuration.

Build docs developers (and LLMs) love