Enet (2026's edition) - #3437
Draft
ohlidalp wants to merge 18 commits into
Draft
Conversation
2 tasks
Member
THIS IS A DIRTY PROTOTYPE! Dumped full .tar.gz download of enet to /dependencies/enet/. Tested to build and link (windows 10, VS2019)
For maximum backwards compatibility, RoRnet version was bumped, SocketW is kept and server still listens for TCP connections on ip/port advertised on master server. Only if client version matches, the server instructs the client to reconnect using ENet (using pre-existing unused RoRnet message MSG2_VERSION). ENet communication is exactly the same as legacy TCP connection, with only one cosmetic detail - server info is sent to client using pre-existing unused RoRnet message MSG2_SERVER_SETTINGS rather than MSG2_HELLO. This is a prototype done with minimum code changes, for easy understanding. Code changes: * `class Network`: removed send/recv threads. TCP functions renamed. * `ConnectThread()`removed all TCP processing except version check, placed ENet dispatch loop here - the thread now runs until disconnect. * `RecvThread()` changed to `OnPacketReceived()` - it does all it's previous work plus the user auth previously done by ConnectThread(). Function OnPacketReceived() is now called with enet mutex unlocked and must only call safe functions like AddPacket() and DisconnectEnet(). * Added enet_initialize() to main.cpp * Added handling of ENet event CONNECT - packet cannot be queued earlier. * ENet port number must be TCP port + 1. * class Network: renamed func `StartConnecting()` to `Connect()` * class Network: Added mutex protecting enet library; `AddPacket()` and `Disconnect()` lock the mutex. * Network.h: added DisconnectENet(); which locks the enet mutex. * class Network.h - Function `StopConnecting()` fused into `Disconnect()` which now carefully considers current state. * DO NOT reset 'mp_state' cvar and `m_progress` variable on dispatch thread - should be done by main thread after cleanup. * main(): MSG_SIM_UNLOAD_TERRN_REQUESTED - do not crash if no terrain is loaded. * main(): added missing handler for MSG_NET_USER_DISCONNECT. Note: Apparently using non-zero wait timeout for enet_host_service() causes nearby locks to become laggy, eventually never being able to lock. In this case, using timeout 100 causes RoR to hang on disconnecting from server because `Network::Disconnect()` is never able to grab the lock. Observed under Win10/VS2019/Debug.
Take advantage of the fact recv. thread checks for chat messages anyway and console is threadsafe. Also removed dummy `ChatSystem::SendStreamSetup()` because chat doesn't flow through MSG2_STREAM_DATA
Processing of MSG2_STREAM_DATA packets was separated from the rest.
This allows the game to dispatch received packets more effectively (which will become important when networked collisions are implemented). The shared recv. packet queue in 'Network.h' was removed, instead 2 separate were added in 'CharacterFactory.h' and 'ActorManager.h'.
BEFORE: Packets were sent and received on main thread while physics were not running. This means they got delayed by 1/FPS on both ends. With 60FPS (16.6ms per frame) that's 16.6 ms delay. Additionally, a timer was checked to ensure at least 100ms intervals between sending packets. Assuming 60FPS (16.6ms per frame) this would, on average, add another 8.3ms delay. Finally the actor node positions were updated just once per frame, making it unsuitable for collision detection. AFTER: Packets are sent and received directly from physics stepping thread at precise intervals, configurable by cvars: 'mp_actor_send_interval' and 'mp_actor_recv_interval' (values are in milliseconds, both are 100ms by default). Updating actor node positions is also done this way, configurable by mp_actor_calc_interval (default 10ms).
Risk was minimal, but this eliminates any concern.
Cherry picked from RigsOfRods#3049 - original code by @tritonas00 dated May 2023
Cherry picked from RigsOfRods#3050 Since the collision works by "sticking" the character to the actor while in contact, I realized I could extend our existing driver-attachment logic to also handle this attachment. It's glitchy right now, partly because the networked cab offset is always in world coordinates, so it causes sliding when the vehicle turns.
BEFORE: There were separate packet types CHARACTER_CMD_ATTACH*, CHARACTER_CMD_DETACH to persistently seat the character in vehicle or "glue" it to cab to allow cab-walking. Note the ATTACH packet must perform a round trip to take effect. This was bearable for seating but unsuitable for dynamic contact. AFTER: The coupling state is sent as part of regular position update. The client simply detects differences from existing state and updates accordingly.
Cherry picked from RigsOfRods#3056 WIP; Only tested on local machine without any fake lag (I don't know how to set that up under ENet yet).
Principle: 1. I build on top of existing logic: When client A spawns "LOCAL_*" actor, it sends STREAM_REGISTER (type 0) and client B spawns "REMOTE" actor. This stream transmits compressed node positions and vehicle state data. 2. If net. collisions are enabled, the REMOTE actor on client B sends STREAM_REGISTER (type 4) and client A links it to the original "LOCAL_*" actor. This stream sends uncompressed node forces. Status: There is no lag compensation so remote actor reacts with delay... but IT MOVES! :D
…alled when in menu.
PROBLEM: The contact-detection ray points _upwards_ from character's position ~ it's primary function is to make character 'step up' to the elevated cab when coming from ground. FIX: Let's add negative bias to the ray, to avoid losing contact when already on the cab.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

An experimental RoRnet upgrade to use UDP packets (instead of TCP packets) via popular ENet library.
RoRserver counterpart: RigsOfRods/ror-server#143
Features: