Advertisement

Client-side culling of distant entities

Started by August 04, 2017 04:02 PM
3 comments, last by hplus0603 7 years, 3 months ago

Hi folks,

I'm working on a little networked game in which the server breaks its internal model of the world up into geographical segments. Each segment contains items, players, scenery, etc. within that part of the world. When a client logs in, they are sent only the local segments relative to their location, and if they wander around the map, they are sent additional segments as and when required. Once a segment has been received, the player does not receive it again unless they leave the area and come back.

My concern though is that I don't want the client's internal model of the world to grow and grow - it should be culled as they move away from an area - as the server will resend it upon their return, and then it can be bolted back on.

However, if the clients manage this culling themselves, there's a possibility they could mistakenly cull some segment which - according to the server - is still in their "local" area. The server therefore would not re-send this segment, so the player could end up in a situation where part of their map just disappears.

Alternatively the server could instruct the client to cull particular segments, but this seems like a waste of valuable bandwidth, which I'm trying to keep to a minimum.

I'm wondering if there's something I've overlooked here which might make this concern go away. Any thoughts on this issue? Let me know if I didn't explain myself very well (highly likely!)

Short answer: the bandwidth needed to tell a client "delete entity 456" is probably a thousand times less than the bandwidth needed to tell the client about that entity in the first place. It's negligible and you don't need to worry about it. (You do need to worry about accidentally telling the client to delete something one frame and then re-create it the next - you'll want your 'forget' radius to be bigger than your 'discover' radius.)

Longer answer: if there's any situation where the client and server could somehow disagree on something, you either need to let the server decide it, or you need to change it to make it consistent. A client could tell a server "I have forgotten entity 456" so that the server knows to retransmit it, but if the server immediately thinks it's relevant and sends it right back, you'll just have wasted that time and bandwidth for nothing. Alternatively, you could implement a complex caching system, where the client says, "I know about entity 456, as of 4 minutes ago, and entity 555, as of 1 hour ago", and the server could see that entity 555 changed on the server in the last 10 minutes, and send an update for that one only. But why go in for this level of complication when you could just have the server decide what is relevant, all the time?

Advertisement
2 hours ago, Kylotan said:

Short answer: the bandwidth needed to tell a client "delete entity 456" is probably a thousand times less than the bandwidth needed to tell the client about that entity in the first place. It's negligible and you don't need to worry about it. (You do need to worry about accidentally telling the client to delete something one frame and then re-create it the next - you'll want your 'forget' radius to be bigger than your 'discover' radius.)

Longer answer: if there's any situation where the client and server could somehow disagree on something, you either need to let the server decide it, or you need to change it to make it consistent. A client could tell a server "I have forgotten entity 456" so that the server knows to retransmit it, but if the server immediately thinks it's relevant and sends it right back, you'll just have wasted that time and bandwidth for nothing. Alternatively, you could implement a complex caching system, where the client says, "I know about entity 456, as of 4 minutes ago, and entity 555, as of 1 hour ago", and the server could see that entity 555 changed on the server in the last 10 minutes, and send an update for that one only. But why go in for this level of complication when you could just have the server decide what is relevant, all the time?

Thanks that makes a lot of sense, I'll start by widening the forget radius, and see if I need the server to push cull events :)

A belt-and-suspenders approach would also have the server tell the client "you should now have area 458 but if you don't, let me know and I'll be happy to send it."

You'd likely want to not just trust the client blindly when it says "I don't have area 458" but instead verify that that area is actually within view of the client, else clients could request areas far away for whatever gameplay cheating reasons that gameplay cheaters can come up with. Thus, the request the other way would go "I'd like area 458" and the server would either say "here is area 458" or it'll say "you're not close enough to area 458."

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement