Results 1 to 9 of 9

Thread: Warrior's Guild - A development journal

  1. #1
    Join Date
    Nov 2011
    Posts
    1,532
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default Warrior's Guild - A development journal

    I am sure most are familiar with the minigames - http://runescape.wikia.com/wiki/Warriors'_Guild. I was bored and I decided to see if it was at all possible to do something about the minigames.

    - Animation room
    - Catapult room
    - Dummy room
    - Keg room
    - Shotput room

    I have only started working on the first minigame, but I plan to work on others if I have incentives and time. This will be a development journal showing how it was done and some of the considerations I had when making. I hope this will open some of your eyes as to how a scripter makes his decisions, and hopefully learn something from it.

    5/21/2012 The catapult minigame - Is it at all possible?

    It was an idea I had sometime ago, and I decided to give it a go at one of the more challenging minigames among the 5, the catapult one.

    You should know how it works. You get a shield from that guy, and you stand on the stand to be shot by the catapult and change your shield to different styles in order to block and earn points.

    1. Setting up our player

    The difficulty in doing the minigame mainly has to do with the fact that we have very little time to determine what the object is and switch to the correct style. So in order to make our lives easier, the first thing we do is to position ourselves at a better angle.



    1. Getting object colors

    Now it's up to me to decide how this is going to work. Apparently we need to get the colors of the projectiles so that we can detect them. And this is where the 2nd problem comes in - colors false positive with the background, which is not good news for us.

    But before we look at our problem, we first define a simple data structure that will house our objects.

    Simba Code:
    type
      projectile = record
        color, tol, minc: integer;
        hmod, smod: extended;
        name: string;
      end;

    var projectiles: array of projectile;

    Now with our objects, after a bit of ACA-ing, I happen to only get some of the values...

    Simba Code:
    with projectiles[0] do
      begin
        color:= 1545178;
        tol:= 7;
        minc:= 30;
        hmod:= 0.11;
        smod:= 0.92;
        name:= 'magic';
      end;

      with projectiles[1] do
      begin
        color:= 6841443;
        tol:= 7;
        minc:= 30;
        hmod:= 0.48;
        smod:= 0.07;
        name:= 'stab';
      end;

      with projectiles[2] do
      begin
        color:= 8748670;
        tol:= 8;
        minc:= 25;
        hmod:= 0.00;
        smod:= 0.11;
        name:= 'slash';
      end;

    This is not good news at first sight, because I have only managed to get 3 of the required objects out of 4 in ACA. But if you think about it more deeply, if a detection does not return the either 3 as the result, it's very likely the object is the last one that we didn't have. It's not perfect, but at least it will work and we are gonna use that.

    3. Designing our script logic

    The minigame itself is simple enough. You see Magic projectile, you click magic shield, and you do that for other projectiles. So our next step would be scripting the part where you click the correct style.



    Apparently we can do the easy way where we simply get a point in each "box" and call Mouse(x, y, 15, 15, mouse_left) to deal with it. But that wasn't very satisfying and I wanted to use a Mousebox. To use a mousebox, however, I will have to do some trial and error to get the box areas with paintsmart.

    Simba Code:
    procedure Draw;
    var i: integer;
    begin
      for i:=0 to 3 do
        SMART_DRAWBox(IntToBox(564, 232+56*3, 564 + 156, 232 + 49 +56*3));
    //  for i:=0 to 3 do
    //    SMART_DRAWBox(IntToBox(575, 235 + 57*i, 575 + 135, 235 + 40 +57*i));
    end;

    So I went do do some trial and error, and in a few minutes I get these values. They draw our boxes very well, and now we can proceed to code our functions.

    In order to select a style, we need to decide which style is active at the moment, and whether we need to actually click another box to switch style. Effectively this means we need two functions - one that tells us what we're choosing now, another one that tells us to click a style.

    Simba Code:
    function ActiveStyle(style: string): boolean;
    var i: integer;
    begin
      case style of
        'stab': i:=0;
        'blunt': i:=1;
        'slash': i:=2;
        'magic': i:=3;
      end;
      SetColorToleranceSpeed(1);
      result:= CountColorTolerance(3908062, 564, 232+56*i, 564 + 156, 232 + 49 +56*i, 27) > 100;
    end;

    This decides what is active. Active means the lighter yellowish-orange borders in the box. To play it safe, CTS1 with 25 tolerance has never really failed me in circumstances with menus, which colors are mostly static Now, onto selecting the style, it keeps getting easier, isn't it?

    Simba Code:
    function SelectStyle(style: string): boolean;
    var i: integer;
        v: TVariantArray;
    begin
      result:= true;
      if ActiveStyle(style) then Exit;
      case style of
        'stab': i:=0;
        'blunt': i:=1;
        'slash': i:=2;
        'magic': i:=3;
      end;
      MouseBox(575, 235 + 57*i, 575 + 135, 235 + 40 +57*i, mouse_left);
      v:= [style];
      if not WaitFuncEx('ActiveStyle', v, 100, 2000) then
        result:=false;
    end;

    We use a simple WaitFuncEx here to make sure we the clicked style activates before returning the true/false values. In reality, however, we might not really need to check the success/failure, but the function is written to return a boolean just for the sake of easy debugging later.

    4. Deciding which projectile to defend against

    Here's the most important part of the script. Once we get onto the stand and gets barraged, we need to react to the projectiles and select the correct style. However, we know TPA finding is not perfect, and it might find the wrong object, so what we need to look for here is a more robust approach that gives high success rate. Also we must take care of the potential issue of switching between the styles too often.

    Here is an example. Assume the object finder returns the following series of decisions:

    Progress Report:
    Stab, magic, stab, stab, stab, blunt, slash, magic


    So what could this object be? Common sense tells us it could more likely be stab than others, because for this series of decisions "stab" style has the most number of occurrence. We are going to use this in our decision making function.

    Simba Code:
    function FindMode(a: TIntegerArray): integer;
    var i, m: integer;
        b: TIntegerArray;
    begin
      setlength(b, 4);
      for i:=0 to high(a) do
        Inc(b[a[i]]);
      m:= max(b[0], max(b[1], max(b[2], b[3])));
      for i:=0 to high(b) do
        if b[i]= m then
          result:= i;
      writeln('mode: ' + IntToStr(m) + ' style: ' + IntToStr(result));
    end;

    The above concept is realized into the above block of code, returning the mode of a sample. In our application, we will call our object finders a number of times, and use the found mode as the guess of what the object might be. This is far from being perfect, but robust enough to give high success rates, given our object finders are accurate.

    Simba Code:
    function DecideStyle: string;
    var i: integer;
        a: TIntegerArray;
    begin
      setLength(a, 7);
      for i:=1 to length(a) do
        FindProjectile(a[i-1]);
      case FindMode(a) of
        0: result:= 'stab';
        1: result:= 'blunt';
        2: result:= 'slash';
        3: result:= 'magic';
      end;
      writeln('decide style: ' + result);
    end;

    Here is the meat we're looking for. We apply our knowledge of statistics and use the mode to guess the current projectile. We have also decided we do a sampling of 7 times and use the data to make our decision. Of course, this number can be changed, but remember TPA finding takes time and we need to balance between making a decision too quickly and missing the time to make a decision and get hit by the catapult.

    5. Filling in the blank - setting up our object finder

    All our pretty talk does not work if our object finder returns trash. This is also the most difficult part of setting up the script correctly - determining the correct style given the TPA finds.

    I am not going to give the exact code here. It worked for me one day, it messed up on the other, so it's pretty much a trial and error thing, but with the code below you will start to see the logic and how the pieces fit together.

    Simba Code:
    function FindProjectile(var v: integer): boolean;
    var i, x, y: integer;
        s: TIntegerArray;
        tpa: TPointArray;
        pass: boolean;
    begin
      SetLength(s, 3);
      SetColorToleranceSpeed(2);
      v:=-1;
      for i:=0 to high(projectiles) do
      begin
        SetColorSpeed2Modifiers(projectiles[i].hmod, projectiles[i].smod);
        FindColorsTolerance(tpa, projectiles[i].color, MSX1, MSY1, MSX2, MSY2, projectiles[i].tol);
        s[i]:= length(tpa);
      end;
      writeln(format('magic: %d stab %d slash %d', [s[0], s[1], s[2]]));

      //Process the colors
      //Code your own logic here
      if (s[0] >= projectiles[0].minc) then
        v:=3 //magic
      else if (s[1] >= 25) and (s[2] <= 25) then
        v:= 0  //stab
      else if {(s[1] <= 50) and}  (s[2] >= 25) then
        v:= 2  //slash
      else if (v=-1) then  //blunt
        v:= 1;

      case v of
        0: writeln('projectile guess: stab');
        1: writeln('projectile guess: blunt');
        2: writeln('projectile guess: slash');
        3: writeln('projectile guess: magic');
      end;
    end;

    Basically what we do here is to iterate through our objects and get the color counts. Our decision will be based on how many colors of each style we find, and we decide what values will fit to which style. Because colors change all the time, something that worked yesterday might not work today, and I'm leaving it here for you to do the trial and error and relate the found color counts to a particular style.

    To facilitate the process I also have a small snippet to do the sampling without select a style. This might come in handy for observing.

    Simba Code:
    procedure Test;
    var s: integer;
    begin
      while true do
      begin
        FindProjectile(s);
        wait(100+random(50));
      end;
    end;

    6. Putting it all together - main loop

    This is quite self-explanatory. I never really expect it to be unattended, so I don't go over the crap of setting up the player angles with the script. Also FindNormalRandoms seems to misdetect the area as Cap'n Arnav random, so I am forced to drop it here. All in all, it will be a babysit script, you will eventually die depending how well your colors fit and how well the object finder makes the correct decisions, but for an attempt to simply cut you some slack in playing the minigame, it's a good try nevertheless.

    Simba Code:
    procedure MainLoop;
    var style: string;
    begin
      reincarnate:= true;
      while LoggedIn do
      begin
    //    FindNormalRandoms;
        FindDead;
        SelectStyle(DecideStyle);
        wait(100+random(50));
      end;
    end;

    End result



    The script is made and tested in action. Needless to say I died a few times, but with some tweaking and babysitting for an hour or 2, I have already accumulated enough tokens for hours of defender hunting if used in the Multi-token mode.

    Script is attached for reference. ACA colors might need redo, and you're expected to make FindProjectile work for your own circumstances. It's one of the more difficult challenges for which I don't think it's worth the efforts to make it fully automatic, so I will just leave it here for those who're willing to DIY to get their tokens
    Current activity: Recovering from vacation
    - Nulla pars vitae vacare officio potest -
    SRL membership? Can I buy that?
    Scripts - AGS - SWF - WAR - EMS - W100S-EM
    If you need scripting help, you can pm me. Remember, if you need help you have to ask for it properly though

  2. #2
    Join Date
    Dec 2011
    Location
    The Netherlands
    Posts
    1,631
    Mentioned
    47 Post(s)
    Quoted
    254 Post(s)

    Default

    Nice progress so far
    I was thinking about making a Warriors Guild script aswell, but mine would only kill the animated sets and the cyclopses. This is even better
    What about adding Cyclops Killing aswell to make it truly AIO?

    Script source code available here: Github

  3. #3
    Join Date
    Nov 2011
    Posts
    1,532
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by J J View Post
    Nice progress so far
    I was thinking about making a Warriors Guild script aswell, but mine would only kill the animated sets and the cyclopses. This is even better
    What about adding Cyclops Killing aswell to make it truly AIO?
    AIO is not worth the efforts in my opinion They're very different minigames and some of them I think should only be babysit, say catapult.

    As for cyclope killing, it's another thing as well. One simple way is to put narcle and deal with it. Not on my list anyway :P

    The animation game has been on my todo list for my while I am not sure if it is next on my list though. But I am guessing a little competition can't really hurt.
    Current activity: Recovering from vacation
    - Nulla pars vitae vacare officio potest -
    SRL membership? Can I buy that?
    Scripts - AGS - SWF - WAR - EMS - W100S-EM
    If you need scripting help, you can pm me. Remember, if you need help you have to ask for it properly though

  4. #4
    Join Date
    Feb 2006
    Location
    Canada
    Posts
    2,254
    Mentioned
    21 Post(s)
    Quoted
    238 Post(s)

    Default

    Nice work dude! A question for you, what is your current success rate with defending against the correct incoming object? A method that just popped into my head while reading your blog would be to just do getcolor() on a point where the projectile crosses every time (I don't know if all 4 projectile types take the exact same route every time) and when it returns a different value than whatever the background color would be, make some type of guess at which projectile it was using a tolerance at first then checking if exp/token were gained do determine if that was a correct prediction. Anyways I'm rambling, nice work!

  5. #5
    Join Date
    Nov 2011
    Posts
    1,532
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by cause View Post
    Nice work dude! A question for you, what is your current success rate with defending against the correct incoming object? A method that just popped into my head while reading your blog would be to just do getcolor() on a point where the projectile crosses every time (I don't know if all 4 projectile types take the exact same route every time) and when it returns a different value than whatever the background color would be, make some type of guess at which projectile it was using a tolerance at first then checking if exp/token were gained do determine if that was a correct prediction. Anyways I'm rambling, nice work!
    It highly depends on the colors imo. If I set up the FindProjectile correctly and the colors don't change a lot, the success rate can be more than 80%. In fact there was one day where I got quite lucky and it basically played the minigame with only 5 fails for 20-30 minutes.

    Usually if it doesn't go well, it will fail a particular object more often, so it would be 60-75% in average.
    Current activity: Recovering from vacation
    - Nulla pars vitae vacare officio potest -
    SRL membership? Can I buy that?
    Scripts - AGS - SWF - WAR - EMS - W100S-EM
    If you need scripting help, you can pm me. Remember, if you need help you have to ask for it properly though

  6. #6
    Join Date
    Nov 2011
    Location
    Australia
    Posts
    158
    Mentioned
    0 Post(s)
    Quoted
    13 Post(s)

    Default

    no offence but one of the scripters made me a token script within hours of requesting it and i used it to get 65k tokens within a day. link: http://villavu.com/forum/showthread.php?t=69404

  7. #7
    Join Date
    Dec 2011
    Location
    The Netherlands
    Posts
    1,631
    Mentioned
    47 Post(s)
    Quoted
    254 Post(s)

    Default

    Quote Originally Posted by awesomem8 View Post
    no offence but one of the scripters made me a token script within hours of requesting it and i used it to get 65k tokens within a day. link: http://villavu.com/forum/showthread.php?t=69404
    What is the point of posting this? Er1k is obviously working on a much more advanced way of getting tokens, which is a harder activity aswell. The script you used barely used any randomization.

    Anyways, are you still working on this Er1k?

    Script source code available here: Github

  8. #8
    Join Date
    Nov 2011
    Location
    England
    Posts
    3,072
    Mentioned
    296 Post(s)
    Quoted
    1094 Post(s)

    Default

    Quote Originally Posted by J J View Post
    What is the point of posting this? Er1k is obviously working on a much more advanced way of getting tokens, which is a harder activity aswell. The script you used barely used any randomization.

    Anyways, are you still working on this Er1k?
    I believe he isn't due to the fact he wanted to make a aio warriors guild but didn't want to undertake killing the monsters that drop the defenders, I may be wrong though.

  9. #9
    Join Date
    Nov 2011
    Posts
    1,532
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Well I am actually on a break, but last time I was still scripting, I had the dummy game half completed. Going on a vacation next week, so I aint sure
    Current activity: Recovering from vacation
    - Nulla pars vitae vacare officio potest -
    SRL membership? Can I buy that?
    Scripts - AGS - SWF - WAR - EMS - W100S-EM
    If you need scripting help, you can pm me. Remember, if you need help you have to ask for it properly though

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •