SRL Archive - Bugs

WalkPath - Major CPU Usage


rogeruk

2011-03-18 08:56:20

Not sure if its a known bug..

Walking with WalkPath on one SMART caused CPU to go from ~20% to around 85-90%. Using two SMART's if they were both walking the CPU load would reach 100%.

I can run 4 clients when not using WalkPath.

Can anyone look into it?

Floor66

2011-03-18 10:33:30

I've been running 2 clients, using WalkPath, haven't noticed this :/ Maybe it's because of my CPU. I'll try it on a weaker CPU later.

rogeruk

2011-03-18 12:02:03

Running Win7 X64, Dual core 3.2GHz. 4 GB Ram. Nvidia 8800GTS 512

Floor66

2011-03-18 12:45:26

Well at those specs it shouldnt lag, really. I've got a quadcore q9550 @ 2.8ghz with an asus eah hd4890.

edit:
experienced the exact same on my laptop just now. strange :S

rogeruk

2011-03-18 18:11:00

From: Floor66
Well at those specs it shouldnt lag, really. I've got a quadcore q9550 @ 2.8ghz with an asus eah hd4890.

edit:
experienced the exact same on my laptop just now. strange :S


Lag or?.

Another user i spoke to is getting the same problem. Walking with WalkTile or WebWalk is fine

Floor66

2011-03-18 18:13:59

The lag, yeah. Im down to 1 SMART cause of it now.

Bad Boy JH

2011-03-18 23:34:33

Interesting, I always thought that the WalkPath procedure was a little "bloated" and over complicated. But I wouldn't have thought it would do this…

Feroc1ty

2011-03-19 01:04:47

I personally use my own WalkPath function (which I have stored in an include), because I always thought the reflection one was lacking; here it is… hoping it will bring some use to anyone (and hopefully someone will try to optimize it?).

{ Feroc1ty's walking include...

Functions of the include:

fWalkPath(tpa:TTileArray);

}

procedure MoveToBox(box:TBox);
var tpt:TPoint;
ttl:TTile;
begin
repeat
ttl := Tile(RandomRange(box.x1, box.x2),RandomRange(box.y1, box.y2));
sleep(500+random(300));
until TileOnMM(ttl);
tpt := TileToMM(ttl);
Mouse(tpt.x, tpt.y, 3, 3, true);
R_FindRandoms;
FindNormalRandoms;
end;

procedure AssimilatePoint(var point:TPoint;target:TPoint;range:integer);
begin

repeat
if point.x > target.x then
begin

if (point.x - range) > target.x then
begin
point.x := point.x - range;
end else
begin
point.x := target.x;
end;

end else
begin

if point.x = target.x then break;

if (point.x + range) < target.x then
begin
point.x := point.x + range;
end else
begin
point.x := target.x;
end;

end;
until (true = true);

repeat
if point.y > target.y then
begin

if (point.y - range) > target.y then
begin
point.y := point.y - range;
end else
begin
point.y := target.y;
end;

end else
begin

if point.y = target.y then break;

if (point.y + range) < target.y then
begin
point.y := point.y + range;
end else
begin
point.y := target.y;
end;

end;
until (true=true);

end;

procedure fWalkPath(tpa:TPointArray;reverse:boolean);
var i,target:integer;
t:TPoint;
begin
fDebug('Feroc1ty Walk','Begining to walk a path in reverse('+tostr(reverse)+')');
if not reverse then
begin

for i := high(tpa) downto 0 do
begin
if TileOnMM(PointToTile(tpa[i])) then
break;
end;

if i = -1 then
begin
if DistanceTile(GetMyPos,tpa[0]) > DistanceTile(GetMyPos,tpa[high(tpa)]) then
target := high(tpa)
else
target := 0;
repeat
t := GetMyPos;
AssimilatePoint(t, tpa[target], 10);
WalkToTile(t, 4, 2);
until TileOnMM(PointToTile(tpa[target]));
i := target;
end;

for i := i to high(tpa) do
begin
MoveToBox(PtToBox(tpa[i],4));
end;

