XNA Creators Club Online
Page 1 of 1 (22 items)
Sort Posts: Previous Next

RPG Toolkit How To:

Last post 12/10/2009 11:25 by Constant Change Media. 21 replies.
  • 26/06/2008 11:08

    RPG Toolkit How To:

    So as I'm going through the RPG toolkit I thought I'd create a post describing the things I'm changing and how I went about changing them. Others may find this useful as they start modifying this toolkit, and feel free to share modifications that you have done and how you did them.

     

     

  • 26/06/2008 11:42 In reply to

    Re: RPG Toolkit How To:

    Drop Rate Quests

    Goal : My plan was to turn this more into an MMO style game instead of the single player style. A common quest in an MMO is a quest that relies on drop rates. ie. Collect x amount of an item from y monster. I wanted the item to ONLY drop when the player has the quest that asks for them, and STOP dropping when they have the desired amount the quest is asking for. It's common to have a < 100% chance for this item, making the player kill more monsters to collect the desired amount. This posses a problem with the way the current game works, not having monster respawns, but I will address that in another post as I get there.

     

    Execution : So here is what I did to achieve my goal.

    1) In the RolePlayingGameWindows project I went into Content->Characters->Monsters. Each monster xml file in here has a section called GearDrops. If I want "gear", ie a Glimmering Ruby, to drop from a monster I would add it to the GearDrops section. The only problem is given the current way the system works, that monster would ALWAYS drop a Glimmering Ruby at the given %. so clearly a change is needed.

    2) Inside each monsters xml file I added another tag to the GearDrops tag. I called it QuestName. The result looked something like:

    <GearDrops> 
              <Item> 
                  <GearName>Items\MinorHealingPotion</GearName> 
                  <DropPercentage>60</DropPercentage> 
                <QuestName></QuestName
              </Item> 
            <Item> 
              <GearName>Items\GlimmeringRuby</GearName> 
              <DropPercentage>100</DropPercentage> 
              <QuestName>The Goblin Brigade</QuestName> 
            </Item> 
          </GearDrops> 

     3) So as you can see the MinorHealingPotion doesn't have anything in the QuestName section, which is fine. Code will be added to the project saying that if the QuestName is blank, just give this item a chance to drop on every kill. Notice the GlimmeringRuby has something in it's QuestName tag. Code will be added to say that if the player is on this quest, then give this item the drop % chance, otherwise don't drop at all.

    4) Bring forth the code. So how did I make this work. First off I have to load and store the new xml tag QuestName. To do this, I needed to modify the GearDrop class in the RolePlayingGameDataWindows. I added another property in there called questName after the other 2 properties (I read somewhere that the order of the properties in your code is important. I think some reflection is being done with this content pipeline). So that looks like:

          

    /// <summary> 
            /// The content name of the gear. 
            /// </summary> 
            private string gearName; 
     
            /// <summary> 
            /// The content name of the gear. 
            /// </summary> 
            public string GearName 
            { 
                get { return gearName; } 
                set { gearName = value; } 
            } 
     
     
            /// <summary> 
            /// The percentage chance that the gear will drop, from 0 to 100. 
            /// </summary> 
            private int dropPercentage; 
     
            /// <summary> 
            /// The percentage chance that the gear will drop, from 0 to 100. 
            /// </summary> 
            public int DropPercentage 
            { 
                get { return dropPercentage; } 
                set { dropPercentage = (value > 100 ? 100 : (value < 0 ? 0 : value)); } 
            } 
     
            /// <summary> 
            /// The content name of the gear. 
            /// </summary> 
            private string questName; 
     
            /// <summary> 
            /// The content name of the gear. 
            /// </summary> 
            public string QuestName 
            { 
                get { return questName; } 
                set { questName = value; } 
            } 

    5) Then in the GearDropReader I added the read in code which looks like:

          

    public class GearDropReader : ContentTypeReader<GearDrop> 
            { 
                protected override GearDrop Read(ContentReader input, 
                    GearDrop existingInstance) 
                { 
                    GearDrop gearDrop = existingInstance; 
                    if (gearDrop == null
                    { 
                        gearDrop = new GearDrop(); 
                    } 
     
                    gearDrop.GearName = input.ReadString(); 
                    gearDrop.DropPercentage = input.ReadInt32(); 
                    gearDrop.QuestName = input.ReadString(); 
     
                    return gearDrop; 
                } 
            } 

    6) Now I have to do the write code. That is found in the RolePlayingGameProcessors project under Gear->GearDropWriter and will look like:

        public class GearDropWriter : RolePlayingGameWriter<GearDrop> 
        { 
            protected override void Write(ContentWriter output, GearDrop value) 
            { 
                output.Write(value.GearName); 
                output.Write(value.DropPercentage); 
                output.Write(value.QuestName); 
            } 
        } 

    7) So that is all that is needed to get the data from the xml file into our project for us to use. So now we have to actually use it. After digging around it seems the Monster is responsible for deciding what it will drop. So we'll modify the Monster class from the RolePlayingGameDataWindows class.There is a function called CalculateGearDrop in Monster.cs. I first needed to know what the current quest the player was on, so I changed the definition to include a Quest object. I'll explain later where I pass this into this function. So in here it's going to loop through each GearDrop item tag in the xml file and use the drop % to determine if the item will drop or not. Well we want some additional logic in here to determine if an item that is specific to a quest should drop at all. Here is what I did to achieve that.

     public List<string> CalculateGearDrop(Random random, Quest q) 
            { 
                List<string> gearRewards = new List<string>(); 
     
                Random useRandom = random; 
                if (useRandom == null
                { 
                    useRandom = new Random(); 
                } 
     
                foreach (GearDrop gearDrop in GearDrops) 
                { 
                    // if the gear drop quest name is blank then just do normal random 
                    // on this item 
                    if (gearDrop.QuestName.Length == 0) 
                    { 
                        if (random.Next(100) < gearDrop.DropPercentage) 
                        { 
                            gearRewards.Add(gearDrop.GearName); 
                        } 
                    } 
                    else 
                    { 
     
                        // if there is a name, then this item will only drop off this 
                        // mob if they are currently on the said quest name 
                        if (q.Name == gearDrop.QuestName) 
                        { 
                        // if we already met our gear requirements, then skip this 

                                        if (q.AreGearRequirementsMet) continue;

     

                        // item from possibly dropping, note that I created the below property from the Quest.AreRequirementsMet method. This method checks if the gear requirements and monster requirements are complete all in once property. I felt it better to split these out into their own properties since in this case I only care about the gear requirements. I then use both new properties inside the AreRequirementsMet property so existing code continues to work.                      if (q.AreGearRequirementsMet)                          continue
                            if (random.Next(100) < gearDrop.DropPercentage) 
                            { 
                                gearRewards.Add(gearDrop.GearName); 
                            } 
                        } 
                    } 
                } 
     
                return gearRewards; 
            } 
     

    8) Alright so this is all fine and dandy but your build will fail because we added another parameter to the function, but the actual call hasn't passed the 2nd parameter yet. So I basically did a Find for the function name CalculateGearDrop. Turns out it's being called in the RolePlayingGameWindows project under Combat->CombatEngine.cs. I modified the function call to look like:

    monster.CalculateGearDrop(Session.Random, Session.Quest) 

    After digging around in the Session object I noticed that the Quest property returned the current quest the player was on.

     That's it. We now have a monster that will drop a Glimmering Ruby ONLY if the player is on the quest. Also, once you have received the amount of Glimmering Rubys the quest requires, more kills of that same monster while on that same quest will not drop a Glimmering Ruby. Feel free to ask question or give comments. More to come...

                  
  • 26/06/2008 21:51 In reply to

    Re: RPG Toolkit How To:

    This is an outstanding tutorial!  Nice work!
    Matthew Picioccio
    XNA Developer Connection
  • 27/06/2008 1:48 In reply to

    Re: RPG Toolkit How To:

    I've added a link to this tutorial to the a new "Community Resources" section on the Role-Playing Game starter kit page.  :)
    Matthew Picioccio
    XNA Developer Connection
  • 27/06/2008 14:28 In reply to

    Re: RPG Toolkit How To:

    Very cool. I'm honored to be the first. :) This is good motivation to keep sharing my ideas. I hope others will join me.

     

    Next on my list are the screens. I have in the works a more non intrusive style of screens for the games inventory, statistics, etc. The screen system is pretty cool, and once you can follow the flow pretty simple to understand.


  • 30/06/2008 15:38 In reply to

    Re: RPG Toolkit How To:

    I've been having a great time playing with the RPG starter kit.  I've done a lot of customizations for it, but so many times I've added some classes or changed existing ones just to realize that I could've accomplished the same thing by just changing the XML itself without adding anything to the project code at all.

     This is a super tutorial and it provides a lot of valuable insight as to what is going on inside the ContentLoaders.

  • 10/07/2008 6:48 In reply to

    Re: RPG Toolkit How To:

    Hi great post, I like the direction you are taking the starter kit in.

    However, shouldn't the check for AreGearRequirementsMet on the Quest object be done within the if (q.name == gearDrop.QuestName) block?

    Otherwise you could be checking the gear requirements on a different quest ?

  • 10/07/2008 20:20 In reply to

    Re: RPG Toolkit How To:

    Good tutorial - it really helped me in my current plan to extend the quest mechanism - the first task being to add a hidden attribute.

    However - I came across a couple of comments, that I thought might be useful.

    The first is not a problem - but you can make an attribute optional by putting '[ContentSerializer(Optional = true)]' between the definition of the attribute type and the definition of the get/setters. Have a look at Quest.cs -> GearRewardContentNames for an example.

    The second comment is that you may have to watch out for custom Clone methods. In the case of Quest - this may need to have the attribute copy added to it as well - in my case, I need to look at the quest details in the QuestLogScreen.cs, so I had to enhance the Quest.Clone to copy across the hidden attribute.

    If anyone is interested, I will post a new thread on my plan and progress on enhancing the Quest functionality.

    Cheers
      Andy Stratton
  • 10/07/2008 23:01 In reply to

    Re: RPG Toolkit How To:

    FatalFrenchy:

    Hi great post, I like the direction you are taking the starter kit in.

    However, shouldn't the check for AreGearRequirementsMet on the Quest object be done within the if (q.name == gearDrop.QuestName) block?

    Otherwise you could be checking the gear requirements on a different quest ?

     

    You are correct. I made the change above. The editing of code boxes seems all messed up but I did my best.

  • 10/07/2008 23:02 In reply to

    Re: RPG Toolkit How To:

    Andrew Stratton:
    Good tutorial - it really helped me in my current plan to extend the quest mechanism - the first task being to add a hidden attribute.

    However - I came across a couple of comments, that I thought might be useful.

    The first is not a problem - but you can make an attribute optional by putting '[ContentSerializer(Optional = true)]' between the definition of the attribute type and the definition of the get/setters. Have a look at Quest.cs -> GearRewardContentNames for an example.

    The second comment is that you may have to watch out for custom Clone methods. In the case of Quest - this may need to have the attribute copy added to it as well - in my case, I need to look at the quest details in the QuestLogScreen.cs, so I had to enhance the Quest.Clone to copy across the hidden attribute.

    If anyone is interested, I will post a new thread on my plan and progress on enhancing the Quest functionality.

    Cheers
      Andy Stratton

     

    I was wondering how to make it optional. It was kind of a pain to go back and alter those xml files. :)

     

  • 04/08/2008 19:47 In reply to

    Re: RPG Toolkit How To:

    i like the tutorial but every time i do it i get an error,i am trying a different more faster and easier route to completeing the end result
  • 04/08/2008 19:49 In reply to

    Re: RPG Toolkit How To:

    We really can't help you if you don't give us more information, like what error you're getting.
    Jim Perry - Microsoft XNA MVP
    If people spent a minute searching the forums and reading the FAQs before posting I'd be out of a job.
      Got some XNA Game Studio/XNA Framework development info to share with the community? Put it on the XNA Wiki.
        Please mark posts as Answers or Good Feedback when appropriate.
  • 05/08/2008 21:33 In reply to

    Re: RPG Toolkit How To:

    hey

    thanks a lot for that tutorial, that was exactly what im looking for!! thx


  • 05/08/2008 22:02 In reply to

    Re: RPG Toolkit How To:

    i get an error when i add: session.quest at

    monster.CalculateGearDrop(Session.Random, Session.Quest)

    it says 2 is too much
  • 06/08/2008 17:04 In reply to

    Re: RPG Toolkit How To:

    does some1 know the answer pls :)
  • 06/08/2008 18:31 In reply to

    Re: RPG Toolkit How To:

    DeadlyInstinct:
    i get an error when i add: session.quest

    We need to know the exact error you're getting. Visual Studio has never issued the error message "2 is too much". I can assume that you mean it's saying there is no overload for CalculateGearDrop that takes two arguments, which means you haven't changed the declaration of CalculateGearDrop in Monster.cs as directed in the tutorial. Carefully check your work; make sure you've done EVERYTHING as directed in the tutorial. If you skip any of the steps, it won't work.

  • 06/08/2008 19:29 In reply to

    Re: RPG Toolkit How To:

    ye u were right, i meant that.

     

    but it still get this error and

     

    (sry i dont know exactly the english sentence for that error - cause i have the german editor :) )

    RolePlayingGameData.Quest includes no definition for "AreRequirementsMet".                   in Monster.cs


  • 06/08/2008 19:57 In reply to

    Re: RPG Toolkit How To:

    DeadlyInstinct:
    RolePlayingGameData.Quest includes no definition for "AreRequirementsMet". 

    Something is wrong with your copy of the code. Line 161 of Quest.cs quite clearly says "public bool AreRequirementsMet". Go to Quest.cs and search for it. If you can't find it, you may just want to start over with a new project.

  • 06/08/2008 23:11 In reply to

    Re: RPG Toolkit How To:

    it was all fine xD

    i just hat to retype "arerequirements" and restart the program

    now it works all perfect

     

    now i can start making quests ;)

     thx a lot

     

    i'll write you into credits if u want

  • 25/08/2008 3:44 In reply to

    Re: RPG Toolkit How To:

    so Andrew; should the code look like?

            private string questName;

            /// <summary>
            /// The content name of the inventory.
            /// </summary>
            [ContentSerializer(Optional = true)]
            public string QuestName
            {
                get { return questName; }
                set { questName = value; }
            }

    I take it [ContentSerializer(Optional = true)] allows the xml file to have or not have the content without causing a crash?


  • 12/10/2009 4:25 In reply to

    Re: RPG Toolkit How To:

    Yes Andrew, please post a thread on your plan/progress for enhancing quest functionality (if you havent already)

    Thanks

    I am not sure if the comments you made above were actually required to make this mod work.

    I am still getting

    Error    1    'RolePlayingGameData.GearDrop' does not contain a definition for 'QuestName' and no extension method 'QuestName' accepting a first argument of type 'RolePlayingGameData.GearDrop' could be found (are you missing a using directive or an assembly reference?)    C:\path\RolePlayingGameWindows1\RolePlayingGameProcessors\Gear\GearDropWriter.cs    37    32    RolePlayingGameProcessors


    Error    2    No overload for method 'CalculateGearDrop' takes '2' arguments    C:\path\RolePlayingGameWindows1\RolePlayingGameWindows\Combat\CombatEngine.cs    1633    29    RolePlayingGameWindows


    and


    Error    3    'RolePlayingGameData.Quest' does not contain a definition for 'AreGearRequirementsMet' and no extension method 'AreGearRequirementsMet' accepting a first argument of type 'RolePlayingGameData.Quest' could be found (are you missing a using directive or an assembly reference?)    C:\path\RolePlayingGameWindows1\RolePlayingGameDataWindows\Characters\Monster.cs    109    31    RolePlayingGameDataWindows

  • 12/10/2009 11:25 In reply to

    Re: RPG Toolkit How To:

    Slickman:
    Andrew Stratton:
    Good tutorial - it really helped me in my current plan to extend the quest mechanism - the first task being to add a hidden attribute.

    However - I came across a couple of comments, that I thought might be useful.

    The first is not a problem - but you can make an attribute optional by putting '[ContentSerializer(Optional = true)]' between the definition of the attribute type and the definition of the get/setters. Have a look at Quest.cs -> GearRewardContentNames for an example.

    The second comment is that you may have to watch out for custom Clone methods. In the case of Quest - this may need to have the attribute copy added to it as well - in my case, I need to look at the quest details in the QuestLogScreen.cs, so I had to enhance the Quest.Clone to copy across the hidden attribute.

    If anyone is interested, I will post a new thread on my plan and progress on enhancing the Quest functionality.

    Cheers
      Andy Stratton

     

    I was wondering how to make it optional. It was kind of a pain to go back and alter those xml files. :)

     



    Can you guys please explain this more explicitly - ie what files and what code are you changing here. 
Page 1 of 1 (22 items) Previous Next