Red Alert 2 (Westwood Studios) and Age of Empires 2 (Microsoft) were two games which defined the era of computing just getting used to GUI (mid/late 90’s).
Originally designed for DOS, Red Alert was built by Westwood Studios – RTS pioneer through titles including Dune. The game was a breakthrough due to its realtime nature.
Add to that a killer storyline, amazing graphics and near-mythical gameplay mechanics and you have a winner. As a software developer, it’s easy to be in awe at games like this… but it’s another knowing how they work. This tutorial is a brief introduction into what I know about it.
OOP (Object Orientated Programming)
The most important thing you need to appreciate with any game is that they are programmed using OOP principles. OOP stands for object orientated programming, and basically the opposite of flow-based programming:
- Flow based programs work with the flow of an application. They will focus on user input and manage their system based on forms – typically refreshing the UI each time an input is provided.
- Object orientated programs work by loading a base application and using that to load a series of variables (objects). These variables are held in memory and can be interacted with on the screen in realtime.
The core of OOP is the ability to “invoke” classes. Classes are a type of variable which allow you to store “attributes”, and use those attributes in “public” (class) and “private” (instance) methods.
The way almost all games work is to invoke a number of data objects into memory, populate them with the appropriate attributes (hit points etc) and then proceed to call the various instance / class methods on them as the user interacts with them in-game.
Data + Renderer
On top of a core OOP architecture, RTS games work with two elements – a data backend and “renderer” front end. Understanding how these work together is the core of whether you’ll understand how to make an RTS game work from a programmatic perspective.
Imagine an RTS as a simple application. Ignore the graphics and artwork etc – focus on how you’d make the objects move around on-screen.
It works like this – the application loads up. This gives you the ability to manage your credentials (load past games, change your details etc). The job of the application (in an RTS) is to then create new “games”. These games exist between two or more players, and acts like a giant chessboard onto which you’re able to add new buildings, units etc.
Each “game” loads up two sets of data (your data & the other player’s). The job of the game is to help you manipulate this data to beat out your enemy.
Data (Buildings / Units / etc)
When a new “game” is loaded, the data for you and your enemies are loaded into memory. For example, you may have a data-set which looks like this:
Each number above corresponds to an ID for a data object. In relational databases, the ID will act as a foreign_key.
The way you manage these objects is to have a central data store (for example a relational database) which stores the buildings as specific objects on their own.
This way, when you create a new building, what you’re doing is creating a new reference in the database. For Rails, you’d have the following setup:
- factions_table (has_many buildings, has_many units through buildings)
- objects_table (this will be superclassed as buildings & units)
- games_table (acts as a join table for players) (belongs_to:player_1, belongs_to:player_2)
- actions_table (this records the actions of the game “player 1 started building x”)
The way you’d set up the game is the following:
- The aim of the application is to create players
- Once the player has “logged in” (either with serial or email), they’ll be able to create a “game”
- The game will then allow each player to “build” buildings and construct units. The units are available through buildings (you have to build units in order to make units available)
- Each building/unit is available through a faction.
- You need some sort of tech tree to enable specific unit / building production for certain research investments
The way this would work is to load a “blank” data set when the game loads.
From here, the user is able to build the various lower level buildings / units with the resources they’re able to gather. Each time the user “creates” a new building, they’re creating a new data object which adds to their array of buildings / units.
Please appreciate this data-set has absolutely no bearing on how the game looks.
Part of what makes RTS games so appealing is the seamless bridge between data and renderer. Imagine the data as a pure list of numbers, etc. There is NOTHING visual about it.
In fact, if you ran a “console” view of the game, you’d basically see two sets of data, constantly having their attributes (hit points, position, etc) changed by the game engine.
This is where the magic happens, and is of course the most complicated aspect of the game itself. I don’t have anywhere near the level of experience with this as I do with the pure data.
The renderer is typically what throws off most would-be developers.
The way it works is very simple.
Firstly, when a new “game” is loaded, it creates a “chessboard” onto which your data objects are placed. This chessboard is obviously the map.
The map has constraints (dimensions) which gives the application the ability to “draw” a grid. This grid allows you to use a series of co-ordinates to “position” new buildings (objects).
Whilst the dataset doesn’t care about the positions, the renderer does. This means that if you wanted to build a new building in a location already occupied by another, you will be unable to.
The way you’d handle this is to send the co-ordinates through in a new build request to the server. The co-ordinates will then allow the server to manage whether the user is able to build a new building. If the response is positive, the engine will showcase the building’s construction. If not, it will not allow the building to be built.
The biggest factor with the renderer lies in the “AI”.
This is the real magic of the game. When you move a unit from position A to position B, how does it interact with other elements in the game, for example.
Programming Languages / Architecture
How you design an RTS depends entirely on the medium in which it will be delivered. Back in the day, you just had to create a desktop application.
Today, you have the web, mobile and desktop to consider. As such, the overall landscape of games has changed to be a more inclusive experience.
More importantly, we’ve seen the movement of game mechanics to the server. This means that if you play a game in your browser, on your desktop or through mobile, all you are doing is sending requests to the server and it will respond with updates for the renderer.
None of the physics, game data or build mechanics are kept in the client side application anymore.