Project Design Specification
and “How it Really Works”
for
SkyNet
Original Author(s):
Justin Crites
THE PURPOSE
or, “Why am I reading this document?”
The goal of this document is to provide a resource that allows newcomers to quickly familiarize themselves with the SkyNET system. This document is designed both for the technically-inclined manager and the developer to learn how the systems work at a high- and low-level.
Throughout this document we detail the goals the system had from the beginning, the design we created to meet the goals, and then the (sometimes dirty) implementation of the design.
It is not going to be easy to take up where we left off developing SkyNet. Plan to devote a significant amount of time to understanding existing systems. The reason it will take so long is not (only) because our project is unorganized, but (also) because we rely on a large number of other complex technologies.
A solid understanding of the following technologies is necessary to begin understanding SkyNet[1]:
- Voltron, which is incorporated into our Network, runs on the PASTRY[2] P2P application framework, provides a distributed, redundant file system.
- SQL Server, Microsoft’s relational database engine, and how transactions affect datasets.
- Enterprise Services, and how COM+ applications can be accessed from within .NET.[3]
- DirectX, and other graphical systems, used to provide the display within SkyNet.[4]
- THE PROBLEM
or, “I don’t have a car, I just have an abstract notion of a car”
The problem as presented to us by the client was to create a secure, distributed, redundant, massive gaming system that could run on multiple platforms. Each of these key points was expressed by the client as a specific system requirement.
The world itself was to be tile based and very large-scale. The client expressed the notion that the game might be used by defense contractors to model global warfare scenarios (whence the term “Global Violence Simulator”). The game world’s design goal was to allow for incredibly massive simulations, including multiple countries at once with a game space of many thousands of square miles.
The system was to be distributed so that no central authority is responsible for managing the network. Devices could enter and exit the network without disrupting the flow of the game. This includes both clients and servers. We interpreted this to mean that servers should share and redistribute responsibility for various game regions[5], with load shifting to meet demand and server availability.
The redundancy requirement flows from the distributed nature of the network: if devices leave the game simulation network, the simulation will continue to go. It should be very difficult to bring the simulation down by accident or attack because processing power should migrate to use available resources and ensure data is redundant.
The system was to be massive on a scale not seen before in other simulation games. The client wished to see conflict on a global level, with the ability to look at the scenarios from the size of countries down to individual troops on the battle field.
The client specified that the world was to be discrete (tile-based), not continuous.
ABSTRACT
or, “What we wanted to do”
SkyNet is, at its essential level, a framework for a distributed, simulated environment. SkyNet consists of a few important components. These components are:
- The Client
The client is the program loaded by users when they wish to interact with SkyNet. The client contains a number of interaction devices which can be dynamically loaded and change the way the user interacts with the program. - The Server
The server is where game simulation takes place. The server is actually a group of COM+ components which respond to requests on behalf of clients. - The Network
Although originally intended to be much more, the network consists of a Windows Service that runs Voltron[6] capabilities.
The interaction between the components creates the game experience as experienced by the user.
HISTORY
or, “Everything that didn’t work”
SkyNet came to be in its present state by going through a number of evolutions. Unfortunately for us. SkyNet changed significantly through all of them.
During the initial few weeks of the class, we began attempting to meet some basic requirements of the client. We created a 3-dimensional view, some elementary components for transport of “messages” via the networking, and a basic model of the server. The ‘server’ aspect of the program was solely responsible for managing game elements and had no hand in networking or synchronizing itself with other servers. This is in great contradistinction with the modern server system.
After a few weeks the system condensed into a single prototype we named Sangria. Sangria was the first singular system demonstrated to the client (as opposed to various independent pieces).
Sangria, however, did not function as we had hoped. A number of subsystems in the project were rushed to completion, and, as a result, these subsystems were full of hacks and bad design. Some individuals attempted to rid Sangria of its former bugs, and the class moved into spring break.
Over spring break, a single student wrote an independent implementation of the project, codenamed “Ryan’s Code”. His program was capable of simulating a world, load-balancing it across servers, and loading pieces of it onto a client on demand. The class spent about a week looking at the two systems and determining which to use to continue the project.
At the same time, another student began yet another implementation of the project. His implementation was based on COM+ Transactions, and grew into the codebase Tequila. Transactions simplified a great deal of development.
However, the transition to this final codebase made obsolete a great deal of code. The Network system previously was responsible for managing synchronization and data flow between multiple servers. That behavior was folded into one server system based on transactions. The Network effectively ceased to exist beyond Voltron.
SERVER
or, “Ready to work!”
The fundamental problem that the server had to deal with was distribution of the game data. We intended to have many servers running simultaneously, each handling a separate aspect of the world. This means that when information about the world changes, all servers must correctly update their state to reflect the change.
The SkyNet server is effectively a distributed transaction framework. The server allows one to design rules that affect an object-oriented system, determine how those objects serialize to a relational database, then finally execute changes against the objects in transactions.
The technologies that we used to develop this framework are Enterprise Services and SQL Server. Enterprise Services handles the transactions against general DataSets, while SQL Server acts as the backing store for the information.
The game representation consist of entities, behaviors, and attributes. An entity is a single unit within the game, such as a tank or a soldier. An attribute is a property of an entity, such as the amount of ammunition, health, or speed. Behaviors define how entities interact with each other and generally rely on attributes to govern these interactions, changing them afterwards.
For example, two Soldier entities might have a Health attribute equal to 100 and AttackPower equal to 25. One soldier could execute its Attack behavior on the other soldier, dealing 25 points of damage to it, and dropping its health to 75.
Entities and Attributes in the game are described using XML. Only Behaviors are compiled into the game. Any of them can be injected into the system at runtime.
The system is sufficiently extensible that it could be used to implement any grid-based game. There exist a number of different scenarios showing implementations of different rules, including a “Warchess” implementation designed to mimic the game developed by the Spring 05 COMP 446 class[7].
NETWORK
or, “No witty quote”
The network aspect of the SkyNet server is actually intertwined with the Server Assembly. Conceptually, however, their roles are distinct.
The Network is responsible for keeping track of the servers present on the SkyNet grid. All servers on the SkyNet network maintain a table of every server on the network. When a server attempts to join the SkyNet grid, a transaction is executed against all servers’ tables to update them with the new, joining server.
If any transaction fails, the Network handles the failure by re-trying the transaction a few times. If the transaction fails a pre-determined number of times[8], the point of failure is determined (i.e., an individual computer or set of computers) and removed from the grid. If such a removal takes place, the SkyNet grid is effectively broken into two independent grids, which can diverge in gameplay.
The Network also consists of the Voltron-based network file system. This file system is designed to distribute information that many agents on the network would need. The primary user of this system is the Media Package Framework: media packages that are uploaded to the SkyNet network file system are distributed throughout the grid so that anyone who needs the information can receive it. See Voltron[9] documentation for more about the services that that file system provides.
Another aspect of the network is the security system. Although not developed in much depth, the security system restricts access to the game based on user account. At login time, users must enter a valid username and password to be given access to the system. Although not currently implemented, it would be possible to restrict access to the game further based on user name. For example, currently all users can inject new units into the game and otherwise affect the game in Administrator-like ways, but it would be possible to implement new Permissions in the existing security system to restrict Administration access to only a few accounts.
VIEW
or, “LOL VisUaLiZaTiOnZ!!!!!~oneone OMG ROFLCOPTER!!”[10]
The View system was designed to be highly independent of the model. We intended to be able to “plug in” many different implementations of the view to listen to information coming from the model. Different (planned) views included: text-based view for PDAs, sound, 3D, 2D, 2.5D (isometric).
Throughout the development of SkyNet, many different views were implemented (sometimes concurrently) and later discarded. That is partially attributed to the changing focuses of our project, but also attributed to the highly robust nature of the view architecture.
The SkyNet client is built with a Service-Oriented Architecture (SOA)[11]. What this means is that the providers and consumers of a particular resource (say, game information) are distinct and not aware of each other. The SOA architecture connects them together at runtime.
Effectively, this means that new View devices can be developed highly independently of the rest of the view system. Some of the view devices currently implemented include:
- A tablet pen interface, where one can draw selection shapes in the game world to select units
- A sound view, although this is currently not very polished
- A 3D display view, which supports changing camera angle
- A 2D overhead view, which is more lightweight
With the current architecture it would be trivial to extend the view to any conceivable implementation. For example, one could easily implement a component that sends an email to a player when his units are under attack (if he is away).
Another important aspect of the View system is Media Packages. Media Packages are zip files that include information about how an entity in the game should be displayed. They could include graphics, sounds, meshes, etc. They are automatically distributed across the server grid using the Network/Voltron file system.[12]
Finally, the view includes a simple AI framework.[13] Fundamentally, the move behavior supported by a unit only allows that unit to move one square at a time, with a cooldown inbetween moves. The View’s AI allows the player to specify a goal destination, and the AI will conduct each necessary individual move to get the entity to its destination. The AI framework determines the ideal path using an implementation of the A-Star algorithm.
User Model
The user model is the data system connecting the View to the Server. It provides abstractions necessary for any sort of system to interact and send commands to the server.
Two clients of this system include a (possible) full user AI and the existing view system.
[1] One person doesn’t need to understand all of these technologies, but collectively your group will. The technologies are very closely interweaved with SkyNet and people working on particular systems will need a strong working knowledge of the technologies on which SkyNet relies.
[2] Pastry was originally developed at Rice in Java. Microsoft took up the project and ported it to C#. Now, COMP410 uses their version in Voltron.
[3]
[4]
[5] Note that although we attempted to engineer this, it did not end up happening. See specifics of the server; currently all servers model information about all regions.
[6] As this is not a design document for Voltron, I will not go into detail describing what Voltron is. Just kidding; I know you’re lazy. Voltron is a distributed filesystem that allows information to be stored onto the network without concern for where it is or how it’s backed up. We use it to store any information that might be widely used across the server network, such as images used to display elements of the game.
[7] Warchess was a chess-like game played in realtime. It consisted of units identical to chess units except placed on varying shaped and sized maps, with resources and ability to create new units. It effectively was a RTS game with chess pieces. The best reference I can find is:
[8] As of the time of this document, each transaction would time out after 1 second, and the system would retry the transactions 5 times each.
[9]
[10]
[11] Please read more about SOAs here:
[12] See the “Network” section.
[13] This is to be distinguished from full AI, which coordinates a full set of units to conduct a strategy.