CPU usage going through the roof when running script

Asked by David Bachschmid

Hi everyone,

I've created a farming bot for a mobile game which I am playing on my PC with the android emulator Nox.
My problem is that once I start the script the CPU usage goes up really high. Here's a SS: https://imgur.com/a/HcKIm

And here is my script / code:

Settings.MoveMouseDelay = 0.1
running = True

def runHotkey(event):
    global running
    running = False

Env.addHotkey(Key.F1, KeyModifier.CTRL, runHotkey)

while running:
    if Screen(1).exists(Pattern("1516809781721.png").similar(0.90)):
        Screen(1).click(Pattern("1516809781721.png").similar(0.90))

    if Screen(1).exists("1516823633104.png"):
        Screen(1).click(Pattern("1516823633104.png").targetOffset(125,220))

    if Screen(1).exists(Pattern("1517864572951.png").similar(0.60)):
        Screen(1).click(Pattern("1517864572951.png").similar(0.60))

    if Screen(1).exists("1516823633104.png"):
        Screen(1).click(Pattern("1516823633104.png").targetOffset(-70,230))

    if Screen(1).exists(Pattern("1516820524383.png").exact()):
        Screen(1).click(Pattern("1516820524383.png").exact())

    if Screen(1).exists(Pattern("1516812605236-1.png").similar(0.90)):
        Screen(1).click(Pattern("1516812605236.png").similar(0.90))
        Screen(1).wait("1516812737846.png", 60)
        Screen(1).click(Pattern("1516812737846.png").targetOffset(320,134))

To run the script I'm just pressing on "run / execute" (Ausführen in German) in Sikuli.

So if anyone knows how to reduce the CPU and RAM usage, please tell me!
If I do not set the FPS in the emulator to 10 my PC crashes within 20 mins or so.

Greetings, Dave

PS: I'm a noob on this territory. This is the first I've ever coded something so please explain it so I can understand what I should do. :)

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:

This question was reopened

Revision history for this message
RaiMan (raimund-hocke) said :
#1

-- 1. latest version of SikuliX? at least 1.1.1? http://sikulix.com

-- 2. understood, how SikuliX works?
http://sikulix-2014.readthedocs.io/en/latest/basicinfo.html#sikulix-how-does-it-find-images-on-the-screen

--3. reduce CPU usage
- reduce the search region to the minimum acceptable
- reduce the scanrate

general recommendation: name your images.

instead of:
    if Screen(1).exists(Pattern("1516809781721.png").similar(0.90)):
        Screen(1).click(Pattern("1516809781721.png").similar(0.90))

use:
if regionOnScreen1.exists(image1, 0)): regionOnScreen1.click()

- searches only once, does not wait 3 seconds
- clicks what was found before in regionOnScreen1

Optimize your image shots:
- as little background to the edges as possible
- concentrate on the key differentiating aspects

Good shots are found with a score of 0.95+, so no need for Pattern.similar

Revision history for this message
David Bachschmid (soundslikedave) said :
#2

Ok ty. I will adjust everything now.
However, I still do not get how to implement the neccessary lines for scanrate reduction.

This is how it is displayed on the features site:

def myHandler(e):
        print "it happened"
# you may wish to save the actual settings before
Settings.ObserveScanRate = 0.2
onAppear(some_image, myHandler)
observe(FOREVER, background = True)
# the observer will look every 5 seconds ;-)

Revision history for this message
RaiMan (raimund-hocke) said :
#3
Revision history for this message
David Bachschmid (soundslikedave) said :
#4

Danke RaimMan ;)

Now sikuli has a problem with this line:

20 if Screen(1).exists(Pattern("rewards.png").similar(0.90)):click()
21 Screen(1).wait("rewards2.png", 6):click()

Error msg:
[error] script [ dd always restart ] stopped with error in line 21 at column 8
[error] SyntaxError ( "mismatched input '' expecting DEDENT", )

Everything is alright with the length of the tabs but I can't find the error...

How do I implement "setWaitScanRate(rate)" in my code? Does including "simular" cost more CPU?
Here's what I have so far:

Settings.MoveMouseDelay = 0.1
running = True

def runHotkey(event):
    global running
    running = False

Env.addHotkey(Key.F1, KeyModifier.CTRL, runHotkey)

while running:
    if Region(2927,567,639,340).exists("image1.png", 0):click()
    if exists(image2.png):click()
    if Region(3037,617,584,324).exists(Pattern("image3.png").similar(0.95), 0):click()
    if Screen(1).exists("choosehero.png"):
        Screen(1).click(Pattern("choosehero.png").targetOffset(-70,230)) //old code, will change it after posting this
    if Screen(1).exists(Pattern("rewards.png").similar(0.90)):click()
        Screen(1).wait("rewards2.png", 6):click()

Revision history for this message
RaiMan (raimund-hocke) said :
#5

It is Python ;-)

i guess you tried to transform this:

if Screen(1).exists(Pattern("1516812605236-1.png").similar(0.90)):
        Screen(1).click(Pattern("1516812605236.png").similar(0.90))
        Screen(1).wait("1516812737846.png", 60)
        Screen(1).click(Pattern("1516812737846.png").targetOffset(320,134))

would get:
if Screen(1).exists(Pattern("1516812605236-1.png").similar(0.90)):
        Screen(1).click()
        Screen(1).wait("1516812737846.png", 60)
        Screen(1).click(Pattern("1516812737846.png").targetOffset(320,134))

Go back and understand:
instead of:
    if Screen(1).exists(Pattern("1516809781721.png").similar(0.90)):
        Screen(1).click(Pattern("1516809781721.png").similar(0.90))

use:
if regionOnScreen1.exists(image1, 0)): regionOnScreen1.click()

or better:
if regionOnScreen1.exists(image1, 0)):
    regionOnScreen1.click()

With the click() you have to specify the region, that remembered the match to click!
Screen(1) in your case.

BTW:
once at the beginning say
screen1 = Screen(1)

and use screen1 later instead of Screen(1)

The latter each time creates a new Object, which is costly.

Revision history for this message
David Bachschmid (soundslikedave) said :
#6

Thanks again. Solved the first problem.
My second problem is that sikuli does not click the point in the image which I set it to click on. Right now it only clicks the middle of the search region.

Here's my new code:

Settings.MoveMouseDelay = 0.1
running = True

def runHotkey(event):
    global running
    running = False

Env.addHotkey(Key.F1, KeyModifier.CTRL, runHotkey)

while running:
    if Region(2927,567,639,340).exists("Fight.png"): Region(2927,567,639,340).click()
    if Region(2804,219,332,161).exists(Pattern("hero.png").targetOffset(-97,251)): Region(2804,219,332,161).click()
    if Region(3037,617,584,324).exists(Pattern("Dungeon.png").similar(0.95)): Region(3037,617,584,324).click()
    if Region(2804,219,332,161).exists(Pattern("hero.png").targetOffset(-202,247)): Region(2804,219,332,161).click()
    if Region(2255,174,612,493).exists(Pattern("rewards.png").similar(0.90)):
        Region(2255,174,612,493).click()
        Region(3243,632,211,237).wait("skip.png", 6)
        Region(3243,632,211,237).click()

Revision history for this message
RaiMan (raimund-hocke) said :
#7

Again Python and OOP:
if Region(2927,567,639,340).exists("Fight.png"): Region(2927,567,639,340).click()

both Region() each create different (new) objects and hence have different content/attributes.

region1 = Region(2927,567,639,340)
if region1.exists("Fight.png"): region1.click()

BTW: is rather easy in the IDE:
write
region 1 =

leave the cursor behind the = and click the "select a Region" button.

Watch and be enthusiastic ;-)

Revision history for this message
David Bachschmid (soundslikedave) said :
#8