end else
begin

for i := 0 to high(tpa) do
begin
if TileOnMM(PointToTile(tpa[i])) then
break;
end;

if i = -1 then
begin
if DistanceTile(GetMyPos,tpa[0]) > DistanceTile(GetMyPos,tpa[high(tpa)]) then
target := high(tpa)
else
target := 0;
repeat
t := GetMyPos;
AssimilatePoint(t, tpa[target], 10);
WalkToTile(t, 4, 2);
until TileOnMM(PointToTile(tpa[target]));
i := target;
end;

for i := i downto 0 do
begin
MoveToBox(PtToBox(tpa[i],4));
end;

end;

R_FFlag(0);

end;

Coh3n

2011-03-19 03:01:52

It's because there's no wait in the procedure. The same thing happened in MSI's path walking function. Once we added a small wait (200-500ms), the lag/CPU usage people were experiencing went away.

Floor66

2011-03-19 04:37:35

Ah I've seen that before, Coh3n. For me it was especially in loops; no waits there = lag.

Bonfield

2011-03-19 04:37:40

On the subject of rewriting/optimizing walkpath how about adding a reverse Boolean? Shouldn't be to hard but could be a drama with breaking scripts

Floor66

2011-03-19 04:48:03

I support that idea, Bonfield. Right now I have a big case to check if the path needs to be inverted/stay this way and the inverting costs me about 4-5 lines which -could be- just 1 line.

Or maybe add a WalkPathBack or something similar? To not break scripts.

Feroc1ty

2011-03-19 12:40:07

From: Floor66
I support that idea, Bonfield. Right now I have a big case to check if the path needs to be inverted/stay this way and the inverting costs me about 4-5 lines which -could be- just 1 line.

Or maybe add a WalkPathBack or something similar? To not break scripts.


You can use my code, :P.

It has invert path boolean, and if your character is out of the range of the path it will automatically move to the closer end of the path.

EDIT: If your path is messed out though it might get stuck in an infinite loop (it would have to be REALLY messed up though, because it generates a random tile, and a random point, until that point is on the minimap,) meaning the path would have to have points that are higher in distance than ((size of MM) + (2 tiles) + (3 pixels)) on path maker.

grats

2011-03-19 12:51:53

I've been asking what caused the extreme lag when walking on small spec'd virtual machines for a while.. I'd assume it is the WalkPath?

It definitely peaks the cpu in all of my virtual machines and lags very bad (less than 1 FPS)

Feroc1ty

2011-03-19 12:53:18

From: grats
I've been asking what caused the extreme lag when walking on small spec'd virtual machines for a while.. I'd assume it is the WalkPath?

It definitely peaks the cpu in all of my virtual machines and lags very bad (less than 1 FPS)


Good way would be to either add a wait to the walk path function, or try my function, and see if it fixes the problem.

Floor66

2011-03-19 13:18:30

I don't know if this fixes anything but this is what I whipped up for 1 of my private scripts:

