Castetime suggestion

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Message
Author
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Castetime suggestion

#1 Post by rock5 » Fri Jun 11, 2010 1:58 am

From what I understand, if a spell is caste with a castetime of > 0 then it waits for that time before continuing.

If it failed to caste that spell then it will still wait and do nothing while waiting.

Is it possible that, while waiting, it checks GetSkillCooldown? If it failed to caste then GetSkillCooldown will return 0 so the bot can continue without having to finish the wait. This will, of course, need tab and tab numbers for the skill.

What do you think?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#2 Post by Administrator » Fri Jun 11, 2010 12:09 pm

This could cause issues with latency, I expect. When does the client count a skill as on cooldown? As soon as you attempt to use it (and assume it's on cooldown till the server says it's not), or does it start when the server says so?

If it doesn't go on cooldown till the server responds, telling the client that the skill is now on cooldown, then it could cause problems. It would always assume the skill failed to go off. This can be corrected by checking that some time has elapsed (say, 500ms) before actually checking the cooldown that way. It would work a good portion of the time.

Another problem, though, is the execution of macros at quick intervals. Since skills are checked very rapidly by the bot, this means that it would be spamming the macro execution code, which is already causing issues for some people.

It's a good idea, but there's a few problems to work out first.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#3 Post by rock5 » Fri Jun 11, 2010 1:27 pm

Administrator wrote:This could cause issues with latency, I expect. When does the client count a skill as on cooldown? As soon as you attempt to use it (and assume it's on cooldown till the server says it's not), or does it start when the server says so?

If it doesn't go on cooldown till the server responds, telling the client that the skill is now on cooldown, then it could cause problems. It would always assume the skill failed to go off. This can be corrected by checking that some time has elapsed (say, 500ms) before actually checking the cooldown that way. It would work a good portion of the time.
Seems I misunderstood the meaning of GetSkillCooldown(). It's for cooldowns (duh!). I meant caste time. Looks like the correct function is UnitCastingTime. eg.
local name, maxValue, currValue = UnitCastingTime("player")

I did some manual testing by clicking Heal and spamming this function and a timer with a macro. Looks like it takes about 700ms before it returns values indicating that it is casting. As long as you wait for about a second you should only need to check this once at the 1 second mark. A bonus to using this is you could then readjust the remaining wait time to match what is returned from this function for better accuracy. Otherwise if it returns 0 then you stop waiting.
Administrator wrote:Another problem, though, is the execution of macros at quick intervals. Since skills are checked very rapidly by the bot, this means that it would be spamming the macro execution code, which is already causing issues for some people.
I thought that when casting a spell that takes time to caste, that the bot goes into a wait state. I thought checking this function during that time shouldn't interfere with anything. Also it may only be feasible for spells that take longer than 1 second to caste and you would only check it once per spell so I wouldn't expect it to happen often enough to cause any noticeable problems. Of course I could be wrong.

Here is how I expect the logic to work.

Code: Select all

Caste spell
if spellcastetime > 1 then
    wait 1 second
    local name, maxValue, currValue = UnitCastingTime("player")
    if maxValue == 0 (or maybe name == nil) then -- didn't caste spell
        return -- stop waiting
    else -- spell is casting
        wait a further (maxValue - currValue) seconds 
    end
end
What do you think?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#4 Post by Administrator » Sat Jun 12, 2010 2:12 am

Skill cast time is totally different. That would work fairly well with the way the code is set up. Give it a shot and let me know what happens.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#5 Post by rock5 » Sat Jun 12, 2010 7:16 am

Administrator wrote:Skill cast time is totally different. That would work fairly well with the way the code is set up. Give it a shot and let me know what happens.
I'm looking at the "wait" part of casting at line 301 of player.lua. I think to do a proper job I need to ask some questions about it to understand what's happening here.

Line 306 and 323

Code: Select all

				if( self:check_aggro_before_cast(JUMP_TRUE, skill.Type) and
				   ( skill.Type == STYPE_DAMAGE or
					 skill.Type == STYPE_DOT ) ) then	-- with jump
					printf(language[82]);	-- close print 'Casting ..." / aborted
					return;
				end;
