Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit packets sent per tick #104

Closed
oscar-broman opened this issue Feb 27, 2016 · 17 comments
Closed

Limit packets sent per tick #104

oscar-broman opened this issue Feb 27, 2016 · 17 comments

Comments

@oscar-broman
Copy link

When a player teleports or spawns in a new area, it's hard to maintain a stable connection until all objects have streamed in.
900 object create, destroy (from prev) and texture information takes quite some bandwidth, especially when players have slight packet loss.

Would it be possible tonstream in new objects in smaller pieces (e.g. 15 chunks with 60 objects each) to avoid the lag issues?

@ghost
Copy link

ghost commented Feb 27, 2016

Yes, this would be very good. This needed.

@samp-incognito
Copy link
Owner

It would be possible, though I would need to think of a good system for this first, otherwise there might not be much of a benefit to be gained.

Some questions I'd have: how many "chunks" would be appropriate, and how far apart they should be spaced? Should it be something like 15 chunks across 15 consecutive server ticks? Would that significantly impact the amount of time it takes to stream everything? I don't really have any empirical data for any of this. I suppose the options could be customizable, though.

@oscar-broman
Copy link
Author

It would be best if those 2 parameters could be tweaked (chunk size and ticks).

It's hard to approximate without testing it in different areas of the map.

I realize functionality like this will beg the question of which object to stream in first.

Being able to set priority per object or per model along with this would be incredibly powerful - one could prioritize large objects and set things such as grass and small objects at a low priority.

Another way this could be approached is to read from the server how many RPCs are waiting for ack from the client, and only send more objects if that number is below X.

Related: IS4Code/YSF#8
@kurta999 may have some useful input.

@samp-incognito
Copy link
Owner

Right, that could be useful in combination with #86.

@oscar-broman
Copy link
Author

I see you implemented #86 now. What about this? The two in combination will be invaluable for those with both bad connections.

@samp-incognito
Copy link
Owner

I'll see about adding it soon. It will just require some thought and refactoring, so I've put it off, admittedly.

@oscar-broman
Copy link
Author

I could help out with this, if you can just give me a few hints as to what I should be refactoring.

I think this could really reduce lag spikes and timeouts!

@samp-incognito
Copy link
Owner

samp-incognito commented Sep 14, 2016

Basically, this bit of code just needs to be refactored. It could just be put in a separate function inside of a player loop. There should be a check that limits the number of iterations through discoveredObjects on each tick. Of course, discoveredObjects and existingObjects also need to be cached for each player.

I guess I could just go ahead and do this, actually, but I don't really have time to test it properly right now.

samp-incognito pushed a commit that referenced this issue Sep 14, 2016
This is an attempted implementation of #104. It has not been thoroughly
tested yet. Basically, objects (as well as map icons and 3D text labels)
will now be created in 'chunks' on each server tick until all discovered
objects have been iterated through. The chunk size by default is 100,
but this can be configured with Streamer_SetChunkSize. A lower chunk
size will result in slower object streaming but less stress put on the
server. Conversely, a higher chunk size will result in faster object
streaming but more stress put on the server.

Additionally, each player now has an independent tick rate. This can be
configured with Streamer_SetPlayerTickRate. Streamer_SetTickRate now
just controls moving and attached item updates, pickup streaming, and
callback execution.

Hopefully, these changes will fix some of the problems in servers with
high player and/or object counts, but it does need to be tested.
@oscar-broman
Copy link
Author

Cool! I'll give it a try shortly.

@oscar-broman
Copy link
Author

oscar-broman commented Sep 23, 2016

Not sure what goes wrong, but I don't see any objects at all.. How should I approach debugging this?

Edit: Using CreateDynamicObject rather than CreateDynamicObjectEx worked. I'll look into what went wrong.

@oscar-broman
Copy link
Author

If I set the tick rate to 1000 and the chunk size to 1, it does not behave as expected.

I'm guessing object deletion is not taken into account.

@samp-incognito
Copy link
Owner

Using CreateDynamicObject rather than CreateDynamicObjectEx worked. I'll look into what went wrong.

Hm, strange that CreateDynamicObjectEx isn't working. I don't see how these changes would affect that.

If I set the tick rate to 1000 and the chunk size to 1, it does not behave as expected.

Could you elaborate?

@oscar-broman
Copy link
Author

I would expect it to stream in one object/second, but watching object count in F5 showed objects are destroyed/created much faster. It seemed as if it disregarded the chunk size completely.

@samp-incognito
Copy link
Owner

If the chunk size is set to 1, it should only create one object (and also possibly destroy the farthest object if no room is left) before the next tick. There are usually only a few milliseconds between each tick, though, so it would move to the next object much faster than just one second. (That's for the best. If it were only streaming one object per second, it would take over 8 minutes for 500 objects to be created.)

However, if any objects are completely out of range, then they're destroyed all at once. Maybe that's what you're seeing? I suppose this also needs to be staggered in some way.

@oscar-broman
Copy link
Author

Here's what it looks like. Have a look at ObjectSlotsUsed.

Tick rate 1000, chunk size 1:
https://youtu.be/xeDe_q9qEvk

Tick rate 1, chunk size 1:
https://youtu.be/r8FSCIRqJgM

I realize now I thought you meant streamer tick, when it appears the chunk streaming happens each server tick. I suppose what's missing is a way to configure how often the chunk streaming happens, in a similar way the tick rate is configured.

@samp-incognito
Copy link
Owner

Oh, I see what you mean. That could be easily configured.

samp-incognito pushed a commit that referenced this issue Nov 16, 2016
samp-incognito pushed a commit that referenced this issue Nov 19, 2016
Now certain items (map icons, objects, 3D text labels) will be destroyed
in chunks before the new ones are created in chunks as well. Related to
#104.
@samp-incognito
Copy link
Owner

You can configure the "chunk tick rate" now. Objects should be destroyed in chunks now as well.

samp-incognito pushed a commit that referenced this issue Nov 19, 2016
This was from the other commit. Related to #104.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants