NPC Movment Sample
Taking a break from the marketplace stuff, I thought I’d head into uncharted waters with a stab at NPC activities.
Probably most important would be the NPC merchants. These guys simulate other traders in the game in two (one actual, one hypothetical) ways:
- They should move around the sector with a purpose, like the player.
- They should be responsible for “pollinating” goods between stations.
Before I can even consider item #2, I need to take care of item #1. In other specific game designs, I could use a pathfinding solution like A*, but from what I’ve been reading, the instructional videos I’ve been viewing, and my resulting (limited) understanding, that kind of pathfinding requires a semi-flat, 2Dish layer that the nav mesh understands.
In my case, the NPCs need to be able to enter from a jumpgate, head to a station, and then head to another (or the same) jumpgate to leave the sector. Because I’m looking to handle this in three dees, the NPC could theoretically start it’s leg from below or above a target. If I wanted to limit the action to just the X and Z axis, then I might be able to set something up with A*, but I thought I’d try something more rudimentary instead.
An NPC merchant isn’t a complex beast. On a normal day, they have one job: buy low, sell high. In order to complete the first step, they need somewhere to buy.
An NPC would spawn at the ingress point outside a jumpgate’s trigger bubble — doesn’t matter which one — and would then need to move to a station and dock. While there, they would buy whatever they felt was the best deal, what they had room for, and what they could afford.
For the second step, they’d leave the station and head out to bring those goods somewhere to sell. So they’d need to ID a jumpgate, ideally heading off to a place where they know they can sell their items to make a profit.
Right now, the NPC “capsule” object has two scripts: NPCComms, and NPCMovement. NPCComms will tell the object what to do when it encounters an obstacle, based on the obstacle type. If it’s a planet, NPC, asteroid, black hole, 18 wheeler, or slow person at Wal-Mart, the object will move around it. That’s all theoretical at this point and the script has been written but not tested.
NPCMovement, though, calculates a route at the start by agreeing on its mission: find a station, then find a jumpgate. It cycles through objects in the scene tagged “Station” and picks a random one from the collection, adding it to the routePlan list. Then it searches through the objects in the scene marked “Jumpgate”, picks a random one from the collection, and adds it to routePlan.
The object then performs a LookAt towards the first destination and moves forward. When it determines that it’s within 10 units of the destination (using vector math, one of the worst types of math), it picks the next destination in the list, turns to it, and moves forward.
Along the way we may need to pause (to dock for a time) or dodge some things, but that’s for another phase. Right now, I wanted to get the waypoint method out of the way and see if it works, and if it is/can be streamlined and/or made more generic than looking for specific tags to do specific things.
Simulate or Just Look Nice?
Further on down the road I have to decide if I want this to just look nice — NPCs moving along with apparent purpose — or to have the NPCs really do work.
One mechanic I need to work with is the re-distribution of commodities. A player should see goods moving without her intervention, simulating NPC merchants who are doing the same thing she is doing. I could handle that when the player isn’t looking: shuffle the deck and say “oh! That was the NPCs doing that while you were napping!”.
That could be considered cheating by some who prefer a more “honest” (but more complex to create) approach. For a more realistic take, the NPCs that “dock” at a station would use their own cash to buy the best bang for their buck, load the inventory just like the player, and actually pathfind their way to a station in the game which buys for more than they bought for.
I’m not sure I know how to handle the second option. I mean, I can set something up so the NPC’s docking triggers a goods transfer to an NPC data record, ejecting the NPC object from the station and sending them to the jumpgate. Then I’d need to simulate the journey of that NPC beyond the current sector. Since the sector technically only “runs” while the player is in it, it would involve calculating travel time for the NPC, route determination from origin to destination, determination of destination based on best sale value, and all that…for every NPC merchant in operation, all the time.
But from the player point of view, seeing an NPC dock (vanish from view once they hit the trigger sphere) and reappear after a few minutes, and fly off to a jumpgate where they vanish (are destroyed) might be just as good as actually moving product. How would the player know that the NPC is just a visual shell that didn’t actually do anything? Technically, if the player opted to, say, destroy the NPC then a decision would need to be made: destroy everything, or jettison cargo in the debris? If we go with the jettison option, then the NPC would need to eject something commodity-oriented. Either it’s officially what they bought, or I could spawn a canister of a random commodity. These are the thoughts that keep me up at night.
I guess it depends on what’s good for performance, what actually looks good in terms of believably, and how true-to-life I want to make this — as well as what players are willing to accept. I think initially I’ll stick with the easy road, because having something that looks good is going to need to happen anyway. Later, if I have the bandwidth in terms of time, desire, and performance, I can look into making things behave in a more “realistic” fashion.