Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    7
  • comments
    7
  • views
    3829

About this blog

Development journal of Project AV, an experimental game using the latest .Net technology.

Entries in this blog

 

Serialization code

Figured it might be interesting to post my serialization related code with some explainations.

Documentation/assertions/error checking are removed and replaced with comments if necessary for this snipplet.

First the attribute which helps to identify which field to serialize and what name to serialize as.

public sealed class SerializeAsAttribute : Attribute {
public string NameToUse {
get { return name_; }
}

public SerializeAsAttribute(string name) {
name_ = name;
}

private readonly string name_;
}



Next up, the helper

public sealed class SerializationHelper {
internal struct MarkedField {
internal FieldInfo field_;
internal SerializeAsAttribute attribute_; // stored so that I don't have to do another runtime query on field.
}

private static MarkedField[] GetSerializableFields(ISerializable o) {
List list = new List();

Type t = o.GetType();
FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

foreach (FieldInfo field in fields) {
object[] attributes = field.GetCustomAttributes(typeof(SerializeAsAttribute), false);
if (attributes != null && attributes.Length > 0) {
MarkedField marked = new MarkedField();
marked.field_ = field;
marked.attribute_ = attributes[0] as SerializeAsAttribute;

list.Add(marked);
}
}

return list.ToArray();
}

public static void Serialize(SerializationInfo info, ISerializable o) {
MarkedField[] fields = GetSerializableFields(o);

foreach (MarkedField field in fields) {
info.AddValue(field.attribute_.NameToUse, field.field_.GetValue(o));
}
}

public static void Deserialize(SerializationInfo info, ISerializable o) {
MarkedField[] fields = GetSerializableFields(o);

foreach (MarkedField field in fields) {
field.field_.SetValue(o,
info.GetValue(field.attribute_.NameToUse, field.field_.FieldType));
}
}
}



And a sample usage

[Serializable]
public sealed class TestObject : ISerializable {
#region ISerializable Members

public TestObject(SerializationInfo info, StreamingContext context) {
SerializationHelper.Deserialize(info, this);
}

public void GetObjectData(SerializationInfo info, StreamingContext context) {
SerializationHelper.Serialize(info, this);
}

#endregion

[SerializeAs("Name")]
public string Name;

[SerializeAs("Number")]
public int Number;

[SerializeAs("RealNumber")]
public float RealNumber;
}



Now, probably the most interesting point to take note is that, i can set the values of private fields via runtime reflection. Bug/loophole, or feature? I'll leave that for the reader to decide.

PS. Reflection rocks!

dot

dot

 

Serialization

Since the core application might be abstracted from the presentation layers, most core game objects would have to be serializable to and from a stream. This implies marking an object with SerializableAttribute at the least, so that the member data can be properly serialized. However, this default serialization would mark each piece of data as its variable name, and the variable name could be less than desirable at times. Of course, I could always rename the variable name, but there are times where I probably cannot use my preferred name.

I then search around in the framework to see if there's any serialization attribute where I can actually specify the name I want the variable to be serialized as. Surprisely I found none, except for xml serialization. Those attributes can't be carried over to soap nor binary serialization, so I had to forgo those.

Not finding such an attribute, I decided to create my own, as well as helpers to serialize all marked variables in a class. Now, I would have to inherit from ISerializable, and implement both the constructor and GetObjectData methods to make a class serializable.

I'll explain the reasoning for custom names in my next post...

dot

dot

 

Logging

Logging is another essential tool of every developer. Logging provides the developer with logs of the application flow and state, which are essential information used in solving bugs.

One can argue that a debugger is more powerful and useful than logging, and bugs should never make it to deployment. The latter statement is too idealistic, since not all input to the application can be controlled perfectly, and unexpected input or steps might cause unexpected application state. Logging can help us track the steps the users take, allowing us to (hopefully) reproduce the bug, and exterminate it. A program log is also a more friendly way for users to report bug, as compared to asking the user to 'try to remember what they did before the bug occur'.

I could create my own logging utility, but I am not so confident that I can invent a better wheel. Instead, I will write a small simple abstraction logging layer over an existing 3rd party logging utility. Why another layer of indirection? Quite simply to decouple the 3rd party logging utility from the application, in the event that I wish to change to another 3rd party logging utility.

I searched around, and between the Microsoft Building Block's Logging Framework and log4net, log4net seems more 'interesting'.

Granted though, log4net is probably overkilled, when a simple file logging class could do...

dot

dot

 

Quick Process Description, and Documentation

Probably a quick description of the development process.

I am using Visual Studio 2005 as my development environment and C# as my primary development language, on a Windows XP Pro with IIS 5.1, .Net Framework 2.0 and WinFX SDK Jan CTP installed.
I start off with a mind map of the game features, using the tool: Free Mind. The mind map should be sufficient enough to serve as an overview of the game components.
Next (which is the current stage), I would outline the application components/architect/flow. This would again, be a high level outline. A short description of each component would be written as well.
A simple schedule, or roadmap would be then produced. This will be a form of progress indication for the project.
The follow up process would probably be slow and iterative. I would pick a particular component, do a more detail design (in terms of gameplay, application flow, communication, etc). After implementation, I would follow up with a journal entry, and the process would repeat until the game application is complete.

Depending on cases, I would employ unit tests/test-driven development on the component. The choice of unit testing tool would most likely be NUnit.

Subversion repository would be set up locally (though ideally it should be remote), and check-in performed after each milestone of the component schedule (be it minor or major). At the very least I would have a roll back capability of source code if required.

And finally, on the code documentation aspect. With C#, the most logical choice would be the xml commenting feature it supported. I could either externalize the comments of have it within the source.

On the issue of externalizing the comments, I might stress that it is NOT a good idea. First, having comments in another file can easily cause inconsistencies. The comment might, at a later date, no longer reflect what the method/field/class do. This is mostly due to neglience, and is pretty common if the comments are just not at the place where you change the code.

The xml commenting feature, however good it may sound, might prove excessive in cases. Unless you do wish to generate a help documentation out from code, they are not necessary. In my case, I do not intend to generate the help documentation (or at least not one that is as comphresive), so having the xml comment reiterating what the method does even though the method name is clearly explainatory is... excessive. As such, comments would only be used in places to furthur describe the internal workings of a method (though in such a case, one should always consider renaming the method to be more self-explainatory, or if it gets too long, consider refactoring it into multiple smaller methods).

Taking a step furthur, I create addition attributes to furthur help in the commenting. NotNull, ValidString are examples of attributes I can apply on parameters (ideally it would be good if they can be enforced as invariants, but I believe I need to use Spec# for that feature). Additionally, Document, Summary, and ToDo can be applied on classes, methods, events, etc. In this way, the comment are 'embedded' into the code, and even read when the final product is reflectored. Of course, I have to agree that these could be excessive baggage to carry around...

I hope I can get around to posting the application outline in my next post.

dot

dot

 

Start Development

After almost two years of having a gdnet+ journal, I've finally decided to start writing on it.
First off, to justify the WHY of this writing:

I needed to start a project to fuel my desire to learn and experiment new technology.
A game related project would be more fun, though I am going to try my best to employ enterprise related practice and terminalogy into it (This could act as a demo as well if I am to look for a non-game related job).
I want to start a development journal on the project as well, to document and discuss the various technology used.
A personal blog site could be easily set up, but it would not have the traffic gamedev current has (not that traffic == good, but more traffic might mean more constructive comments).


Next, for a brief description of the project.

No, AV does not mean adult video, you dirty minded eechi hentai. It's a code name! And no I'm not saying what it is yet!

It will be an online game (notice the omission of multiplayer) using the web browser as the front end. In a vague overview the game would probably feature the player recruit, train and send bands of units on missions (Shameless plug for www.lordsofmidnight.com , which influenced the game idea to some extent, though i MUST stress that the original idea existed before I knew of it), unlock areas, etc. I do have a mind map of all the game features I would like in it, but I'll refrain from revealing it because the primary purpose of this project is still technology first, game second, and posting the game feature list might lead to discussions on the game play instead of the technology.

Note, if you do intend to make a game, please, do not do it this way. Get a comprehensive Game Design Document up first before you start development.

The choice of a web browser is primarily to experiment with Atlas, Microsoft's Ajax solution (in a way, some might argue it's more than just Ajax). On a later phrase, window clients might be developed which connects to the web services exposed from the server, but that's unconfirmed (and even if I do that, it might be using avalon, xaml, browser control, or whatever's interesting at that time). A main game world application might be running constantly, and highly likely as a window service (I might justify that when I get to develop it). Remoting would be used to talk between the web application and the game world application, and Indigo/Windows Communication Foundation could be used for that task as well. Database software have not been decided yet. I would need to check up on the licensing scheme of SQLExpress. The Web server would be IIS, using ASP.Net 2.0 (please, do not even suggest mono on apache).

The time might be long between posts, depending on how busy I am, and what new design decisions/technology discoveries I made.

dot

dot

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!