Features

This document explains some of the major features of Spirit of Half-Life.

  1. MoveWith
  2. Angles and Rotations
  3. Customizing Monsters
  4. Triggering Things
  5. Special Effects
  6. Masters and States
  7. The Locus System
  8. The HEV suit and the Player
  9. Scripted sequences

This list is by no means exhaustive. (For example, I haven't even mentioned aliases.) If you're looking for a list that is, see the Spirit Entity Guide.
In future releases, I intend to get more of this document written... so if there's anything you'd like to request more detailed coverage of (like aliases, perhaps), or you want to suggest a better way to explain something, please let me know in the Forums on the Spirit website.


MoveWith

The MoveWith system allows you to make entities move around as though they were attached together. For example, you can make a lift with buttons inside, a breakable glass door, and many many other things, all with a minimum of effort.

Example:
The effect is simple to set up. Suppose you have a func_train named "mylift", and a func_button inside it. To make the button move when the lift moves, you would simply type "mylift" into the button's "Moves With" field.

You aren't limited to just one entity, either. MoveWith can be chained together, to create objects as complex as you want. For example, you could make a train, and a door that MovesWith the train, and a button that MovesWith the door, and an env_spark effect that MovesWith the button! The env_spark will now move when the train moves, and also when the door moves, and also when the button moves, all as you'd expect.

All entities can use the MoveWith system. If you find one that doesn't have a "Moves With" field, you can even add it yourself - Worldcraft users would just turn off SmartEdit and create a new keyvalue named "movewith".
The system does have limitations, however.

  1. It can't follow the movement of certain entities - specifically, things won't properly MoveWith a func_pushable, a player, or a monster. (If you want an entity to follow one of these, though, you may find a motion_manager can do what you want.)

  2. If you want something to properly MoveWith an entity that rotates, you'll have to put its origin at that entity's origin. (For a brush entity, this means you give it an origin brush at that position. For a point entity, this means that the X in the centre of the entity must be at that position). Yes, in other words, when a rotating object MovesWith another rotating object, they must always rotate around the same point. So you can't create an egg whisk. This limitation will hopefully be removed in a future release.

  3. Sometimes, the player can get in the way of doors and other entities, stopping them from moving. If this happens when something is MovingWith the door, or when the door is MovingWith something else, then the two entities may start to get out of sync. For this reason, I recommend that when you use MoveWith on entities, you make sure the player can't block them. (It's no problem for them to push the player - just don't push him into the wall. One good way to ensure this is to make the entities non-solid.)
(Many of the example levels use Movewith, particularly SpiritDemo and GatlingGunDemo.)

Advanced MoveWith facilities:

The info_movewith entity allows you to dynamically change what entities MoveWith. So for example, you could build a crane with a magnet. You turn on the magnet and it picks up a box; thereafter the box follows the movement of the crane.

To use an info_movewith entity, essentially you link your entities together as normal, but insert the info_movewith into the chain. So in the crane example, you would have your box MoveWith an info_movewith entity, which would MoveWith the crane when it was active, and MoveWith nothing (a blank value) when it was inactive. Switching the info_movewith on and off would then effectively connect and detatch the box from the crane.

(Example level)


Angles and Rotations

In Spirit, func_rotating (as well as most other rotating entities) has an "Axis Multipliers" field. This allows you to make an object that rotates along more than one axis at a time.

For example, see the CogWheelDemo level. This shows a rotating cogwheel, mounted on an axle which is itself moving.

Essentially, the Axis Multipliers field is a more versatile replacement for the "X Axis" and "Y Axis" flags that rotating objects have. So for example, consider the little wheel in the set of cogs on the floor. This has an Axis Multipliers field of "-2 1 0". In other words, its pitch factor is -2, its yaw factor is 1, and its roll factor is 0. Since its Rotation Speed setting is 30, this means its yaw rate (i.e. the movement of the axle) is 30 degrees a second, its pitch rate (i.e. the turning of the wheel) is 60 degrees a second, and it doesn't roll at all. The fact that its pitch is negative means that the wheel rotates anticlockwise instead of clockwise. This much is fairly self-explanatory, I hope.

Unfortunately, rotations in Half-Life are a little more complicated than they look. Notice the two sets of cogwheels near the ceiling. The left-hand one is clearly wrong - it's swinging around all over the place - whereas the other one looks fine. If you open up the map file in your level editor, you'll see the difference between the two... one is built pointing down, the other is pointing east. The Axis Multipliers are set correctly on both, but the left one still doesn't work. Why?

The answer is that Half-Life processes its rotations in a set order: Yaw, then Pitch, then Roll. When an object pitches, it rotates around the axis given by its current Yaw. When it rolls, it rotates around the axis given by its current Yaw and Pitch. Now, obviously, we would expect a wheel to rotate around its axle. This means that the axle's movement needs to be handled before the wheel's own rotation.

So: for the cog on the floor, the axle moves in the Yaw axis, while the wheel turns in the Pitch axis. That's fine - Yaw comes before Pitch. The axle on the right-hand cogwheel moves in the Pitch axis, while its wheel is Rolling. That's fine too - Pitch comes before Roll. But for the broken cogwheel, the axle moves in the Pitch axis, while the cogwheel rotation is in the Yaw. And that's why it looks wrong; Half-Life applies Yaw before Pitch.

I don't expect you to digest that the first time! But hopefully, now, if you find you have problems with multiple-axis rotations, you'll have some idea how to fix it.

One important note - MoveWith entities are also affected by this limitation. So, imagine that you made the axle and the wheel as seperate entities which each rotated around just one axis, and you told the wheel to MoveWith the axle. This would produce almost exactly the same effect as the Axis Multipliers did. The left-hand wheel would still look wrong. (This problem may possibly be fixed in a future release.)


Customizing Monsters

Spirit offers you many ways to change the appearance and behaviour of your monsters. For instance, every monster has a "Health" field which determines how tough it is. (Note that on Easy mode, monsters are usually less tough than they are on Hard mode. The Health value overrides that, so that the monster will be equally tough on all skill levels. If you don't like that, you could make two different monsters, and use the new Skill setting to have one of them appear only in Hard mode, and the other one appear the rest of the time.)

In a similar vein, all monsters now have a "Scale" setting - 1.0 is normal scale, and higher numbers make them bigger. With a small offset like 1.1 or 0.95, you can subtly adjust your monsters so they're no longer exactly the same height - they'll look a little less like clones. with a large offset like 2 or 0.1, you can create new "super zombies" who tower over the player, or decorate your level with "toy soldiers".
Note that this setting won't change the actual size of a monster, just how big they "look". (As it happens, though, monster_generic also has an option to change its size.)
This setting can be changed dynamically, using an env_render. If you want, it can even make monsters grow or shrink over time.

Another new feature is the "Behaves As" field. This changes the monster's alignment; for example, you could make a grunt who's "reliving Nam" and attacks everyone, including the other soldiers; or maybe a "strong-minded scientist", who's been turned into a Zombie but is refusing to attack the other scientists. Note that this doesn't change the monster's actions (for instance, that zombie will always shamble around, and attack its enemies with its claws) - it just changes who its enemies are.

To accompany this field there's a Reaction to Player option, which lets you override the above behaviour. For example, you can make a barney who's joined the military - so he shoots scientists - but still won't attack the player.

To change the appearance of a monster, you can use its Model field. Be careful when using this, though - you can't just give a Zombie model to a Barney and expect it to work. You'll find it can walk around, and will talk to you (in a Barney's voice), but that's about it. It will still drop a pistol when it dies. Basically, this can only be used for cosmetic changes - reskinning a monster, or changing the appearance of its weapons.
Tied into this is a new option on monster_barney; the Weapons field, where by popular demand, you can tell him to use the .357 handgun instead of his normal pistol. This changes the gun's sound effects, the amount of damage, and the weapon he drops when he dies. Unfortunately the one thing it doesn't change is his appearance; there's no "Barney with 357" model provided with Spirit. To use it, you'll have to make your own, and use the Model field to set it. (If someone has a "Barney with 357" model that they'd like to provide, please let me know - I would be delighted to include it in the next release. With credits, of course.)

Another interesting option is the "Speak As" field, which only applies to Barneys and Scientists. This is for use with the sentences.txt file, where a Barney's sentences all start with the prefix "BA", and a Scientist's sentences all start with "SC". The value you type into the Speak As field will be used as a replacement for this prefix; so for example, typing SC into a Barney's Speak As field will make him talk like a scientist, and BA in a Scientist's Speak As field will make him talk like a Barney.
Needless to say, this isn't very useful as it stands; a Barney asking "who ate all the donuts?" may be amusing, but not especially interesting. The main purpose of the Speak As field is for modmakers who want to create their own sentence groups, creating unique NPCs with their own voices.
For example, if you edit sentences.txt, copy all the "BA" sentences, rename them from "BA" to "BB", and provide your own sound files to use for each one, you can then tell a Barney to Speak As "BB", and he'll have a different voice.

Monster_barney and monster_human_grunt now have a "Don't drop gun" flag. It's fairly self-explanatory - when they die, they won't drop the gun they're carrying. This allows you to make a non-combatant mod, for example, where the player doesn't actually do any fighting himself.
Approaching this from the other direction, monster_alien_grunt now has a "Drop gun" flag, so that when it dies it'll drop its hornet gun, which the player can then pick up.

Most of the above settings can also be adjusted dynamically (i.e. changed half-way through a level), by triggering an env_customize entity. It basically works like an env_render, except that it has a lot more options. Don't get intimidated - in a newly-created one, most of the options are set to "No change". Simply set up the fields that you're interested in, and ignore the rest.

Good news for people who like embedding their monsters in walls - you can now tick the "No Yellow Blobs" flag, so that Half-Life won't surround them with that annoying cloud of, er, yellow blobs.

One last thing to note about monsters - in Spirit, a monster on an elevator will look fine. The ugly flickering bug has been fixed.


Triggering Things

Spirit offers you many many new options for triggering things. The most useful one is that you can put + or - at the beginning of a trigger field, to trigger something "on" or "off", instead of just toggling it. The On/Off concept is in normal Half-Life, too - it's usually done with a trigger_relay - but isn't very widely used or supported. In particular, func_door and func_button never responded to it in a useful way. In Spirit, though, these entities both have an "On/Off Aware" field. When this field is set to "yes", triggering "on" will always open the door/press the button, and triggering "off" will always close the door/unpress the button.

Other features: when debugging your levels, it's sometimes useful to trigger entities manually. You can bring down the console and type type "fire" to trigger the entity you're looking at; or type "fire flargle" to trigger all entities named flargle. ("fire +flargle" and "fire -flargle" will also work, triggering flargle on and off respectively.)

Approaching this idea from the opposite direction, it's also possible to automatically activate console commands in response to a trigger during your maps. See the trigger_command and trigger_changecvar entities. (Note that trigger_command is able to set cvars too - the advantage of trigger_changecvar is just that it gives you a "duration" setting, so that it's easier to control.)

There are also many new features that can be useful when triggering things...


Special Effects

Everyone wants to make impressive special effects in their levels, right? Well, Spirit lets you do... lots of new things.

New triggered effects: These all act like env_explosion - you trigger them, and you get a special effect wherever the entity is.

Other new entities include env_fog, which is a much-requested way to make a distance-fogging effect. Essentially this entity is used like an env_fade - you'd trigger the env_fog entity to make fog appear, and then trigger it again if you want to get rid of it. (Note that since this is a pretty old game we're mapping for, the fog is just a global fadeout effect - you can't make a patch of low-lying fog on the ground. Also, to get this fogging effect, you must be running the game in OpenGL mode. These are both fundamental limitations in the engine, so please don't ask me to change them.)
env_fog is used in the SpiritDemo level.

env_rain provides a rain effect, just as it sounds. It's a brush entity: to use it, you need to provide a volume for the rain to cover. (This can only be a cube. Don't bother making a more complex shape, because only its bounding box will be used.)
The effect works by choosing a random point on the top surface of your cube, tracing it down to the bottom of your cube, and drawing a beam between the two points. If you specify an angle, then that angle will be used as the direction for the trace. (NB: this means that your beams may actually hit the ground outside the cube.)
Yes, in other words the rain effect is just a bunch of beams. It looks almost exactly like the rain effect seen in mods like They Hunger... but to set that up, you needed hundreds of beams to be set up manually, whereas env_rain is just one entity which does it all for you.
By default, env_rain will make its beams shift around randomly. Some people like this effect, others don't - so if you don't want it, simply set the "Time between updates" to 0.
Other options: since it's just a bunch of beams, you can change which sprite you want the beams to use. So for example, you could use this to make a randomized lightning effect. Another option would be to make the beams extend horizontally (use the "Beam Direction" field), and tell them to use the laser beam sprite, to simulate some kind of high-tech security barrier.
There's also a cryptic field called "Extent type"; this lets you define how the beams are traced. Choosing "obstructable" will mean that when a line is traced from the top to the bottom of the cube, the line will stop as soon as it hits a solid object. In other words, your rain will no longer fall through solid objects. "Reverse obstructable" is the same, except that the line is traced upwards. So the rain beams will all be visible at floor level, but they'll stop at the first obstacle above them.
"Arcing" is like "obstructable", except that a beam will only be drawn if it hits an obstacle. If it reaches the bottom of your env_rain cube without hitting anything, the beam won't appear. And "reverse arcing", as you can probably guess, is like "Arcing" - except that the lines are traced upwards.
env_rain is used in the SpiritDemo example level.

There are also many changes to existing entities. env_render is now able to make objects fade in and out, instead of suddenly changing their appearance. It can adjust the scale of a sprite or model in the same way, which lets you (for example) make a smoke effect that gradually spreads out and disappears, or a monster that "mutates", growing to twice its normal size.

A new renderfx setting, "Reflection", has also been added. It only works on monsters; as seen in the ShinyFloorDemo example level, it basically creates a reflection under the monster's feet. The effect is a little limited, and doesn't look quite perfect yet - but nevertheless, it's rather nice.

env_beam now has the option "Draw solid", so that you can make a beam that looks like a rope. (This feature is used in the GarageDoorDemo and SpiritDemo example levels.) You can also make a beam that triggers something when a player walks into it, as simulated in many Half-Life levels.
While we're on the topic of env_beams, note that info_target now has a "use null.spr" flag. Normally, if you make an env_beam attached to an info_target, and tell that target to move around, the beam won't move. Tick "use null.spr" to get around that.
(If you're interested: the problem, basically, is that a beam can only move around if it's attached to an entity that has a model or a sprite. If you tick the "use null.spr" flag on an info_target, then you're telling it to use the null.spr sprite, which is just a transparent box. So the player won't actually see any difference, except that an env_beam will now be able to follow it properly.)

env_fade now has a "Permanent" flag, which means the fadeout will last forever. (Or until you trigger another env_fade to change it back.)

env_sprite can now attach itself to an entity, at any attachment point. So for example, if you want barney's gun to act like a torch, then one part of the effect could be to make a flare sprite at his gun's attachment point.

env_laser has always been very useful, one of the few ways to make a moving sprite or a moving damage source. Spirit gives it a whole new range of features. You can specify exactly what its beam will be blocked by (windows, monsters, or just walls), and also specify whether the beam should actually stop when it reaches the target position.
So for example, you could build a helicopter, make an env_laser which MovesWith it, and set the laser's target position to be the middle of a window. Tell the laser not to stop at its endpint, and as the helicopter flies around, the laser will always shine through the middle of the window, and into the room beyond.
To go with this, you can now make a laser which is "interpolated". When a normal laser moves, it tends to look a little jerky. If you make it interpolated, then although the beam will lag slightly, it will look much smoother.
Other new features: you can give a laser a start sprite as well as an end sprite. And if you want, for each of those entries you can tell it the name of the env_sprite entity you want it to use, instead of just giving it a sprite filename. This allows you customize the sprites on the laser beam: you're not limited to just using the render settings of the laser.
Also, note that since you've now given your end sprite a name, it would be possible for other entities to refer to it. For example, you could have a light_glow entity Moving With your end sprite, or an env_explosion that creates explosions there.

Spirit gives even the humble light entity a raft of new features. For a start, it now has a concept of "how long it takes to turn on/off", and you can specify the lightstyle for it to use while it's doing so. So for example, you can make a light which takes a few seconds to turn on, and uses the "fluorescent flicker" lightstyle while it's doing so - one of those lights which takes a few seconds to warm up.
More interesting, the trigger_lightstyle entity allows you to change the current lightstyle of any light, regardless of whether it's currently on or off. (It's probably best not to mix these features on the same light - either use trigger_lightstyle entities to control it, or else trigger the light to turn on and off, but not both). Note also that trigger_lightstyle includes a "fade time" option, so that your lights can fade in and out over whatever time you specify. This is easier to control than if you'd typed "abcdefghijklm" in your light's appearance; it also tends to work more reliably.

Using the compile tools that come with Spirit, you also have the option to make texture lights that switch on and off - every func_whatever entity has a new "Texlight style" value, which will control the appearance of that entity's light-emitting surfaces. For more details, see the readme file for the compile tools.


Masters and States

In Spirit of Half-Life, every entity has a State. Some, like trigger_relays, are boring - they're always Off. Others, such as env_sprites and func_trains, change from On to Off when triggered. A few are more complex; for instance, func_rotating will be Off while it's stationary, Turning On while it's accelerating, On while it's at full speed, and Turning Off while it's slowing down. Similarly a func_door will be Off while it's closed, Turning On while it's opening, On while it's open, and Turning Off while it's closing. A func_button works the same way- it's normally Off, but it's On while it's pushed in, and when it moves it's Turning On or Turning Off.
Finally, some less obvious examples: A multi_manager is On if it's in the process of triggering things, and it'll be Turning On if it's active but hasn't fired the first trigger yet. A scripted_sequence is Turning On while the monster is walking into position, and On when the animation is playing. And a trigger_inout is On while there's somebody standing in it, and Off the rest of the time.

So, how is this useful?

Well, as you probably know, an entity with a Master value is unusable until the master becomes active. For example, you can lock a door by giving it a master, and then unlock it by triggering the master. Normally in Half-Life only the multisource entity can be used as a master.

In Spirit of Half-Life, though, you can make any entity a Master, and its State will be used to determine whether it's locked or not. When the master is On, it's unlocked; the rest of the time, it's locked. (To a master, Turning On and Turning Off are the same as Off.) So for instance, this could be used to make a time-based lock: a door with a button as its master. The player has to press the button, and then run to the door before the button resets itself.

Another useful feature: you can put a ~ (tilde) at the beginning of any Master field, to reverse the relationship. The door would then refuse to open when the button was pushed in, but would open quite happily the rest of the time.

State-related entities:


The Locus System

The Locus system is a relatively new feature, introduced in Spirit 0.7. It's quite complex, and so far a lot of people seem to have trouble understanding it (due, no doubt, to the almost negligible documentation - which hopefully is now more helpful). If you still don't get it after reading this section, please ask. And if you can think of a better way to explain this stuff, please let me know!

The system is essentially two seperate features - a special value "*locus", and a set of calc_ entities. Each can be useful on its own - but combined, they form a weapon of incomparable power, able to level mountains with a single blow.
Or... maybe that was something else.

The value *locus:

When you're making a Spirit level in Worldcraft, you'll see that some entities have fields marked with an "[LE]". These are fields where you'd usually write an entity's name. (For example, the "Target to affect [LE]" value for an env_render). What the suffix tells you is that instead of typing a name, you may type "*locus" into that field. The field will then refer to the current Locus Entity, not something called *locus.

"But what's the current Locus Entity?"

I'm glad you asked me that. In Half-Life, there's a rarely-used concept of "who caused a trigger to be activated". Usually, this is a player. (If you've used the "Targeting: Activator" setting on a func_mortar_field, or the "Activator Only" flag on env_fade, then you probably have some idea what I'm talking about.) Essentially it works like this - if a player presses a button to open a door, the button will tell the door who it was pressed by. Equally, when a trigger_multiple gets activated, it will tell its target who walked into it.

And the Locus Entity? That's just my word for "activator". When you tell an entity to affect "*locus", you're telling it to affect whoever caused it to be triggered.
Example: an obvious use for this would be in a multiplayer level, to make a special invisibility powerup. Have a trigger_once which targets an env_render, and tell the env_render to affect "*locus". The first player who walks into the trigger will then be the "locus" of your env_render, and it will make him invisible.

Handy, yes? I'm just getting started...

The Locus can also be preserved throughout a sequence of triggers. For example, if a button targets a trigger_relay, and the trigger_relay targets a door, that door will still be told which player pressed the button. Even more useful, a multi_manager can do the same thing.
Example: What if you only wanted your invisibility powerup to last 20 seconds? No problem! Simply get your trigger_once to target a multi_manager, and make your manager target two env_renders - one at time 0, the other at time 20. Each env_render would target *locus - which would be the player, as before.

