I couldn’t find any helpful articles about this, so I’m hoping to help the next person struggling with this.
I ran into a situation where I was pooling missiles in Cleared Hot, and occasionally when a unit would shoot them, they would originate from a different location. A few would come from where they were supposed to, then a few would come from like 50 meters to the left, and some would come from way off in the distance, presumably at 0,0,0.
I was doing all the standard precautions for moving rigidbodies:
Using Rigidbody.position
Setting it to kinematic
Turning interpolation off
However the last thing I was doing was adding a force to launch the missile.
The only thing that seemed to fix it was to retrieve the pooled prefab, and then queue up the addForce call until the next FixedUpdate.
Perhaps there’s some issue with teleporting a rigidbody and adding force to it at a time other than a FixedUpdate interval.
So if you’re seeing your rigidbodies appearing all over the place, here’s your lifeline. Get them from the pool whenever, and then wait for FixedUpdate to use them.
Welcome back, intrepid pilots and nostalgia seekers. Today we have a deep dive into the world of NPC AI. But first allow me to tell you a story about the first AI behavior I ever wrote.
We have to go way back to a time so shrouded in nerdiness and embarassment that nobody in their right mind would ever revisit it. Computer camp.
Yes, 13 year old me learned to program at a week long camp surrounded by other uber nerds whose collective abilities quickly showed me I was not the smartest one in the room. Where I learned that you could actually be tired from just thinking all day. Where I learned that losing in Risk really sucks.
Our first task was to create a tic-tac-toe game in C++ (I really wish Python existed back then), and then create an AI player who would never lose. It was a monstrous if-else disaster of listing every possible case of what the AI should do. Eventually I got it working and it would never lose. It was a “perfect” AI player.
Soon I discovered that the game was no longer fun to play. Something about that stuck with me; a fun opponent is imperfect. If you’ve ever said “the AI is cheating” in a game, you know what I mean.
So the goal is to make AI that is human-like, instead of god-like. Well, let’s start with Behavior Trees.
Behavior Trees
Behavior Trees are basically a flow chart of decisions and actions. For example:
My first take on AI in Cleared Hot was pretty simple: If you see an enemy, shoot them. If you have a destination, walk towards it. If you were a friendly unit and the helo landed near you, get in. It was governed by a Behavior Tree.
Sounds pretty simple, right? Well here is what the behavior tree looked for this simple behavior.
The real culprit was this: Combining State and Actions in one tree. For the non-programmers, state is something you have to keep track of about the world, that will determine what you do. For example: Am I currently attacking, am in the helo or not, etc. So every time the tree was executed, you would have to dive into the right sub-tree for that state.
Behavior Trees inside State Machines
After experiencing enough pain with the behavior tree approach, I stumbled upon a GDC video. In this talk, Bobby Anguelov mentions an approach that uses State Machines for… state, and Behavior Trees for actions. This is based off his experience creating AI for the Hitman series! Pretty cool.
This approach made so much sense to me that I figured it was worth implementing before I added anything new to the NPCs. So I build a simple version. The NPCs have a small set of states:
Idle
Attack
Flee
Hit
Dead
Each state contains it’s own behavior tree, that is set up when entering that state, and cleaned up when leaving. These behavior trees are just actions. They aren’t making decisions and they aren’t running any sensors. They are just executing actions. This cleans things up a TON. Look at the attacking behavior tree, which is currently the most complex one:
The really cool thing about this is that you can update your knowledge separate from running the behavior. Previously the NPCs were doing raycasts everytime they executed the behavior tree, but now they only need to update their knowledge base at the speed of a human reaction, and yet they can drive their behavior trees much faster.
Perception and Knowledge
In order to make decisions, the state machine needs some knowledge of the outside world. This is done by implementing “sensor” scripts that allow the NPC to see or hear things in the world. Each NPC updates their knowledge base about every 200-250ms (typical human reaction time) and will change state if needed.
These sensors react to “Stims” or AI Stimulations, which are just things you can drop in the world for an action that you want the NPCs to know about. So far I’m using these for: shots being fired, shots impacting a surface, explosions, all NPC and player positions, etc.
A trail of minigun bullet impacts create “Stims” in the world that NPCs can see and hear.
The game also adds some randomness into their update timing, so it tends to spread the processing time across frames, making the game run smoother. I’ve yet to fully stress test this, but I’ve put about 50 NPCs in view at once with no problems.
My favorite example of new behavior is the “RPG Warning”. When an enemy is about to fire an RPG (or other high damage weapon), they create a “RPG about to fire” Stim. If another NPC can see that, they will play an RPG warning voice line (RPG!!!) which also creates an audio stim. If another NPC sees the RPG enemy but already heard someone else yell the warning, they won’t repeat it.
All of this makes it possible for the NPCs to react to things in the world. Like being shot at.
This is where I will release the first play test builds! I’ve already been interacting w some of you over email. Thanks for your thoughts and feedback, your emails are super motivating.
I am back to working on the hard to define task of “game feel”. This involves making the things you do over and over feel… good.
One of my main playtesters is a friend I’ve known since 1st grade. I’ve played every generation of video game with him. We’ve been comrades in arms in n64 goldeneye, being repeatedly gunned down by his older brother, I think we actually got into a fight one time over Tekken3 or maybe some Dreamcast boxing game, and we’ve shut down entire battlefield servers as helicopter pilot & copilot.
So when I send him a build, I can easily tell if it “feels good” or not. The last time he played, it was clear something was missing from the minigun. He sent me back a gif from Blackhawk Down and said “this is how I want to feel”. Alright. Mission accepted.
Game feel is more of an art than a science… The best way to improve it is just to experiment with a bunch of things.
So let’s get our paint out and Bob Ross this minigun, shall we?
Making the minigun feel more powerful
The Before
Screen shake + Barrel Flash Effects
Screen shake is a common game feel tweak- you make the camera move slightly in reaction to powerful events in the game scene.
So much better already. even without audio it’s clear when you’re shooting.
Thankfully the asset we’re using for camera work (Cinemachine) has a nice system for adding screenshake impulses to events. All we have to do is define the rotation + position waves that shake the camera.
As you can see, the camera shake involves 3 different frequencies rotating on the 3 separate axes. This gives a good shake effect that feels natural without having a weird oscillation in only one direction.
I decided not to use any position shake, since that tends to be more jarring than rotation.
Splash Damage + Spread
Part of the issue I wanted to fix was how lame it felt when you shot right next to an enemy, and nothing happened. The easy improvement here was to add splash damage to the rounds. So now when a shot impacts a surface, it tries to add damage directly to what it hit, and then uses the existing splash damage system to add damage to anything in a 2 meter radius around it.
The other part of this was that the rounds would go EXACTLY where you were aiming. This sounds like a good thing, but it looked and felt strange. So I added an angle of spread that can be adjusted.
Better Tracers
Ok I have to admit something. Before now the tracers didn’t actually go where the bullets were hitting. Forgive me. It was good enough at the time but not good enough anymore. Even worse, they would go through surfaces that stopped the bullets. This irritated me for awhile and I was so happy to fix it.
Now the tracers actually follow the path of the bullets, and stop where the bullets stopped. This means the spread of the minigun is directly visible in your tracers.
Aiming Parallel
Previously both miniguns (left and right) would aim towards a single point.
By keeping them parallel, you increase the actual area covered by their shots, and I think it just looks better too.
I also improved the look of the lasers which designate their aim, and added small laser dots to the end. This makes it clear to the player where the shots will land, if they’re blocked by an object, and it responds slightly to changes in the helicopters angle.
NPCs are now scared of your bullets
Another way to make something feel powerful, is to make the NPCs afraid of it!
This took an entire rewrite of the NPC AI. Which was on my list for a long time and this was reason enough to do it. More on this next time, it will probably be the topic of the next devlog.
Each NPC has sensors that it can use to make decisions about what state to be in. If they see or hear a shot near them, and don’t see a current target, they will run away. This uses a common method of adding AI Stimulations or “Stims” to the world that each NPC can choose to react to.
A fun bug that exists currently: The NPCs don’t differentiate between their own shots and their enemies shots. So they can essentially shoot and then startle themselves, and run away. I’m working on a fix to give them a bit more courage.
More Bass
The minigun sound effect doesn’t have much in the low frequencies, and it’s hard to really distinctly feel when the individual rounds are being fired. I experimented with adding a small bass pop when the gun actually fires each bullet. It’s subtle, but it feels a lot better.
I don’t have a gif for this. 😉
Recoil
This one is subtle… I wonder if you noticed it in the above gifs? The minigun has a bit of recoil that it exerts onto the helicopter when firing. Notice how in the before gif, the helicopter is totally stationary, but in the other gifs it’s moving slightly backwards.
I think I will use this more for the minigun upgrades in the game. If you unlock a more powerful gun, it might have higher recoil.
Wishlists help me a ton. And thank you all for your continued support. I’ve heard from a bunch of you over email and twitter and it helps a lot to know you’re along for the ride!
This post is a devlog from Cleared Hot, our current game in development.
Welcome, gather round and take a seat, as I fill this dark chrome window with half-intelligible war-stories of trying to make a rope, a simple rope, that hangs beneath a helicopter… It’s been a long summer of solo-dev, and it’s time to open the kimono.
Why A Rope?
I think the coolest part of having a helicopter in a game is that it’s still able to interact with things on the ground. And the rope just expands those possibilities.
There’s a lot of interesting gameplay scenarios that involve moving things around: people, vehicles, supplies, etc. And I want the game to be very open ended as far as what you can pick up and how you use it. So we need a rope, and it needs to be physics based.
Enter Particle Physics
My first attempt used a rope that was simulated with particle physics. It also had a magnet that could shoot out towards your crosshair. But the rope was limited in length, and often times you wouldn’t hit what you wanted to.
The problems with this approach were:
It was very performance intensive
Objects would swing way too much, and placing things precisely was impossible
Objects would swing around and on top of the helicopter and land on the rotor blades
Connecting to objects was frustrating and time consuming
No Rope, Best Rope?
After a trip home where I got sick and took a full week off, I returned with fresh eyes and had an idea: what if I separated the rope from the actual physics of carrying things? Then I could code the behavior directly, and just add a purely cosmetic rope to make it look right.
Had I been searching for the best rope, but really what I needed wasn’t a rope at all? I took a deep breath, deleted the rope from the helicopter object and stepped into the void.
I thought, if I’m not just using a rope, and designing the behavior from scratch, what actually is the desired behavior?
Objects under the helicopter are highlighted so you know which one you’ll pick up
Once you select an object, you know it’s the one that will be picked up
Objects are pulled in and hang mostly underneath the helicopter
Objects don’t bounce or swing too much, so they can moved and placed effectively
Objects under a certain mass should move similarly, but really heavy objects should move more slowly, or should slow down the helicopter.
On a whim, I decided to try a PID algorithm to move the objects directly.
WTF is a PID?
The PID algorithm is one of those things that sounds complicated because it’s an acronym (also when you call it an algorithm), but it’s actually fairly simple. It’s just a way to move something to a target, and being able to control how fast it gets there and how much it slows down as it gets closer. PID stands for the 3 parameters you can tweak: proportional, integral, differential.
You can use PID control for many different things; it’s used by thermostats to get the temperature right, used by robots to move objects, etc. I was an electrical engineer in a past life, so that’s where I heard about it.
So how do we use it here? We have a PID controller that tries to move an object to a place under the helicopter. We have another one to add torque (change the angle) of the object, so it sways with movement. In the Unity Debug view it looks like this:
The green circle shows the range of objects that can be picked up, and the magenta line shows the force being added to the cube once it’s picked up.
Then we connect the helicopter and magnet with a “cosmetic” rope, and it looks pretty good. This rope still uses particle physics but is much more performant.
What Can you Pick Up?
Vehicles (even when being driven by AI)
NPCs, both friendly, enemies, and civilians/VIPs.
Inventory Supply crates, which give you additional ammo or other items once reeled it.
Any kind of movable objects (burned out cars, crates, etc).
To make all of these possible, there were some edge cases to cover.
NPCs have to be “unpinned” so they behave as a ragdoll
NPCs are carried by their hips, but if you calculate the force by using their hip mass, it’s not enough. So we need a way to override the mass used by the PID in certain cases.
Vehicles should generally work but we don’t want to flip them over
Inventory Supply crates should give us ammo and then get destroyed cleanly
To solve this, each object that can be picked up has a PickupRoot component on it, that can declare it’s type, mass, and can be inherited from for the things that need special care. For example, there is a PickupRootNPC that can unpin the NPC when picked up.
NPCs can be picked up, and actually still animate while being carried around. Should they still shoot at enemies while hanging?
What Do You Want To Know?
Ok, you read this far. You’re a pro. What do you want to hear more about? What should I cover next time? Hearing from you is motivating, so let me know!
If you’re interested in eventually getting a steam key to play a closed beta, you can sign up for my email list: https://clearedhotgame.com/email-list/ I don’t have a date set for this yet, but you will be among the first to get access.
I made this game for the 7DFPS game jam. It’s the first shooter / first person game I’ve done, and it was a lot of fun.
Overall I think it could be a fun mechanic. It needs a new exploration of what the world / feel would be like. I’m leaving this here until next year. Perhaps then I will do another second order prototype of this one.
This one was really fun to build. You can connect objects in the game world together, and add logic to change their behavior.
There are some issues with the prototype, like the connections aren’t being hidden when you hide the module view. I spent a couple weeks on this one and am moving on for now.