MS 1.35 Mapping Tutorial and Reference (with notes for MSC)

  • Thread starter
  • Admin
  • #1


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005
Note: The information here is intended for MS1.35, but the majority still applies to MSC, except as noted by (sword.gif)

sword.gif - Hammer Configuration Note: With MSC you are intended to use BOTH the half-life.fgd and ms1.4.cfg included in your msc/dev folder. (Halflife.fgd should be added first.)

I'm going to try to keep this, for the most part, to MS entities. I'm not going to explain how to use Hammer or how to compile a map here, although I'll provide some links to how to do that at the end of the article, and maybe a tip or two.

This way-too-long-to-read tutorial is broken into the following sections:
- Spawns
Gotta start somewhere
- Map Transitions Gotta go somewhere
- Monsters & NPC's Gotta kill somethin
- Using Monster Deaths as Triggers Somethin's gotta get killed
- Spawning Rewards Gotta get something fer killin
- Chaining Events
Goal oriented maps
- Forcing Map Changes Don't get to press enter
- Random Events Randomness
- ms_npcscript A Mystery Solved
- Keys Unlock da powah
- Teleporters Breaking up maps
- Coralling Monsters Prevent wandering monsters
- Other Entities Decorate your dungeons
- MS Oddities Beware, the oddness
BASIC MAPPING TIPS Rules to live by
CRITICAL LINKS Places to go, things to see, stuff to download
- MSC mapping tutorials RMF's to learn from

...and here we go:

:arrow: - Spawns -

• message "messageString"
- Determines the transition this entity is tied to
• target "trigger on spawn"
- Targets this entity whenever a player spawns here
(Note that whenever a player spawns, the map event "player_spawned" fires, and whenever a new player joins the server, "player_joined" fires, you can use these events to trigger entities that need to be active after players first arrive.)
(angles, origin)

You'll need at least one of each of these in your map. The messageString should be the same as the desttrans of as the msarea_transition that points to it (explained below). If there is no msarea_transition leading to this map, use the name of the current map instead. Angles determines the direction the player will face when he spawns.

Note: You cannot have an info_player_spawn on an MS map, or the game will kick anyone who joins the map. There's a work around for this towards the end of the article. (sword.gif this is not an issue in MSC)

Example: (Edana)
"origin" "1792 2550 -88" //note: origin does not appear in Hammer
"message" "a3trans"
"classname" "ms_player_spawn"
:arrow: - Map Transitions -
entity: msarea_transition
• destname "Title of Destination" (eg. "Helena Under Siege" - do not use quotes in title)
- This is the name the player will see when the transition makes its pop-up
• destmap "destination bsp" (sans the ".bsp", eg "Helena")
- This is the map the transition will change to/vote for when activated
• desttrans "messageString" ("message" property of ms_player_spawn on destination map, see below)
- Which spawn to use on the destination map
• targetname "messageString" ("message" property of ms_player_spawn on this map, see below)
- Which spawn to use on this map after this transition is touched

note: This is a brush entity. If used as a point entity, only one player will be able to use it at a time.

Most of this is fairly straight forward. Desttrans is the tricky part. It must match the "message" property of an ms_player_spawn on the receiving map, otherwise the players will be kicked from the new map upon connect. Targetname, on the other hand, should match the "message" property of an ms_player_spawn on the current map (ie. the map the msarea_transition is actually in - preferably the one nearest to it). If a player dies after touching an msarea_transition, he will respawn at the ms_player_spawn entity matching the transition's targetname.

Example: (Gateroom to Thornlands, Edana entrance side)
"destname" "The Thornlands"
"destmap" "thornlands"
"desttrans" "SE-A3"
"targetname" "gateroom"
"classname" "msarea_transition"
:arrow: - Monsters and NPCs -
point entities:

