Netcode progress
- Today: got bullet timer and shape energy event updates working by fixing not flushing the WriteStream instances when sending data to clients. It turned out this was a major issue that caused data sent to clients to be sometimes incomplete. This fix helped improve the event update system a lot.
- Have been working on multiplayer, lots of good progress on it the past few months. Including: proper support for movement resims to reconcile with server's past when it differs from the client's past (same method Rocket League uses)
- This past month: Inspiration from Halo multiplayer GDC talk titled I Shot You First that shows event-based netcode that uses delay. This is kind of a hard-coded and custom-tailored solution which I am avoiding. Instead I am showing the simulation's events and then rolling them back if any differ in the past, like for position and movement resimulation. This implementation should be easier for me to implement and maintain than Halo.
- This past month: resimulation was fixed by:
- Changing input polling to happen before world simulation (which should have been the case anyway but in 2018 I guess I must have made a mistake)
- Sorting the b2Body list in b2World whenever a body is added. Effectively this means the body list is always sorted by ID (which is synchronized from server to client), so that on each physics frame the body graph is traversed in the same order between the client and server. This ensures the simulation doesn't diverge for simple box shapes (without joints) anymore.
- This past month: RNG is slightly better synchronized between client and server. It still needs work though. This was accomplished using boost::hash_combine to combine the tick number of the "server" on the client (that is, the client's translation of its own tick number to that of the server's absolute time1) with the ID of the shape of each enemy, reseeding the RNG with this value before every enemy instance's AI is processed.
Footnotes
-
clarification: the game uses ticks to track time. Each tick is one frame of the game. The client may deviate due to freezing, therefore falling behind the server's ticks. The client may also run slightly faster than the server due to operating system scheduler timing differences. For these reasons the server will tell the client if it needs to run faster or slower, or if the difference is too great then the server will just tell the client to add or subtract from its current tick translation. The tick translation allows the client to continue tracking time in its own ticks, but then to translate when comparing the server's ticks to its own: subtracting the server's tick units by the translation amount gets the client's tick units. Likewise the client can translate the ticks that the server sends to it to be in its own tick units (by adding). ↩