Fear the Hunter


Pillars

The second of four design pillars I have for this game is Fear of the Hunter. From my design doc (such as it is):  

"Collisions, other drivers, gang members, and the cops present a challenge, but the things that must be feared are the Hunters. When they have a contract with your name on it, they are death. They stalk the player like the Predator. The fight or flight response can only break one way. You fight, you die. You might get a lucky shot in, but a head-to-head confrontation is a recipe for disaster. You see one, you run, or you hide."

Alas, the Hunter has been persistent, but not fearsome. I wrote a state machine for it based on GDevelop's Pathfinding behaviour. That was a reasonable place to start, I thought.

Seeking

Like the player and the commuters, the Hunter also has a finite state machine driving its behaviours. By default, it is in a state called Seeking. While in that state, it’s a little meandering. The Hunter rarely has perfect information about the player’s whereabouts. It always has some information, but not enough to decide on an exact location. It starts somewhere far from the player and will pick a random location within a set search radius of the player. Then, using the Pathfinding behaviour, it moves towards that location. Periodically, it will pick a new location that, again, is within a radius. The radius contracts as time progresses – almost like the contracting storm circles in Fortnite, but less explicit. Whenever the Hunter reaches its destination, or a period of time elapses (10 seconds), it picks a new location to Pathfind to. Every time the Hunter reaches its destination, or the time elapses, the period between finding new locations is reduced. The result is that the Hunter’s knowledge of the player’s location gets better over time, and the Hunter’s searching becomes more and more insistent. When the Hunter is close enough to see the player, it enters a state called Pursuit.  

This worked great and still works great.  

Pursuit

By design, the Pursuit state would have the Hunter look for a path to the player frequently, multiple times per second, and then move quickly towards the player, at about double its usual movement speed while Seeking. Simultaneously, at a rate of 5 times per second, it would raycast towards the player. If the raycast was successful, it would fire. The Hunterˋs weapons hit hard and have a tendency to send the player spiralling, so any successful shot felt like a hammer-blow and could set the player up for a second one.

Using the Pathfinding behaviour for the Pursuit state was a frustrating affair. Pathfinding is heavy, computationally. Doing it too frequently would bring the game to its knees. And trying to Pathfind to the player in a way that made it look like the Hunter was actually pursing it was hit-or-miss. There was little control over rotation while pathfinding. So frequently, the mighty Hunter would get hung up in one spot, recalculating paths, missing obvious shots, and getting thoroughly out-maneuvered but the nimble Hopper driven by the player. With the new weapons I added to the game, like the Magnetic Plasma and the Nitro Cracker, I was even able to get the drop on the Hunter and take it out.

That’s not to say that this approach didn’t have some successes, though. It did legitimately jump-scare me from time to time, with the Hunter materializing from offscreen only to shoot me down mid-delivery, emerging from a side street like the raptors in Jurassic Park. Clever girl.

But those successes paled in comparison to the disappointment I felt when the Hunter would glitch out and sit, twitching, trying and failing to find a pathfinding solution while I danced around in front of it.  

The Problem with the Solution

This seemed like an easy enough problem to solve. Give the Hunter the Physics2D behaviour, and when it entered the Pursuit state, simply rotate it towards the position of the player and apply a force along its own angle. In theory, this would keep it on target better, which means it could take more shots, and it wouldnˋt get stuck trying to find a path towards the player. The only path would be forward and the only navigation would be toward. The intensity of this could be dialled up or down by adjusting the speed of rotation and the strength of the force applied to move the Hunter forward, the raycast rate and distance, and which weapon the Hunter fires. I had thought about a system whereby the Hunterˋs behaviours could be affected by an Anger stat and some RNG – like, itˋs more likely to switch to a more devastating weapon when itˋs been chasing you longer and youˋve shot it more, or if youˋve made it shoot a building or a commuter by mistake.  

Hereˋs the problem, though. As soon as a GDevelop object has both the Pathfinding and the Physics2 behaviour, they both stop working. The Pathfinding behaviour prevents the object from reacting like a proper dynamic physics object, and the Physics2 behaviour stops the object from moving along its Pathfinding path.  

I tried some experiments whereby I used forces and torque to move objects from node to node along its path, but the bobbling, wavering result I got was less than intimidating. Back to the drawing board.  

The Solution

GDevelop veterans will know the solution to this immediately, but I didnˋt, and had to come at it from a completely different angle, and while exploring a totally different problem.  

When I recently added 3D models to my game, including a 3D model of the Hopper, I experimented with using the Physics3D behaviour to move the player vehicle instead of the 2D Physics2 behaviour I was using before. Long story short, most of the player movement is governed by Physics2, but when the player is destroyed, the Hopper becomes a 3D physics object so that it can careen to the ground and crash. This took some experimentation to get working, but eventually I figured out the trick: When I need 2D physics, I use and activate Physics2 and deactivate Physics3D. When I need 3D physics, I use and activate Physics3D and deactivate Physics2. This is done simply by adding a De/activate Behaviour action at the top of the stack of actions in the event.  

So with this accidental realization in hand, I went back to the Hunter and added the Physics2 behaviour. At the start of the scene, I deactivate the Hunter’s Physics2 behaviour. When it enters the Seeking state, I make sure to activate Pathfinding and deactivate Physics2. When it enters the Pursuit state, I deactivate Pathfinding and activate Physics2D. From there, I add the rotation and forces I described above.  

It worked immediately.  

A couple of cool emergent things from this behaviour:  

  • Sure enough, giving the Hunter the ability to rotate more quickly allows the Hunter to draw a bead on the player more easily and more consistently. On the one hand, it makes the Hunter much more effective, and on the other, it makes it far more effective at shooting me down. Rude.
  • Because the player doesn’t disappear immediately when it’s shot down, the Hunter will and does keep shooting as you go down and crash into the ground. It’ll then orbit the player, continuing to shoot until the player is fully destroyed. It’s genuinely shocking the first couple of times it happens.  

So – success!

A couple of other fun items I added


  • Obviously there have been big UI updates lately. When I’m a little bit happier with how they're implemented, I’ll write about them. I am happy with them directionally, but there’s definitely more work to do. 
  • Lots of new text and a handful of new pickup locations. 
  • A couple of new sound effects to help draw the player's attention to the events on screen. 
  • When the Hunter fires and the player is in range, if the Hunter’s fire hits a building, it’ll shake the camera, which I think really helps sell the power of the Hunter’s hits.  

That’s it for this one. I’m temporarily out of commission with computer issues (this is being written from my cursed Surface Pro 3 running Ubuntu) but I am dying to get back to work.  

As always, folks, paddle your own canoe.

Trevor

Files

bHopper-2025-06-14.zip Play in browser
22 days ago

Leave a comment

Log in with itch.io to leave a comment.