mas-bandwidth / yojimbo

A network library for client/server games written in C++
BSD 3-Clause "New" or "Revised" License
2.49k stars 243 forks source link

Network simulator settings are ignored #213

Open dbechrd opened 1 month ago

dbechrd commented 1 month ago

I've noticed a number of places in the tests, such as this: https://github.com/mas-bandwidth/yojimbo/blob/c868d55f49c0fc78be3b4262ff549e34df0096ff/test.cpp#L1454-L1464

Where we're calling client->SetLatency() etc. on a newly allocated client. If you look at the implementation for this setter, it doesn't do anything when networkSimulator is null: https://github.com/mas-bandwidth/yojimbo/blob/c868d55f49c0fc78be3b4262ff549e34df0096ff/source/yojimbo_base_client.cpp#L91-L97

I also noticed this happening in the soak test: https://github.com/mas-bandwidth/yojimbo/blob/c868d55f49c0fc78be3b4262ff549e34df0096ff/soak.cpp#L75-L82

These set calls should all be moved to after the InsecureConnect() call, because that's when the networkSimulator gets created (indirectly, via CreateInternal(): https://github.com/mas-bandwidth/yojimbo/blob/c868d55f49c0fc78be3b4262ff549e34df0096ff/source/yojimbo_base_client.cpp#L143-L146

This maybe happens with some server instances, too; I don't remember. I'm not going to submit a PR for this as I don't remember all the places it happens, and don't have the energy to audit it right now, but I wanted to document the problem in an issue.

This should be audited properly at some point by searching for all calls to those setters and ensuring they're happening on a valid networkSimulator instance. Alternatively, maybe the setters should just assert() when networkSimulator is null instead of silently ignore the parameters, so that it's not possible to call the setters when the networkSimulator doesn't exist, because who would ever want that anyways? The assert would make it very easy for users to notice when they messed up, vs. the network simulator not having the latency/jitter you expect, which is very difficult to notice since the tests still pass. 🤷

gafferongames commented 1 month ago

Add an assert at the top to check that the network simulator is non-NULL before the if check. Then fix all the tests so they pass, if necessary, move the network simulator allocation earlier -- thanks

gafferongames commented 1 month ago

I'm OK with any attempt to set things on the network simulator asserting out, because it's better than failing silently in debug....

dbechrd commented 1 month ago

I already fixed this in my local copy, but it's in a different programming language (I'm porting Yojimbo). I don't have the C++ version building locally, so all of my PRs have been done through Github UI, and it's not trivial for me to fix this from the web since it affects a lot of different files. I probably won't get around to it, but I completely agree with your assessment (adding the assert and re-ordering is what I did in my version).

gafferongames commented 1 month ago

What language are you porting it to?

dbechrd commented 1 month ago

What language are you porting it to?

I just finished (mostly) doing a native port of Yojimbo (and Serialize/Reliable/Netcode) to Jai.

I made a few changes as I went, but it's mostly on par:

Overall, it was a joy to read your code. Your test coverage is phenomenal and the port would have failed catastrophically if it weren't for the tests. I fixed at least 50 bugs in my implementation while porting the tests. I will say that the uber-C++-ified Yojimbo was the least fun part of the library to work on, and was quite difficult to understand since it's spread across tens of files and uses tons of inheritance/virtual/macros. The C libraries were extremely trivial to port in comparison, and felt much more straightforward and consistent. It would be cool to see a C version of Yojimbo one day.

I mostly did this project to learn Jai, and to better understand the internals of Yojmibo et al (which I was already using in an unreleased game written in C++). I don't plan to keep my port up-to-date with the main branch, and even if I publish it, I would still recommend people just generate bindings instead of using a point-in-time native port. I honestly didn't realize when I started this how often you're still updating the libraries (which is awesome!). I'm also not sure if my protocol is compatible with the C++ version, because I haven't implemented encryption yet so I can't test it. My original plan was to port Yojimbo, then use what i learned to refactor it heavily, perhaps into something else entirely, but I dunno what will come of that. I may also try to make a network traffic visualizer to provide more insight into how it works in a visual/interactive way. I'll let you know if anything cool comes of it.

gafferongames commented 1 month ago

Hey that's awesome! Well done!

gafferongames commented 1 month ago

ps. I agree about the C version, the main reason is because of the serialize stuff using the C++ templates for unified serialize, and how that is used throughout the library in message serialization. I think if messages were reduced to byte buffers and sent that way instead, a C port would be a great idea. Planning on something like this in the future, as a separate library.