Let's Discuss How to make NPC moving fast

INTRO

every npc driven by server right? nah in it can make npc move as slow as a turtle, I’m not here to discuss about movement speed. 
but npc walking speed when the players fight NPCs 
nah I would argue that if the system can adjust the npc is the client, and whether it can npc driven by client but requires only a little data from the server as the location path of the attackers then sent to the client to move the npc.

I would like to know the opinion of you all about it.

Sorry for bad language because i’m not good in english lesson 😛

So basically, moving all the logic for NPC’s to the client except for moving? Well, since this is combat related, you’d move all the combat related logic to the client. The server would need to know the the health of the player and npc as well as the damage they’re dealing to each other. But wait, this is online right? This means that more than one player can attack an npc. But clients don’t communicate with each other, right? They communicate with the server which passes off information to the other clients.

In case you don’t understand where I’m going with all this, it would only put more stress on the server. A client is only a window of what’s really happening on the server. Anyways, I don’t think the problem of attack speed has to do with the server itself. The way EO combat is made is not supposed to be fast paced.

To put it plainly, quickly, and /threadly, this is generally a bad idea, for reasons behind cheating, the general convention, and the fact that it’s not actually as efficient an idea as you may think it is.

EDIT: That being said, I am all for making clients process NPC movement, on the basis of tiny timestamped instructions from the server. I’ll explain more if you’re interested.

the real problem lies not in the speed of attack, but lies in how the npc runs slowly when the attack occurred, like we attack the NPC and the NPC will automatically follow us right? well when it was going on the slow movement of NPC.

the server that makes it slow was because the pathfinding, where the npc always looking for the right path and sends it to the client and make a whirling like that, no matter the result of the time delay npc start moving and it was not good in view

EDIT: That being said, I am all for making clients process NPC movement, on the basis of tiny timestamped instructions from the server. I’ll explain more if you’re interested.

I’m interest ! 😄

As for a faster NPC movement in the server. You can change the server loop UpdateMapLogic timer. Right now, it runs every half second. I don’t know if there’s any harm to changing it, I haven’t messed with it personally… However, you’ll only want to run the entire process on playable maps so make sure there’s a PlayersOnMap check after the Map loop.

Throwing NPC’s movement logic on the client would be as Carim says, bases of cheating and really not efficient.

OK, I’ll try to put it plainly.

Currently, the way NPCs work, the server just loops constantly, for absolutely every NPC, and just randomly moves them if no logic is required. If logic is required, then we update constantly with archaic pathfinding techniques.

As you can imagine, this is absolutely wasted power, to loop through EVERY NPC on EVERY map, as you can imagine, as more players go on different maps, processing power increases more and more. When we require pathfinding, that increases even more. Eventually, we end up with a huge portion of processing onto a part that doesn’t even need to be handled by the server about 90% of the time.

So, what can we do? Our options range from letting the client do all of the work, but obviously, we can’t do that. People will cheat. NPCs will never function properly. Peoples’ gameplay experiences will differ.

My solution is to generate and buffer a path for each NPC beforehand. When it’s needed, (how I handled it) a queue of about 100 numbers is generated, the numbers range from 0 to 3, 0 for left, 1 for up, 2 for right, 3 for down, so we can literally send a byte array, which is -tiny-.

Instead of sending when an NPC moves repetitively, we send the path to the client, and the NPCs initial position, and we let the client do all of the walking work.

OK, we have a sound theory, but the problem now is, different people will walk onto maps at different times, their NPCs will act differently! Where one person might be at the 45th step, a person joining starts from 1.

This is where the server comes in, alongside the path, the server also increments a single byte counter (or more, if you want varying walking speeds for NPCs). This counter keeps track of where we are in each and every NPCs step. So, we can send this out, meaning that clients that just join will be able to pick up where they were left off, and carry on with a relatively similar experience.

When we hit 100 (or however long your byte array is), we roll back to 0, and we generate a new path, and send it out. This means that the only processing for idle NPCs that the server does at this point is a single counter in a simple timer, and a basic procedure to just create a path

OK. Pretty good, but this doesn’t work for cases where players directly influence the NPC (ie. attacking/being sighted).

When this happens, I have a flag that determines whenever an NPC needs to be taken care of by the server or not. If it’s being attacked, or it’s staring down a player it wants to kill. At that point, I flag this true, and then the server sends out to all clients that their typical behaviour is being overridden. At this point, we process anything that needs to be processed, exactly as you have it now (well, it could be better, but more on that.).

When an NPC is done, we generate a new path for it, and it carries on as normal, sending out the new path and its now current position.

At this point, we require the following to be done by the server:

  • Increment a single variable, and loop back to 0 every now and then. When we do loop, generate a new path.
  • Check whether an NPC based on it’s interpolated position needs to chase a player. Set an override flag if this is the case.
  • Check whether a player has attacked an NPC. Set an override flag if this is the case.
  • If the override flag is on, process pathfinding to chase players, and attack as you normally would.

It’s a fairly complex model, but I’m sure it can be simplified, and I’m willing to bet that Stein will either comment on whether some of these actions are necessary/improve on them, but should you choose to to go ahead, you will see a notable decrease in what’s being flung back and forth by your server, and a respectable increase in your CPS (which of course, means everything. :p)

Mind is blown. 😛

That works but still leaves a desync issue in rare occassions and players will be unable to attack the NPCs properly (first hit, since the location is handled on two locations it may not always match up) although we’d need to see this done in practice to see the full extent of such a possibility. I don’t think it would happen often enough to worry about it, but it never hurts to bear this in mind. (Also with the randomized movement timers mentioned below and people joining later, or longer movement timers this WILL cause issues, so possibly resetting the movement timer back to default for everyone might be nessecary when someone joins a map)

Another issue is that if the steps are done for every NPC on every (active!!!) map without variable speed between each execution in said Byte array you’ll get a crapload of new numbers to regenerate every time and the Random() function isn’t exactly kind on resources so using it a couple hundred times in a row may not be a great idea. I’d add a random delay to each movement frame (ranging from between say 200ms and 5 seconds so they move at seemingly random intervals) to avoid having to regenerate a lot of arrays at the same time. Using such a method we can cut down the byte array size to around 50 or so as well because we’d have more space to recalculate them.

This will not fix the speed for NPCs in combat though, but we may be able to patch that up a little if we have more space for processing each individual in-combat NPC as well.

TL;DR: A great concept in theory Carim, but it leaves a few vulnerable situations. For example when a player joins a map mid-timer, they will always be off by X amount of time on each NPC.

This is a little off topic, but there are a few articles out there on how the Source Engine handles things like networked movement.

https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

You might be able to pull something out of here that’ll help you.

Log in to reply