How would i go about rendering hostile mobs to specific clients?

So in my game there’s basically a system where players can queue and create rooms with other players. Once a room is created they get sent to the room (on the same server) and they have to fight hoards of enemies. These enemies are really simple, they find the nearest target and chase/attack them depending on the distance.

I want the enemies to be as optimized as possible, because worst case scenario a server could have 6 rooms with 40 enemies each, which leads to 240 enemies being moved on the server.

What i decided to go with is having the enemies only be rendered on the clients inside the room. Which leads me to this post, I’m not too sure how to go about this.

One idea i might go with is:

  1. Creating a hitbox part on the server
  2. Rendering/Loading the NPC on the client and welding it to the part.
  3. Setting the network ownership of the part to the target client.
  4. Handling the parts movement (chasing the player) on the server(?)

My thought process for this is basically, if the npc’s model and network ownership is on the client then that might take SOME strain off the server, while keeping everything in sync for each player.

I know this process is extremely flawed. For example exploiters can move the npcs where ever they want due to the network ownership being on the client. But hey, that’s the reason i’m making this post.

I’m not asking to be spoon fed, just a nod in the right direction is enough. So please send some suggestions if you have any!

Personally I would go about this by calculating on the server, rendering on the client.

Calculate anything critical on the server (damage, spawns, etc) and leave EVERYTHING else on the client. The number 1 rule of optimization is to only use server space for needed game features. Basically think about the bare minimum your game would need to run and handle only that on the server.

Let’s say you have a zombie enemy that is currently 100% handled on the server. You could improve it by first off handling animations client sided. This especially applies if you are using some form of procedural animation. Next you could handle the hitboxes client sided, just remember to include logic checks.

Let’s say you have a system of 100 entities. I personally would design it in the following way:

Server broadcasts to clients that enemies have been spawned.

Clients render and animate enemies, then start listening for hitbox collisions

Clients send info about enemies positioning semi regularly to the server. These positions can be cross checked against other players as the odds of getting a full party of exploiters is rare.

Any time a hitbox is triggered the client broadcasts it to the server. Server uses enemy positioning stated above combined with known info about the player and enemy (player/enemy health, player damage, etc) in order to run logic checks.

Once server validates info it relays it to the other clients and updates any server values accordingly.

Notice how in this example the only thing the server is doing is running logic checks and acting as a client middleman.

Quick warning: remote events are not instantaneous. There is no way around this, if you wish to offload computations on the client you will need to deal with a small bit of lag. This can be crippling depending on what game your making, so just think before you implement and see what you can get away with in terms of client-server lag.

3 Likes

I love the idea of comparing and crosschecking the positions thats smart.

Quick question tho, where would the position syncing come in to play? I want the mob to be in the same spot for all clients rendering it. If each client handles their own individual positioning then it might get out of sync wouldn’t it? Correct me if i misread

You’re good, I forgot to mention that part. There are three ways you could handle this.

You could broadcast positions/targets when enemy’s are spawned. This is easy to implement and should sync perfectly, the only issue is you won’t be able to change targets while an enemy is spawned unless you broadcast a new position from the server which I doubt will happen much.

You could calculate positions on the server and then relay them to the clients. Most of the lag will come from actually loading/moving the parts so if you keep the entities unloaded on the server it should be fine.

You could use the same calculation algorithm for every client. This option might be a little iffy due to ping and connection differences between players but in theory if you use the exact same pathfinding algorithm across all clients the entities should pathfind the exact same way across all the clients.

Personally I would go with number 2, maybe a mix of 2 and 3 if I was feeling ambitious. If you calculated waypoints on the server every few seconds and then did the pathfinding client side between waypoints that would probably be the most optimized system, it might be a little hard to sync between especially laggy players though.

1 Like