Code Project: Epic Quest! Starting up…

Howdy all,

As promised (somewhat belatedly!) I’m going to undertake a small coding project that, hopefully anyway, fits around my current commitments and the incredible weight of jobs I need to do before my impending wedding.

The plan, in the long term, will be to revisit Unity 3D as well as to continue the journey and forays into other technologies that I’m less familiar with. For now however, I just fancy (whether the results are good or bad) coding.

To that end I’m going to do a series of posts on creating an RPG/Adventure (classic D&D dice roller) packaged into a simple console application.

The snapshot below shows a set of stub classes, interfaces and other utility files that I’ve mocked up to start development on the project. This is all subject to change of course but I always find it relatively helpful to plan ahead and start drawing up interfaces and base classes upfront. These elements can always be removed later if it is discovered that there is a touch of over-engineering going on, therefore leading to a need to tighten the reins on a project and move to a simpler model. All of the code is presently tucked into the application project; I’ve opted to create no additional class libraries at this time (unless some interesting, reusable code comes out of this that I want to keep under source control for later use).

Epic Quest Solution

Epic Quest Solution

Most of the files are currently empty with the exception of some static utility methods and the following code in the core GameManager class.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using EpicQuest.GameEnums;
using EpicQuest.Models;
using EpicQuest.Utility;

namespace EpicQuest.Manager
{
    /// <summary>
    /// Epic Quest core GameManager class
    /// that handles general game state.
    /// </summary>
    internal class GameManager
    {
        #region Private Data Fields

        //Private List representing the party members involved with this adventure
        private List<Hero> partyMembers = new List<Hero>();

        #endregion Private Data Fields

        #region Main Game Loop Method

        /// <summary>
        /// Main Game Loop 'Start' method
        /// called from the Main entry point method of the 
        /// Program class (for this executable).
        /// </summary>
        internal void RunMainGameLoop()
        {
            //Debug information (method entered)
            Debug.WriteLine(Utils.MethodDebugMsg());

            //Game startup initialisation logic
            GameStartup();

            //Always run the game loop at least once (currently, break when user types EXIT)
            do
            {
                //Start game message
                Console.WriteLine();
                Console.Write("Do you want to venture into the dungeon? Type EXIT and hit ENTER to flee in terror or simply press ENTER to continue: ");

                //Does the user want to quit...
                if (Utils.InterpretUserInput(Console.ReadLine()) == GameAction.ExitGame)
                {
                    break;
                }

                //Clear the current game state (i.e. Party Members)
                ClearGameState();

                //Create a new Party of heroes
                CreateQuestParty();
            } 
            while (true);

            //RunMainGameLoop method exit (confirmed via the output window)
            Debug.WriteLine(Utils.MethodDebugMsg(DebugMsgType.MethodLeft));
        }

        #endregion Main Game Loop Method

        #region Private GameManager Helper Methods

        /// <summary>
        /// Private helper method that contains all of the Epic 
        /// Quest game initialisation logic (on start).
        /// </summary>
        private void GameStartup()
        {
            //Write out a formatted string (in a red text colour) that represents the Games Title
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(Utils.WriteGameTitle());

            //Reset the console to it's default colour scheme
            Console.ResetColor();
        }

        /// <summary>
        /// Private helper method that can be called to clear
        /// down the Epic Quest game state.
        /// </summary>
        private void ClearGameState()
        {
            partyMembers.Clear();
        }

        /// <summary>
        /// Private helper method (to be refactored/potentially moved) that
        /// allows the creation of a Party of heroes (currently allows 3 members).
        /// </summary>
        private void CreateQuestParty()
        {
            //Input help information - print to the console
            Console.WriteLine();
            Console.WriteLine("Create your Party (BRW = Brawler, CLR = Cleric, MAG = Mage, NEC = Necromancer, THF = Thief)...");

            //Loop three times and allow the creation of the relevant heroes
            for (int i = 0; i < 3; i++)
            {
                //Create a new hero (based on user selection)
                Console.WriteLine();
                Console.Write("Choose your hero number {0}: ", i);
                Hero newHero = null;

                switch (Utils.InterpretUserInput(Console.ReadLine()))
                {
                    case GameAction.ClericChosen:
                        {
                            newHero = new Cleric();
                        }
                        break;
                    case GameAction.MageChosen:
                        {
                            newHero = new Mage();
                        }
                        break;
                    case GameAction.NecromancerChosen:
                        {
                            newHero = new Necromancer();
                        }
                        break;
                    case GameAction.ThiefChosen:
                        {
                            newHero = new Thief();
                        }
                        break;
                    case GameAction.BrawlerChosen:
                    default:
                        {
                            newHero = new Brawler();
                        }
                        break;
                }

                //Safety check - Only add the hero if it's set correctly
                if (newHero != null)
                {
                    partyMembers.Add(newHero);
                    Console.WriteLine("{0} added to the Party.", newHero.GetType().Name);
                }
            }
        }

        #endregion Private GameManager Helper Methods
    }
}

Nothing overly ‘classy’ (bad pun, sorry!) here to kick us off. I just wanted a stub class with the main game loop placed in to give us a template. The few take away points here are that all of the hero classes (Brawler, Cleric, Mage, etc) all feed off a, currently very lightweight, ‘Hero’ base class. A simple List of type Hero is serving as a way to keep track of the different adventurers as of this iteration; this is stored within the GameManager which may well change.

A very useful language feature worth mentioning here, which comes in especially handy when programming WPF applications and working with the MVVW design pattern, is the CallerMemberName attribute. In this case I’m using it as a debug mechanism via a call to Utils.MethodDebugMsg. This attribute essentially exposes a very simple way to gain access to the calling method/properties name in a called method (without using the archaic StackFrame class).

/// <summary>
/// Internal static utility method that consumes a string method name and  
/// formats it as a short debug message (denoting when we enter or exit a method).
/// </summary>
/// <param name="msgType">The message type (have we entered or exited a method for example) as a enum. Defaulted to DebugMsgType.MethodEntered.</param>
/// <param name="methodName">The calling method name as a string</param>
/// <returns>A formatted string representing the method called (depending on the debug message type).</returns>
internal static string MethodDebugMsg(DebugMsgType msgType = DebugMsgType.MethodEntered, [CallerMemberName] string methodName = "")
{
    //If a valid method name is not provided simply return an empty string
    if (string.IsNullOrEmpty(methodName))
    {
        return string.Empty;
    }

    //Use the DebugMsgType provided to return a formatted string (Have we entered/exited the given method name). Default = string.Empty
    switch (msgType)
    {
        case DebugMsgType.MethodEntered:
            {
                return string.Format("Entered the {0} method.", methodName);
            }
        case DebugMsgType.MethodLeft:
            {
                return string.Format("Exited {0} method.", methodName);
            }
        default:
            {
                return string.Empty;
            }
    }
}

CallerMemberNameAttribute MSDN Reference

As far as architecture goes this is pretty much it for the time being.

Concept wise, I envisage a game with the following mechanics:

  • 5 Hero classes with different skills and attributes.
  • A ‘Dice’ rolling system supporting 3 different types of die (Green, Blue and Red).
  • The concept of attack and defence dice (anyone remember Hero Quest!? Would like a spin-off of that).
  • Various monsters to take on.
  • Various weapons, armour and items to interact with and the ability to sell and purchase (via a simple vendor system).
  • Basic sounds plugged in to accompany the game play.

Running the application, as it stands (with a few utility methods firing that I haven’t shown here yet), gives the following output in the console window:

Epic Quest Console Window.

Epic Quest Console Window.

You can tell you’re a developer when everything is zero indexed (hero number 0 come on down!), I probably need to change that!

As usual, comments and thoughts welcome; drop me a line if anything crosses your mind. As a little muck around, and as I’m still getting a feel for the various word press features available (the dream being to chuck some money at this later in the year), I’ve included a poll here to allow readers to pick a monster to be included in the game. Push buttons! You know you want to. Cheers all.

Work Practices and the Quest for (a little) Self Improvement

An interesting week at work has just been topped off (this was a great little delectable cherry as far as I’m concerned) by a Tech Day, providing developers an opportunity to spend time reviewing content on a myriad of new technologies and coding methodologies. As we all know, the life of a developer can occasionally feel like sprinting, barefoot, over ground covered in broken glass with hands outstretched to grab the prize…the Holy Grail of knowledge…which is unfortunately dangling from a piece of string attached to stealth bomber hauling ass up, up and anyway. Yeah, yeah; perhaps a little over the top agreed, but the underlying feeling this particular vision instils has likely been experienced by every developer at one time or another – The feeling of utter helplessness in the face of technologies and learning curves far outpacing the average mortal. So as an aside to coding I’d like to briefly cover some material that I myself have found useful, in part at least, in pushing back the tide.

I managed to get a video, featuring Scott Hanselman (Program Manager at Microsoft, details below) entitled “It’s not what you read, it’s what you ignore”, featured as part of our Tech Day and it seemed to get a good reception. Viewing this several months ago and having time to experiment with a few of the suggestions made in the presentation I was confident it would certainly push a few buttons with the other developers I work with. Overall, the general feelings on this seemed fairly good and I’ve had some feedback to suggest this has, at the very least, got juices flowing regarding how we approach work practices in general. It’s from a few years ago but still feels relevant:

Scott Hanselman Presentation

Other links:

www.hanselman.com
www.hanselman.com/blog

Scott is a charismatic, funny and ultimately candid presenter who portrays his opinions with grace and decisiveness. He has produced a myriad of other talks on coding and technology (i.e. surrounding web development, ASP.NET and Azure) which is his area of expertise, but this window into his day to day thoughts and work management strategies could well be just as invaluable as any technical presentation.

Here’s a few take away points from this content:

  • The Pomodoro Technique. A technique for time management/instigating short, focused work ‘bursts’.
  • Trello Boards. A scrum-like piece of software for workload management/to-do lists.
  • Rescue Time. Software that monitors a user’s activity to show work trends over days, months and years.
  • Instapaper. A way to receive information, at a time convenient for you, in a clean, newspaper format.
  • Outlook tips and tricks for handling email.

First up is the Pomodoro Technique; so called due to its link with the ‘Pomodoro’ (tomato) kitchen timer. The concept is deceptively simple but, has for me anyway, had noticeable effects. The idea is that you fire up a timer for 25 minutes and sit down to do a piece of focused, uninterrupted work during this time. At the end of the 25 minute period (a ‘Pomodoro’) a short 5 minute break is taken before starting a further Pomodoro. The cycle is then repeated for up to 4 Pomodoro’s before an extended break is taken (in the implementation of the technique I have been following). During each Pomodoro it’s necessary to note down how many distractions…………………………….So, I’ve been hunting through steam just looking at the featured games this weekend…Damn it – You see what I mean!!!

Distraction!!!

Distraction!!!

Ahem…So you log how many times you get distracted during the Pomodoro, covering both times you distract yourself and when others distract you, in the hopes of limiting this down as much as possible. As noted, it’s surprising just how difficult 25 minutes of focused work is. Try it for yourself and see. This has, in no small part, contributed to the development of what Claire calls my ‘arse-face’ – The face pulled when I don’t want to be distracted! Sorry Claire…Kudos to you for having to look at my face for any length of time – Especially during any kind of coding (hat-tip).

Here’s some links that may prove useful (One for the Pomodoro Techniques official site, another for an online timer and an amazon search for kitchen timers if you need the physical object!):

The Pomodoro Technique
Online Pomodoro Stopwatch
Amazon Search

Moving on, Trello Boards are a useful tool for general work management and for treating work entities that drop on your desk in a scrum-like fashion. It’s certainly worth a poke around, it can be found here:

Trello

In fact, outside of the scope of ‘development’, Claire and I have found this a great way to visualise things we have to do for our Wedding (yes, I have tried to ‘scrum’ our Wedding, full blown nerd alert!). The boards can be shared with other people so contributions can be made by multiple team members for example (supporting notes, due dates, to-do lists and basic colour coding of board items).

Below is an example Trello Board outlining how it may look on any given day for me (well, with a few additions that probably won’t normally make an appearance but you get the picture):

Example Trello Board

Example Trello Board

I have a few explicit sections on my board:

  • Categories which acts as a key (colour coded) for board items.
  • Long Term/Massive Asteroids’ outlining those big, bad-boy hopes and dreams to achieve in the long-term (currently on a personal development level).
  • Rule or 3 section where I like to list the 3 key things I would like to achieve on a given day. These can be physical pieces of work or more abstract concepts (such as understand a particular coding concept/do some investigation or research).
  • A Today list where I list the actual items of work I plan to complete on a given day (colour coded with due dates and task lists where appropriate).
  • Once items are completed they get moved to the final ‘Done’ list for archiving later that day.

There are obviously a multitude of ways to leverage this organisational tool but this is just my personal preference.

RescueTime is a utility, after reviewing the content of the presentation, that I adopted right off the bat to monitor my own working habits. Personally, the results it collates on a daily basis I’m not entirely sure are 100% accurate but as an indicative tool it’s great.

Here’s the link for anyone who wants to try it out:

RescueTime

My own standpoint on this is that these metrics are very useful for deciding if you are spending your time in the right places as per your job placement (i.e. are you spending too much time on distracting tasks or unnecessary administration tasks instead of physical coding). If you are looking for an indication of your effectiveness then this could be your first ‘finger in the wind’ – A basis for reconsidering your general working habits if required should you find yourself straying from the tasks you should be chewing into.

A friend at work contacted me today and made me aware of this alternative (which works fully offline):

ManicTime

Thanks to Mike for this. I haven’t had a chance to look into this yet but I know he plans on checking it out so I’ll grab a copy to see how the information provided stacks up to Rescue Time.

A particular problem that I started to face (thankfully, quickly nipped in the bud), which I know is a commonplace office plague, is ‘craptonneofchrometabsitis’. I’m sure, if you’re not already this person, you’ve walked past someone with a gazillion chrome tabs open; slowly squeezing the life out of whatever box is wheezing its way through this malady. Either this or a billion favourites are currently sitting in your browsers favourite list as ‘to read’ sites if and when ‘time allows’. This is where Instapaper comes in.

Via a browser extension (shown below) you are able to identify a piece of web content for addition in your queue of Instapaper ‘to read’ articles. Instapaper is great for cutting out all of the fluff and rubbish associated with a site; so you are literally just left with the base content. The bit I like most, however, is that you get an ability (for free) to configure a schedule to ‘post’ a digital newspaper containing all of the content you’ve been marking as interesting in a given time frame. In my case, I get information pushed directly to my Kindle every Friday afternoon (if I’ve marked at least three pieces of content each week as of interest). Bloody brilliant…A great excuse to close tabs and destroy some unneeded favourites!

Instapaper Extension

Instapaper Extension

You can have a little read up on Instapaper by following this link:

Instapaper

Here’s an example of how the web interface looks (and a few articles I read many moons ago) – It’s themeable and contains great configuration options for pushing out content as and when to designated devices (or just reading the content there and then minus adverts and other guff found on the related sites):

Instapaper Web Interface

Instapaper Web Interface

Lastly, if you watch the presentation and read into the advice surrounding managing Outlook I think you’ll find a few great golden nuggets of sage advice. Some of these I’ve had trouble implementing, although I agree with them in principle and completely see the point, such as explicitly responding to email in the afternoons (and not even checking it in the mornings). Others have been a massive triumph, such as how to manage and split your Outlook Inbox. I now have folders containing emails from Management, CC only emails, External emails in addition to my physical Inbox (i.e. things intended for me specifically). All other junk has been moved out to a dumping ground folder that simply isn’t my Inbox – This is the first time my actual Inbox has been empty for seven years! If anything, this at the bare minimum produces a feeling of liberation so I’m counting it as a win!

Whilst this was fresh in my mind I wanted to blurt it out into a post with the caveat being that I’ll try to get some damn code up again on this blog soon! Either way, I hope all or some of this turns out interesting and/or helpful.

Happy Easter! Eat Chocolate, drink beer, etc. Thanks all and bye for now.