Client/Server Communication Data Formats

by Cameron Albert 5. January 2009 23:41

While developing Perenthia I tried several different communication formats from sending JSON serialized objects back and forth to sending byte arrays containing mostly integers indicating what should be loaded and displayed, what commands to execute etc. What I eventually settled on was a bit of a hybrid. I've created a simple set of "tags" that can be sent to and from the server. The tags are nothing more than pipe delimited strings contained within curly braces and there are a limited number of tags that provide simplicity yet flexibility with the data that is transmitted. The tags are represented in C# by tag objects allow me to create them, query them, etc.

A simple command tag for the SAY command might look like this: {CMD|SAY|"Hello World!"}

I wrote a custom tag writer class that parses the tag objects into strings to be sent to the client and likewise a tag reader that reads the strings sent from the client and parses them into tag objects.

The client can only send commands to the server but the server sends commands, messages and objects to the client. The commands are all the same, the CMD text then the one word name of the command and then a list of arguments, messages are system, chat and tell messages but objects have a bit more information. For instance, an object tag encompasses several different types starting with a base ACTOR, a PLACE, a PLAYER and a PROP or property. The ACTOR, PLACE and PLAYER tags all define the ID, Name and Descriptions of the objects, with some additional data per type but the PROP tag defines the object id of its owner and a name/value pair. An example of a PLAYER tag with properties for x, y and z coordinates might be:

{OBJ|PLAYER|3756|"Aldarian"|"My character description..."}

{OBJ|PROP|3756|"X"|45}

{OBJ|PROP|3756|"Y"|26}

{OBJ|PROP|3756|"Z"|0}

The client can find and parse the player tag and then find the properties associated with that player instance. The way the server works now it will send the full player tag once logged in and a character is selected and then from then on out it just sends property updates.

Using this type of tag structure allows quite a bit of flexibility for the client. I could choose to write a very simple client that only displays MSG tags, much like a MUD, I could write a simple 2D interface client and display and move sprites about the map using the properties from the server, etc. Once Perenthia is up and running I will probably post some information on the tags and how to talk with the server should someone feel the need to write their own client. :)

Data Format for Socket Server Packets

by Cameron Albert 2. March 2008 22:35

For my PBBG Engine I started off programming it all for the web and AJAX. Recently I added support for sockets by porting over my socket server code I wrote for a Flash server and incorporating the code into the PBBG Engine. In a previous post about my PBBG Engine Architecture I outlined my plans for how the socket and web pieces would work together. I spent some time today refining my command pipeline and server protocol for the socket side of the engine and will probably utilize that on the web side as well.

I decided on the following format for the data packets that will go to and from the server and client. Since it is just bytes going back and forth and I wanted to keep the data streams as small as possible I decided to abandon the string based command protocol and use this instead:

The first 2 bytes of the packet will be used to store an Int16 (short) value that indicates the command to execute. I have an event being raised from the game engine that allows the implementing libraries to set the game commands. This was a Dictionary<string, ICommand> but I am going to change it to a Dictionary<short, ICommand>. That will save me some bytes back and forth without passing the command names. I can have the clientsend the proper short value for the command typed into the console or just have the links and events in the client supply the proper short value.

The next 4 bytes will be the integer length value of the message. This will allow me to know when this message ends and the next one begins.

All the bytes following up to the length value will be the actual message sent to the client or sent to the server.

The server is already validating commands, I will just need to modify to validate these bytes and watch for buffer over runs. I still need to work out validating that a logged in user is sending the information but I will work out something, maybe have the client send the encrypted authentication key to the server after a connection is opened but before commands can be processed. 

 

PBBG Engine Architecture

by Cameron Albert 26. February 2008 22:37

Thought I would go ahead and post a little about the architecture I have set up for my PBBG engine so far. Basically, the engine is a library that other projects can reference to make building PBBGs a little easier. All of the logic for handling incoming requests and parsing commands is contained within the engine. My PBBG engine is kind of like a MUD driver, it requires a MUDLib to define objects, persist data, etc. Some interfaces are defined within the engine library to make it extensible while it also contains base class implementations of those interfaces to make building on top of working logic possible. When the engine starts up it raises a set of events and when it processes commands it also raises events to allow the implementing application to control loading of commands, determining the server implementation and creating command instances.

 

Not the best diagram in the world but kind of gives you the idea of how it works. The column down the middle are the interfaces defined by then engine, which also define base classes, except for the CommandManager which is just a static class for processing commands.

