Files
factorio-ai-agent/docs/plan.md
21in7 8c90e80582 feat: 인벤토리 캐시 및 JSON 인코더 추가
- 인벤토리 캐시 기능을 추가하여, RCON으로 인벤토리를 읽지 못할 경우 이전에 성공적으로 읽은 데이터를 활용
- Lua에서 JSON 인코딩을 위한 간단한 함수 추가, 일부 Factorio 버전에서 `game.table_to_json`이 없을 경우 대체
- `README.md`에 인벤토리 캐시 및 JSON 인코더 사용에 대한 설명 추가
- `scan_resources()`와 `mine_resource`의 반경을 확장하여 자원 탐색 실패를 줄임
2026-03-25 23:03:08 +09:00

5.9 KiB

채굴 실패 시 제외 좌표 반복 버그 수정 계획

문제 재현/관찰

  • mine_resource에서 실패한 타일을 failed_positions에 추가한 뒤 Lua에 exclude 테이블로 전달하지만, 다음 시도에서도 동일 좌표(예: 388,2)로 다시 이동하는 로그가 발생합니다.

원인 후보

  • Lua에서 제외 판정에 쓰는 좌표 키가 string.format("%.0f,%.0f", ...) 기반인 반면, Python에서 exclude["{fx:.0f},{fy:.0f}"]를 만들 때 반올림/절삭 방식이 Lua와 1:1로 일치하지 않는 케이스가 있을 수 있습니다.
  • 이 경우 exclude[key]가 항상 false가 되어, Lua가 “가장 가까운 광석”을 계속 같은 엔티티로 반환할 수 있습니다.

변경 목표

  1. failed_positions를 “Lua 키 생성과 동일한 정수 타일 좌표(tx, ty)”로만 저장합니다.
  2. Lua에서 후보 광석 엔티티를 검사할 때도 정수 타일 좌표를 계산해 키/반환/마이닝 좌표에 일관되게 사용합니다.
  3. 그 결과, 제외한 좌표는 다음 루프에서 절대로 다시 선택되지 않도록 보장합니다.

구현 범위

  • action_executor.py
    • mine_resource 내부에서 좌표 처리 로직을 정수 타일 기반으로 통일
    • Lua 반환값을 tx,ty 정수 문자열로 변경하고 Python 파싱을 이에 맞춤

README 업데이트 계획

  • 채굴 제외(exclude) 로직이 “정수 타일 키 기반으로 통일”되도록 README의 기술/동작 설명(또는 체크리스트)을 업데이트합니다.

자원 패치 중심 오차로 인한 채굴 실패 완화 계획

문제 관찰

  • scan_resources()가 패치의 평균 중심(center_x/y)을 추천 좌표로 사용하면서, 플레이어가 해당 좌표로 이동한 직후 mine_resource의 엔티티 탐색 반경 안에서 실제 자원 엔티티를 찾지 못해 실패하는 케이스가 발생할 수 있음.

근거(팩토리오 Lua API)

  • LuaInventory.get_contents()dictionary[string -> uint]를 반환하므로, 인벤토리 판독은 name -> count 형태로 처리하는 것이 맞다.
  • 자원 엔티티의 e.position은 부동소수(MapPosition) 좌표이므로, 타일 중심/평균 중심과 실제 엔티티 좌표 간 오차가 생길 수 있다.

변경 목표

  1. scan_resources() 결과에 패치 대표 좌표를 평균 중심뿐 아니라 플레이어 기준 가장 가까운 실제 엔티티 좌표(앵커 anchor_x/yanchor_tile_x/y)로 함께 제공
  2. summarize_for_ai()에서는 평균 중심 대신 앵커 좌표 기반으로 거리/추천을 계산
  3. mine_resource 후보 엔티티 탐색 반경을 더 크게 잡아(행동 레벨) 이동 직후 실패를 흡수

구현 범위

  • state_reader.py
    • scan_resources()anchor_x/yanchor_tile_x/y 추가
    • summarize_for_ai() 거리 계산을 앵커 우선으로 변경
  • action_executor.py
    • mine_resource에서 후보 엔티티 탐색 반경을 80250으로 확장

GLM 응답 지연 원인 계측/완화 계획

문제 관찰

  • ai_planner.py에서 GLM 호출이 [GLM] 생각 중... 이후 30초~1분 이상 지연되는 현상 발생
  • JSON 파싱 실패로 인한 재시도는 가끔 발생(하지만 느림의 주 원인이 아닐 가능성도 있음)

1단계(증거 수집)

  • ai_planner.py_call_glm()에 타이밍 로그 추가
    • total: 요청 시작~콘텐츠 반환까지 전체 소요
    • http_read: HTTP 응답 본문 수신까지 소요
    • json_parse: 응답 JSON 파싱 시간
    • prompt_chars/system_chars/max_tokens: 입력 크기 동시 기록

2단계(완화: 로그 확인 후)

  • json_parse가 아니라 http_read/total이 큰 경우:
    • max_tokens를 우선 크게 줄여 생성 길이 상한 조정
    • SYSTEM_PROMPT/state_summary 길이를 더 강하게 제한
  • json_parse가 큰 경우:
    • JSON 파싱/복구 로직 비용 또는 응답 형식 편차 원인 재점검

README 업데이트

  • README.md주의사항/실행 섹션에 GLM 지연 계측 로그 출력 방식 및 파라미터 조정 힌트를 반영

Cursor Hooks - Windows sessionStart 앱 선택창 원인/해결 계획

문제 재현/관찰

  • Cursor @cursor.hooks 로그에서 sessionStart 훅 실행 중 ./hooks/session-start가 stdout JSON을 내지 못하거나, Windows에서 앱 선택창이 뜨는 현상이 관찰됨

원인 후보

  • Windows에서 확장자 없는 ./hooks/session-start를 실행할 때 bash로 해석되지 않아, OS가 실행 대신 “어떤 앱으로 열지”를 요청할 수 있음

변경 목표

  1. 프로젝트 훅은 powershell로 stdout에 JSON을 출력하도록 고정
  2. superpowers 플러그인의 Cursor 훅은 bash로 감싸 실행되도록 구성 변경

구현/검증 범위

  • E:/develop/factorio-ai-agent/.cursor/hooks.json
  • E:/develop/factorio-ai-agent/.cursor/session-start-hook.ps1
  • .../superpowers/.../hooks/hooks-cursor.json
  • 검증: Cursor 재시작 후 View -> Output -> Hooks에서 sessionStart 훅이 정상 파싱되어 OUTPUT에 JSON이 나타나는지 확인

인벤토리 캐시(메모리) 추가 계획

목표

  • 파이썬 에이전트만 종료/재실행할 때 RCON으로 인벤토리를 읽지 못하거나({} 반환) 빈 값이 나오면, 직전에 성공적으로 읽은 인벤토리를 기억해서 프롬프트에 반영한다.

정책(사용자 선택: 1번 fallback only)

  • get_inventory()가 성공적으로 읽어서 값이 비어있지 않으면 캐시를 갱신한다.
  • get_inventory() 결과가 빈 딕셔너리이면(실패/빈 값) 캐시 파일을 로드해서 대체한다.

구현 범위

  • state_reader.py
    • inventory_memory.json 로드/저장 유틸 추가
    • get_inventory() 반환값을 캐시 fallback으로 교체
  • README.md
    • 인벤토리 캐시 동작과 파일명(inventory_memory.json)을 설명