Skip to main content

Automate android games built on game engines other than Unity

Project description

GameDriver

Automate android games built on game engines other than Unity

Install

pip install gamedriver

Setup

import os
import time

import gamedriver as gd
from gamedriver.settings import set_settings as set_gd_settings

# For example, we will use an adb client to provide the tap_xy and swipe
# functionality, and a scrcpy client to provide the image of the device screen.
import adbutils  # https://github.com/openatx/adbutils
import scrcpy  # https://github.com/leng-yue/py-scrcpy-client

# Recommend setting a SRC_DIR var in the project's top level __init__ file
# SRC_DIR = os.path.dirname(os.path.abspath(__file__))
from my_project import SRC_DIR


# Boilerplate for however you are providing adb tap + swipe, and get device
# screen functionality

# For example, the adb device is available on the standard port, 5555
serial = "127.0.0.1:5555"

# Initialization for this adb client
# Note there must be an adb server* (see the lib for specific behavior)
adb_client = adbutils.AdbClient()
adb_client.connect(serial)
adb_device = adb_client.device(serial)

# Initialization for this scrcpy client
scrcpy_client = scrcpy.Client(serial)
scrcpy_client.start(daemon_threaded=True)
# Wait for the server to spin up...
while scrcpy_client.last_frame is None:
    time.sleep(1)


# Set settings

# I'd recommend setting these settings at minimum
set_gd_settings(
    {
        # For example, next to our top level __init__ file we have a folder
        # "img" that contains all of our template images
        "img_path": os.path.join(SRC_DIR, "img"),
        "img_ext": ".png",
        "get_screen": lambda: scrcpy_client.last_frame,
        # Since we are streaming the screen using scrcpy, we can choose a very
        # high polling frequency. Screenshotting should use closer to 1+ seconds.
        "refresh_rate_ms": 10,
        "tap_xy": lambda x, y: adb_device.click(x, y),
        "swipe": lambda x1, y1, x2, y2, duration_ms: adb_device.swipe(
            x1, y1, x2, y2, duration_ms / 1_000
        ),
    }
)

For the full settings reference, see settings.py.

Usage

Cookbook

# Recommend using this function by default
#
# Opens image <SRC_DIR>/img/buttons/confirm.png, searches the device screen for
# it, and taps it when it becomes visible.
gd.tap_img_when_visible("buttons/confirm")

# Wait until text/success is visible, then tap a different image
gd.wait_until_img_visible("text/success")
gd.tap_img("my-other-image")

# Keep tapping the image until it goes away or the timeout is reached
gd.tap_img_while_visible("buttons/back")

# Find all instances of an image, and do something with them
add_btns = list(gd.locate_all("buttons/add"))
if len(add_btns) > 3:
    gd.tap_box(add_btns[3])

# By default matching is in grayscale. However sometimes there is a need for
# color matching. For example, if the same button has different colors.
if not gd.touch_img_when_visible(
    # Wait until the button changes from disabled (gray) to enabled (blue).
    # Use a lower timeout in case this might not occur; then if it doesn't
    # we won't be waiting too long.
    "buttons/submit-blue", timeout_s=5, convert_to_grayscale=False
):
    raise Exception("Failed to submit")

# Perhaps you are missing matches or getting too many - try adjusting the
# threshold. For our default OpenCV match method, the threshold is a value in
# [0, 1], and lowering it makes matching more strict.
#
# The cancel button is not matching even though it is present. Loosen (raise)
# the threshold value since the match is of lower quality.
gd.touch_img_when_visible("buttons/cancel", threshold=0.1)

# Not recommended, but you can alternatively use a more implicit style.
#
# Maybe you need to tap whatever is at a location no matter what image it may be.
gd.tap_xy(500, 1000)
# Using an implicit wait avoids needing to have an image file to wait for.
# Hopefully you have a very good idea of about how long it should be.
gd.wait(0.1)
gd.tap_xy(750, 250)
gd.wait_until_img_visible("text/done")
gd.tap_xy(100, 100)

API Documentation

// TODO

FAQ

Why only games, and why not Unity?

This can be used to automate other things, but using image matching for automation (this) should be an absolute last resort. For other use cases see Appium, and in the Unity case the Appium AltUnity plugin.

Other PLs/platforms/I need more?

While I'm open to PRs, for the long term, effort is probably better directed at integrating this project into the Appium images plugin. While it comes with challenges, especially of streaming the screens of various devices, integration with the WebDriver API would instantly provide support for many PLs and devices.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gamedriver-0.0.1.tar.gz (20.3 kB view details)

Uploaded Source

Built Distribution

gamedriver-0.0.1-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file gamedriver-0.0.1.tar.gz.

File metadata

  • Download URL: gamedriver-0.0.1.tar.gz
  • Upload date:
  • Size: 20.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.5

File hashes

Hashes for gamedriver-0.0.1.tar.gz
Algorithm Hash digest
SHA256 8e96bd5689902751c92ffb27ed1d0a9727e0cbd06e6ef3275e00cbe2bb7b421c
MD5 6690616437cc5e6f4eb46d79b461c46c
BLAKE2b-256 ac8b7b18802c0b07de592e9db411090d423ed87a48b9a76e8f7578f347b08961

See more details on using hashes here.

File details

Details for the file gamedriver-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: gamedriver-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.5

File hashes

Hashes for gamedriver-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 de14f53293709806c0dcf7c2cd34f8f4899711fdea05d896c525a69065865c5e
MD5 0a91f85c6badfbcc1984565731dd0794
BLAKE2b-256 66165025f460f9f29bc813463b5abf1177ea41774913ee9dea0d2b4fb861d5f9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page