15. May 2009 18:34
I thought I would share one of the core concepts I implemented in Perenthia that has been working quite well. Early on in development I decided to create templates and instances in regards to game objects. A template would define common, unchangable properties of an object whereas an instance would be the opposite. An example would be a Sword; there is a template for a Sword that defines its damage value, price, required skill level, etc.
I have one table that stores all the objects for the game. Since objects being actively used are loaded into memory and the table is indexed for those queries it runs pretty fast. Since I store all of the objects into one table I make heavy use of the XML data type in SQL 2005 to provide a bunch of XML Serialized Key/Value pairs that define the properties of an object. On the code side of things a dictionary provides the underlying data store for properties of the object. For instance, the Sword example above has a Power property that is used in combination with the wielder's skill in swords to determine damage. The Power property just fetches the Power value from the properties dictionary using the property name. This works a lot like the dependency properties, just my collection serializes to XML for database storage. When an object is loaded from the database the xml from the template is retrieved and added to the object, then the object instance xml is dropped into the object, overriding any template properties of the same name.
This property dictionary also allows me to store whether or not the property belongs to a template or instance. If the property belongs to a template then when the instance is serialized and saved to the database those template properties are excluded. Likewise saving a template does not serialize and save the instance properties. This structure allows for a lot of flexibility with my objects and has been working out quite well. I probably would not have used serialization and xml the way I am if I was doing a typical call to the database qith each request as the extra overhead would not have been worth the effort. However, since my objects are loaded into memory and my saves are background threaded I experience a lot of benefit of an easy to use object.
I shuld note that players character data is stored in a separate table from the core objects table. It follows the same design buy allows me to migrate and change data in the objects table without overwriting player data, since players are essentially the same as mobiles.
3. July 2007 10:38
While building the persistent browser based game Perenthia I have been putting together a PBBG Engine that I am going to use to build additional games. Among those additional games will be Aelerion, which will be a space adventure game in which I plan to use Silverlight as the front end user interface.
The Knights of the Realm 2 uses a mixure of some of the code I wrote for the PBBG Engine and some of the code I migrated from the first version of the game. I also chose to try something new with Knights of the Realm in that I stored XML serialized objects in the database using my XQuery class. I decided to try this method to see what kind of impact it would have on game play performance and maintainability. Since Knights of the Realm is not a real time game and executes tournaments in the early hours of the morning I figured this would be a safer test.
Since writing Knights of the Realm 2 I decided not to use the XML serialiazation for my PBBG Engine because I want the engine to be able to support real time game play and serialization is just too slow. I did some perf testing with a database, xml serialization and flat text files and found that flat text files were the fastest when saving information, xml serlization was the slowest and database fell in the middle. When loading information back into objects the database was the fatest because I didn't have to do a lot of conversions from strings to integers like I did with the flat text files. Xml serialization came in last in loading as well and not just in miliseconds but was a good 3-4 seconds behind the database and flat files in both loading and saving. However, using an XmlReader and XmlWriter to read and write the Xml values into an Xml data type column in the database turned out to be faster than serialization but still slower than straight database access because of the need to convert Xml node value strings to integers.
My PBBG Engine will utilize a mixure of regular data type columns and xml columns in the database. The reasoning is that static things such as player name, race and gender will be static columns but the player table will also feature and xml data type column for storing custom properties. A base player object will contain a key/value collection where custom properties can be stored and that collection will use the XmlReader and XmlWriter to save the key/value pairs in the xml data type column.
I also plan on making use of the application cache in ASP.NET for some of the common objects such as rooms so that I am not making thousands of database calls everytime a player moves around in the world. Some of my initial tests have worked out quite well using a lightweight set of objects that represent rooms or tiles on a map. These objects contain just enough information to determine whether or not a player can move into the room and their coordinates in the overall map.