(note: all of the above entities function the same, they only affect the model display in Hammer and the defaultscriptfile)
• lives integer
- number of times monster will respawn, if omitted or set zero, respawns forever.
• spawnchance [1-100]
- chance of monster respawning with each spawn check, generally this should be 100%
• delaylow seconds
- minimum time between spawn checks, in seconds
• delayhigh seconds
- maximum time between spawn checks, in seconds
• spawnarea spawnAreaName
- Ties monster to an msarea_monsterspawn (see below). Do not attempt to place monsters without monster spawns, it leads to issues.
• killtarget triggerString
- [optional] Triggers this entity when monster dies. (It does not remove the target the way the same property of trigger_relay does)
• perishtarget triggerString
- Trigger this when all lives are exhausted
• scriptfile scriptfile
- determines monster/NPC type (see list of applicable script files sword.gifMS:C Note: Some monsters/items maybe dated, see also Wiki and J-M's monster script list the newest monsters are in the betpack change log)
NOTE: If you enter a script name wrong your map WILL crash (also be aware that script names are cAsE sEnsItivE).
• descriptfile scriptfile
- [optional] As above, but seems to be required for some monsters. Generally, it's best to leave this as the FGD sets it.
sword.gif nplayers integer - Only spawn this monster if there this number of players, or more, present (AUG2007 or later)
sword.gif reqhp integer - Only spawn this monster if the total HP of all players on the server is above this number (AUG2007 or later)
sword.gif title string-Change the monster's name to this (SEP2007a or later)
sword.gif dmgmulti float-Multiply the monster's damage by this factor (must be > 1, SEP2007a or later)
sword.gif hpmulti float-Multiply the monster's hitpoints by this factor (must be > 1, SEP2007a or later)
sword.gif params token-string-Additional Parameters to adjust the monster. (Usage of this system is explained here.)
• targetname targetString (used by other entities, such as ms_npcscript (below) or trigger relay, to target the monster )
(angles, origin)

"origin" "-2664 -664 72"
"targetname" "finalwave_corpses"
"lives" "1"
"angles" "0 177 0"
"spawnchance" "100"
"spawnarea" "finalwave"
"defscriptfile" "calruin/cavespid"
"delayhigh" "2"
"delaylow" "1"
"nplayers" "0"
"reqhp" "0"
"classname" "msmonster_giantrat"
brush entity: msarea_monsterspawn
• targetname spawnAreaName
- monsters with spawnarea property matching this are tied to this monsterspawn area
• spawnloc "0|1"
- [optional] 0 = Monster's spawn at their own origin, 1 = Monsters spawn within the bounding box of the brush (careful with the latter, it may cause monsters to be stuck in walls or one another). Note also when setting this to 1 that spawn areas are always box shaped, and thus msarea_monsterspawn's must always be made of a single, boxed brush - they cannot be assembled from multiple solids nor solids of anything but a basic box or rectangular shape.
• "spawnstart" "1"
- [optional] If set, monsters tied to this will not spawn until this entity is triggered (target'ed) by another. This is usually recommended, as it prevents errors and CPU load issues.
• "fireallperish" "triggerName"
- [optional] Triggers entity with targetname matching triggerName, when all monsters tied spawn are slain [out of respawns]. This has some bugs that sometimes prevent it from working proper (see below).
(angles, origin)

sword.gif MS:C Note: Brush monster spawns were always iffy, but even more so in MS:C, so don't use brush area spawns and spawnloc 1 unless you have no other choice - and then be very careful there is PLENTY of space between the monsterspawn brush and anything you don't want your monsters inside of (walls, trees, etc) leave 128+ units. Do not 'break up' monster spawn brushes by linking multiple spawns into a single entity. Each spawn should be but one single brush.

"origin" "-2911 -31 32"
"fireallperish" "finalwave_dead"
"spawnstart" "1"
"targetname" "finalwave"
"classname" "msarea_monsterspawn"
You always want to use an msarea_monsterspawn together with any of the msmonster_xxx or ms_npc entities. Otherwise you cannot control how many lives the creatures have, when they spawn, or their grouping. In addition you can generate CPU lag or MOD:Extra_Data Precache errors. You can, of course, tie multiple monsters or NPC to the same msarea_monsterspawn by defining each monster's spawnarea property accordingly.

It is common practice to have an msarea_monsterspawn named "global", for all wandering monsters of non-consequence throughout the map. However, too many active monsters will lag a server, so it's best to have most monsters only spawn when players enter a certain area, or trigger a certain event. Common entities used for doing this include trigger_once and func_breakable.

:arrow: - Using Monster Deaths as Triggers -
- Fireallperish "targetname"
As mentioned, this property of msarea_monsterspwan is fired when all the monsters tied to it are out of respawns. There is a recurring bug with this. If you have monsters of different types with different numbers of lives, there's a chance that the event will not fire. So keep that in mind when building monsterspawns.

sword.gif MS:C Note: Actually, it got worse with MS:C. You can activate single events with Fireallperish - but chaining monster spawns together is haphazard. For a workaround, see alternate trigger_counter method described in yonder thread.

Common uses the Fireallperish target to trigger doors, break open walls leading to new areas via func_breakable, multi_managers to do multiple tasks with special effects, or spawn yet more monsters, by triggering another monster spawn.

- Killtarget
The killtarget property of msmonster_xxx or ms_npc, instead of removing an entity, triggers it. As such you can use this to trigger an event when an individual monster dies.

:arrow: - Spawning Rewards -
point entity: msworlditem_treasure
• scriptfile scriptfile
- (see list of useful items and treasures sword.gif MS:C Note: Some monsters/items maybe dated, see also Wiki )
• defscriptfile "worlditems/treasurechest"
- [optional] (seems to be primarily for compatability)
• delayhigh seconds (maximum delay before treasure appears)
• delaylow seconds (minimum delay before treasure appears)
• spawnchance [1-100] (chance of treasure appearing)
• spawnarea spawnAreaName
- [optional] You can tie this to a msmonster spawn with "spawnstart" set to 1, so the chest will only appear when said spawn is triggered.
• targetname targetString [optional] (Used by other entities to affect this item)
(angles, origin)

note: Delayhigh, delaylow, and spawnchance often have no effect, but should be kept for compatibility reasons.

Be careful: players can access treasure chests through walls, if they are thin enough. Do not spawn treasure chests until the players are supposed to be able to get them.

"origin" "380 -984 -248"
"spawnchance" "100"
"targetname" "mayorstreasure"
"scriptfile" "edana/eTC1"
"defscriptfile" "worlditems/treasurechest"
"delayhigh" "300"
"delaylow" "30"
"classname" "msworlditem_treasure"
point entity: msitem_spawn
• scriptfile "scriptfile" (see list of useful items and treasures sword.gif MS:C Note: Some monsters/items maybe dated, see also Wiki )
• duration "seconds" (time before item vanishes - but the longest it will stay is about 30 secs, regardless of setting.)
• spawnstart "0|1" (when set to 1 entity must be triggered before item appears, recommended)
• targetname "targetString" (each time this is triggered, item appears)
(angles, origin)

"origin" "2071 911 1432"
"scriptfile" "health_mpotion"
"duration" "9999"
"targetname" "freepot"
"spawnstart" "1"
"classname" "msitem_spawn"
You should keep your players supplied with occasional arrows and pots, particularly on large maps. The list of useful items and treasures I currently have up only lists low end re-supply items, for the most part, but you should only have one major treasure per map or set of maps in any case, while these you can feel free to be more generous with (especially the expendable items).

Since items spawned with msitem_spawn entity vanish after a minute or so, you only want them to appear when the characters are nearby. I strongly suggest using a playonce sprite and audio que* and perhaps a light to make sure the players see the items drop and grab them before they vanish.

* ambient_generic is currently bugged in MSC, use env_message instead

Sometimes treasures chests will conflict, and their content will merge through some shared interdimensional gateway. The ones in the list should not do this, but you may have to experiment if you run into this issue.


:arrow: - Chaining Events -
trigger_relay and trigger_counter or multisource can be used when you want multiple conditions to be met before an event occurs. For instance, the map change event that happens when all the civilians on Helena are dead. Each NPC and Helena has a unique killtarget property, each aimed at its own trigger_relay, each relay in turn targets a multisource with the targetname "deathnotice". Once all the trigger_relays are fired, the multisource, fires "kickplayers", which is a multi-manager that gives the players the lose message and boots them back to thornlands.

In theory, it's simpler to use a trigger_counter, have all the NPC's trigger it upon death, and when the pre-requisite number of NPC's are dead, have it trigger the final event.

You can chain multiple monster spawns together in this fashion as well. The final orc wave in the new Helena was created this way. There are five orc monster spawns with eight lives a piece. Only once all five spawns are depleted and trigger their fireallperish events, does the War Wagon appear.
sword.gif MS:C Note: All references above to Helena only apply to MS 1.35's Helena - the new Helena operates quite a bit differently.

:arrow: - Forcing Map Changes -
point entity: mstrig_changelevel
• desttrans "messageString " (message of ms_player_spawn on dest map, see msarea_transition description)
• destmap "bspname" (sans the .bsp)
• targetname "triggerName" - this event must be triggered

If this event is triggered, it will force the players to the indicated map.

"origin" "344 32 248"
"desttrans" "NE-A3"
"destmap" "thornlands"
"targetname" "backtothornlands"
"classname" "mstrig_changelevel"
sword.gif MS:C Note: This alternate version can be used to prevent players from crashing via transition bug:

AMX enabled servers can receive the message "force_trans_mapname". Any entity firing this event will force a transition to said mapname. For instance, you could setup a multi_manager to trigger "force_trans_edana" to force the players to warp to Edana.

You can also start votes for maps with "touch_trans_mapname"

:arrow: - Random Events -
point entity: mstrig_relay
• target triggerName (map event to fire)
• triggerstate "0|1|2" [optional] (see trigger_relay's triggerstate description)
• random "integer" (percent chance of the target to be triggered)
• targetname "triggerName" (this entity must be triggered, common methods would be trigger_once, or trigger_multiple)
• spawnflags "1" [optional] (as there is no official documentation, I've no idea what this spawnflag does, but I if it works like trigger_relay, then setting this one will cause the entity to 'remove on fire' - meaning it can only be triggered once, but cleans itself up afterwards for better map optimization.)

Example: (10% chance for orc raiders to appear in Thornlands, if you walk under the bridge where the trigger_once is.) sword.gif MS:C Note: In MS:C it has been reduced to a 5% chance.
"origin" "-1600 -64 96"
"target" "orcraid"
"random" "10"
"triggerstate" "2"
"targetname" "rand_orcraid"
"spawnflags" "1"
"classname" "mstrig_relay"
Basically just use this entity as a go between the event you want to fire, and its trigger and there will be a percent chance that the event will actually happen as determined by the 'random' property.

Point entity: multi_manager: The "random" property.
By setting "random" to 1, instead of firing events in sequence, as a multi_manager normally does, it will fire one of its events at random, each time it is triggered.

:arrow: - ms_npcscript -
ms_npcscript can be used to make an individual NPC or monster move to a specific locale, or play a particular animation. Some NPC's and monsters have special 'eventnames' that make them do special things. (Note that in MSC, unlike MS 1.35, you usually cannot use ms_npcscript to affect more than one monster at a time.)

Example: This makes Edrin freak out when you trample his flowers in the original Edana:
"origin" "1328 96 -112"
"angles" "0 260 0"
"targetname" "edrinstrict1"
"firewhendone" "edrinspot"
"eventname" "trig_flowercompliant"
"moveanim" "run"
"target" "edrin"
"firedelay" "4"
"type" "4"
"classname" "ms_npcscript"
The ms_npcscript has the following properties:
Target - The monster or npc to be affected (matches targetname of the npc you intend to affect)
Type - The type of NPC script
0 = make this the movement destination for the npc
1 = play an animation (use Jed's Model Viewer to determine which animations sequence names are available.)
2 = Run script event, ie. use one of the NPC's embedded eventname's (see more below)
3 = Move, then play anim - move to this location, then play the animation
4 = Move, then Run Script Event - move to this location, then use the eventname.
Moveanim - which animation to use while moving (most NPC's have walk and run animations)
Actionanim - which animation to play for Type1 or Type3.
Eventname - the eventname to use for Type2 or Type4 (see below)
firewhendone - After the movement is made and/or animation is played, trigger this map event
firedelay - Delay before event starts
stopai - Setting to 1 disables the monster AI (prevents monster from attacking, etc.)

Eventnames: There are far too many available eventnames to list them all here (indeed, I'm not even sure I have a complete list, short of combing over every script) - but here's some examples:
calruin/cavetroll (Lord BS) - responds to: give_clubs (give him his clubs), invincible_on, vulnerable (toggles invulnerability)
monsters/orc_unarmed (developer orc) - responds to: superorc (godmode), godoff (returns to vulnerable)
The orc warboss - godon_warboss, offgod_warboss, infernal_warboss (adds fire damage), normal_warboss (returns to normal)
Atholo and Undamael - vulnerable (makes vulnerable - both are invulnerable by default)
All specific keyholes - return_keys (causes keyhole to return any keys used after this event is run)

Universal Eventnames:
for use with ms_npcscript, these work with most NPCs, including monsters/lure:
XXXX_race - where XXXX is, replace with desired race. This is buggy, and may cause issues (including crash). Common uses include: orc_race, hated_race, beloved_race, human_race. Full faction list and relations can be found here.
ELEMENT_immune: Where ELEMENT is, replace with desired element. Valid elements currently include: lightning, fire, poison, and cold. Using normal_immune sets all immunities to normal (including any immunities the creature might normally have).
fifty_armor - sets 50% damage absorption.
eighty_armor - sets 80% damage absorption.
make_invulnerable - makes monster invulnerable (godmode)
make_vulnerable - makes monster vulnerable
add_XXX_health - where XXX is use 10, 100, 500, or 1000 (untested)
double_health - Doubles creature's health based on current. Prefixes name with "Strong ", can be used repeatedly (but name effect stacks)
quad_health - Quadruplescreature's health based on current. Prefixes name with "Very Strong ", can be used repeatedly (but name effect stacks)

Note that: sometimes second spawns of monsters will not respond to the eventname requests from the ms_npcscript, if they were used on the first spawn. This does not seem to affect playanim nor movement requests, however.

If you have issues with a monster being 'stuck' after running a script event such as quad_health on him, add an animation the monster has to actionanim and moveanim. If yer not sure, "idle" is usually a safe bet. You can use Jed's Model viewer to view models and examine what anims are available for each monster.

For a tutorial RMF & BSP that demonstrates ms_npcscript in detail, download the ms_npcscript_tutorial archive.

sword.gif MS:C Note: The ms_npcscript entity was accidentally left out of the MS 1.4 FGD. You can add it by appending the fgd with the code below.
 @PointClass base(named) = ms_npcscript : "NPC Script"
    target(string) : "Monster Name"
    type(choices) : "Type" : 0 =
        0 : "Move"
        1 : "Play Anim"
        2 : "Run Script Event"
        3 : "Move, then Play Anim"
        4 : "Move, then Run Script Event"
    moveanim(string) : "Move Anim"
    actionanim(string) : "Action Anim"
    eventname(string) : "Script Event"
    firewhendone(string) : "Fire, when finished"
    firedelay(string) : "Fire Delay" : "0"
    stopai(choices) : "Disable Monster AI" : 0 =
        0 : "No"
        1 : "Yes"
:arrow: - Keys -
sword.gif MS:C Note: This section updated for use with MSC

There are several methods for creating keys. The best way usually involves a model and a trigger_once. The trigger_once kills the sprite or env_model that renders the model, and triggers a door unlocking via killtarget and target properties, respectively. It is, however, just as simple to do the same thing with a func_button, exchanging the key for a button or lever instead, which in some ways, makes more sense.

The only way to ensure only the player with the actual key can open a door, is to use the Script Keyhole method.

They keyhole itself is placed via an msworlditem_treasure or ms_npc spawner:
"origin" "1200 -364 -526"
"spawnchance" "100"
"angles" "0 270 0"
"defscriptfile" "other/keyhole"
"delayhigh" "2"
"delaylow" "1"
"classname" "msworlditem_treasure"
("origin" is wherever you put it, and cannot be seen inside Hammer)

The other/keyhole script creates a keyhole that floats where it is placed, and that triggers the event "ustart" when activated properly by a player using any key via the standard F11 NPC interaction menu. In addition it will fire an event name matching the name of the key item used to activate it. (So if one uses "item_key_rusty" to activate it - a map event by that name will fire, in addition to "ustart".) You can use a multi_manager to capture and respond to these events.

If you want a generic keyhole that returns the key to the player after use, use the scriptfile:
Keyhole_return uses a small skull model for a keyhole, instead of the large standard keyhole - which is also has the side benefit of being little easier to line up with.

If you want keyholes that respond only to specific keys, then you need to use the specific keyhole scripts:
other/keyhole_red - takes key_red ("crimson key"), fires "key_red", and "ustart"
other/keyhole_blue - takes key_blue ("sapphire key"), as above
other/keyhole_green - takes key_green ("jade key"), as above
other/keyhole_gold - takes key_gold as above
other/keyhole_brass - takes key_brass as above
other/keyhole_skeleton - takes key_skeleton as above
other/keyhole_rusty - takes item_key_rusty, as above
other/ keyhole_storageroomkey - takes item_storageroomkey, as above
You can use msitem_spawn (above) to any particular key.

If you want one of the specific keyholes above to return keys after use, run the eventname "return_keys" on it, shortly after it spawns, via ms_npcscript shown above.

The keyhole model itself is kind of buggy. You have to be aligned up just perfectly with it, and it can be frustrating to use, so I really recommend the first method, if at all possible.

Note that the old sfor/keyhole_1 script now creates the generic keyhole (same as other/keyhole).

:arrow: - Teleporters -
brush entity: trigger_teleport
- target "info_teleport_destination's name"

point entity: info_teleport_destination
- targetname "name_of_destination"
(origin, angles)

"model" "*1"
"target" "tele_dest2"
"classname" "trigger_teleport"
"origin" "2344 -72 1377"
"targetname" "tele_dest2"
"angles" "0 0 0"
"classname" "info_teleport_destination"
("model" only indicates the brush number the entity is tied to, it cannot normally be seen from inside Hammer)

It's that simple. Just make a trigger_teleport brush with the target of an info_teleport_destination entity. You'll want to use an env_sprite to mark the teleporter. Good sprites to use include (tele1.spr, exit1.spr, e-tele1.spr, enter1.spr, etc.) - I suggest additive render and a frame rate of 10-30 for each of those. The ability to activate and deactivate teleporters is beyond the scope of this tutorial, however the VERC reference should give you some info on that. You can also place a trigger_multple in the exact location of the trigger_teleport, and have it activate a sound, via ambient_generic.

Separating sections of maps completely, and linking them with teleporters, is a VERY effective way of cutting down on frame rate lag.

:arrow: - Corralling Monsters -
brush entity: func_monsterclip
• targetname targetname - You can use the targetname to remove this clip later, but it is strongly suggest you do not use this to pen monsters in until players come near - instead simply do not spawn the monsters until players are present.

Use func_monsterclip to create an invisible wall that only monsters obey. Beware, monsterclips are not perfect - sometimes monsters will slip through - they are particularly iffy if they border another brush entity (such as water, or a func_breakable). So try to surround them with solids and don't try to make fancy staircases with them as you might do with a clip textured brush. Also be VERY careful not to place your monsterclips in such a way that players can simply hide behind them and kill monsters at will.
sword.gifMS:C Note: Beware that Skeletons that die on the rim of a monsterclip may ignore the monsterclip when they get backup - if they resurrect partially within it.

:arrow: - Other MS entities -
There are a few more MS entities than this, but most that I can think of off hand aren't terribly useful. Some are problematic. Monster_furniture, for instance, will crash the server if a player hails something else in the area. I recommend using env_sprite instead. Msarea_music can be used to activate music on the midi player, but said feature is disabled by default, and causes issues for some players (usually just lag). I recommend using trigger_cdaudio instead.

sword.gif MS:C Note: msarea_music can now play custom mp3s
brush entity: msarea_music
Properties: special:
"musicname.mp3" "minutes:seconds"
Example, from thornlands:
"model" "*183" //this cannot be seen from within hammer, it references the brush
"msthornlands_exterior.mp3" "3:00"
"classname" "msarea_music"
By default, the mp3 to be played is assumed to be in the msc/music folder-but you can build paths to other folders. Currently only the minutes property is used, so be sure to place at least 1 more minute than your song actually is intended to loop. The new music will only begin to play on players who have touched the entity.

• MP3 cannot contain any ID1/2/3 tags
• MP3 must have a bitrate of 256Kps or less
• MP3 must be sampled at 48000 or 44000 hz
• Must be CBR (no VBR files)
• No spaces or non ASCII chars in the MP3's filename

sword.gif New for MSC:
point entity: mstrig_music
• targetname-plays music to all players when this map event fires
special (as msarea_music)
"musicname.mp3" "minutes:seconds"

When this entity is targeted, it will play its defined music for all players on the server. This entity has a bug where it has been known to stop target chains, so try to make sure it doesn't share a targetname with other entities.

sword.gif MS:C Note: env_model now replaces monster_furniture and works better than env_sprite for models.
point entity: env_model
• model modelname
- Model with path (msc is treated as the root).
• body submodelindex
- Submodel to display * currently seems bugged
• sequency integer
- Animation sequence to play
• framerate float
- Animation speed to use (1 = normal frame rate, 0.5 = half frame rate, 1.5= 150% frame rate)
• rendercolor RRR BBB GGG
• renderfx [1-16]
• rendermode [1-5]
- Rendering properties, see: Half-Life Rendering Properties
• dmg 0|1
- When set to 0, model is non-solid.
• mins
• max
- Not entirely sure how these two work, but they have something to do with the model's bounding box, I think. I'd leave them at their defaults.
- As per usual, the direction the model will face
• targetname targetname
- You can use this targetname to affect this model with other entities, such as env_render or trigger_relay.

Example: Calrian's image returning to laugh at you in Calruin2:
"origin" "-1103 -1121 -338"
"targetname" "calghost"
"angles" "0 90 0"
"maxs" "16 16 36"
"mins" "-16 -16 0"
"rendercolor" "0 0 0"
"renderamt" "1"
"rendermode" "5"
"renderfx" "16"
"framerate" "1"
"model" "models/monsters/skeleton2.mdl"
"classname" "env_model"
:arrow: - Oddities with MS -
env_laser and env_beam:
too many uses of these entities will cause crash.
xen_ ornaments and standard HL monster_xxx: are not available, together with a few other entities that were deemed superfluous. Xen ornaments, such as xen_trees, hairs, and slime lights can still be called in as models with env_sprite or env_model (above) however. They won't be interactive, but they will play their idle animation, so some still make very good dungeon décor.
Gordan and MS player collision boxes do not quite conform: just because Gordan can't get stuck, it don't mean the MS player won't be able to.
Lighting: Lighting system is a tad different between HLDM and MS
Frame Rate: HLDM offers slightly better rendering rates than MS. This maybe due to lighting effects.

:arrow: Structural:
- Avoid long vistas (break up your maps with turns)
- Conform to the grid (anything that doesn't will get spliced, and this may cause leaks and errors, as well as FPS lag - also objects break up at regular 64 unit positions in render, so conforming to the grid means for less extra polys from broken brushes - thus improving render speeds)
- Try to make sure the player sees as few brushes as possible, especially in areas with lots of action.
- Remember the HL engine really draws just about every poly the character can reach, not just those he can physically see.
- Big brushes are okay - lots of little ones, are not.
- The HL engine works best for cramped, indoor or underground spaces. Take this into account when designing map ideas. Spacious outdoor maps are harder to make look and perform well.
- We have enough 'medieval mini-mall maps' thank you very much, so don't make safe-area town maps, Edana covers that well.
- Don't release a map until you've gotten HLRAD to run properly on it. Plzktnx. ;)

See also
Ye 10 Commandments of HL1 Mapping
-Thou shall not hollow anything, ever
-Thou shall not carve anything, ever
-Thou shall not use cylinders without aligning every vertex to the grid
-Thou shall not scale spikes, and thou shall make sure each vertex of a spike aligns to the grid
-Thou shall not overlap brushes
-Thou shall not scale or rotate complex nor oddly shaped objects nor rooms nor hallways
-Thou shall not build a box around your map to avoid leaks (nor for any other reason)
-Thou shalt always snap to grid
-Thou shalt always align to a large grid (x16+) when not drawing details
-Thou shalt follow the omni-present law of KISS

:arrow: FPS Optimization:
- Solid brushes that touch each other break each other apart - but this is not true of brush entities. As a general rule, if you have furniture, or a rug, or some such thing the player can see and/or walk around, you want to either leave a 1 unit gap to avoid splitting the brush (best solution) or make the item a func_wall to avoid this effect (next best). Anything that won't block the player's vision should also, generally, be made a func_wall or have a similar 1 unit gap. (See notes on gl_wireframe below for info on getting a visual representation of brush splitting, in game.)
- Similarly, if you have a pillar or pipe with many sides, cap its base and top with a func_wall or leave a 1 unit gap to prevent breaking up the floor or wall it touches.
- You can avoid having too many clip nodes, by making complex objects into func_illusionary's and surrounding them with a clip brush.
- Learn to use Hint Brushes (don't ask me).

:arrow: Stability
- Avoid too many active entities
- The biggest offenders are entities that generate models and “think”. This includes any visible entity brush, including:
func_wall, func_wall_toggle, func_illusionary, func_door, func_door_rotating, func_button, func_button_rotating, env_model, and especially, env_sprite
- Unspawned monsters don't think, but too many active monsters will cause lag, and monsters that cast spell and such, generate more sprites and models

:arrow: Aesthetics:
- Don't use tech prefabs.
- Keep it medieval. (Avoid large pains of clear glass, chain link fences, and the like)

:arrow: Map testing:
- RMF/MAP files are not consistent! Periodically export your RMF as a MAP file and then open the resulting map file in Hammer. Beware of discarded brushes "due to errors in map file". Such discarded brushes may appear in game, but they will not have proper clip nodes. This harms VIS optimization, and sometimes results in being able to walk through walls! To avoid this: keep each brush as simple and well aligned as possible. It is often better to split an oddly shaped brush into multiple, more right-angled parts.
- Port your map to Valve/maps for structural testing. Copy the ms wads, and sub folders to the valve folder (except dlls/client_dlls folders) to allow this to work without error.
- Instead of using the Create Server function, use map mapname in console. You'll have access to more testing features this way.
- In console type developer 1 and r_speeds 1 to view map performance. Try to avoid having more than 3k wpolys at any angle the player can see.
- Use gl_wireframe 2 to see an outline of every poly the engine is actually drawing. (This function will lag you to hell, btw) - use gl_wireframe 1 to see where brushes break apart in render.
- Keep backup RMFs of every testable incarnation of your map.
- TEST YOUR MAP WITH MULTIPLE PLAYERS - just because it works single-player, does not mean it works with multiple players. Extra players causes many more issues than you would imagine. Test multi-player before final release, if at all possible.
- If you or your friends need higher level characters to help you test, contact the team for special test charaters.

:arrow: Ents:
- Don't have too many monsters running amuck, it will lag. Use trigger_once and spawnstart 1, so monsters do not spawn until character's walk into their area.
sword.gif MS:C Note: This also seems to make monsters "ice skate" like mad, so remember, spawnstart 1 is your friend.
- Remember you can use Ripent (part of ZHLT) or BSPEdit (part of Half-Life Took Kit) to make your map do things that you might no be able to do in Hammer.
- Keep the number of entities to a minimum, merge all the brush entities you can into a single entities (ie. If you have a bunch of transparent func_illusionary's with the same rendering properties - make them all a single entity). Don't use superfluous FX entities. Too many entities can cause "No Free Edict" errors during periods of heavy activity.

:arrow: Content:
- Be sure to get GCF Scape and examine the content of the Half-Life.GCF. All the content of the valve folder therein is available to you without having to supply it to people who download your map. Pay particular attention to sprites, sounds/ambience, and models folders. (You may need sprite explorer, Goldwave, and Jed's Model viewer to actually view their content, respectively. All of those are included in the Half-Life Took Kit)
- Keep the distribution of your map package small. You cannot transfer to clients from content servers any individual files larger than 16MB. Use built in Valve or MS content whenever possible. If you have large wave files, cut them down with Goldwave. If you have a large wad file, compile with -wadinclude, or -nowadtextures.
- Include res files with your maps, and make sure the res files point to themselves, so that people who download the map from servers can host them properly and spread them yet further.

:arrow: info_player_spawn workaround: Since MS1.35 is so damned unstable, plus the load time, you'll likely want to do all your structural and lighting testing in HLDM (valve). Since you can't have an info_player_spawn on the map, Gordan will always spawn at 0x0x0. I recommend making a small box here, with a teleporter that goes to your ms_player_begin. Saves goads of time.
sword.gif MS:C Note: MS:C starts quicker, and is generally more stable than MS 1.35 - so HLDM testing may be less desirable than it once was. But you still need to test your map in HLDM for access to the gl_wireframe optimization.

sword.gif As of JAN2010, gl_wireframe now works fine in MSC, so no need for HLDM testing anymore.

Tools: Slackiller's HL1 Tool Collection Includes Hammer, JHLMV, Sprite Explorer, and others.
Reference: All basic HL1 Entities
Reference: List of MS NPC and Monster Scriptfiles with descriptions
Reference: Partial list of MS Item Scriptfiles
Reference: Tommy14's "OMGWTF NOW!?" list of map errors and possible solutions.
File: Half-Life FGD (critical, more dependable link) sword.gif MSC FGD is in your msc/dev folder.
Tutorial: How to Compile
Tutorial: Hint Brushes (Detailed tutorial)
File: Hammer 1.35 (You can use Source Ver 1.5, but needs tweaking)
File: ZHLT
File: SHLT (Newer, modded ZHLT set.)
File: VHLT (Even Newer, modded ZHLT set.)
File: Half-Life Took Kit (Includes Hammer, ZHLT, GCF scape, and Goldwave, and many other very useful tools)
File: Various Half-Life dev files individually listed.
File: Half-Life SDK (In case you're curious)
Tutorial: Counter Map Tutorials (If it ain't here, no one knows)
sword.gif Reference: MS:C Wiki
sword.gif Reference: J-M's monster script list - Just about every MSC monster scriptfile is listed here.


How to Make Caves
- A local tutorial thread covering various methods on creating nice looking and functional caves.
Ms_npcscript Tutorial
- The aforementioned tutorial that demonstrates in painful detail how to use ms_npcscripts.
- This also shows you how to get around the MSC ambient_generic limitation by making looping sounds through env_messages, multi_managers, and mstrig_random.
Weather tower tutorial
- Demonstrates how to control weather dynamically by spawning special monster entities.
- Also demontrates how to use lures, and monster-based teleporters.
Calruin2 Advanced Tutorial
- An uncommented but extensive tutorial demonstrating complex brush builds as well as extensive entity interaction and management, built from the Lord BS chamber on Calruin2.
Catapult Tutorial
- Old, half-assed catapult tutorial that shows you how to use the catapult script. It does not, however, include a catapult model at the moment. (We have one, need to update the map.)

I should point out that I am no 'l337 expert mapper' myself. Most of my mapping experience comes from rebuilding and repairing other people's maps, and the only one I've finished myself is rather simplistic. I still don't understand how Master toggles work, nor how to make use of Hint brushes outdoors (if at all). In otherwords, for most advanced non-MS mapping questions, you will have to go to a 1337 mapper forum.

And if you make a cheatmap with this information, I will send my lesbian ninja hitsquad to kill you dead. ;)
"Give me a new world to run to, and I will be forever yours." - Susan Song
Saint Thoth

added link to env_message
- Added notes for MS:C and Wiki link
- Changed miss-information on mstrig_relay
- Added func_monsterclip info
- Added FPS Optimization tricks
- Updated ZHLT link for 3.3.
- Reinterated the boxing map cardinal sin.
- Added the importance of multi-player testing
- Added Gabe Moses ^_^
- Updated ms_npcscript info.
- Updated keyhole info.
- Added current universal ms_npcscript eventnames
- Added ms_npcscript rmf tutorial
- Added mapping tutorial links
- Added env_model and msarea_music entities
- Removed monster cleanup tip (no longer needed, and confusing)
- Added link to J-M's monster script list
- Cleaned up a bit
- Updaded Half-Life FGD link
- Added MSC FGD note (thought was already there but...)
- Added FGD configuration note at top
- Added reqhp and nplayers properties to msmonster/ms_npc's
- Added title, dmgmulti, hpmulti to msmonster/ms_npc's
- Added stability tips
- Added mstrig_music
- Removed game_text not working
- Redirected trigger_counter link to monster chaining tutorial
- Box your map example link
- msarea_monsterspawn must be a single box brush note (in the entity description)
- note regarding re-importing maps (under Map Testing section)
- multi_manager "random" property note (under Random Events section)
- Test characters link
- Redirected VERC articles to web archive (RIP Verc!)
- MP3 file requirements
- Cave tutorial thread link
- Fixed weather tower tutorial link
- Added SHLT link
- Added link for Additional Parameters
- Fixed some old internal forum links.
Last edited by a moderator:


New Adventurer
Nov 10, 2005
under a rock
Neat :D i wounder if i can make a map whats soo ever

after looking at the maps that are in MS right now

im justing going hmm ehhh i stink
i gota make it so the player feels small and have over hanging clifes
just gota remmember that part "downloads halflife tool kit thingie"
  • Thread starter
  • Admin
  • #6


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005
I made a boo-boo in the tutorial that would carry over to this version that MSC mappers should be aware of:

The "random" property of mstrig_relay is not a 1 in X chance, rather it is the percentage(%) chance that the target will be activated.

So, I've noticed in MSC Thornlands (in case you are wondering why orc raids seem so rare now) that the mstrig_relay's "random" attribute has been reduced to 5... That means 5% chance of seeing an orc raid on any given Thornlands map.

The information has been corrected in the description above. If you want more detailed info on mstrig_relay I suggest you read it.

I'm going to try to comb through this and make notes on things that are different in MSC.


New Adventurer
Jan 5, 2006
Hey Thothie, your a fu***** genius! Do you happen to know how to create new items, monsters etc? I'm trying to make new weaps with special custom stuff like enchantments and powerups. Of course, if you can tell me how to find the source of other items and then I'll edit some stuff to make some custom weapons via an enchanter or something. Once I get to translate stuff in the dlls or wherever it is, I think that would be a piece of cake :)


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005
Hey Thothie, your a fu***** genius! Do you happen to know how to create new items, monsters etc? I'm trying to make new weaps with special custom stuff like enchantments and powerups.
Forums are a tad buggy for me sometimes (prob cuz I'm subscribed to the front page - and I get 'false reads' sometimes). As a result I didn't see this post, and probably am too late to respond to it, but no, I don't have the source to create custom items and weapons, however, you can read about it in the Wiki, and if you are really serious, you may be able to get Lord K to help you as described therein.

If this was going to be a sticky, I'd probably sort through the FGD and make a paragraph for each MSC entity - granted, that would take awhile. This tutorial is not complete, and most was discovered by trial and error and extrapilation, as I'm not privy to the exact workings.


New Adventurer
Jan 7, 2006
Near St. Louis, MO
I never saw that post either :?.
This tutorial may not be complete but it is still better than nothing, and without it there is nothing :), so a sticky is still a good idea I think.


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005
Nein, spreche ich nicht Deutsches, aber du kannst babelfish benutzen. ;)

Although if someone here does speak German and wants to re-write that novel...


MSC Developer
Sep 14, 2004
Thothie said:
Nein, spreche ich nicht Deutsches, aber du kannst babelfish benutzen. ;)
Da die Babelfishübersetzung schon an einem solch simplen Satz zu scheitern scheint, ist es sicher interessant zu sehen, was aus dem gesamten Tutorial wird :wink:

Well, if I got to many time tomorrow I'll give it a try, but hope for nothing


New Adventurer
Jun 19, 2006
I compiled a map and when half life wanted to start it a fatal error message popped up saying: ms.wad not found.
WHAT THE HELL? I didn't even use any master sword wads, there is no ms.wad in the texture compilation and I couldn't even find ms.wad file on any of my hard drives, is he kidding me?

E: Alright, deleted all textures and added them again but now the hammer editor just closes if I want to compile.
I think it's something to do with the textures, could anyone pls list all needed textures you have to add in the hammer editor?

E²: Added all textures I know and created a new testmap, now halflife is asking vor rinat.wad , which is part of the name of my steam account, what's going on?


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005
Don't use wad files in your steam directory - paticularly if it has an "@" in its name, it tends to fubar things.

Copy all the wads you are going to use to some shallow directory somewhere, such as "C:\hldev\wads".

Under Hammer's texture options, remove all your current wads, add the ones you intend to use at the new location, apply, close and restart hammer, load and re-export your map, and ya should be good.

Also try not to use too many wad files.


New Adventurer
MSS Developer
MSC Developer
Jun 14, 2006
too many would be 8+.

use around 3 or 4 or just combine all of the wads into a super wad like me :oldlol:

(P.S. I just saw the texture count in mine and it said something like 6003)


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005
Thought I added this a long time ago, but since someone pointed out that I had not, I've stuck it onto the tutorial now:

Ms_npcscript Tutorial
- The aforementioned tutorial that demonstrates in painful detail how to use ms_npcscripts.
- This also shows you how to get around the MSC ambient_generic limitation by making looping sounds through env_messages, multi_managers, and mstrig_random.
Weather tower tutorial
- Demonstrates how to control weather dynamically by spawning special monster entities.
- Also demontrates how to use lures, and monster-based teleporters.
Calruin2 Advanced Tutorial
- An uncommented but extensive tutorial demonstrating complex brush builds as well as extensive entity interaction and management, built from the Lord BS chamber on Calruin2.
WW3d Advanced Tutorial
- A similarly advanced tutorial with some commentary, demonstrating a massive array of MSC entities, built from the boss chamber at the end of World Walker Series I.
Catapult Tutorial
- Old, half-assed catapult tutorial that shows you how to use the catapult script. It does not, however, include a catapult model at the moment. (We have one, need to update the map.)

J-M v2.5.5

Feb 26, 2005
Nijmegen, the Netherlands.
I'm afraid I don't know.

Thothie keeps the script names for items scrictly secret (for very obvious reasons) and that's why I never bothered to look into them. But if you PM Thothie, he'll probably tell you the script name you need to spawn a torch.


Staff member
Lead MSC Developer
MSC Developer
Apr 8, 2005

It'll vanish eventually though, and leave a sticky sprite when it does... For a permanent one, you'll have to use an env_model, env_sprite, and a light with a flicker pattern. (Don't go nuts with that.) ;)

The Man In Black

Staff member
Lead MSC Developer
MSC Developer
Jul 9, 2006
If you're trying to test your map for brushes... Don't add the monsters? >_>

Other than that, you can wait for Thothie or Blasto to get you some character backups