Mud Designer's world clock

Tonight I was able to finally get a world clock built in to the Mud Designer engine. The world clock is pretty flexible, allowing users to specify how many real-world hours pass before 1 in-game day is completed. The engine then does a break down and broadcasts updates every in-game minute.

Time of day states

If you set your in-game to real-world hour ratio to 4:24, then the update event will get called every 10 seconds. This means that 1 in-game minute will pass every 10 seconds. If the ratio is to low, the engine will switch over and broadcast updates every in-game hour instead, to prevent stress on the server.

The engine uses an ITimeOfDayState implementation to determine what the current time of day is. It holds a collection of these objects and transitions between the different times of day as needed. The ITimeOfDayState objects have a StartTime property that tells the engine when it needs to transition to the state. This allows users to create their own time of days, such as Evening and LateNight, and let the engine handle moving between the states.

Building a time of day state is really simple. You can just inherit from it's parent class like this:

public class AfternoonState : TimeOfDayState
{
    public AfternoonState()
    {
        this.StateStartTime = new TimeOfDay();
        this.StateStartTime.Hour = 12;
    }

    public override string Name { get { return "Afternoon"; } }

    public override TimeOfDay StateStartTime { get; set; }

You can of course choose to implement a state from ITimeOfDayState, but by inheriting from the abstract TimeOfDayState class, the time of day engine clock will be managed for you, along with the in-game to real-world time conversions.

The engine's IWorld implementation is notified every in-game minute that goes by (or hour if the frequency is to low). When the world is notified, it updates itself accordingly, and checks to see if the state needs to be changed. If so, it transitions the states and posts it's own event that notifies registered objects that a state change took place. This allows developers to publish messages to the users when the time of day changes.

The Engine Timer

Since the engine is being built with full cross-platform support via Portable Class Libraries, I ran in to an issue with the .NET built-in thread-safe Timer class missing. After doing some searching around, it seems that Microsoft did include it in their Portable Class Library profile, but Xamarin has not. Since I am targeting iOS and Android as well, I loose out on the classes Microsoft includes in their latest profiles, until Xamarin updates their profiles.

In order to work around this, I built a custom Timer for the engine, called EngineTimer. It's pretty simple to use and looks like this.

var worldClock = new EngineTimer<IWorld data-preserve-html-node="true">((stateData, clock) => DoSomething(), this);
worldClock.Start(startDelay: 0, interval: 5000);

The EngineTimer is what the Mud Designer will use through-out to handle it's internal state. The Worlds will use one for updating the time of day, Zones will use one for updating their weather conditions, the game class will use one for auto-saving and there will be more usage through-out the engine with it.

Mud Designer Code Analysis: Sealed Attributes

I had mentioned a couple of times that I would be refactoring the current engine re-write using the NDepend statically analysis tool. I performed an initial analysis last night and reviewed the report and started to dig in. Some of the issues that I ran in to were really simple to fix. Let's start with those first.

Avoid unsealed attributes

Microsoft's MSDN states that for performance reasons, you should avoid unsealed attributes whenever possible. Considering that the engine's built-in validation mechanics are built off of attributes, I want to make sure and grab any performance increase that I can get.

I started out with an existing Fixture model that I created during development. The model is really simple and includes three properties, each being validated in some manor.

public class ValidatableFixture : ValidatableBase
{
    private const string PasswordConfirmationDelegateName = "ConfirmPasswordsMatch";

    public ValidatableFixture()
    {
        this.Name = string.Empty;
        this.Password = string.Empty;
        this.PasswordConfirmation = string.Empty;
    }


    [ValidateValueIsNotNullOrEmpty(ValidationMessageType = typeof(MessageFixture), FailureMessage = "Name must be set.")]
    public string Name { get; set; }


    [ValidateValueIsNotNullOrEmpty(ValidationMessageType = typeof(MessageFixture), FailureMessage = "Password must be set.")]
    [ValidateStringIsGreaterThan(GreaterThanValue = 4, ValidationMessageType = typeof(MessageFixture), FailureMessage = "Password must be greater than 4 characters.")]
    public string Password { get; set; }


    [ValidateWithCustomHandler(DelegateName = PasswordConfirmationDelegateName, ValidationMessageType = typeof(MessageFixture), FailureMessage = "Passwords do not match.")]
    public string PasswordConfirmation { get; set; }


    [ValidationCustomHandlerDelegate(DelegateName = PasswordConfirmationDelegateName)]
    public IMessage PasswordConfirmationValidation(IMessage message, PropertyInfo property)
    {
        return this.PasswordConfirmation.Equals(this.Password) ?
            null :
            message;
    }
}

This fixture contains four total validation rules that will be invoked during the test. The most expensive of the four would be the ValidateWithCustomHandler attribute. Unlike the rest of the validation system, the ValidateWithCustomHandler attribute does not cache the MethodInfo object it fetches via reflection. At the moment, the engine just caches the attributes themselves and their associated properties for re-use across multiple instances. Caching of method delegates will make its way in to the system at some point in the future.

To get started, I wrote a simple unit test that creates 1,000 instances of the ValidatableFixture class and invokes ValidateAll(). The unit test ran through all 1,000 instances, invoking Validate() on each attribute, which caused the attribute validation to take place. In theory, there shouldn't be a huge penalty here due to the caching I am doing. Once the first ValidatableFixture is instanced, the rest of them use the PropertyInfo and ValidationAttribute cache that the first one generated. There won't be any deep walking of the attribute heirarchy.

// Arrange
var fixtures = new List< ValidatableFixture>();
var watch = new Stopwatch();
for (int index = 0; index < 1000; index++)
{
    var model = new ValidatableFixture();
    model.Name = "TestName";
    model.Password = "pass";
    model.PasswordConfirmation = "pass";
    fixtures.Add(model);
}

// Act
watch.Start();
foreach(ValidatableFixture fixture in fixtures)
{
    fixture.ValidateAll();
}

watch.Stop();
Debug.WriteLine(watch.Elapsed.TotalMilliseconds);

I ran the test 5 times and ended with an average of 41.3199ms.

Finally, I went through and sealed all of the validation classes and re-ran the test. To my surprise, the results ended up be slower than leaving them unsealed, with an average time of 43.3881ms.

I found this to be really interesting, as sealing the class should technically make it faster.

I did some research online and discovered there is actually a debate over whether you should or should not seal your classes. I'm in the camp that they should be sealed unless there is an explicit need to override them. In the case of the validation attributes, they should remain sealed, even at the cost of a bit of performance. The idea behind the validation rules is that developers should write their own implementation of IValidationRule rather than inheriting from an existing one and trying to change one step out of many within the classes validaiton process. It opens up the possibility of unexpected results happening behind the scenes during the validation process.

Mud Designer Alpha 3 Analysis with NDepend

I was finally able to get the Mud Designer in to a usable state over the weekend. It has an improved Telnet server that is completely decoupled from the IGame interface. The only coupling the server has with the engine at the moment is a reference to IPlayer, which I might be able to get rid of at some point down the road.

I thought this would be a good time to run some code analysis on the project and see where it stands. Unfortuantely, the report didn't bring the good news I was hoping to see. Let's take a look at the report.

The project contains 1,270 lines of code (compared to Alpha 2 which had 3,852) along with 89 Types (compared to 152). The Alpha 2 release contained 8 critical rule violations and 828 standard violations. Looking at the numbers for Alpha 3, they're roughly cut in half. I was hoping for the number to be lower, but it's early enough in the re-write that I can address this and lower these numbers. The goal of the re-write is to produce a more reliable code-base that provides greater flexibility and is easier to maintain. Proper patterning, architecture, design and code quality is critical for this. NDepend does an excellent job of identifying the areas that I need to address, and allows me to research and apply code designer philosophies.

One of the things that has greatly improved with the current code base is the Cyclomatic Complexity of the source. The overall average is about the same, but the maximum is down from 74 paths to 23.

Over the course of this week as I address some of these code violations, I will post a blog entry for the rule(s) I am currently working on addressing. The problematic source will be posted along with the end result of the refactor to satisfy the NDepend analyzer

Improved Validation for Universal Windows Apps

I wrote a couple weeks back on my attempt to re-write the ValidatableBase class I wrote for Universal Windows Apps. The original idea was great, but in practice it turned out to be a headache. Writing a method per property (in some cases more than one!) really bloated the code and made it difficult to read. So I set out to tackle this in a different way.

To demonstrate the improvements, I want to first revisit how the previous version worked. The following is a simple User model that would perform validation on a user name and password with the old ValidatableBase.

public class User : ValidatableBase
{
    private string email = string.Empty;

    private string password = string.Empty;

    public User()
    {
        this.RegisterProperty("Email", "Password");
    }

    public string Email
    {
        get 
        {
            return this.email;
        }
        set 
        { 
            this.email = value;
            this.OnPropertyChanged("Email");
        }
    }

    public string Password
    {
        get 
        { 
            return this.password; 
        }
        set 
        { 
            this.password = value;
            this.OnPropertyChanged("Password");
        }
    }

    public override void Validate()
    {
        this.ValidateProperty(this.ValidateEmailIsNotEmpty, "Invalid Email Address.", "Email");
        this.ValidateProperty(this.ValidateEmailIsFormatted, "Email Address is not in the correct format.", "Email");
        this.ValidateProperty(this.ValidatePasswordIsNotEmpty, "Password can not be empty.", "Password");
        this.ValidateProperty(this.ValidatePasswordIsToShort, "Password must be greater than 8 characters.", "Password");
        this.ValidateProperty(this.ValidateIfPasswordContainsSpaces, "Password must not contain spaces.", "Password");

        base.Validate();
    }

    private IValidationMessage ValidateEmailIsNotEmpty(string failureMessage)
    {
        if (string.IsNullOrEmpty(this.Email))
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }

    private IValidationMessage ValidateEmailIsFormatted(string failureMessage)
    {
        string[] addressParts = this.Email.Split('@');

        if (addressParts.Length < 2)
        {
            var msg = new ValidationErrorMessage(failureMessage);
            return msg;
        }

        string[] domainPiece = addressParts.LastOrDefault().Split('.');
        if (domainPiece.Length < 2)
        {
            var msg = new ValidationErrorMessage(failureMessage);
            return msg;
        }

        return null;
    }

    private IValidationMessage ValidatePasswordIsNotEmpty(string failureMessage)
    {
        if (string.IsNullOrEmpty(this.Password))
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }

    private IValidationMessage ValidatePasswordIsToShort(string failureMessage)
    {
        if (this.Password.Length < 8)
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }

    private IValidationMessage ValidateIfPasswordContainsSpaces(string failureMessage)
    {
        if (this.Password.Contains(' '))
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }
}

As you can see, I had to write a single method for each different type of validation I wanted to perform. In this case, as shown in the Validate() method, I have 5 different methods to validate 2 properties. Imaging a more complex model? This quickly turned in to a messy model.

The solution

I heavily modified the ValidatableBase class and its interface initially, but ultimately ended up being able to keep it mostly unchanged and just add on to it. The validation via method delegates certainly has a place, and I didn't want to loose that. The goal this time-around however was to make delegates the last choice instead of the first choice.

The class now supports attribute based validation, very much like Microsoft's DataAnnotation. Since Data Annotations are not supported in Universal Apps, I set out to build my own version, which actually ended up being a bit different with some nifty features.

Let's take the User class, and re-write it to use the new validation scheme.

public class User : ValidatableBase
{

    private string email = string.Empty;

    private string password = string.Empty;

    [ValidateValueIsNotNull(FailureMessage = "E-Mail can not be left blank.", ValidationMessageType = typeof(ErrorMessage))]
    [ValidateWithCustomHandler(DelegateName = "ValidateEmailFormat")]
    public string Email
    {
        get
        {
            return this.email;
        }

        set
        {
            this.email = value;
            this.OnPropertyChanged("Email");
        }
    }

    [ValidateStringIsGreaterThan(GreaterThanValue = 6, FailureMessage = "Password must be greater than 6 characters.", ValidationMessageType = typeof(ErrorMessage))]
    [ValidateStringIsLessThan(LessThanValue = 20, FailureMessage = "Password must be less than 20 characters.", ValidationMessageType = typeof(ErrorMessage))]
    public string Password
    {
        get
        {
            return this.password;
        }

        set
        {
            this.password = value;
            this.OnPropertyChanged("Password");
        }
    }

    [ValidationCustomHandlerDelegate(DelegateName = "ValidateEmailFormat")]
    private bool ValidateEmailIsFormatted(IMessage failureMessage)
    {
        string[] addressParts = this.Email.Split('@');

        if (addressParts.Length < 2)
        {
            return false;
        }

        string[] domainPiece = addressParts.LastOrDefault().Split('.');
        if (domainPiece.Length < 2)
        {
            return false;
        }

        return true;
    }
}

Now we are down to just a single method that performs validation. The Email property has two validation attributes, a ValidateValueIsNotNull and a ValidateWithCustomHandler attribute. The value is not null attribute is self explanatory, it just ensures the value isn't null and progresses. The ValidateWithCustomHandler allows you to specify a delegate name that you want th validator to use when performing validation. You'll notice that there no longer needs to be a method within the model called Validate() as this is part of the base class and handles invoking all of the validation attributes, and their custom handlers if they exist.

We use validation on the Password property as well, by ensuring it meets the minimum and maximum length requirements we define.

A really cool feature of this, is the ability to perform validation based on other property values. For instance, let's assume that validation for the Password can only fire when the Email property has a value set. If that is the case, then we just modify the Password attributes to specify that the Email property must be valid in order for our validation to fire.

    [ValidateStringIsGreaterThan(GreaterThanValue = 6, ValidateIfMemberValueIsValid = "Email",  FailureMessage = "Password must be greater than 6 characters.", ValidationMessageType = typeof(ErrorMessage))]
    [ValidateStringIsLessThan(LessThanValue = 20, ValidateIfMemberValueIsValid = "Email", FailureMessage = "Password must be less than 20 characters.", ValidationMessageType = typeof(ErrorMessage))]
    public string Password
    {
        get
        {
            return this.password;
        }

        set
        {
            this.password = value;
            this.OnPropertyChanged("Password");
        }
    }

As you can see here, by setting the ValidateIfMemberValueIsValid, the validation will only get fired if the Email property is not empty or null. What if we wanted to have validation fire only if the Email property was empty? We can do that be prepending an exclamation mark in from of the string representation of the Email property.

ValidateIfMemberValueIsValid = "!Email"

This works with boolean values by checking if it is true or false, floats, doubles, ints, longs, shorts and decimals by checking if they are zero or not along with empty strings and null objects.

Finally, the method delegate feature still exists, and can be used by external objects to enforce additional validation on the model. Let's use a view model as an example. Assume the view model has a PasswordConfirmation property, that must equal the users Password before user creation validation is considered acceptable. We can do the following in our view model, within a CreateUser method or an ICommand.Execute method.

    public void Execute(object parameter)
    {
        // Perform validation on the user's built in validation.
        this.AppUser.ValidateAll();

        // Piggy-back on top of the user default validation with an additional level of validation in our view model.
        // We ensure the password and password confirmation matches.
        this.AppUser.ValidateProperty(
            () => PasswordConfirmation.Equals(this.AppUser.Password),
            new ErrorMessage("Passwords do not match!"),
                "Password");

        // Check if there are any errors.
        if (this.AppUser.HasValidationMessages<ErrorMessage data-preserve-html-node="true">())
        {
            return;
        }

        // Do stuff.
        return;
    }

Here, we fire the user validation off, then we piggy-back on it by creating our own validation via an anonymous method, and assigning it to the "Password" property of the user. If validation fails, it will be added to the Users validation message collection. We then check if the user has any validation error messages. If they do, we abort the user creation.

The API still has a bit of tightening up to do before I can upload it, but it should be ready before the end of the week on GitHub. It's taken a bit of time due to ensuring that what I end up here can run properly. I managed to wire it up in to the latest build of the Mud Designer engine tonight which will really help with development.

Building an app targeting desktops & mobile

The Mud Designer is currently being developed to support a wide range of operating systems.

  1. Desktops
    1. Windows 7
    2. Windows 8
    3. Windows 8.1
    4. OS X
  2. Mobile
    1. WinRT 8
    2. WinRT 8.1
    3. Windows Phone 8
    4. Windows Phone 8.1
    5. iOS
    6. Android

To facility this, the engine at the lowest level will be wrote using Portable Class Libraries (PCL) so that I can target all of the operating systems with the same low-level codebase. The engine itself will be developed fairly abstractly, implementing a series of patterns that will help facilitate this requirement, with the bulk of the components hidden behind interfaces.

At the moment the engine is broken up in to 4 layers. From the highest layer to the lowest layer, the following provides an idea of what the overall acrchitectural layout looks like.

  1. App
  2. Engine
  3. Data Access
  4. Services

Each layer is broken down further, to facilitate the level of abstraction needed to provide cross-platform support.

App

The App layer looks like this

  1. Universal App
    1. Windows Phone
    2. WindowsRT
    3. Shared
    4. Presentation
  2. Windows
    1. Desktop
    2. Modules
    3. Infrastructure

As you can see, the mobile apps will be wrote within the Universal App layer while the Windows Desktop apps will be wrote under the Windows layer. Each will be able to target a version of the engine (and it's repositories and services) that is designed specifically for that platform.

I really want to avoid using #if WinRT #elif Win7 #endif kind of macros through-out the engine, as that makes maintaining it difficult and doesn't provide the level of support I want to provide for 3rd party developers. Since the engine will fully support engine and editor plugins, it needs to be modular and flexible enough to allow other developers to target a specific device or platform if they want, without having to rely on macro's.

For instance, the core project contains an IGame interface that exposes the following contract.

/// < summary>
/// Gets or Sets the current World for the game. Contains all of the Realms, Zones and Rooms.
/// < /summary>
ICollection< IWorld> Worlds { get; set; }

Since Universal Apps don't support ObservableCollections in the same manor that WPF Desktop apps do, I can implement the IGame in a Desktop library like this.

/// < summary>
/// Gets or Sets the current World for the game. Contains all of the Realms, Zones and Rooms.
/// < /summary>
public ObservableCollection< IWorld> Worlds { get; set; }

This still satisfies the interface's contract, yet provides support for WPF XAML's binding engine. Ideally, I will be able to build an abstract implementation of IGame in the Core engine, and then have the individual platforms inherit and override/implement the specific components that apply to them.

While the solution is still being organized and structured, this is the initial look of how the over-all application suite will be set up.