GDC 2001: 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond

RTS3 Multiplayer: Goals

RTS3 is the codename for Ensemble's next-generation strategy game. The RTS3 design builds on the successful formula used in the Age of Empires series games, and calls for a number of new features and multiplayer requirements.

With RTS3, we made the decision early on to go with the same underlying network model as Age of Empires 1 and 2 -- the synchronous simulation -- because the RTS3 design played to the strengths of this architecture in the same ways. With AOE/AOK, we relied on DirectPlay for transport and session management services, but for RTS3 we decided to create a core network library, using only the most basic socket routines as our foundation and building from there.

The move to a fully 3D world meant that we had to be more sensitive to issues of frame-rate and overall simulation smoothness in multiplayer. However, it also meant that our simulation update times and frame-rate would be even more prone to variation, and that we would be devoting more time overall to rendering. In the Genie engine, unit rotations were faceted and animations were frame-rate locked -- with BANG! we allowed for arbitrary unit rotation and smooth animation which meant that the game would be visually much more sensitive to the effects of latency and see-sawing update rates.

Coming out of development on Age of Kings, we wanted to address those critical areas where more up-front design and tool-set work would give the biggest payoff in terms of debugging time. We also realized how important the iterative play-testing process was to the design of our games, and so bringing the multiplayer game online as early as possible was high priority.

RTS3 Communications Architecture

Figure 6. RTS3's strongly object-oriented network architecture.

An OO approach. RTS3's network architecture is strongly object oriented (see Figure 6). The requirements of supporting multiple network configurations really played to the strengths of OO design in abstracting out the specifics of platform, protocol, and topology behind a set of common objects and systems.

The protocol specific and topology specific versions of the network objects have as little code as possible. The bulk of the functionality for these objects has been isolated in the higher-level parent objects. To implement a new protocol, we extend only those network objects that need to have protocol specific code (such as client and session, which need to do some things different based on the protocol). None of the other objects in the system (such as Channels, TimeSync, etc.) need change because they interface with client and session only through their high level abstract interfaces.

We also employ the use of aggregation to implement multi-dimensional derivation (such as with channels, that have an ordered/non-ordered axis of derivation, as well as a peer/repeater axis of derivation) behind a single generic interface. Virtual methods are also used for non-intensive notifications, rather than using callback functions.

Peer topology. The Genie engine supported a peer-to-peer network topology, in which all clients in the session connect to all the other clients in a star configuration. With RTS3 we have continued the use this topology because of its inherent benefits when applied to the synchronous simulation model.

The peer topology implies a star configuration of connected clients in a session (Figure 7). That is, all clients connect to all other clients. This is the setup that Age 1 and 2 utilized.

Figure 7. A "star" configuration of peer-to-peer clients in a session.

Peer-to-peer strengths:

Peer-to-peer weaknesses:

Net.lib. Our goal when designing the RTS3 communications architecture was to create a system that was tailored for strategy games, but at the same time we wanted to build something that could be used for in-house tools and extended to support our future games. To meet this goal, we created a layered architecture that supports game-level objects such as a client and a session, but also supports lower level transport objects such as a link or a network address.

Figure 8. The four service layers of the network model.

RTS3 is built upon our next-generation BANG! engine, which uses a modular architecture with component libraries such as sound, rendering, and networking. The network subsystem fits in here as a component that links with the BANG! engine (as well as various in-house tools). Our network model is divided up into four service layers that look almost, but not entirely, unlike the OSI Network Model, if you applied it to games (see Figure 8).

Socks, Level 1

The first level, Socks, provides the fundamental socket level C API, and is abstracted to provide a common set of low level network routines on a variety of operating systems. The interface resembles that of Berkley sockets. The Socks level is primarily used by the higher levels of the network library, and not really intended to be used by the application code.

Link, Level 2

Level 2, the Link Level, offers transport layer services. The objects in this level, such as the Link, Listener, NetworkAddress, and Packet represent the useful elements needed to establish a connection and send some messages across it (see Figure 9).

Multiplayer, Level 3

The multiplayer level is the highest level of objects and routines available in the net.lib API. This is the layer that RTS3 interfaces with as it collects lower level objects, such as links, into more useful concepts/objects such as clients and sessions.

The most interesting objects in the BANG! network library are probably those that live at the multiplayer level. Here, the API presents a set of objects that the game level interacts with, and yet we maintain a game-independent approach in the implementation.

Game Communications, Level 4

The communications level is the RTS3 side of things. This is the main collection of systems through which the game interfaces with the network library, and it actually lives within the game code itself. The communications layer provides a plethora of useful utility functions for the creation and management of multiplayer-level network objects and attempts to boil down the game's multiplayer needs into a small easy to use interface.

________________________________________________________

New Features and Better Tools