Revised Design Report
TABLE OF CONTENTS
1.1 Purpose of the system
1.2 Design goals
2. Proposed software architecture
2.1 current software architecture
2.2 SUBSYSTEM DECOMPOSITION
184.108.40.206.1 SERVER MANAGER
2.3 BOUNDARY CONDITIONS
This document describes important aspects of the implementation of the Heroes of Might and Magic game.
1.1 Purpose of the system
Heroes of Might and Magic will be a turn-based strategy game that will be played over network. The proposed system permits two players to play the game at once. In this document we will describe how to implement functional requirements while adhering to non-functional requirements.
1.2 Design goals
Our system has 4 main goals that we will adhere to:
· Developing reusable components that are easy to modify and maintain by paying attention to low coupling- high cohesion principle. We strongly believe that, using well-known design patterns can help us to attain this goal.
· Developing efficient and reliable network components.
· Providing users with an easy-to-use graphical user interface.
· Developing a robust system that can handle errors such as network problems and invalid inputs and give meaningful feed-back to users.
Heroes of Might and Magic is a turn-based strategy game which can be played over network. The game should have a flexible design to allow the changes and extensions as much as possible, since changes will be needed to improve the game. Design patterns were used in the design of Heroes to achieve a flexible, maintainable system.
2. Proposed software architecture
The game will be played over the internet between two players at a time, so the Client/Server architecture is used. Client/Server architecture supports reusability as it makes each system component visible. The thin client model is used so the server maintains the game facilities while the client deals only with the graphical interface of the game.
2.1 current software architecture
The system of the Heroes of Might and Magic consists of 2 machines, one of which is the host that has one of the clients and the server, and other is the second client. The server and client in the host machine will communicate in the same way as if they were in distinct machines using TCP/IP protocol.
Diagram-1: System architecture
Server is the main component of the game which manages the entire game and leads the other two clients by updating clients’ user interface. On the other hand, clients are responsible only for taking user inputs and displaying the results of the computations of the server based on these inputs. When they get a user input, they send a request to the server. The server processes the request, creates the corresponding response to that request and sends the corresponding response to the clients via the network. Note that, both clients are connected to the server via TCP/IP protocol.
Heroes of Might and Magic has an event based control flow in clients and the server. The server is initiated by the client that wants to be the host. So the host machine runs two threads, namely Client and Server. When a user creates a new game, the server part of the system is created without waiting for the second client. Machine of the other client has only one thread, Client.
2.2 SUBSYSTEM DECOMPOSITION
In the following sections system is portioned into subcomponents. Basically, at the highest level client-server structural architectural pattern is used. Moreover, in both client and server, Observable pattern is used so as to reduce coupling.
Diagram-2: System Decomposition
This package contains the AbstractClient & ClientProxy which are elements of the Client component, AbstractServer & ServerProxy with ConnectionToClient which are elements of the Server component, Request & Response which are elements of the Protocol component. ClientProxy inherits from AbstractClient and ServerProxy inherits from AbstractServer object. ConnectionToClient holds the connections to the clients.
The ClientProxy and the ServerProxy are the most crucial elements of the network since they are the only way to send messages to a Server or a Client. ClientProxy and the ServerProxy are the communication interface between the clients and the server. Both of ClientProxy and ServerProxy use the Response and Request objects to communicate so ServerProxy is the only gate through which Responses are sent to the Clients and ClientProxy is the only gate through which Requests are sent from the clients to the server.
Response\Request objects both contain a list of arguments. The first of these arguments is the type argument that is used to determine who the receiver is. This argument is checked by ServerManager\ClientManager to determine the address of the receiver. Once a response or a request is delivered to the destination, the receiver partitions the argument list in a type specific manner, depending on what is expected in the content of the receive Response\Request.
When a client or a server receives a message from the other side, the message is received by the Proxy of the receiver unit. Then usage of Observable Pattern directly sends this message to the ServerManager [if the receiver is ServerProxy] or the ClientManager [if the receiver is ClientProxy] and the messages are handled there.
Heroes of Might and Magic has a thin-client/fat-server architecture, therefore server is the main part of the game. All the data of the game is involved in the server, all the computations related to the specific game actions are processed and all the user-game interactions are handled in the server. The clients only deal with the graphical user interface part of the game and are commanded by the server via ‘Response’ messages which are sent to the clients over the TCP/IP protocol.
Below is the class level static decomposition of the server side. Note that, to maintain simplicity some of the lowest level components are left to be elaborated in the following sections.
Diagram-3: Server Side class diagram
This package contains the ServerManager that controls communication within server and perform all computations [with GameManager] related to the game.
220.127.116.11.1 SERVER MANAGER
Server Manager is the brain of server side in the sense that it organizes communication within the server. It is a bridge between GameManager, ServerProxy and SaveLoadManager.
There are two types of messages that are sent over the TCP/IP protocol from server to clients or from clients to server. Request massages are sent from clients to the server and requests some kind of response from the server for a user generated event in the client side. The server handles the Request by making the corresponding computation and change of data in the server side and by constructing the corresponding Response to update the UI of the clients. The other message, Response is a server generated message that is transmitted from the server to clients and that handles UI changes in the clients.
Diagram-4: Activity diagram of system-wide communication process
The Observable pattern best suits for the relation between ServerManager, ServerProxy, SaveLoadManager and GameManager. When the ServerProxy gets a Request from the ClientProxy, it notifies the ServerManager so that the request is checked whether it is a save game request, a load game request or any other kind of request. If the incoming request is a save or load request, then the message is transmitted to be processed by SaveLoadManager. All the other messages except these two are sent to be processed by the GameManager.
When any of the GameManager or the SaveLoadManager constructs a Response, the ServerManager is notified and the response to send to the ServerProxy.
As the name implies, this package is responsible for save\load functions and contains the SaveLoadManager, which saves or loads a game. When SaveLoadManager is faced with a load request, it loads the specified game and sends the data of the previously saved game to the GameManager. Similarly, when SaveLoadManager is faced with a save request, it saves the current game to the host machine.
This package contains game elements with the manager, namely the GameManager, that controls all these game elements..
GameManager is the most functional part of not only the server side, but the whole system. It is the part of the server side which holds almost all the data of the game and players, performs all the computations.
The player is the representation of the user of the game. The player object has heroes (at least 2, at most 4 for now) and a castle (the city of the selected race). Since the maximum number of heroes is predefined by the GameManager, it is better to use an array to hold the heroes. The GameManager process requests of a user via using his/her corresponding Player object.
The hero is the most crucial game element. The player can navigate the map and attend battle only via the heroes. The path that is determined after the user input is taken kept as an attribute of the hero. Since the length of the path varies we decided to use an ArrayList to hold the heroes potential path. Every hero has a spell book that is composed of a limited number of spells, which that hero can cast on the troops of his army or the troops of the enemy. As a result, the spells of a hero are kept in an array.
A magic is a spell that can be casted in the battles on either friend troops or enemy troops.
Diagram-5: Magic hierarchy
A castle is the representation of the city of a race which has different buildings in it. The building list of a castle is kept in a constant array, since the number and type of the buildings are defined for each castle. Each race has different buildings allowing different types of units to be recruited. One of the most important properties of the castle is the defensive walls, which are used for the protection of the city in case of an invasion. The number of the castle walls are determined as four, so a constant array is used for them.
Buildings are used to construct different types of game elements such as magic, unit, other buildings and hero. As a result there exists a building hierarchy shown below. In order to construct some buildings there is a prerequisite list of other buildings which is a constant static array.
Army represents a collection of different troops, which are assumed to be composed of the same units. Every hero has an army and every army has at least one -at most 10- troop. In a battle, only one of the troops of the army can be active at a time.
Since the maximum number of troops that an army can possess is fixed, the troops are hold in an array.
A troop consists of units that are of the same type. The number of units that a troop can possess is not restricted so an ArrayList is chosen to hold the units of a troop, since an ArrayList would do well in such a dynamic structure. Every troop can be exposed to a spell in a battle, and the spell casted on a troop is held in ‘castedMagic’ attribute.
Units are the elements that form troops. Every unit has different properties [such as attack rate, health etc.] that depend on the race of the unit. As a result, one can only recruit a specific unit from one of four different types of castle in our game. There is also a hierarchy of the units according to their properties like RangedFighter and CloseFighter, which is given in the class hierarchy below. Unit is the last element that is used to evaluate the requests of the users in many different situations.
This class has only one static method called addUnit() that at first [just after the game is created] reads the properties of the whole units and then by using the specified static method creates units according to the information [this information is about the properties of each unit] it has read from the file.
HeroesMap is the base that is composed of mapitems. Double array [map] is used as the structure of the map. Also another double array [upperLayer] is used for keeping track of the elements that has special responsibilities on the map( Gold,Hero etc). This class is responsible for everything related with the map of the game.
This is the class through which HeroesMap can access the MapItem class. It basically returns the MapItem object of a specified type. So HeroesMap knows the MapItems and MapItems knows the MapItem class.
Involves the main components of the map. It has the information about each tile, such as friction, id etc.
This is the class that the HeroesMap uses to find the path from a location to another location on the map.
As can be see from system decomposition diagram, the client side is a thin one and contains just two packages, one of which is responsible for graphical user interface and the other is responsible for communication with server. Client side do not have any computational functionality, it’s just an interface.
Note that in the following sections, when we explain any GUI component, we will also give the lists of requests and responses that can be created and processed during the time interval in which the control of the flow is under that specific component. We believe that this will provide consistency and enable the reader to step-by-step identify communication protocol of the system.
Below is the subsystem decomposition of the client side. Note that contents of PreGameFrame and InGameFrame are eloborated later.
Diagram-9: Client subsystem decomposition
Basically this package’s components are responsible for taking input from the user, creating corresponding requests to be sent to server and updating graphical interface components according to the responses taken from server. Note that, the default screen is MainGameFrame, which can include one of PreGameFrame or InGameFrame at a given time. As discussed in the Analysis Report, while playing the game all functions other then navigating the map will open an upper frame that covers the MainGameFrame and locks its functions until the player exits that specific frame. For example, when the user enters the castle, the castle will show up it self and will be the only active screen until it is exited. All control flow is under control of ClientManager, which is the brain of client side.
This class is the brain of client side and stands as a bridge between GUI components and ClientProxy. Note that ClientManager observes all the lowest level GUI components. If a request is created in any of the GUI component's listener, ClientManager is notified immediately and takes required action. Note that ClientManager is made singleton so that GUI components can reach it and get some data for painting purposes.
To sum up, from the start to the termination of the execution, ClientManager is responsible from the management of communication transfer within the client and global control flow in client side such as transitions among windows, hence plays a similar role with ServerManager of server side. It has 5 methods;
· update: Interprets a request object created by any of the GUI components and determines whether the request is need to be sent or to be handled by client. If the request is to be send to be processed in client side then processes the request, otherwise send it to server.
· sendRequestToServer: Takes a request created by any of the GUI components and transfers it to Proxy to send to server.
· processResponse: Processes the response send from server and updates necessary views. Note that not all responses are directly transferred to GUI components. because sometimes the responses may require system-wide process, such as closing the connection and terminating the game, which is also job of this method.
· initServer: Initializes the server.
This is the top level container for default GUI components at any time. It initially contains the PreGameFrame component and after a successful game creation or join, it changes its content into InGameFrame.
This is the high level container for all low level GUI components that perform pre-game functions such as creating a new game, joining a game, selecting local and global elements and setting game options. Below is the subcomponents of PreGameFrame. Note that although not shown here, all GUI components include an Observable object so as to be observed by client manager.
Diagram-10: PreGameFrame Subcomponents
This is the high level container for default in-game GUI components namely the NavigationScreen and InfoBar. Below is the subcomponents of PreGameFrame.
Diagram-11: InGameFrame Subcomponents
This package contains only SoundManager class, which is responsible for sound effects of the game. Note that, as we will add more utilities in our game this package will contain more utility classes.
2.3 BOUNDARY CONDITIONS
§ When the network connection between the clients and the server during the game is lost, the client of the other machine is informed that the other user is disconnected and then asked if s/he wants to save the game.
§ Connection is initialized after the establishment of the server. When a user wants to create a game or load a game, the first thing to do is to establish the server and then to establish the connection between the host client and the server. And then the system waits for the other client to connect to the game.
§ Game is initialized after the host client is connected to the server.
§ When the host saves a game, the game is saved in his machine and the [non-host] client will be informed of this action.
§ Player loads a saved game, as the host. To be able to load a game the user has to enter his/her nickname and password, so that the personal data of the players of the previous game will match the right players in continuing game.
In our system, we tried to apply Object-oriented approach and have low coupling and high cohesion . In order to achieve this goal, we used suitable design patterns since the use of design patterns are crucial and since their successes have been proved in O.O.Aproach. We used “Observer Pattern” in both the client and the server part to separate the use of components and to lower the coupling. The “Delegation Pattern” is used especially in the server part during the process of transmitting the client’s requests and servers responses. The decomposition of the system is made logically and the aim is to achieve classes, which are highly, logically related. As a result, in both the ServerManager and the Client Manager part, the low level system components are unaware of the fact that upper layer components use them. Also the client and the server, with all of their high level and low level components, are only dealing with the use of request and response messages. So even if the server or the client side is redesigned while remaining respectfull to the request-response-message comprimise then the system will still be consistent. This implies the low coupling and the high cohesion of the whole server-client architecture. In this way, we would be also able to handle the complexity of our system.
Making our game as maintainable as it could be was one of the most crucial motives of our design process, and the use of the mentioned patterns helped to sustain this motive. The future expansions and the maintenance of the project will be quite easy since the general design decisions about the game is taken while obeying the constraints of this non-functional requirement.