Monday, August 20, 2007

Data structure

Thinking how your data structure (entities) will be built is always something you must do carefully. Because if you did a mistake or forgot a "use case", it will pop into your face when you have already half the application coded. That's about when your code start to get messy. I have seen (and done) enough projects that suffered from this.

Here's what I currently have for my MMORPG project. It's not finished but this currently allow me to have a world where I can walk and chat.

  • Players
    • Characters
      • Inventory
  • Props
    • Props families
      • Family Properties
    • Props types
    • Properties
  • Zones
    • Tiles
  • Events
    • Zone events
    • Character events
  • Chat
    • Zone chat
    • Character chat

Players - Characters


Simple. I separated those two so if I ever want to allow multiple characters on the same account, I can. This won't be part of the game at first since it's not critical. Already some less work here!


Props


Any object in the game is a prop. Buildings, weapons, chests, clothes. A prop only have a "prop type", name, description, properties and an owner.

The prop family is used to defined properties. Prop types are used to defined specific members of a family. So if I want to add a chest to the game, I'll first create a "Container" family. All containers have the same properties (space, locked, key, ...) with default values. Then, I'll create a prop type named "Chest" (I could then create another type named "Big Chest" or "Locker"). After, I just have to create an instance of a chest and set its properties to the value I want.

So once I've created a "Building" family, I can create any building without bothering to remember which properties I need to assign. If I need a new property for my buildings, I'll just add it to the family.


Inventory


The current form of inventory is quite simple. It's just a link between a character and a prop. I already did some preparation to allow stacking but since it's not critical, I won't spend energy on this for now. I don't need this to release a first version.


Zones

A zone is a part of the world and have a name, description, width, height and a default "type of tile" (grass, dirt, water). Each zones are made of tiles (a 15x15 zone would have 225 tiles). Tiles allow to set different kind of graphics to the map. With this, I can draw a road or create a lake in the middle of a zone.

For "collision", I use what I called "elevation" (it was called "level" at first but it was too confusing with the possible notion of character level). A character can walk on any tile with the same elevation as his. So a character currently on elevation 0 wouldn't be able to walk on water which have an elevation of -1 or a building which have an elevation of 1. By the way, there won't be any collision detection between PC, NPC.

There won't be any jumping or climbing. Creating a feeling of 3D would be nice but would be a lot more work. However, if I ever want to add those, the system is ready to receive it.

My current system allow me to have only 1 prop per tile in a zone. This limitation prevent me from being able to stack props on top of each other (say I want to put a plate on a table, the plate would have to be part of the table instead of being a prop on it's own). I thought about this for some time then decided that I would live with it. It's not critical and the current system is easy enough to understand and maintain.


Events


When a character or prop enter or leave a zone or when it moves, an event is added to the zone. This event tells the interface what it must show, how and where. If a character fight a monster and kills it, an event will be added to the zone telling the interface to show a graphic of the monster dead. All characters in a zone are receiving the events from it. This is what allow you to see that someone is moving from one side of the zone to the other.

Character events are received only by the concerned character. Say a character open a chest. The server receive the command, check if the chest can be opened and if so, send the content of the chest back to the character with a character event. Only the character opening the chest is receiving it. This could be useful to return a change of HP and stuff like this.


Chat


Well, chat is chat. It was actually quite simple to do. Each zone have it's own chat room and each character can receive private messages. Private messages can be /tell or can be just system message like "You can't open this chest, you don't have the key".

Since there was no need to reinvent the wheel here, I based my work on the example shown here.


Other data structure not yet implemented

Since this is a work in progress, there's still some pieces missing. So far, I'm able to move around and chat. While I know quite some players that are actually just doing this in MMORPG, I feel there's a bit more to do ;-)

Those missing pieces will be posted later when I have actually done some work on them.

0 Comments: