ITT: I have no idea how to work with NPCs

Wow, okay. Where to begin.

So while I’ve been using Hammer for several years, I’m still very much inexperienced in it. I think a big part of that is because almost all of my mapping experience is with Left 4 Dead, which means a lot of things that go for singleplayer mapping go out the window. A good majority of that is NPC-related stuff.

In order to educate myself more on how things work, I got the idea in my head to try my hand at my own extension of On A Rail. To be clear, I don’t have any intention of one-upping Text’s OaRU or .RK’s Loop Mod, they’re both much better at this than I am. I just figured OaR would be a good place to experiment - it’s mostly indoors, and despite how a lot of people feel about it, I have a bit of a soft spot for the original.

I’m currently on the first “original” map, which includes the Vort/HECU showdown over the two parallel tracks. However, I’m running into problems with the NPCs pretty much all over the place. Here goes:

  1. There’s a grunt manning the turret on the HECU side of the tracks. The problem is, I can’t get him to shoot at anything - I think it might be that the Vorts are too far away, but I’m not really sure how to rebuild the area to put them closer. I tried giving him an npc_bullseye to shoot at, but he’s not shooting at that either. For that matter, even if I force him off the turret, he doesn’t get out a weapon or try shooting anything, he just stands there.

  2. There are AI Nodes across the track so the NPCs can run up to each other instead of staying static on one side (also to avoid that issue where Vorts wouldn’t attack, since I’ve heard that’s still present). This includes over the track that the player drives the tram over - I’ve had a soldier run out in front of the tram and get stuck between it and the security gate twice now. I’d like to keep them from running out into the track if possible - and if not, I can just stick a trigger_hurt filtered to NPCs on the front of the tram or something - but I’d rather not delete the nodes so as to avoid any funny NPC behaviour as a result. I’ve tried using an info_radial_link_controller, but the NPCs still run out into the track. The only thing I can think of using to stop them is an ai_battle_line, which brings me to…

3) In the upstairs office area, I’ve got a scripted assault between the HECU and some Vorts that I want to play out. Problem is, it just won’t work properly. The HECU have two ai_battle_lines to prevent them from straying too far from the “showdown” area, but they… just ignore the lines entirely. As far as I can tell, the entities are set up correctly - pretty much the same as they are in BM’s c2a2b - but the HECU will just run past them like it’s no big deal. I don’t know if that’s because they don’t have sufficient cover, but I can’t figure out what’s wrong here.
Both the battle_line entities are set up like this:

Name: hecu_office_no_retreat
Actor(s) or squad to affect: c2a2a1_office_showdown_hecu
Active: Yes
Strict: Yes
Use parent’s orientation flag unset

To prevent the player from getting absolutely smothered upon entering, they have an ai_relationship set to ignore the player until all the Vorts are dead. It’s kinda strange to see them run to the end of the hallway where the player is and not do anything, to say the least, which is part of why I have the battle_lines set up.

  1. As part of said showdown, I’ve got an AI Assault - admittedly a half-finished one - that’s supposed to trigger once the first wave of Vorts is dead - the HECU are supposed to run down the hallway and around the corner to confront the next wave. It… seems to be halfway working. The HECU will run up to the hallway corner as intended, but inconsistently, and they don’t go any further than that. Based on what the VDC says, I can’t see anything wrong with my setup.

ai_goal_assault:
Name: hecu_office_assault
Actor(s) to affect: c2a2a1_office_showdown_hecu
Rally Point Set: office_hecu_assault_point_*
Search Type: Entity Name
Start Active: No
Assault Cue: Don’t wait for a cue
Rally Point Selection Method: Random

assault_rallypoint:
Name: office_hecu_assault_point_* (5 total, one for each soldier)
Assault Point: office_hecu_assault_goal
Assault Delay: 0
Priority: 1
Force Crouch: No
Urgent: No

assault_assaultpoint:
Name: office_hecu_assault_goal (there are three total, the other two have numbers appended)
Next assault point: office_hecu_assault_goal_2/3 (respectively)
Assault time out: 3.0
Clear on contact with enemies: No
Allow diversion: No
Never Timeout: No
Strict?: No
Force Crouch: No
Urgent: No
Attack Tolerance: Large (10ft)
Clear this point upon arrival flag is unset
(all of these have the same settings, minus goal_3 not having a next assault point target)

A math_counter keeps track of how many Vorts are alive, and when the first wave is dead, it fires an Activate output to the ai_goal_assault entity. When a BeginAssault input is fired (which it turns out I’d accidentally deleted, oops) the soldiers will run to the corner of the hallway, but still make no real effort to actually stay around the first assault point. After that, they crowd around the next assault points without spreading out at all. Is this behaviour something that happens when they don’t have any targets to attack?

  1. Last thing, pretty minor compared to everything else - in the office area, there’s a small storage closet in the hallway that has a bullsquid hiding in it. The bullsquid is only woken when the door’s open, to surprise the player - the thing is, upon opening the door, it promptly turns around and starts eating next to one of the walls. There aren’t any ragdolls or NPCs… or pretty much anything in that corner yet, but it just ignores the player. I imagine it won’t be too hard to work around this, but I’m still wondering, what in the world is this all about?

Whew, lots of questions, I apologize. Still, if anyone could point me in the right direction for any of these, it’d be very much appreciated! Thanks.

EDIT: So I just realized that I don’t know how to read, and missed the part where ai_goal_standoff’s are necessary to make ai_battle_line’s work.

Oops.

EDIT 2: I have dreadfully screwed something up in modifying the office showdown. I’ve tried turning it into a standoff instead, but the game has a tendency to crash when the second ai_battle_line is enabled. Is there a specific way to go about this?

Bumping this back up. I’ve been having… limited success with some of these issues. From the top:

  1. I managed to get the grunt to shoot using an npc_bullseye, so there was that. But, uh, in trying to figure out other NPC stuff, I seem to have broken things, because now he won’t get on the turret at all. He still shoots (not sure if he’s targeting the bullseye or the vorts themselves), but the input to get an NPC on the turret doesn’t seem to do anything. I suspect it’s related to the next issue…

2/3) I am having a lot of issues with ai_battle_line’s here, and I have no idea what I’m doing wrong. More often than not, NPC’s completely ignore the line and its settings - passing it when it’s set to strict, a squad of Vorts immediately moving to the wrong side of the line (I’ve tried changing the angles, so AFAICT that’s not the issue), the office soldiers running way ahead towards the second battle line before it’s even enabled… I just have no idea what I’m doing wrong here. Can anyone explain how to set these up in a way that even an idiot like me can understand?

  1. I’ve actually ditched this setup in favour of the battle lines. For what I want to do (have the grunts starting in one area of the hallway until the first wave of vorts is gone, then running around the corner to confront the next wave - if the player follows them after all the vorts are dead, they would ideally hang around in that corner of the hallway using cover and such), is it better/easier to use an Assault or a Stand-off? If an assault is the answer, how do I get those working nicely?

5 (Which I mislabelled as 6, oops)) This one I did manage to figure out without too much difficulty, I had the bullsquid set to think outside its PVS by mistake, causing it to take interest in a ragdoll in the next room over. Oops.

Last question: Is there a way to make NPC’s “alert” when waking them? In some of the maps, there are grunts that are supposed to “ambush” the player, but they don’t do a very good job - the default reaction time kicks in, so they take a few moments to actually target the player. Is there a way around this?

You could try using a scripted schedule to set them to COMBAT and target the player. As for notifying them of the player’s location, ai_relationship has a flag that allows you to do that. I’m not entirely sure if that’s necessary though.

If they’re far too stubborn to actually take notice that the player is there, you may want to consider using an npc_enemyfinder to make them omniscient, at least temporarily.

Just tried using a scripted schedule to see how it’d go - It worked like a charm, thanks! Having said that…

Isn’t the npc_enemyfinder entity deprecated in Black Mesa? I tried using it for the office section of the second map at one point, as well as npc_create’ing it just now, and I’m getting an unknown entity error message.

Huh, it may well be in Steam Mesa. I know it was definitely available back in the mod version. I guess it’s gone now.

Hmm. Well if you really want omniscience, like I said, ai_relationship should have a flag that notifies subjects of target location. Actually I’m not entirely sure if that works the way it should, but I’ve never had reason to doubt that it does…

Actually, y’know, I’m not sure what the deal is with npc_enemyfinder in Steam Mesa. On one hand, as mentioned, I’ve tried using it - it still appears in Hammer, I guess since it’s defined in the base Source .fgd - and gotten negative results, but doing a filesearch in Notepad++ shows that it’s used several times in the official levels… Maybe one of the devs can shed some light on this?

On that note, I’m still stumped on what the deal is with ai_battle_line’s. Short of using NPC clip brushes, is there anything I can do to make sure NPCs don’t actively try to cross the line? Particularly Vorts, I haven’t been able to get battlelines working for them at all.

I can confirm that it does work like it should.

On the func_tank, whats the Maximum target range? Try increase it?

  1. On opening the door, input the bullsquid with

SetReadinessHigh
UpdateEnemyMemory !player

Should probably make it want to attack the player.

I think the npc_enemyfinder is currently busted, and is on the fix list for CU3, as a few of our own sequences rely on it. Hence why the entity is still in our FGDs and in our levels too.

Don’t you just love engine ports?

It’s also missing some functionality compared to Ep2, like the settings for FOV and distance, if I recall correctly.

aiscripted_schedule is generally a bad idea. While it will get the enemies to where you want them to go, it basically disables their common sense getting there. The advantage of using an assault, even a simple assault where the rallypoint and assaultpoint are next to each other, is that the AI will work its way there while still being able to do other things and advance tactically. aiscripted_schedules are also easily foiled if the player blocks the path in some way. Enemies will give up and stand around looking stupid. This is less probable in Black Mesa since the player can’t manipulate the world as easily, but it can happen if everyone is shuffling through one doorway.

The UpdateEnemyMemory input invokes the same mechanism that the “Notify” options on ai_relationship do. It basically says, “Hey, the player is over there. Make of that what you will.”

Some of Black Mesa’s enemies have a weird reaction delay, for whatever reason. The stairway Vorts on the return trip in Bravado are a great example. They’ll take a good 2-3 seconds to engage you, even if you’re standing right in front of them. It doesn’t feel like the hallway Vorts earlier have the same issue. Couldn’t really tell you why. Perhaps it has to do with whether or not they already have line-of-sight when they spawn in.

Standoffs are great for many reasons, but as you discovered, they need the ai_goal_standoff entity. In actuality, the battle line is completely optional. With or without it, enemies will seek info_node_hints with cover as they advance to their target or to the line. I personally think they make the HECU more fair and fun, because they aren’t blazing headlong toward you trying to turn every battle into an in-your-face gunfight. Standoffs force them to keep their distance and pop in and out of cover. It forces a medium-range gunfight to occur, so I use them in most of my work and save the close-range stuff for Shotgunners and the like, making them distinguishable from the rest of the group because they are the ones who don’t stop advancing.

On the other hand, aiscripted_schedule is pretty much the only consistent way to get them to shoot at a specific target (in, for example, a scripted scene). Use the right tool for the right job.

Founded in 2004, Leakfree.org became one of the first online communities dedicated to Valve’s Source engine development. It is more famously known for the formation of Black Mesa: Source under the 'Leakfree Modification Team' handle in September 2004.