Saturday, December 12, 2009

Program Architecture

A program's architecture is very important. Like with a real house, it literally prevents the program from breakng down. If you don't make enough preparations (walls not solid enough), your program might not be able to have the features you want (a billard table). If you want to place a billard table in your house, you better make sure it can bear one.

A very common architecture in enterprise- and web-applications is the Multitier-Architecture. in this architecture, there are multiple tiers that communicate with each other and add abstractions. a very popular separation of tiers is the following (from bottom to top)
  • Data tier
    This tier is not much more than a database server, responsible for storing and retrieving data.
  • Logic tier
    The logic tier communicates with the data tier and processes the information. For example, it could sum up the prices of a shopping cart.
  • Presentation tier
    This is where the user comes into play. The presentation tier doesn't know the data tier directly, it only calls the logic tier to get structured information. It then transforms that information into something the user might like, like an HTML-Page.
Enterprise applications are - don't be offended - pretty dumb in my mind. Most of the time, all you do is retrieving data, apply some calculation, and pass it to the user. there's not the "art" in it that makes programming interesting - complex algorithms and data structures; the sort of thing you get your success moments from.
On the other hand, games are by definition complex. It's what makes the game fun - easy to scope, but deep in possibilities. Look at Settlers of Catan, you know what I mean.

So, this "primitive" multitier architecture is perfect for business applications, but not for a game like magic. I have, however, some architecture in mind:

All of these parts are fairly complicated:
  • The game state includes all of the cards with their abilities, the zones, turns and phases, the players and even a random number generator.
    The random number generator should make it possible have two games being absolutely identical, which allows for duplicating a game for network play, saving, replaying and so on. The generator also has to support the "Undo" i described.
  • The rules engine is the classic of a complicated thing. I don't think it's possible to fully separate this from the game state. For example you control a Glorious Anthemn. Is the +1/+1 bonus part of the game state or of the rules? However, other parts can clearly be separated: A player's starting life and hand size in Vanguard, or alternate winning conditions, and the ability to play the general in Elder Dragon Highlander
  • The payer abstraction in the next stage is different from the one in the game state. the state's player's purpose is to store his information, like life, cards and so on. In this stage, a player's purpose is to make decisions. The way of making a decision is of course different for the three types of players.
    • You yourself want to see the game state in a nice GUI.
    • The AI "only" needs to access the game state and rate its possibilities
    • A network player has his own GUI at his side of the connection, but what you see is only the decision he sends to you, which is enough because the game states are identical on both sides.
i hope you enjoyed that insight! bye!

1 comment:

Bruno Cardoso said...

This is a very interesting topic. I code web applications for living so I'm very familiar with the MVC (Model-View-Controller) arquitecture. Now, this doesn't mean that there is only three layers in the application. Usually this three layers may split into sublayers, specially the Model and Controller layers, view is usually just one. It's very common in the Model layer to have a Data Manager and a Data Access Objects sublayers for example.

Anyway... I already had some inner brainstorms about this subject.

Web application and standalone/gui based are a little diferent: In the web, your entry point is usually a Servlet (aka Controller) and it controls the flow between the logic, model and interface. In GUIs your entry point is the GUI itself, so the call to the controller has always to be from the GUI.

About your arquitecture. I understand it but not sure if it is the right representation of it.

Of course you will have an API that controls all the flow of the game (rules engine) and all actors (network, gui and ai) are going to interact with it to change the state of the game. The goal is to have no redundant code. I agree with you, I don't see how the rules engine can be separated from the game state, you should make them two distinct layers but they will always be very coupled with each other.

It's not easy to arquitecture a model for this kind of project, specially if you want to abstract it for other TCGs. Whatever way you define the layers, separation of responsabilities is very important.