diff --git a/SKILL.md b/SKILL.md index 5da2512..0f69600 100644 --- a/SKILL.md +++ b/SKILL.md @@ -258,19 +258,23 @@ gameSpeed: 0 ← 0=暂停, 1=1x, 2=2x, 3=3x ### 铁律(必须遵守) ``` -铁律 1: 任何时候 AI 需要向用户提问,必须先暂停游戏。 - → python3 tools/oni_api.py pause "Waiting for user input" - → 用户回答后 AI 恢复操作时 unpause +铁律 1: 任何时候 AI 开始推理/决策前 → 必须先暂停游戏。 + 工具在获取游戏状态数据时会自动触发暂停, + 保证 AI 获取的信息是当前时刻的准确快照。 + → 工具自动执行 pause(无需手动调用) + → AI 完成所有操作后主动 unpause -铁律 2: 任何时候 AI 结束回答/退出操作状态,必须确保游戏处于暂停态, +铁律 2: 任何时候 AI 需要向用户提问,必须先暂停游戏。 + → 工具自动暂停,用户回答后 AI 恢复时 unpause + +铁律 3: 任何时候 AI 结束回答/退出操作状态,必须确保游戏处于暂停态, 除非用户明确要求不暂停。 - → 如果游戏正在运行且 AI 不再操作 → 必须暂停 - → 原因:防止游戏在 AI 不监控时状态恶化(窒息/过载/高温) + → 防止游戏在 AI 不监控时状态恶化(窒息/过载/高温/CO₂) -铁律 3: 任何时候 AI 执行写操作(dig/build/deconstruct/batch/pipe/wire), - 必须先暂停、后恢复。 +铁律 4: 任何时候 AI 执行写操作(dig/build/deconstruct/batch/pipe/wire), + 工具自动确保暂停态。 -铁律 4: 重大操作前必须先 save 存档,失败后允许 load 回滚。 +铁律 5: 重大操作前必须先 save 存档,失败后允许 load 回滚。 ``` ### 核心操作循环 diff --git a/scripts/event_daemon.py b/scripts/event_daemon.py index a00adec..483cbf0 100755 --- a/scripts/event_daemon.py +++ b/scripts/event_daemon.py @@ -26,6 +26,10 @@ import datetime TOOLS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'tools') sys.path.insert(0, TOOLS_DIR) +# Disable auto-pause for event daemon — we poll frequently and should not pause the game +import oni_api +oni_api.AUTO_PAUSE_ENABLED = False + from oni_api import api_get, api_post, api_url diff --git a/tools/oni_api.py b/tools/oni_api.py index c34cefa..c4c219a 100644 --- a/tools/oni_api.py +++ b/tools/oni_api.py @@ -6,6 +6,11 @@ import os CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config.json') +# Auto-pause control +AUTO_PAUSE_ENABLED = True +"""When True, api_get and api_post auto-pause game before executing. +Set to False for event daemon polling (lightweight, frequent checks).""" + def load_config(): with open(CONFIG_PATH) as f: return json.load(f) @@ -14,7 +19,22 @@ def api_url(endpoint): cfg = load_config() return f"http://{cfg['modHost']}:{cfg['modPort']}{endpoint}" -def api_get(endpoint): +def _auto_pause(): + """Auto-pause the game before any AI operation, ensuring data freshness.""" + if not AUTO_PAUSE_ENABLED: + return + try: + cfg = load_config() + url = f"http://{cfg['modHost']}:{cfg['modPort']}/api/action/pause" + req = urllib.request.Request(url, data=b'{}', headers={'Content-Type': 'application/json'}, method='POST') + with urllib.request.urlopen(req, timeout=3): + pass + except: + pass + +def api_get(endpoint, auto_pause=True): + if auto_pause and AUTO_PAUSE_ENABLED: + _auto_pause() url = api_url(endpoint) cfg = load_config() try: @@ -24,7 +44,9 @@ def api_get(endpoint): except urllib.error.URLError as e: return {"error": str(e)} -def api_post(endpoint, data): +def api_post(endpoint, data, auto_pause=True): + if auto_pause and AUTO_PAUSE_ENABLED: + _auto_pause() url = api_url(endpoint) cfg = load_config() try: