The new boots and move vs moveXY


#1

I wonder if someone could post some example code of using the new boots, in particular showing a case where it does something better or differently than moveXY? I sorta understand the conceptual point about blocking vs not, but it isn’t obvious to me how I use that in practice… (cue that Yogi Berri quote we all see frequently)

Or maybe this will be introduced on a new level soon or is there documentation on this somewhere?

Also, what is the point of jump/leap? Is it faster than move or is it meant to be equivalent to moveXY?


Need Help for Backwoods Brawl and Sarven Brawl (python)
#2

Sure, lets say you are using a ranged character, and you want to move to coordinates (50, 50) and attack anything that comes within your attack range during that move. Below are examples showing the difference between moveXY and move for this situation.

# moveXY will block all other commands until it completes, so you will move to (50, 50) first, and only after you arrive will you attack enemies within range.  If you encounter an enemy en route, you will ignore it.
loop:
    self.moveXY(50, 50)
    target = self.findNearest(self.findEnemies())
    if self.distanceTo(target) < self.attackRange:
        self.attack(target)
# move is non-blocking, so you will move towards (50, 50), but will still be able to detect and attack enemies en route.
loop:
    self.move({"x": 50, "y": 50})
    target = self.findNearest(self.findEnemies())
    if self.distanceTo(target) < self.attackRange:
        self.attack(target)

Also, be aware that unlike moveXY, move will only function properly in a loop.

As for jump, I think its just intended as a way to move around faster. It does not seem to jump over obstacles or anything. Even on the Boots of Leaping the jump distance seems too short to be useful.


Headhunter is vicious
#3

I hope I am not being dense here… but what do you mean it will “only function properly in a loop”?

And I think I get that you start moving towards x,y but can then do other actions along the way (walk and chew gum!), but is there a point when the move is turned off? Like, is the move to x,y in effect until you get to x,y and then it turns off?

And what about cases where I actually do want my hero to focus on moving and not do other things (like pick up items) would I combine move and wait to insure the hero only moves in the direction I want for the duration of the wait?

Not sure what I am doing but I did manage to get my hero spinning like the tasmanian devil! Perhaps because I was combining the move with some “if self.now() > x” sort of code that worked with moveXY but I guess is not appropriate with move…


#4

As I understand it, move({“x”:x, “y”:y}) will move you in the direction of (x, y) for one cycle. So if it’s not in a loop, you will only move a very short distance in the direction of (x, y), you won’t move all the way there. Essentially, the move is ‘turned off’ after every cycle, which is why it needs to be in a loop to work. Try it and you’ll see what I mean. If you are moving towards an object you can also use move(object.pos).

Combining move and wait will only result in you standing still until the wait action is complete.

The move command sets self.targetPos(x, y), so you can check self.distanceTo(self.targetPos) to tell when you’ve reached your intended destination. If you want to focus on moving until you reach your destination, you can use something like:
if self.distanceTo(self.targetPos) < 1:
and just don’t do anything else until that condition is met.


#5

Thanks, I appreciate the help. But what exactly is a cycle?

OK, but that would be a “while” not “if”, right? Maybe like this? (if I wanted to move to an item and not do anything else until I got there)

while self.distanceTo( item.pos ) > 0:
   self.move( item.pos )

#6

Hi, you can think of each run through the loop as a cycle. In times past there were (probably still are) other methods than the plan method that is used for the levels now, which would behave like having an outer for loop around the plan. This would mean your code got run over and over for each ‘frame’ of the game (i.e. each cycle). Hope that helps?

So yes you could do this with the while loop you wrote. I think Glacian was thinking in terms of cycles, in which case the if block would do the trick, since it would be run each time the code cycled through.


#7

Yeah, some, although along the lines of sotonin’s question in another thread, I’m still a bit foggy about what the unit of movement is here. Like is it something based on percentage of time or percentage of distance? And is there a good way to adjust that unit? Like, if I want more emphasis on moving towards something compared to fighting an enemy, could I repeat the move method 3 times to move faster (given that it puts less emphasis on attacking enemies, of course).

Well, to give a concrete example, on backwoods treasure I basically had the moveXY code such that I would fight enemies and grab items most of the time, but if time was between 30 and 35 seconds, I’d move from one section (ogre-infested) to another (munchkin-infested). For things like that I temporarily need to ignore enemies and items.

I think I figured out how to do this, but it required a bit of restructuring to do it with move instead of moveXY. But having the code dynamically adjust to nearest item while attacking enemies certainly works much better with move than moveXY for sure. So that part is really nice as I had been too lazy to try and program partial movements with moveXY.


#8

The unit of movement is, how far your character can move in each cycle. So say the cycle time is a tenth of a second, then the code will be run every tenth of a second, and your character will move by whatever distance they can in that time (say 2meters/second for normal boots I think, so 0.2meters). The key thing is that for each cycle you pick one thing to do, so move, or attack; because the code doesn’t block on any line of code it all runs, and the last selected action is what happens. If you select a particular action more often (say move), then the character will do that more.

Does that make any sense?

But yes it does mean your code ends up reacting more dynamically to the environment, since you don’t get stuck trying to do one thing (say moving), when things have changed (an ogre has appeared for example).


#9

Yeah, thanks Matt, that makes sense. I’ll have to play around a bit more and get comfortable with it though.


#10

I think the easiest way to see the difference between the two is in the following code:

self.moveXY(10, 20)
loop:
    enemy = self.findNearestEnemy()
    if enemy:
        self.attack(enemy)

will move your hero to (10, 20), and only after arriving at (10, 20) or giving up (“I can’t get there!”) will the hero move and attack the enemy, while

self.move({"x":10, "y": 20})
loop:
    enemy = self.findNearestEnemy()
    if enemy:
        self.attack(enemy)

will cause the hero think about moving to (10, 20) and do so until the ‘if’ statement interrupts and sets the action to ‘attack.’ As this code is written, if an enemy is found, the hero will never complete the move to (10, 20), because the order to move is interrupted and not re-issued.

This is nice because it doesn’t lock the hero down into moving, which can be really annoying.


#11

Yeah, I get how it works now, although don’t you mean to have self.move inside the loop?

But my remaining question is what about the times when I want it to work like moveXY? I guess you can do a while like I posted above, but it’s to bad the new boots don’t give you access to both move and moveXY.


#12

So, you can get it to work that way with

while self.pos.x != 10 and self.pos.y != 20:
    self.move({"x":10, "y":20})

I agree it would nice just to keep the moveXY method available (we could even keep moveRight, moveLeft, etc.!)


#13

Poll: for those who have played with the move-based boots, how often have you wanted to also use moveXY? I could consider putting it back in. It seemed like a simplified version of the real API back when I decided to make the more advanced boots just use move, but if there are enough reasons to still use moveXY, maybe we can keep it around.


Closed Poll: Should move-boots also provide moveXY?
#14

I think preserving moveXY would be convenient on a number of levels. Not most, but a number of them. Basically any level where you do something in one place, then move to another location after some criterion is met.

Another nice thing is that whenever you redo some old level with new boots it would still run the old code.

Not a huge deal to me, just in the category of something that would be convenient.


#15

OK, I was just going to open a topic to ask “what the ‘point’ of jump was” but the question has already been asked by:

And there was an answer by:

Nobody, commented further on this…

Is this then the consensus: Jump is just a (silly) way to move faster??

(kind of like DDO, where it is faster to jump in the water than to walk/swim in it.)

If so then, how much faster. I notice the jump/leaping boots are both +2m/s. I have the +2.5m/s boots will jumpTo be faster than moveXY? (in terms of raw m/s)

Is there a difference between “move” and “jumpTo” on the same pair of boots besides the animation and movement speed? (why would one want to use move? to go slower?? :wink: )


#16

jumpTo() is more like moveXY() in that it is a one-time command, although it does seem like you can attack while enroute. Also, jumpTo() has a cooldown: seven seconds according to the thang editor.


#17

which can not be because I if I chain 2 jumpTo-commands with my boots of leaping, my hero will not wait 7 seconds, but more like 1 or 2 (didn’t measured that exactly).
I’ll investigate from my side.