
TypeSafe Mario 的功能
TypeSafe Mario 是一个实验性控制器,可让 TypeSafe 的 Jev 模型为原版《超级马力欧兄弟》选择控制器输入。模型接收的不是屏幕截图,而是根据模拟器遥测数据和 RAM 生成的紧凑型、以对象为中心的 JSON。
控制循环采用以下架构:
NES emulator -> telemetry/RAM parser -> structured JSON -> Jev Choice -> controller input
Jev 选择合法操作后,模拟器会推进若干帧并生成新状态。该过程会在整个回合中重复进行。原始本地图块网格仍可在调试日志和控制面板中查看,但不会重复放入面向模型的输入中。
可用的控制器操作
初始操作空间有意限制为七个控制器宏:
nooprightright_jumpright_runright_run_jumpjumpleft
主要功能
- 结构化模型输入:解析器向 TypeSafe 发送具有实际含义的 JSON 对象,而不是扁平化文本或屏幕截图。
- 多项判断:每次请求都会评估控制器选择、向前跳跃的实用性以及即时危险。
- 实测反应时序:状态包含操作持续时间以及从观测到执行操作的延迟。
- 实时控制面板:默认显示将游戏画面与操作概率、置信度、延迟、危险度、奖励和解析后的状态结合在一起。
- 详细运行记录:每次决策都会保存为 JSON Lines 记录,以便后续分析或可视化。
- 调试可视性:人类可读的状态文本和本地图块网格仍可供检查。
要求与合法配置
安装项目之前,请确保环境满足以下要求:
- Python 3.13 或更高版本
- 存储在
TYPESAFE_API_KEY中的 TypeSafe API 密钥 - 合法的《超级马力欧兄弟》本地配置
代码仓库不包含任天堂 ROM 或其他受版权保护的游戏数据。您需要负责合法获取和使用模拟器及游戏文件。
安装
README 提供了用于创建虚拟环境、安装 Mario 和开发依赖项以及配置 API 密钥的 PowerShell 命令。
- 创建 Python 3.13 虚拟环境。
- 以可编辑模式安装项目及所需额外依赖。
- 为当前 PowerShell 会话设置 TypeSafe API 密钥。
py -3.13 -m venv .venv
.venv\Scripts\python -m pip install -e ".[mario,dev]"
$env:TYPESAFE_API_KEY = "your-key"
将 your-key 替换为实际的 TypeSafe API 密钥。由于该命令设置的是 PowerShell 环境变量,请在同一已配置环境中运行后续命令,除非您另行持久化该变量。
先检查模型输入
启动游戏前,使用 state-demo 检查项目将发送给 TypeSafe 的确切 JSON 和文本:
.venv\Scripts\typesafe-mario state-demo
该命令不会启动游戏,也不会调用 API。这是了解面向模型的架构并验证模拟器观测数据表示方式的最安全方法。
了解结构化状态
规范对象会按照用途对观测数据进行分组:
player:位置、速度、是否着地、跳跃阶段和能力状态。trajectory:滞空时间、起跳后的距离,以及马力欧是否已确定要越过缺口。hazard:最多三个敌人、它们的预测位置、预计接触时间以及起跳截止时间。terrain:障碍物和缺口的几何信息、观测可靠性以及上一次着地时的预览。reaction_timing:控制器操作持续时间以及实测的观测到操作延迟。recent_control:上一次操作、其持续时间、取得的进展以及观测到的结果。episode:生命数、计时器、进度、停滞次数、死亡状态以及关卡完成情况。
结构化 JSON 是模型的规范状态。更完整的文本渲染仅用于调试和用户界面。调试快照可以包含马力欧的坐标和移动情况、回合进度、附近敌人以及基于字符的本地图块网格。
运行 World 1-1
启动 World 1-1 环境,让 Jev 每经过八个模拟器步骤选择一次操作:
.venv\Scripts\typesafe-mario play --env SuperMarioBros-1-1-v0 --frames-per-decision 8
--env 选项用于选择环境,--frames-per-decision 8 则决定两次模型决策之间模拟器运行的步数。使用默认显示时,项目会打开一个可记录的窗口,同时显示实时游戏画面和模型遥测数据。
使用控制面板
控制面板会展示跟踪 Jev 行为所需的信息:
- 选定的控制器操作
- 完整的 Choice 概率分布
- 模型置信度
- Jev 请求延迟
- 向前跳跃概率
- 即时危险评分
- 奖励
- 解析后的游戏状态
按下 R 或点击 重新开始,开始新的回合。Mario 死亡或完成关卡后,仪表板仍会保持打开。按下 Esc 或 Q 退出。
选择显示模式
默认的组合仪表板适合观察或录制游戏过程。另外两种模式适用于更具体的场景。
仅显示模拟器
.venv\Scripts\typesafe-mario play --env SuperMarioBros-1-1-v0 --frames-per-decision 8 --display game
game 显示模式仅显示模拟器窗口。
无显示运行
.venv\Scripts\typesafe-mario play --env SuperMarioBros-1-1-v0 --frames-per-decision 8 --display none
none 显示模式以无头模式运行,适用于基准测试式执行。
了解 TypeSafe 的三种判断
每个请求都会基于同一结构化状态,分别进行三种独立判断:
- Choice:选择下一个合法的控制器宏动作。
- Noul:估计当前时刻向前跳跃是否有用。
- Score:为实时可视化衡量即时危险程度。
这些判断各司其职。Choice 结果控制 Mario,而跳跃估计和危险分数则提供额外的解读和可视化信息。
精确的时序计算仍保留在代码中。例如,解析器会将响应延迟、敌人移动、动作节奏和跳跃清空时间结合起来,生成类型化的 jump_must_start_this_decision 事实。Jev 会解读该事实,并继续负责控制器选择;执行框架不会应用脚本化的恢复动作覆盖。
检查记录的决策
每次决策都会写入带时间戳的 JSON Lines 文件:
artifacts/run-<timestamp>.jsonl
记录包括:
- Jev 延迟
- 动作概率
- 置信度
- 规范模型状态
- 原始调试状态
- 游戏结果
这些记录提供了执行后检查游戏过程所需的数据,也可以作为实时叠加层或渲染社交媒体短片的输入。
高级使用技巧
在游戏前验证观测结果
如果想在不启动模拟器或消耗 API 调用的情况下查看面向模型的表示,请在实时游戏前运行 state-demo。请特别注意规范结构化状态与面向人类的调试文本之间的区别。
结合动作节奏解读时序事实
控制器以多帧间隔执行动作,因此反应时序是状态的一部分,而不是外部假设。检查某次决策时,请将所选动作与响应延迟、动作持续时间、预计敌人接触时间以及解析器报告的任何起跳截止时间进行比较。
为任务使用合适的显示模式
- 需要同时检查模型推理信号和游戏过程时,使用默认仪表板。
- 只需要模拟器输出时,使用
--display game。 - 进行无头基准测试时,使用
--display none。
分析完整的概率分布
不要只分析选中的动作。仪表板和 JSONL 工件包含完整的 Choice 概率分布及置信度,可以帮助判断 Jev 是强烈偏好某个动作,还是在多个权重相近的备选动作中进行选择。
运行开发检查
仓库为贡献者提供了格式化、代码检查和测试命令。请在配置好的虚拟环境中运行:
.venv\Scripts\ruff format --check src tests
.venv\Scripts\ruff check src tests
.venv\Scripts\python -m pytest -q
第一条命令检查格式,第二条运行 Ruff 的代码检查,第三条以简洁输出执行测试套件。
结语
TypeSafe Mario 展示了一种不同于基于截图的游戏控制的结构化方案。它将模拟器遥测数据和 RAM 转换为以对象为中心的规范 JSON,让 Jev 从一组精简的合法动作中进行选择,并记录每次决策,以便实时检查或后续分析。请从 state-demo 开始,通过仪表板运行 World 1-1,并使用生成的 JSONL 工件了解状态、时序、置信度和结果之间的关系。