function f_WalkPath(Path : TTileArray; Invert : Boolean): Boolean;
var
i, j, dest, currTile, m : Integer;
t : TTile;
p : TPoint;
moved, nextOnMM : Boolean;
begin
if (not LoggedIn) or R_FindRandoms then
Exit;
if Invert then
InvertPath(Path);
dest := High(Path);
Result := TileOnMS(Path[dest], 0);
if Result then
Exit;
for i := dest downto 0 do //get 1st tile
begin
if TileOnMM(Path[i]) then
begin
currTile := i;
Break;
end else
currTile := -1;
Wait(10 + Random(50));
end;
if currTile = -1 then
begin
Write('None of the tiles in the path were found!');
Exit;
end;
for i := currTile to dest do //walk the rest
begin
moved := False;
if not nextOnMM then
begin
for j := dest downto (currTile + 1) do //find first closest next tile
begin
if TileOnMM(Path[j]) then
begin
currTile := j;
Break;
end else
currTile := -1;
Wait(10 + Random(50));
end;
if currTile = -1 then
begin
Write('None of the tiles in the path were found!');
Exit;
end;
end;
t := RandomizeTile(Path[currTile], 1, 1);
p := TileToMM(t);
Mouse(p.x, p.y, 2, 2, True);
if not WaitToMove(500 + Random(500)) then
begin
MarkTime(m);
while TimeFromMark(m) <= 5000 do
begin
if WaitToMove(500 + Random(150)) then
begin
moved := True;
Break;
end;
Wait(10 + Random(50));
end;
if not moved then
Write('We didn''t move!');
end;
nextOnMM := False;
while (GetSpeed > 0) and (not nextOnMM) do //while moving, check if a new tile in the path pops up
begin
for j := dest downto (currTile + 1) do
begin
if TileOnMM(Path[j]) then
begin
currTile := j;
nextOnMM := True;
Break;
end;
Wait(10 + Random(50));
end;
Wait(10 + Random(50));
end;
end;
Result := TileOnMS(Path[dest], 0);
if not Result then
Result := WalkToTile(Path[dest], 1, 0);
end;

Afaik it has waits in each loop.

Yago

2011-03-19 23:08:37

Can I borrow it Floor66? Ill credit you properly…

Floor66

2011-03-20 04:59:57

sure thing :)

rogeruk

2011-03-20 08:07:07

Looking good Floor66 :thumbsup:.

Floor66

2011-03-20 08:36:32

Small change;
function f_WalkPath(Path : TTileArray; Invert : Boolean): Boolean;
var
i, j, dest, currTile, m : Integer;
t : TTile;
p : TPoint;
moved, nextOnMM : Boolean;
begin
if (not LoggedIn) or R_FindRandoms then
Exit;
if Invert then
InvertPath(Path);
dest := High(Path);
Result := TileOnMS(Path[dest], 0);
if Result then
Exit;
for i := dest downto 0 do
begin
if TileOnMM(Path[i]) then
begin
currTile := i;
Break;
end else
currTile := -1;
Wait(10 + Random(50));
end;
if currTile = -1 then
begin
Write('None of the tiles in the path were found!');
Exit;
end;
for i := currTile to dest do
begin
moved := False;
Result := TileOnMS(Path[dest], 0);
if Result then
Break;
if not nextOnMM then
begin
for j := dest downto (currTile + 1) do
begin
if TileOnMM(Path[j]) then
begin
currTile := j;
Break;
end else
currTile := -1;
Wait(10 + Random(50));
end;
if currTile = -1 then
begin
Write('None of the tiles in the path were found!');
Exit;
end;
end;
t := RandomizeTile(Path[currTile], 1, 1);
p := TileToMM(t);
Mouse(p.x, p.y, 2, 2, True);
if not WaitToMove(500 + Random(500)) then
begin
MarkTime(m);
while TimeFromMark(m) <= 5000 do
begin
if WaitToMove(500 + Random(150)) then
begin
moved := True;
Break;
end;
Wait(10 + Random(50));
end;
if not moved then
Write('We didn''t move!');
end;
nextOnMM := False;
while (GetSpeed > 0) (not nextOnMM) and (not Result) do
begin
Result := TileOnMS(Path[dest], 0);
for j := dest downto (currTile + 1) do
begin
if TileOnMM(Path[j]) then
begin
currTile := j;
nextOnMM := True;
Break;
end;
Wait(10 + Random(50));
end;
Wait(10 + Random(50));
end;
end;
Result := TileOnMS(Path[dest], 0);
if not Result then
Result := WalkToTile(Path[dest], 1, 0);
end;

Yago

2011-03-20 19:26:55

Ok thanks :)

footballjds

2011-03-20 19:33:46

From: Feroc1ty
Good way would be to either add a wait to the walk path function, or try my function, and see if it fixes the problem.


[offTopic] nobody cares….


[onTopic] Floor66, thanks for addressing this! ill attempt using your walkPath. I have a script i wrote that lags like hell, and i'd like to have 4 instances of it running rather then just two.