Serpent.AI Hello World 样例 - nanpuhaha/SerpentAI GitHub Wiki
注意: 在开始阅读此指南之前,请确认你已经针对你的操作系统完成了全部的安装指南步骤,包括运行 'serpent setup'。
在本节中,我们将会创建一个初始的、最小的 SerpentAI 项目: 一个 Hello World 样例。样例将会使用 Steam 版本的 Super Hexagon 游戏作为演示,当然如果你没有这个游戏的话你也可以换其他的。
游戏准备
如果你打算为一个新的游戏开发代理插件的化,无论什么时候你都需要做一些准备工作:
- 购买、下载、安装游戏
- 运行游戏
- 调整视频选项:
- 运行模式选窗口模式
- 选一个适合你的分辨率 (如果可选的话)
- 记下窗口的识别名称:
- 在 Linux 或者 Windows平台: 游戏的窗口名。
- 在 macOS 平台: 游戏的进程名。由于进程名并不是一眼就能看到,而且获取起来还有点麻烦,所以我们提供了一个功能来解决这个问题。在你的项目目录中运行命令
serpent window_name
然后跟着指示做就行了。
创建一个游戏插件
在 Serpent.AI 中,想要为一个新游戏提供支持的话,你必须为它创建一个插件。serpent 程序为创建插件任务提供了一个简洁、完美的方案
运行 serpent generate game
你将会在命令行中看到类似下面的界面:
依次填入关键词:
- SuperHexagon(游戏名)
- steam
你会看到一些插件安装过程中的输出,它们会以这句结尾: SerpentSuperHexagonGamePlugin was installed successfully!
如果你去插件的文件路径下看一看,你会发现我们已经为你生成了为 Super Hexagon 游戏量身定做的插件模版文件,像这样
配置游戏插件
为了通过 Serpent.AI 启动 Super Hexagon 游戏,你需要在生成的游戏插件文件中进行几处小修改。
编辑 plugins/SerpentSuperHexagonGamePlugin/files/serpent_SuperHexagon_game.py。结构体应该看起来像下面这样:
def __init__(self, **kwargs):
kwargs["platform"] = "steam"
kwargs["window_name"] = "WINDOW_NAME"
kwargs["app_id"] = "APP_ID"
kwargs["app_args"] = None
super().__init__(**kwargs)
self.api_class = SuperHexagonAPI
self.api_instance = None
- 用你之前记下的窗口名替换掉 WINDOW_NAME 字段。在这个简单的例子里,请使用 Super Hexagon 替换掉 WINDOW_NAME。
- 用 Steam 的 游戏编号 (APPID) 取代 APP_ID 字段。在这个例子里,请使用 221640 替换掉 APP_ID。
小提示: 一你可以在SteamDB很快速的找到 Steam 游戏的游戏编号。
其他游戏
如果你在用其他 可执行游戏 来开发这个 Hello World 样例的话,举街霸X来说:
def __init__(self, **kwargs):
kwargs["platform"] = "executable"
kwargs["window_name"] = "WINDOW_NAME"
kwargs["executable_path"] = "EXECUTABLE_PATH"
super().__init__(**kwargs)
self.api_class = StreetFighterXMegaManAPI
self.api_instance = None
- 用你之前记下的窗口名替换掉 WINDOW_NAME 字段。
- 用这个游戏的环境变量中的路径或该游戏的绝对路径取代 EXECUTABLE_PATH 字段。
启动游戏
运行 serpent launch SuperHexagon
游戏将会开始运行。如果你的游戏被移动到了屏幕左上角的话,这说明 Serpent.AI 可以定位到这个游戏窗口。
让游戏在那里运行着不要管它。
创建游戏代理插件
在 Serpent.AI 中,如果你想从你的游戏中获取画面帧并与之交互的话,首先必须创建一个游戏代理插件。serpent 程序也为创建代理插件任务提供了一个高效、快速的解决方案
运行 serpent generate game_agent
你将会在命令行中看到类似下面的界面:
填入游戏名称关键词:
- SuperHexagon
你会看到一些插件安装过程中的输出,它们会以这句结尾: SerpentSuperHexagonGameAgentPlugin was installed successfully!
如果你去插件的文件路径下看一看,你会发现我们已经为你生成了为 Super Hexagon 游戏量身定做的代理插件模版文件,像这样
Hello World 你好,世界!
编辑 plugins/SerpentSuperHexagonGameAgentPlugin/files/serpent_SuperHexagon_game_agent.py.
更改 handle_play 函数内容,使之看起来像这样:
def handle_play(self, game_frame):
print("Hello World!")
运行 serpent play SuperHexagon SerpentSuperHexagonGameAgent
一切顺利的话,你会在你的终端中开始看到一连串输出的 "Hello World!" 字样。
更加可视化的方式
在刚才的样例中,每次你的终端中出现一个新的 "Hello World!" 字段,你的游戏代理程序都获取到了来自游戏的最新的一帧图像。你有可能已经发现了这个流传输并不是特别的快,这是因为程序设置了一个限制器,它会限制每秒钟代理程序能获取和处理图像帧的数量。这个参数是可以自行定义的 ( 查看 config/config.plugins.yml ),我们将默认参数设置为 2 FPS
是有原因的,这就意味着相当于 120 APM ( 每分钟操作次数 )的操作手速了,这已经快到足够应对绝大多数市面上的游戏了。除非你在开发纯粹处理模拟控制的游戏 ( 举例来说,赛车游戏 ),否则以一个极高的 APM 去处理普通的游戏的话,游戏操作本身会变得 不那么自然 ,而且很多情况下你的代理模型会反应过激。
我们先就此打住,让我们在输出 "Hello World!" 的基础上更直观可视化一些。Serpent.AI 中内嵌了一个名为可视化调试器的应用,它可以在代理运行的同时让你可以方便的检测图像信息。
打开另一个终端,运行 serpent visual_debugger
你应该会看到一个类似这样的界面:
如果你需要的话,调整大小然后放在游戏界面的下面。
现在把 handle_play 改为如下这样:
def handle_play(self, game_frame):
print("Hello World!")
for i, game_frame in enumerate(self.game_frame_buffer.frames):
self.visual_debugger.store_image_data(
game_frame.frame,
game_frame.frame.shape,
str(i)
)
进入 Super Hexagon 游戏的难度选择界面。
运行 serpent play SuperHexagon SerpentSuperHexagonGameAgent
这样你应该就已经能在可视化调试器中看到循环显示的逐帧画面了,差不多跟终端中显示新的 "Hello World!" 字段的节奏一致。
游戏代理会自动维护一些从游戏本身获取的图像帧,在本例中代理程序可以把这些图像帧传递给可视化调试器。
更有交互性的尝试
作为本 Serpent.AI 样例的最后一步,让我们来添加一些键盘交互吧。 首先导入需要的库,在agent file中增加:
from serpent.input_controller import KeyboardKey
按如下方式修改 handle_play 函数:
def handle_play(self, game_frame):
print("Hello World!")
for i, game_frame in enumerate(self.game_frame_buffer.frames):
self.visual_debugger.store_image_data(
game_frame.frame,
game_frame.frame.shape,
str(i)
)
self.input_controller.tap_key(KeyboardKey.KEY_RIGHT)
你能猜到会发生什么吗?
自己动手试试吧!运行 serpent play SuperHexagon SerpentSuperHexagonGameAgent