I'm making a multiplayer game where players fight in vehicles, and I am doubting my server architecture. As it will be physics, network and AI intensive I would like to split these 3 topics into their own thread. Perhaps even one thread per AI.

The physics thread will run at a fixed time-step and do the same loop over and over.

1. Integrate gamestate at fixed timestep of 0,005s (200Hz)
2. Solve gamestate for constraints and collisions
One such constraint is a vehicle controller, which is a struct consisting of throttle, steer, brake etc. is applied to a single vehicle.
3. Callback
1. The network is called every 6 physics frames, thus the networking runs at ~33Hz
2. The AI is also called every 6 frames.
Note: network and AI can be called in lockstep

The AI threads will calculate the next move on a need-by-need basis.

1. Copy gamestate into private memory
2. Calculate next move
3. Update their vehicle controller in the game state

1. Listen for incoming UDP packets, handle them, apply changes to gamestate such as player's vehicle controller, bullet spawn
2. When called for, broadcast the new gamestate to clients
1. Copy gamestate into private buffer
2. Create array of differences from last state
2. Vehicle parts moved/rotated
3. Players joined/left
4. Projectile impacts and damages
3. Pack the differences together and broadcast.
3. When a new player joins:
1. grab the last private game state buffer and send it whole
2. Change gamestate by spawning a vehicle and allocating a controller

# What I'm having trouble with:

1. Creating threads on the fly has overhead, so I would like to avoid it by pre-creating and "parking" the threads, and calling them when needed. Once called, they do their duty, such as calculate the next move for the AI to make. Then the threads "hibernate". Note that I don't want the threads to wait in a busy loop and read some shared memory for "activation".
2. The AI and Network threads need to make private copies of the game state, because the physics run so fast the game state might be changed mid-read.
1. Mitigation 1: swapping game state buffers. Still no guarantee.
2. Mitigation 2: locking the gamestate. This is a bad idea because the physics should not be held up.

How can I achieve this in C++? Does x86 offer actual interrupts for this? How about other architectures, or are there libraries that do this for me?

Or should I do it another way?

• While the idea of putting different systems on their own threads is intuitively appealing, I've never seen a successful implementation in a game or engine. In practice in games, too many things care about the state "now", leading to lots of synchronization or state-copying. Have you considered a "job-ified" or ECS approach instead, where you process your physics ticks, AI, and networking systems sequentially, but within each of these system steps you "go wide", spreading the work between multiple workers acting in parallel? This can often get you better scaling with less coordination overhead. Jan 6, 2021 at 18:24
• @DMGregory That actually sounds like an awesome alternative, I can already picture it. Still, how would I go about efficiently dispatching the jobs? Jan 6, 2021 at 19:45
• Sounds like you might want to do a bit of reading into Job Systems, as this is a whole paradigm of its own, with published material from folks far more knowledgeable than myself. ;) Unity's Data Oriented Technology Stack (DOTS) is one implementation of this idea that's been a focus of some attention in the past few years, and might have some useful inspirations. Jan 6, 2021 at 19:48
• @DMGregory some cursory searches turned up little of interest to me... Can you recommend any clear-cut literature, preferably with code examples/snippets? Or perhaps a book? Jan 6, 2021 at 19:50

1. a std::condition_variable will let you wait_for the event_queue.has_event() when pushing an event you can notify_one to wake up the waiting thread. However the downside of this is that you are depending on the scheduler to actually wake up the thread. However scheduler resolution can be larger than you'd expect.