1. If "self:check_aggro_before_cast(JUMP_TRUE, skill.Type)" has returned "true" doesn't that mean it has jumped and stopped casting? Why do you check "skill.Type" again after it was already checked in "check_aggro_before_cast"? Wouldn't you want to "return" regardless, now that casting has stopped?

To paraphrase the code:

Code: Select all

			while( not self.Casting ) do
				yrest(50);
				self:update();
				if( deltaTime(getTime(), startTime) > skill.CastTime*1000 - settings.profile.options.SKILL_USE_PRIOR ) then
					self.Casting = true; -- force it.
					break;
				end
			end;
			while(self.Casting) do
				yrest(10);
				self:update();
				-- leave before Casting flag is gone, so we can cast faster
				if( deltaTime(getTime(), startTime) > 
				  skill.CastTime*1000 - settings.profile.options.SKILL_USE_PRIOR ) then
					break;
				end
			end
The first while loop happens if, like you said, it takes time for the client to register that it is casting. It loops every 50 ms until self:update() causes self.Casting to equal true. Then it moves to the second while loop.

2. The "if" statement is just in case the skill.CastTime passes without self.Casting becoming true. I can only ever see this happening if the skill failed to caste. Does that sound right?

3.Also why do you set self.Casting to true if the CasteTime has already finished? I'm suspecting it doesn't matter the value of self.Casting when you leave this area so all it will do is cause the script to enter the second loop needlessly.

The second while loop is when the client has already registered that it is casting and loops every 10 ms until the skill.CastTime is over.

4. If the skill ends or is interrupted before skill.CastTime is over does self:update change self.Casting to false?

5. This is not necessary but where does deltaTime come from? I understand what it does but I don't see any reference to it in lua or game functions references. Is it a unique Micromacro function?

So for the changes I make to work properly it needs to;
-continue with the rest of the function if the caste was successful
-"return" if it failed to caste or it jumps and interrupts it's caste.
-use settings.profile.options.SKILL_USE_PRIOR to reduce the wait time
-use check_aggro_before_cast
That sound right?

Answer these questions and I'll do my thing.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#6 Post by rock5 » Tue Jun 15, 2010 11:23 am

I realized the bot does know that the skill failed to caste, it just doesn't act on it.

So the fix is quite simple really, just stop waiting if 1.5 seconds pass without casting becoming true.

2 questions before I commit though.

