Login | Register  
Viewing Category

Current Articles | Categories | Search | Syndication


.NET

    Custom gaming systems through MEF

     294 Views ::  0 Comments :: Categories: .NET, MUD Server

    I finally have time to work some more on WheelMUD. I'm in the process of implementing the Warrior, Rogue, Mage (WRM) combat system. I'm loading it into WheelMUD's GameSystemController, using MEF. The neat thing about this setup, is that third party developers do not have to worry about plumbing details that much. As long as the correct interfaces are implemented, WheelMUD's MEF implementation will load all the different gaming systems/engines, and game attributes from the game's assembly (coded in any language supported by .NET 4.0).

    Here's a screenshot of the console with the custom assembly loaded:

    WRM combat engine through MEF

    The cool thing about this, is that these custom systems will behave exactly like WheelMUD's internal systems.

    I don't have any logic implemented yet, but that is my next step. I'm also looking to see how I can get this thing some unit testing love.

    posted @ Sunday, January 15, 2012 7:22 PM by Fastalanasa

    Gaming Systems - Stats

     1107 Views ::  0 Comments :: Categories: Source Code, .NET, MUDs

    I'm very excited about this latest bit of code and data that I checked in today. I fixed the stats so that they load a template from whatever gaming system is currently setup to run. First let me enumerate the systems that I tested with today:

    • Dungeons and Dragons 4th Edition Quick Start
    • GURPS Lite - Generic system, can literally run any genre
    • PathFinder - D&D 3rd edition clone
    • ShadowRun - Magic and SciFi together
    • The Artifact - Science Fiction
    • Warrior, Rogue, and Mage - Very simple fantasy system

    I got the stats loading for each one. Here are screen captures for each:

    Dungeons and Dragons 4th Edition Quick Start

    GURPS Lite

    PathFinder

    ShadowRun 3rd Edition

    The Artifact

    Warrior, Rogue, and Mage

    As you can see, I have the stats for all of these 5 gaming systems loading. It was relatively painless to do this. It took me about 15 minutes per new gaming system to get the stats up and running. Here are the steps:

    1. Navigate to the Files\GameRules directory
    2. Create a directory to hold your new game system's content
    3. Create a Data and Parsers directories under this root directory
    4. Create a XML file to hold the stat information, and put it in the Data directory
    5. Create a C# parser file, and put it in the Parsers directory
    6. Create a master xml file and place it in the Files\GameRules directory
    7. Adjust the contents of the master file to point to the root game directory
    8. Modify the mud.config file for the new system

    Here's a screen capture of the region of the mud.config file that we need to change:

    The values above will run The Artifact rules. The most important key here is "masterfile" that will tell WheelMUD which system to pick up. The "currentruleset" value is a human readable label that will be used in WheelMUD for admins and builders.

    My main push behind this, is so that I can start figuring out how to do basic combat. I really want to get the core systems working ASAP. I will be moving a lot of stuff off the 0.5 task list, so that we can concentrate on core stuff. The first casualty will be the remote admin stuff. That's just distracting me completing the core systems, which is what we all want to get done.

    posted @ Saturday, April 30, 2011 7:05 PM by Fastalanasa

    RavenDB - More lessons learned

     1166 Views ::  0 Comments :: Categories: Source Code, .NET

     I've been fiddling around with the Behaviors saving and loading using RavenDB. Here's what I learnt... The best strategy is to let RavenDB do what it is good at, which is to store and load documents to/from disk. I was trying to save a dictionary to disk, and running into casting exceptions when converting the dictionary in JSON format to the actual dictionary object. The best strategy, so far, is to save the actual derived Behavior instead. So I've been saving PlayerBehaviors. These load fine, and I don't have to tweak the code to do custom work.

    To load the PlayerBehavior documents, I'm issuing this LINQ query:

    List<PlayerBehavior> playerBehaviors = session.Query<PlayerBehavior>().ToList();

    For saving I'm using this code:

    using (var session = DALUtils.GetRavenSession())
    {
          session.Store(this);
          session.SaveChanges();
    }

        public class DocumentStoreSingleton
        {
            private static EmbeddableDocumentStore _instance;

            public static EmbeddableDocumentStore Instance
            {
                get
                {
                    if (_instance == null)
                    {
                        _instance = new EmbeddableDocumentStore { DataDirectory = DALUtils.GetDbPath() };
                        _instance.Initialize();
                    }

                    return _instance;
                }
            }
        }

            public static IDocumentSession GetRavenSession()
            {
                var store = DocumentStoreSingleton.Instance;

                var session = store.OpenSession();

                return session;
            }

    The RavenDB team has recommended to make the call to the DocumentStore a singleton. That works well.

    I've included a zip with the binaries for this spike. You will be able to create "players" and load them into the UI. You will need .NET 4.0 installed. The source is not ready for distribution, since I would have to copy all the needed assemblies locally.

    Attachments:

    posted @ Sunday, January 09, 2011 6:45 PM by Fastalanasa

    RavenDB & WheelMUD - Take 2

     1143 Views ::  0 Comments :: Categories: Source Code, .NET

    Breakthrough! I finally figured out how to do simple indexes in RavenDB. In hindsight, the answer was staring me in the face. It only took me to look at this when I had a rested mind. Here's a LINQ query to get the PlayerBehavior by name:

    from doc in docs
    where doc["@metadata"]["Raven-Entity-Name"] == "PlayerBehaviors"
    select new { doc.Name }

    To query this just issue this command on the Web UI:

    Name:crashtestdummy

    The playerbehavior document JSON looks like this:

    {
        "Name":"CrashTestDummy",
        "Password":"dummy",
        "Gender":"Female",
        "TimeInstantiated":"12/5/2010 10:27:44 PM"
    }

    You have to make sure that the property you are quering against is typed exactly as it is typed in the document. Notice that Name has an uppercase N. These things are case sensitive.

    My next step is to get this working from C# code.

    posted @ Tuesday, December 14, 2010 10:02 AM by Fastalanasa

    RavenDB & WheelMUD - Take 1

     1070 Views ::  3 Comments :: Categories: Source Code, .NET

    I spend a few hours learning how to use RavenDB yesterday. I first read through the tutorials and documentation on the home page for RavenDB. Unfortunately, the docs are way out of date, as the codebase for RavenDB appears to be moving and changing rapidly.

    The first hurdle was that the documentation doesn't explain what namespaces are needed to use for what functionality. This seems to be a frequent problem an 3rd party APIs. I'm specifically testing the embedded stuff. I used the latest build, which is RavenDB-Build-206.

    Here's how you setup saving:

           using Raven.Client.Client;

            public void Save()
            {
                var store = new EmbeddableDocumentStore { DataDirectory = DALUtils.GetDbPath() };
                store.Initialize();

                var session = store.OpenSession();
                session.Store(this);
                session.SaveChanges();
                session.Dispose();
            }

    My take-away from this code is that saving to the datastore is EXTREMELY easy. So the steps for saving are:

    1. Create an EmbeddableDocumentStore.
    2. Give it the path you want it to create the document files in.
    3. Initialize the data store.
    4. Create a session.
    5. Use the session to actually store. Note that this does not actually save the current document.
    6. Save the changes.
    7. This is optional, but always a good idea, dispose of the session.

    Now the hard part, at least to me, is retrieving this back. I have been able to look at the actual document that got stored. I used that knowledge to write a simple function that loads thae class document from disk. The raw JSON for this document looks like this:

    {
        "Name":"CrashTestDummy",
        "Password":"dummy",
        "Gender":"Male",
        "TimeInstantiated":"12/5/2010 10:27:44 PM"
    }

    The properties were declared like this:

        public enum GenderTypes
        {
            Male,
            Female,
            Neuter
        }

            /// <summary>
            /// Gets or sets the name.
            /// </summary>
            /// <value>The name for this player.</value>
            public string Name { getset; }

            /// <summary>
            /// Gets or sets the password.
            /// </summary>
            /// <value>The password.</value>
            public string Password { getset; }

            /// <summary>
            /// Gets or sets the gender.
            /// </summary>
            /// <value>The gender.</value>
            public GenderTypes Gender { getset; }

            /// <summary>
            /// Gets or sets the time instantiated.
            /// </summary>
            /// <value>The time instantiated.</value>
            public string TimeInstantiated { getset; }

    The metadata is this:

    {
        "Content-Encoding":"gzip",
        "Raven-Entity-Name":"PlayerBehaviors",
        "Raven-Clr-Type":"Behaviors.PlayerBehavior, Behaviors"
    }

     Loading this dynamically like I do from databases has eluded me. You normally would use a LINQ query to get the object. These three queries work:

    from doc in docs
    where doc.Name == "CrashTestDummy"
    select new { doc.Name }

    from doc in docs
    where doc.Name == "CrashTestDummy"
    select doc

    from doc in docs
    where doc["@metadata"]["Raven-Entity-Name"] == "PlayerBehaviors"
    select doc

    What is baffling me specifically, is how to create an index that I can query against. I got the queries above, after I read an entry in the ravendb Google Groups.

    The previous version of the save code, just saved the properties stored in a dictionary. So the old document looks like this:

    {
        "Id":"57b7b3a0-ad7b-46e1-bb92-d0bb879d6522",
        "Name":"CrashTestDummy",
        "Password":"dummy",
        "Gender":"Male"
    }

    The metadata is this:

    {
        "Content-Encoding":"gzip",
        "Raven-Entity-Name":"DictionariesOfStringsOfStrings",
        "Raven-Clr-Type":"System.Collections.Generic.Dictionary`2[]System.String, mscorlib[]System.String, mscorlib[], mscorlib"
    }

    So to load this I did this:

            public Dictionary<stringstring> Load(string playerName)
            {
                var session = _store.OpenSession();

                var playerProperties = session.Load<Dictionary<stringstring>>("dictionariesofstringsofstrings/1");

                session.Dispose();

                return playerProperties;
            }

    I haven't changed this to work with the new save method, which uses the actual PlayerBehavior class for saving.

    So this is as far as I've gotten by myself. I'm going to need to post some questions on the ravendb Google Groups, to move me forward from my current rut.

    The management UI is not out yet, but I did find a workaround. RavenDB comes with a built-in server. I copied the data folder into the Data folder that sits on the same directory as Raven.Server.exe. This is a minuature web server. Once you start this server, you point your browser to http://localhost:8080 to see the web UI. That was good enough to let me examine the documents.

    Anyways, I'm pretty tired, so I'm going to stop here.

    posted @ Monday, December 06, 2010 11:32 PM by Fastalanasa

    WheelMUD and SharpDevelop 4.0

     1272 Views ::  0 Comments :: Categories: Source Code, .NET, MUDs

    I just wanted to show everybody that SharpDevelop 4.0 is a good IDE to work with WheelMUD. Here are some screenshots of me running WheelMUD from SD4:

    posted @ Friday, August 20, 2010 7:53 PM by Fastalanasa

    When .NET 4.0 is having problems loading .NET 2.0 assemblies, try this

     696 Views ::  0 Comments :: Categories: .NET

    While working on fixing the NHibernate stuff, so that it would work at runtime, I came across a very handy tip. You need to add this bit of code to your app.config file to help .NET 4.0:

    <?xml version="1.0" encoding="utf-8" ?>
    <
    configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
      <
    supportedRuntime version="v4.0" />
    </
    startup>
    </
    configuration>

    That is what got me over to hump in moving all the projects over to .NET 4.

    posted @ Sunday, August 15, 2010 10:05 PM by Fastalanasa

    WheelMUD now has a full featured FTP Server

     602 Views ::  0 Comments :: Categories: Source Code, .NET

    Just wanted to let everybody know that I just integrated a multi-threaded FTP server as part of WheelMUD services. The code is working and checked in.

    FTP services are provided through the new ISystemPlugIn architecture, that I just put into the CoreManager. WheelMUD will automatically pick up any assembly that implements this new interface, and put it in the collection that holds plugins.

    posted @ Sunday, June 20, 2010 4:03 PM by Fastalanasa

    C# type switching sucks, but there's hope...

     756 Views ::  2 Comments :: Categories: Source Code, .NET

    I was trying to do use a switch statement using object.GetType() or typeof(). C# doesn't support using the switch statement in this context. After some Googling, I found that somebody had come up with an interesting solution.

        static class TypeSwitch
        {
            public class CaseInfo
            {
                public bool IsDefault { getset; }
                public Type Target { getset; }
                public Action<object> Action { getset; }
            }
     
            public static void Do(object source, params CaseInfo[] cases)
            {
                var type = source.GetType();
     
                foreach (var entry in cases)
                {
                    if (entry.IsDefault || type == entry.Target)
                    {
                        entry.Action(source);
                        break;
                    }
                }
            }
     
            public static CaseInfo Case<T>(Action action)
            {
                return new CaseInfo()
                {
                    Action = x => action(),
                    Target = typeof(T)
                };
            }
     
            public static CaseInfo Case<T>(Action<T> action)
            {
                return new CaseInfo()
                {
                    Action = (x) => action((T)x),
                    Target = typeof(T)
                };
            }
     
            public static CaseInfo Default(Action action)
            {
                return new CaseInfo()
                {
                    Action = x => action(),
                    IsDefault = true
                };
            }
        }

     

    This is how you would use it:

     

    void child_OnMemeEventHasFired(Meme meme, MemeEvent memeEvent)
    {
       string msg = meme.Name + " has fired." + Environment.NewLine;
       SetText(msg);
     
       TypeSwitch.Do(
             meme, 
             TypeSwitch.Case<WanderMeme>(ProcessRoom),
             TypeSwitch.Case<ExhaustionMeme>(ProcessExhaustion)
             );
    }

     

    The blog post with this code is here:

    http://blogs.msdn.com/b/jaredpar/archive/2008/05/16/switching-on-types.aspx

    posted @ Saturday, June 12, 2010 12:12 AM by Fastalanasa

    The memetic library is now on CodePlex

     543 Views ::  0 Comments :: Categories: Source Code, .NET

    This memetic project looks like it's going to get big enough to warrant its own separate project. I went a head and created a new CodePlex Project to store all of my work. I'm hoping to attract more people to this.

    I uploaded what I created yesterday into the project's download page. Please get it from there.

    Memetic NPC Behavior Toolkit

    posted @ Monday, June 07, 2010 1:41 PM by Fastalanasa

    Page 1 of 3First   Previous   [1]  2  3  Next   Last   
    Copyright 2007-2012 by WheelMUD  | Terms Of Use | Privacy Statement
    Google Analytics Alternative