1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond (2001)
gamedeveloper.com
gamedeveloper.com
Here's an older snapshot of the article from back when the site was still called Gamasutra, that includes the full text of the article:
https://web.archive.org/web/20180719170411/https://www.gamas...
He wrote that code when he was 18 or 19 years old I believe. But unlike some of the other devs at Ensemble, he never had a big ego, and he was just generally nice and humble.
He (much) later created the early mobile hit, Words With Friends, which had many copycats later.
AoE2 DE is still lockstep, but through a server. All players are connected to the same server. This has slightly improved on the previous P2P, but not really addressed anything.
Sounds more like client-side prediction to smooth things, than actual simulation desync. I have a hard time believing a deterministic game with such a large state was able to backtrack and resync the sim back to determinism. I did not think that lockstep RTS games would need client-side prediction (the indirect and long-term commands in RTS helps hides latency), but I guess if your gameplay lends itself to high APMs then it becomes necessary.
RTS games have a replay mechanisms at least as far back as StarCraft: Brood War, so a journal of player inputs are likely going to be recorded anyway.
Gotta keep in mind that these games were written in languages that did not have modern garbage collection, so almost certainly stored entity information in arrays to avoid heap fragmentation and malloc costs.
A few dozen Kb is far beyond what you can push over a modem in real time for sure, but memcpy:ing a couple of kilobytes' worth of arrays was still plenty fast in the late '90s/early 2000s.
They weren't running these games on a 6502.
The strategy of occasional save-game storage and backtracking only works, if the cause is rare and not deterministic.
Edit: The checksum for the player includes the content of each attribute of the player, the object state for each object owned by the player, the master object id of that object, the amount of attributes they carry (which is I think resources that villagers carry for example) and the world x/y/z position.
Still a Total Annihilation fanboy at heart.
https://www.pcgamer.com/planetary-annihilation-interview/2/
https://www.forrestthewoods.com/blog/tech_of_planetary_annih...
Definitely worth a read. The deterministic simulation is easy to understand (though not to do), clever and allows for great networking performance.
Afaik this approach is still useful and used today (e.g. in fighting games).
I really enjoyed this GDC talk on rollback networking:
https://www.youtube.com/watch?v=7jb0FOcImdg&t=536s
(From 2019.)
https://www.gamedeveloper.com/pc/the-game-developer-archives...
In the section "Things That Went Wrong Or We Could Have Done Better", it mentions as the final point an insight I often think about:
"8. We didn’t take enough advantage of automated testing. In the final weeks of development, we set up the game to automatically play up to eight computers against each other. Additionally, a second computer containing the development platform and debugger could monitor each computer that took part. These games, while randomly generated, were logged so that if anything happened, we could reproduce the exact game over and over until we isolated the problem. The games themselves were allowed to run at an accelerated speed and were left running overnight. This was a great success and helped us in isolating very hard to reproduce problems. Our failure was in not doing this earlier in development; it could have saved us a great deal of time and effort. All of our future production plans now include automated testing from Day One."
What I found appealing in the description is the idea of keeping your program running for a long time and have it perform all kinds of actions automatically. Nowadays, I often hear about "test-driven development", "unit tests" etc., and it often turns out that they test very specific things out of a vast universe of all possible things. That does not mean that they are useless. As I see it, it means - as they phrased it in this article - that we often do not take enough advantage of automated testing.
Personally, when I test software, I always try to follow the general idea stated in the post mortem: Keep it running, and perform all kinds of actions automatically. I found several crashes and memory leaks in this way, which were not noticed during manual interaction because they only became significant when the actions were repeated thousands of times.
Afaik the AI logic gets processed on the host instance, and the rest just follow the commands sent through the network.
The point of that section is that the earlier you find bugs, the quicker you fix them, and you end up with less overall pain for the length of the project.
HN user "dfan" here wrote a fully deterministic game engine for the DOS game Terra Nova in 1996.
There were probably others but resources about deterministic game engines were very rare for nearly nobody had one so this article about AoE was a gold mine for many.
Some terms may have changed, but the techniques are basically identical.
Blizzard in 2002 with Warcraft III had basically solved that issue for RTS once and forever too (and maybe for Starcraft before that?) and not much has changed since then.
The terminology is dated, but there's some real gold in there. The bits about deer facing snowballing out of sync errors, out of simulation code corrupting simulation state, comparing state dumps... this is exactly what your life will be like if you build your games this way. I know this because I have (although complicated by the addition of rollback).
The Gaffer article barely scratches the surface.
I probably can't even do a (modern) google search on a 28.8 k modem without it feeling absolutely painful.
They used a totally different technique(dead reckoning + game design that was about prediction) but it was pretty smooth given what average pings where back then.
The techniques used in the game ended up being replicated in many other games and apps. Its networking was also key to the low lag it is entirety based on a custom UDP network stack that can send both reliable and unreliable packets.
There are fields where squeezing every tiny bit of performance matters — media compression, 3D software (including game engines), data processing, hardware.
Engineering is not art, it's about building things that can be useful.
Unfortunately most of scripters work never got used for HD and DE2.
I used to have 28.8. I’d play this game for hours on there!
I was always in awe this ever worked, even more so over time as software has become more complex….
My claim to fame was a 4-way deathmatch with Thresh [1], myself, and two other randos (like me) on Doom 2, I think the map E2M7? The rules were first to a score of 100, rocket launchers only. Final score: Thresh, 100; me, 7; other opponents -3 and -6.
[0] https://doomwiki.org/wiki/DWANGO [1] https://en.m.wikipedia.org/wiki/Thresh_(gamer)
What do they mean, "same number of calls to random within the simulation", didn't get it
I could play RTS3 with most people around the world, it seemed, except a few of my best friends. They could individually play with random people all over the world, but not each other or myself, depending on the day of the week or something like that.
Perhaps their decision to move away from DirectPlay was a mistake or premature optimization!
The rewrites/updates have definitely helped in this situation but I think the AoM code was built for and tested on networking hardware that was a lot more error prone than modern routers are, which in turn affects how it behaves even today. Clever NAT bypasses definitely work better now than they did fifteen or twenty years ago, but they're definitely not guaranteed to work still. The rise in CGNAT usage also paints a grim picture for anyone playing video games together.
I've also had my fair share of peering issues between ISPs. At one point I discovered that I could send UDP packets to my friend, but my friend could not send UDP packets to me, no matter the port forwards and even after forcing the modem into bridge mode. TCP worked fine in both directions, though. Something upstream seemed to filter the packets out, I'm guessing to prevent DDoS attacks, so whenever we played P2P games one of us needed to run some kind of VPN.
IPv6 can solve many of the problems I remember having to deal with setting up games back in the day, but most games have become cloud-only anyway. The age of custom servers and P2P gaming is over, killed by lootboxes and shitty NAT implementations.
> For RTS games, 250 milliseconds of command latency was not even noticed -- between 250 and 500 msec was very playable, and beyond 500 it started to be noticeable.
The article mentions this as well, so was ~600ms latency just expected?
Why doesn't it work to execute commands _one_ communication turn in the future?