The Locus isn't always a player. For example, if you make a trigger that goes off when a monster walks into it, then that monster will be used as the locus. So you could get it to trigger a scripted_sequence which affects "*locus", for example. Now, when any monster walks into this area, that monster will perform a particular animation.

Useful though this ability is, sometimes it's not quite what you want to do. For example, if you've ever made a multi-floor lift in Half-Life, you'll know how tedious it is to make a load of different trigger_changetarget entities. Wouldn't it be nice to just make one trigger_changetarget, and tell it what to affect each time you trigger it? Well (surprise, surprise) you can do this with the Locus system, too.

When you trigger an entity, you can specify which entity you want it to use as a locus, by writing that entity's name in brackets. (Sort of like a function call in a computer program.) This will replace the normal locus that would have been used. So, in the trigger_changetarget example, you might call your trigger_changetarget "moveto", and tell it to affect your train, setting its new target to "*locus". When a player presses the call button for the first floor, you would then make it trigger "moveto(firstfloor)" - so instead of making the train target the player, the train will target the path_corner you've called firstfloor.
Yeah, this one isn't the most impressive feature in the world - but it's handy and it can save a bit of copy-and-pasting. Note that typing "blah(*locus)" will usually give you exactly the same results as just typing "blah".

And finally, some triggers use their own special locus. For example, the "Fire on spawn (locus = shot)" field on an env_shooter.
As the name suggests, the entity you specify here will be triggered every time the env_shooter launches a new shot. The locus for that trigger will be the newly-created shot entity. So if your "fire on spawn" entity is an env_render, it can make the shots start to fade out as they appear. Or you could target a trigger_relay, so that they'll fade out after a certain delay. I'm sure you can think of loads of other uses.

The calc_ entities:

The [LE] suffix isn't the only one you'll see - [LP], [LR] and [LV] also exist. These are closely related to [LE], but more specialised.

The combo:

You can also write "*locus" in any [LP], [LV] or [LR] field. This works as you might expect - it tells your entity to use the position or velocity of the locus. This is very useful, and allows you to make some quite sophisticated particle effects, and other things.

As a starting point, consider the "Trigger on firing (locus = barrel)" field on a func_tank. The entity you specify here will be triggered every time the tank fires. The locus will be a reference point that's positioned at the tank's barrel, with its velocity pointing outwards from the end. (Please don't do anything silly like killtargetting the reference point.)
Suppose you make this field target an env_shooter, and tell it to create its shots at the position *locus, with a velocity of *locus. Essentially, you've just made a func_tank that will launch anything you want when it fires.

Not excited yet? How about the "Trigger when hit (locus = position)" field on a func_breakable? Whenever you shoot the func_breakable, this entity will be triggered. The locus will be a reference point that's positioned where the shot hit, with its velocity pointing in the direction the bullet went.
So, what you can do with this? Make it target an env_decal entity, and create your own customized bulletholes in your func_breakable? Nah, not exciting enough. How about targetting a locus_beam entity, so that beams of light shine out of the bullethole? Or targetting an env_shooter, to make water pour out of the hole?

Another idea: The "Fire on collision (locus = shot)" field on env_shooter is triggered whenever a shot hits something. You could use it to make a splash effect when a water drop hits the ground, or to killtarget the shot. (Try writing "*locus" in the "killtarget" field of a trigger_relay.)

A lot of these ideas are explored in LocusDemo.bsp, and GatlingGunDemo also makes use of some calc_ entities. I hope this taster has given you enough inspiration to try the Locus system out. And to complain to me about all the bugs in it.


The HEV suit and the Player

Mapmakers often want the player to start the game with an HEV suit, without that tiresome logon speech. To do so, simply tick the "Start with HEV" checkbox on your info_player_start entity. (There's also an "HEV from start" option in the Map Properties menu, which will do the same thing).

You can now make a scripted_sentence which sounds like the player's HEV suit is talking. Simply leave the sentence's "Target Monster" field blank.
If you want the player to lose his HEV suit (for part of your storyline, presumably), then that's one of the many many options that have been added to player_weaponstrip.

Other things you can now do to the player: the player_freeze entity, as seen in opposing force (the initial helicopter ride) allows you to... well... stop the player moving. He'll also be unable to shoot, select weapons, or use his flashlight - but note that he can still look around. If you want to completely disable player control, you'll have to use a trigger_camera.

If you want to change the player's footstep sounds, you can use the entity env_footsteps. It's most useful when combined with a trigger_inout; simply place the trigger_inout over the area where the sounds should be different, and make it target the env_footsteps whenever a player enters or leaves it.

To change the player's HUD colour, you use the command "hud_color R G B". (without the quotes). For example, "hud_color 255 0 0" will give you a bright red hud. Note that this means you can change hud colour during the game, too, using a trigger_command entity.

And in general, if you want anything to affect or refer to the player, you can do so using the special value "*player". (So if you wanted to use an an env_render to make the player glow, you would write "*player" in its "entity to affect" field. And yes, this will mean a glow effect appears over the player's weapon on his screen. But, NB: only the 'glow' renderfx setting is transferred over to the weapon this way. I'm not sure why...)

The "Skill settings" field, found on monsters and most items, allows you to set up entities to not appear on certain skill levels - just like the skill settings in Quake. To test your game on a particular skill level, you may find it useful to use the command-line parameters "+skill 1" (for Easy mode) or "+skill 3" (for hard mode).


Scripted Sequences

One of Half-Life's greatest selling points has always been its scripted sequences. But did you ever find there were little niggling things that didn't let you do quite what you wanted...?

The scripted_sequence entity now has a "Turn Type" field, separate from its "Move Type". The monster will usually walk/run/do nothing according to its movetype, and then will do nothing/turn to face a particular direction, according to its turntype. So you could make a sequence where a monster simply walks to a particular point, without caring what direction he's facing at the end of it. Or you can make a sequence where a monster simply turns to face the centre of the room, regardless of where he is right now.

In normal HL, a scripted_sequence doesn't work when playing a death animation - the monster will get up again straight afterwards, and it just looks silly. The "Monster dies" flag will override this behaviour, so that those monsters stay dead. Note that if you play a non-death animation this way, the monster will end up frozen in whatever pose the animation finished with.

The scripted_action entity lets you tell a monster to fire its weapons. You can always make it simply fire - but if you want to make it fire at a specific point, you have two options.

  1. Set the "Turn Type" to "Turn to face", and specify an "Entity to attack". This will make the monster face the entity you specified, and fire directly at it.
  2. Set the "Turn Type" to "Turn to face", and set the "Move Type" to "No - Only turn". This will make the monster face your scripted_action entity, and fire directly at it.

Sometimes a full-on script isn't very useful, because it's not flexible enough. For example, you might want a monster to shoot at a particular object... but not if he can't see it, and not if he's in the middle of a fight. The monster_target entity is handy for that sort of thing. Monsters will treat a monster_target as another monster (of whatever type you specify), and will automatically attack it using their normal AI. A nice way to use this is to put a monster_target right next to a func_breakable, so that when they try to attack it, they'll hit the func_breakable instead. When you want them to stop attacking (i.e. when the func_breakable breaks), trigger the monster_target to turn it off.

In a similar vein, trigger_startpatrol allows you to "suggest" to a monster that it should walk along the specified line of path_corner entities. If it's in the middle of a fight, it'll ignore this suggestion - and unlike a scripted_sequence, it'll also stop walking the path when it sees an enemy. (This is used in the MigraineDemo level.)

monster_generic now has a heap of new options. If you've ever tried to make a monster_generic whose model is meant to be used by a player, then you'll know how the player model sinks into the floor up to its waist. Tick the "Player Model" flag so that it works correctly. Spirit also lets you control the initial health, blood color and gib models for the monster_generic to use.

monster_generic_dead is a new entity which, as the name suggests, lets you put any monster's dead body into a map. Want to make zombie corpses or dead alien controllers?
This entity actually has a huge range of options in it, and supports a lot of "death poses" that the entities like monster_barney_dead doesn't let you use... so you might even want to use monster_generic_dead in preference to the more specialised entities.