When it stops waiting it needs to finish then line similar to line 309 (printf(language[82]); -- close print 'Casting ..." / aborted). Should I use that or should I create another language item saying something like "Failed to caste" or "Cast timed out"?

I have a modified version of getpos.lua I call getid.lua that shows the ID of anything under the mouse. I latter added the distance to it as well. Both useful bits of information. Do you think it is useful enough to add to the commit?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#7 Post by Administrator » Tue Jun 15, 2010 1:36 pm

Yes, a second language string should be added for the casting failed text.

I'm not sure how useful getid would be for most people. I do believe that, with debugging enabled, this information is printed out when starting bot.lua.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#8 Post by rock5 » Tue Jun 15, 2010 2:08 pm

Administrator wrote:Yes, a second language string should be added for the casting failed text.

I'm not sure how useful getid would be for most people. I do believe that, with debugging enabled, this information is printed out when starting bot.lua.
By debugging do you mean setting DEBUGGING to "true"? Nothing seems to change if I do that.

The reason I made getid is because if I want to harvest an interactable object, like a quest collect item or a mailbox or bulletin board, I have to set harvest to "test" first, run it to get the id then change it to the value. I find it easier to just run getid in another micromacro window, point at the item with my mouse and read the value.

The reason I added the distance as well is because when navigating narrow passages, to avoid targeting mobs through walls you had to reduce the MAX_TARGET_DIST. Normally you had to guess or just try different values until you were happy with the result. With getid you can point to the offending mob and see exactly its distance to you and set it at the right value first time.

But if you don't think it's useful I wont add it.

Edit: Forgot to ask. Do I just put English versions in the other language files until someone can translate it? Or should I use a translator like Google translator?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#9 Post by Administrator » Tue Jun 15, 2010 3:32 pm

Go ahead and commit it if you'd like.

You don't need to do other translations. Just the English change would be fine for now. Any missing strings for other languages will inherit from the English texts.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#10 Post by rock5 » Tue Jun 15, 2010 10:43 pm

Administrator wrote:Go ahead and commit it if you'd like.

You don't need to do other translations. Just the English change would be fine for now. Any missing strings for other languages will inherit from the English texts.
Done.

I also updataed RBAssist.

I might still look into calling UnitCastingTime once after casting becomes true to fine tune the wait time. Or maybe to avoid using the macro we could use the moment at which casting becomes true to do the same thing. I'll look into it. Might help with a more accurate use of settings.profile.options.SKILL_USE_PRIOR. This will take a bit more work though.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#11 Post by rock5 » Thu Jun 17, 2010 6:35 am

I've been doing some extensive testing of the timing of skills and I wanted to share my findings. And based on these findings I've had what I think is a great idea to rework the timing.

The total time it takes to cast spells from start to start is made up of 3 parts.
1. The time between the cast action and the player.casting equaling true
2. The time player.casting = true
3. The time between the end of the cast and the next cast action.

Findings:
What I found was the first part fluctuated wildly between 100ms to over 1000ms. The second part was very consistently 100-200ms more than the spell casttime. The last part was consistently 1050-1150ms. I guess this represents the time it takes to execute the code between casts. I suspect this will vary bases on the systems CPU.

History
If I remember correctly SKILL_USE_PRIOR was introduced in the hopes that we could undercut the end of the casting to cast faster like we do when playing manually but it often didn't work properly so now it's not much used and is defaulted to 0. I believe a fail-safe has also been put into place so it won't cast while casting = true. So SKILL_USE_PRIOR can only be used to compensate for the time it takes to execute the code between casts. I believe the problems with SKILL_USE_PRIOR was due to the fluctuating first part of the spell messing up the timing.

Testing
What I have been testing is resetting the timer when the second part starts. Then SKILL_USE_PRIOR can be used more confidently to undercut the end of the spell and cast as fast as possible. With a bit of testing I found my optimum value for SKILL_USE_PRIOR to be about 850ms and because the timing excludes the wildly unpredictable first part, it's quite reliable no matter how crowded the area.

Caveats
The problem with this is the last part might take longer or shorter on another machine. Also it's probably not a good idea trying to predict how long some code will take to execute.

Then I had my great idea. What if we did the waiting after the "code between casts" and before casting the next spell?

Currently it goes something like this;

Code: Select all

cast spell
record cast time
wait until spell.casting = true
wait until spell.casting = false or current time - cast time > spell.castime - SKILL_USE_PRIOR
do code between casts
To make the best use of this you need to predict how long "code between casts" is going to take and set SKILL_USE_PRIOR accordingly. But you still will have problems with the first part whose time is unpredictable.

But what if we did this instead?

Code: Select all

wait until lastspell.casting = false or current time - cast time > lastspell.castime - SKILL_USE_PRIOR
cast spell
wait until spell.casting = true
record cast time
lastspell=spell
do code between casts
This way the waiting is done after the "code between casts" and the cast is done immediately after the wait. No need to predict the code execution time.

What do you think? If it turns out as reliable as I think, we can get rid of the fail safe so we can cast 100-200ms before the end of the last spell for super fast reliable casting.

I'll need some positive feedback encouraging me to do this because it will take some work.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#12 Post by Administrator » Thu Jun 17, 2010 12:37 pm

This could potentially work, but I expect problems. If the character tries to unstick, move closer, use potions, or any other number of actions, this would (in most cases) break the casting of the skill. It's not a bad idea though. Certainly worth testing, at the least.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#13 Post by rock5 » Thu Jun 17, 2010 12:58 pm

Administrator wrote:This could potentially work, but I expect problems. If the character tries to unstick, move closer, use potions, or any other number of actions, this would (in most cases) break the casting of the skill. It's not a bad idea though. Certainly worth testing, at the least.
Didn't think of that. Worth considering. Are they the only things it checks between to consecutive casts? I might do a few tests with a few things before proceeding. Can you suggest anything else I should check?

What I might do is, if it doesn't need to do anything else then it will get to the wait time before casting the next spell, still in a casting state. Then we can try to undercut the next spell cast.

If it need to do something else, like drink a potion, then it waits until the casting is finished. I have to do some serious think about it though..
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#14 Post by rock5 » Fri Jun 18, 2010 1:24 am

This is what I'm thinking of doing.

First create a function to wait till the end of the current cast if casting = true because I'll need to use it in a few places namely before using a potion and before casting the next skill. For this I'll need a global variable for the skill start time but I'm not sure where I'm supposed to put it. What should I use? player.LastSkillStartTime maybe? I'd also need player.LastSkillCastTime. Maybe instead I could save the whole skill object player.LastSkill? Then I could use player.LastSkill.LastCastTime and player.LastSkill.CastTime? Sorry but I don't know the preferred way of doing things.

Things like moving closer or taking a step back I just added "and not player.casting" to the if statement so it doesn't do it while casting.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#15 Post by Administrator » Fri Jun 18, 2010 12:00 pm

I would recommend using two variables rather than an additional table (player.LastSkill). You'll need to add these variables to pawn.lua in the constructor function (CPawn = class...). They will then be inherited by CPlayer.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#16 Post by rock5 » Sun Jun 20, 2010 10:57 am

I'm very happy with the result of my work.

It very reliably undercuts spell casts now saving around 400ms per cast when following a timed cast after another timed cast. Instant casts seem to cast quicker too. Alternating timed and instant casts took me a while to get right but I noticed even the unedited version has trouble with that, occasionally missing instant casts.

Pretty much now, what micromacro says it casts it actually casts unless something interrupts it or stops it from casting.


What's the next step? Do I commit it so people can try it out?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5331
Joined: Sat Jan 05, 2008 4:21 pm

Re: Castetime suggestion

#17 Post by Administrator » Sun Jun 20, 2010 11:49 am

Yes, commit it so everyone can test it. If it breaks, they can always revert.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#18 Post by rock5 » Mon Jun 21, 2010 1:28 am

Ok. I've committed my changes to revision 462?

My findings:
  • When alternating instant and timed skills you wont notice much difference although the original tends to occasionally fail to cast instant casts after timed casts.
  • When stringing 3 or more instant casts the original nearly always misses one. Mine occasionally misses one. Also when the original successfully casts all 3 for some reason it casts them with large pauses between them. Mine casts 3 instant casts relatively quickly.
  • Where mine really shines is when timed casts follow timed casts. It should always successfully undercut the spell end saving from 200-500 ms over the original that waits for casting to end. This should be regardless of slow connections
Things to not:
  • Potions can be used at the spell undercut point so I've set it up this way. I'm unable to test it though. It should work.
    I increased the yrest after instant casts from 500ms to 700ms to slightly reduce the number of missed instant casts.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

Starrider
Posts: 164
Joined: Sat May 01, 2010 7:04 am
Location: Germany

Re: Castetime suggestion

#19 Post by Starrider » Tue Jun 22, 2010 8:33 pm

I wrote it in another Topic, the changes are a little bit bad. i dont know, but the bot doesnt cast fast anymore, the german server i play has high ping differences 31/41/68 Ping maybe some casts are lost, but the urgent heal cast doesnt work correctly/anymore. Also the bot seems to be slower

edit: i have compared v462 with v463:
r462 is much faster in attakings, i don't know why,

before r462+ i could use urgend heal directly two times with this code:

Code: Select all

if( 24 > player.HP/player.MaxHP*100 ) then
       player:cast("PRIEST_HOLY_AURA");
       player:cast("PRIEST_URGENT_HEAL");
       player:cast("PRIEST_URGENT_HEAL");
   end;
now i got at the second cast an error messsage that it failed to cast a second time.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Castetime suggestion

#20 Post by rock5 » Wed Jun 23, 2010 9:49 am

Starrider wrote:i have compared v462 with v463:
r462 is much faster in attakings, i don't know why,
The only difference between 462 and 463 is, when drinking potions, 462 will get an error and 463 wont. If you didn't drink any potions then they should perform exactly the same.
Starrider wrote:before r462+ i could use urgend heal directly two times with this code:

Code: Select all

if( 24 > player.HP/player.MaxHP*100 ) then
       player:cast("PRIEST_HOLY_AURA");
       player:cast("PRIEST_URGENT_HEAL");
       player:cast("PRIEST_URGENT_HEAL");
   end;
now i got at the second cast an error messsage that it failed to cast a second time.
I think I may have introduced a problem that's causing the problems with urgent heal. I'm still looking into it. It may take awhile.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests