One of the biggest flaws when I was brought in, is that each avatar (unit/man/truck/etc) was setup with it's own thread that handled its' own move event timer. The issue was that a few dozen avatars in a simulation combined with dozens of simulations on a server would lead to thousands of threads each causing memory swaps, with the need for locking to avoid race conditions and other contention issues.
It wasn't a real-time interface, so a second plus or minus to responses wasn't a huge deal. I refactored the avatars to work of a central loop. The only place with common interaction was a message queue for inbound/outbound messages to the various clients to the engine instances.
This cut down on a lot of the cpu contention and similar issues. This would have been less of an issue for something simple on a single computer, but running many such simulations on a single computer, you come into different problems.
It was actually fun to work around this.