> Isn't it far better to split these jobs out to different threads?
Not necessarily. For games one of the things you're trying to minimize is time from user input to response on screen - that has to go through your input system, your animation system, possibly your physics system, and then all the way through the renderer. You need strict control of ordering and buffering. To allow stuff to be offloaded to another thread adds latency and can make things messy to control.
For simpler games, threads here don't help. They just hurt. Extra complexity, and likely extra latency (if only through mistakes and synchronization).
For more complex games, you can often get away with just going "wide" within the game loop. You have threads, but it's not about splitting off "animation" and "physics" jobs, but instead going wide when updating animation or updating physics. It's more granular and the high level coordination still happens in a traditional game loop.
If you want to get really fancy, your game loop starts updating a graph of systems of system jobs instead of a hardcoded list of system updates. If you strictly specify all inputs, modifications, outputs, etc. you can start making it automatically parallel by walking the graph and dispatching jobs that don't conflict with running jobs.
Even then you still have a game loop, you've just offloaded most of it's work to a fancy job system. Not all - you'll probably still have some API calls that only work on the main thread hardcoded into the game loop (e.g. for pumping OS UI messages using system provided APIs that aren't thread safe).
Not necessarily. For games one of the things you're trying to minimize is time from user input to response on screen - that has to go through your input system, your animation system, possibly your physics system, and then all the way through the renderer. You need strict control of ordering and buffering. To allow stuff to be offloaded to another thread adds latency and can make things messy to control.
For simpler games, threads here don't help. They just hurt. Extra complexity, and likely extra latency (if only through mistakes and synchronization).
For more complex games, you can often get away with just going "wide" within the game loop. You have threads, but it's not about splitting off "animation" and "physics" jobs, but instead going wide when updating animation or updating physics. It's more granular and the high level coordination still happens in a traditional game loop.
If you want to get really fancy, your game loop starts updating a graph of systems of system jobs instead of a hardcoded list of system updates. If you strictly specify all inputs, modifications, outputs, etc. you can start making it automatically parallel by walking the graph and dispatching jobs that don't conflict with running jobs.
Even then you still have a game loop, you've just offloaded most of it's work to a fancy job system. Not all - you'll probably still have some API calls that only work on the main thread hardcoded into the game loop (e.g. for pumping OS UI messages using system provided APIs that aren't thread safe).