Vielen lieben Dank RaiMan!!

No Blue Screens or any crashes since yesterday + my PC doesn't care anymore about running this script (in terms of proccess power usage)

Revision history for this message
David Bachschmid (soundslikedave) said :
#9

Also I can run the game on 60FPS instead of 10. :)

Revision history for this message
RaiMan (raimund-hocke) said :
#10

Danke für die Rückmeldung. Have fun. All the best.

Revision history for this message
David Bachschmid (soundslikedave) said :
#11

Since I added a timeout to the exists commands, I've received this error three times:

[error] script [ sdfsdf ] stopped with error at line --unknown--
[error] Error caused by: Traceback (most recent call last): File "F:\Sikuli\sdfsdf.sikuli\sdfsdf.py", line 15, in <module> if Region(2804,219,332,161).exists(Pattern("hero.png").targetOffset(-202,247), 0.1): Region(2804,219,332,161).click(Pattern("hero.png").targetOffset(-202,247)) Line 2759, in file Region.java
at org.sikuli.script.Region.wait(Region.java:2759)
at org.sikuli.script.Region.find(Region.java:2336)
at org.sikuli.script.Region.getLocationFromTarget(Region.java:3213)
at org.python.proxies.sikuli.Region$Region$3.getLocationFromTarget(Unknown Source)
at org.sikuli.script.Region.click(Region.java:3698)
at org.sikuli.script.Region.click(Region.java:3683)
at sun.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
org.sikuli.script.FindFailed: FindFailed: hero.png: (121x38) seen at (2967, 301) with 0,97 in R[2804,219 332x161]@S(1) E:Y, T:3,0 Line 2759, in file Region.java

Here's an extract from my script:

while running:
    if Region(3092,648,385,133).exists(Pattern("Fight.png").exact(), 0.5): Region(3092,648,385,133).click("Fight.png")
    if Region(3168,686,370,215).exists(Pattern("Dungeon.png").similar(0.85), 0.5): Region(3168,686,370,215).click(Pattern("Dungeon.png").similar(0.85))
    if Region(2804,219,332,161).exists(Pattern("hero.png").targetOffset(-97,251), 1.5): Region(2804,219,332,161).click(Pattern("hero.png").targetOffset(-97,251))
    if Region(3314,757,205,167).exists("skip.png", 0.5): Region(3314,757,205,167).doubleClick("skip.png")
    if Region(2804,219,332,161).exists(Pattern("hero.png").targetOffset(-202,247), 0.1): Region(2804,219,332,161).click(Pattern("hero.png").targetOffset(-202,247))

The error always occurs in the "hero.png" line. Also in these specific lines is a relatively high Target Offset included.

Revision history for this message
RaiMan (raimund-hocke) said :
#12

see comment #7

--- Also in these specific lines is a relatively high Target Offset included.
... does not matter for the search, since only applied to the match

reg1 = Region(2804,219,332,161)
if reg1.exists(Pattern("hero.png").targetOffset(-202,247), 0.1):
    reg1.click() # clicks what was found with exists() before

your solution
    if Region(2804,219,332,161).exists(Pattern("hero.png").targetOffset(-202,247), 0.1): Region(2804,219,332,161).click(Pattern("hero.png").targetOffset(-202,247))

leads to another search with the click, and apparently the image is no longer visible (FindFailed)

Revision history for this message
David Bachschmid (soundslikedave) said :
#13

Ok ty, now I understand why the error occured. Still when I do not include a picture within "click(picture.png)", sikuli will only click on the center of the region in which it was searching for a specific image. Anyways it works really fine by now, thanks to you. :)

Revision history for this message
Best RaiMan (raimund-hocke) said :
#14

with my coding suggestion from comment #12 it should click the last match in reg1, which in turn remembers the given target offset.

For the reason behind my suggestion see comment #7

Revision history for this message
David Bachschmid (soundslikedave) said :
#15

Thanks RaiMan, that solved my question.