In addition to the classes here are the Verb abstract class, the ICommand interface and the Command<Verb> instance for creating commands from Verbs. The CommandManager raises an event when it finds the command text that allows an external library to set the ICommand instance that will execute the current command. When the engine starts up though it raises an event that will allow the implementation library to set all the commands into memory rather than creating a new instance with each command.

The IServer interface defines an IConnectionManager property where connections into the server are managed, either socket or http.

On the WEB side, which is actually a namespace ".Web"; the "Server" instance writes out a JavaScript reference to an embedded js file containing the script required to submit commands to the engine using AJAX. A separate RequestHandler class actually parses the input from the AJAX call and then attempts to locate or create an IConnection instance on the Server's IConnectionManager instance. The Server in this namespace actually sends the command to the CommandManager.

On the NET side, which is actually a namespace ".Net"; the "Server" instance actually contains the socket used to listen for incoming connections on a port specified during startup. From there the individual IConnection instances contained in the IConnectionManager instance handle processing the input and formatting it into a command. The IConnection instance contains the connected socket and will send the command to the CommandManager.

Both IConnection instances in both namespaces allow messages to be sent to the client along with custom data such as stats, gold, map data, etc. The difference between the two is that the WEB instance sends all of this back as JSON in the HTTP response and the NET instance sends the messages down the socket as they are added to the IConnection instance and then sends the additional data once the command completes execution.

That is all I have completed at this point on the engine side, it processes commands from the web and the implementation library sitting on top of it handles the commands and persists the data. There is plenty of work on the implementation library side still yet to be completed.

Perenthia Update

by Cameron Albert 24. February 2008 00:23

I haven't decided yet but am considering using Silverlight 2.0 with the next release of Perenthia. I've completed a good portion of my PBBG engine that will drive Perenthia but want to be able to take advantage of some the features of Silverlight 2.0 to provide better user experience. One of the features that really interests me is the socket support for 2.0. Once I get the 2.0 beta 1 bits I am going to start playing around with running my PBBG engine on a socket server application I wrote for Flash. If all goes well I should be able to provide some better multiplayer features in Perenthia such as real time chat and possibly player vs player combat.

Perenthia will still primarily be a text-based game but Silverlight could allow me to bridge the gap between web and client software. 

Processing Commands

by Cameron Albert 13. February 2008 23:58

I might have mentioned it before but my PBBG engine is basically a commands processor. In other words it accepts commands from the client, processes the information on the server and sends the response back to the clients as JSON. Not really different from a normal web request except it is specific to my PBBG engine and you don't request documents from the server you are telling the server you want your Character to "do" something.

My PBBG engine is essentially just the command processor and the classes surrounding processing commands. I have abstracted it completely from the data source. There are no data providers or data connections at all in the engine. Instead, if it needs to get data it raises events that a deriving library can handle and pass back the required data in the form of simple interfaces. Some assumptions I did make such as ID values defined in interfaces are int values rather than object since I don't design databases with primary keys other than int. :)

One of the things I also did for the CommandManager was to created an abstract Verb class that I can derive from to create command verbs such as move, say, attack, etc. These command verbs can be defined in the deriving library and set in the CommandManager when the game starts up. Another class to assist with commands was a generic Command<T> class where T has to be a derived Verb value. So I can create Command<Move>() and the call an Execute method on the class which in turn creates the Verb instance and executes the code in the Verb class.

This has been working pretty well so far and since the CommandManager raises an event each time if processes a command I can have any number of derived libraries executing their own commands. 

Tags: ,

Game Development | General | Knights of the Realm | Perenthia PBBG

Wilderness Adventuring

by Cameron Albert 8. February 2008 21:31

Perenthia currently provides "wilderness" areas where monsters roam around waiting to attack players who wander beyond the safety of the towns. I had originally wanted the wilderness to auto generate instead of how it works now where all the wilderness "tiles" are stored in the database. This caused over 150,000 records to have to be entered into the table and really limits expanding the word since I have to basically draw all the tiles.

For the Perenthia Beta 2 I worked out a "Regions" table to store a rectangle x,y,z value. The Regions table also stores the min and max levels required to venture into the region. Towns located within regions also carry a safe indicator so that monsters will not auto generate. Using this concept I only have to create the towns or places of importance and can let the "wilderness" be auto generated. 

The auto generated wilderness is infinite in that each wilderness place visited is created and stored on the player record. Wilderness is also exclusive to the player so that monsters generated will be available only to the adventurer. A lot of games have done this with dungeon instances and I thought it was a good idea to implement in Perenthia. There will be ways to interact with others and I still have some work to do to handle group play but wilderness is intended for solo players. Now, given that wilderness is infinite I don't want players getting lost so, the last non-wilderness place they visit will be stored on their player record and if they log out and log back in they will be reset to the previous non-wilderness place. It's kind of a fast way to cheat your way back to town if you get into trouble but I am OK with that. I would rather players leap back to town before their character dies than wander aimlessly around thousands of tiles from civilization. I want the wilderness adventuring to be a fun way to earn gold, not a potential for grief.

Quests may require adventuring through the wilderness to find hidden places so logging out when you are in trouble will cause your quest to take even longer. I think this will be a good trade off because quests will offer greater rewards than adventuring and should require a higher level of mastery. 

Perenthia UI

by Cameron Albert 1. February 2008 21:27

Spent some time today working on the UI for Perenthia. For now it will remain AJAX based but in the future I will probably add a Silverlight front end as well. I will post some screenshots of it soon, I want to get the layout complete first.

I also spent some time working through my data model for quests. I still need to do some work but I think it will be flexible enough to allow for adding all manner of quests and adventures. 

Tags: ,

Game Development | Perenthia PBBG

Admin Tools

by Cameron Albert 31. January 2008 00:22

I spent some time working on admin tools tonight for Perenthia. All the tools I am building will be web based rather than a mix of windows and web, which is what  have for the current beta 1 version of Perenthia. The current version has some web based admin stuff for content and items but the main beast is a windows application for drawing out the maps and terrain. I decided to rebuild this into a web based component so I can admin Perenthia from anywhere. 

The tools I have so far are:

  • Place/Map Editor - Add/edit rooms, exits
  • Connection Viewer - View active connected players
  • Online/Offline Toggle - To shutoff access to the game engine for maintenance, etc.
  • Item Template Editor - To add item templates, from which items are generated or created
  • Log Viewer - View error, chat, etc. logs
  • Content Editor - For news, pages, etc.

Tools I plan to add as I go:

  • NPC Editor - To add/edit NPCs
  • Quest Editor - Add quests, set key NPCs, set rewards, etc. 

Tags: ,

Game Development | Perenthia PBBG

Place Manager

by Cameron Albert 30. January 2008 17:19

In my previous post Memory Management I was talking about storing character and room data in server memory.

For the Character memory management I basically just use a DateTime value that gets updated each time a request is made by the connected player. If the DateTime exceeds a certain limit such as 20 minutes then the character data is saved and removed from memory. If the player just has a long pause between requests their character data will be reloaded if they make another request after the cleanup.

For the Room or Place data I've though about doing the same thing, just store a DateTime value and update it whenever a player performs an action in the room. I am not sure this is the best approach since the only commands that reference the Place object are movement, looking, some inventory and buying commands. Other actions such as casting spells, viewing stats, private chat, etc. do not reference the Place object. Of course, I guess if you are not accessing the Place object no need to have it in memory but once a player attempts to move again I would need to reload the Place. I might just maintain a list in the Place object of all the players currently located there and only remove the object once those references have been removed. I'll try a few things and record what I find.

Tags: , ,

Game Development | Perenthia PBBG

Memory Management

by Cameron Albert 29. January 2008 17:59

For Perenthia I am planning on utilizing server memory as much as possible without crippling the web server. To do that I am going to be maintaining player data and room data in memory for fast access and quicker responses from the interface.

The basic idea is that players login, choose a character and begin playing. This character information will be loaded into memory and persisted to the database when the data is changed, such as when commands are executed. As players move around the rooms they enter will also be persisted into memory to make loading and re-loading rooms faster.

The trick will be effective management of these resources. Character data will be removed after inactivity but I haven't figured out a good scheme for removal of the room data. Hope to have that working before too long though.

Anyway, that is the plan, we'll see how it works out. :) 

Tags: , ,

Game Development | Perenthia PBBG

Powered by BlogEngine.NET 1.5.0.7
Modified Theme by Mads Kristensen

About the Author

CameronAlbert.com I am Senior Software Development Consultant specializing in Silverlight, WPF and the Microsoft .NET Framework. 

I have released an iPhone game called the Adventures of Puppyman that was built using ExEn and am currently working on a WP7 and iPhone version of Perenthia soon to be released.

View Cameron Albert's profile on LinkedIn
See how we're connected

Follow cameronalbert on Twitter

 

Recommended Books

Silverlight 4 Business Application Development - Beginner's Guide:

http://www.packtpub.com/microsoft-silverlight-4-business-application-development-beginners-guide/book

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide