
BattleTech: The Crescent Hawk's Inception 리버스 엔지니어링
BattleTech: The Crescent Hawk's Inception(1988, MS-DOS, Infocom 배급, Westwood Associates 엔진)의 리버스 엔지니어링 — 그리고 진행 중인 Godot 4 / C# 재구현.
이 저장소의 다른 어떤 내용을 믿기 전에 이 섹션을 먼저 읽으십시오. 이 프로젝트는 성숙도가 매우 다른 두 가지 작업이며, 문서 곳곳의 "phase"라는 단어는 코드 작성됨을 의미하지 동작이 입증됨을 의미하지 않습니다.
이 프로젝트는 동시에 두 개의 산출물을 만들어내며, 두 번째는 첫 번째 위에 올라탑니다:
(1) 문서화된 리버스 엔지니어링. reko/ 디컴파일, docs/ 명세, BattleTech 전용 MCP 도구가 포함된 Spice86 에뮬레이터, 그리고 Python 도구. 이것이 실제 RE 작업입니다: 파일 형식, 스토리 텍스트, 메모리 맵, 그리고 엔진 로직의 상당 부분이 문서화되어 있으며 디컴파일러 출력 및 라이브 에뮬레이터 트레이스와 교차 검증됩니다. 이는 그 자체로 하나의 산출물이며, 동시에 (2)의 명세이기도 합니다.
(2) 재구현(BattleTechCHI/). (1)에서 파생된 Godot 4 C# 프로그램으로, 원본 데이터 파일(.BLD, .MTP, .ANM, GAME* 세이브)을 읽고 (1)에 의해 문서화된 대로 엔진 동작을 재구현합니다. 이는 데이터 충실성이지 동작 충실성이 아니며, 원본에 대해 종단 간 검증된 적이 없습니다.
이들은 병렬로 실행되지만, 의존성 방향은 고정되어 있습니다:
(2)는 (1)이 완전하고 검증된 만큼만 충실할 수 있습니다. (1)이 추론됨 또는 미해결이라고 말하는 곳에서 (2)는 추측입니다.
이것이 로드맵이 기능 작업보다 RE 격차 해소(Track 1)와 **(2)의 에뮬레이터 대비 차분 검증(Track 3)**을 앞에 두는 이유입니다. 재구현은 그것을 떠받치는 리버스 엔지니어링만큼만 좋습니다.
비트 단위로 정확한 포트를 찾고 있다면, 아직 존재하지 않습니다. 도구 지원 RE 환경과 원본 에셋에서 실행되는 데이터 기반 재구성을 찾고 있다면, 그것이 여기 있는 것입니다.
범례: ✅ 참 / 완료 · ⚠️ 부분적, 근사적, 또는 조용한 격차 존재 · ❓ 알 수 없음 / 미검증 · ❌ 없음
| 시스템 | 런타임에 원본 파일 읽기 | 동작이 원본과 일치 | 검증 |
|---|---|---|---|
| BLD 복호화 + 암호문 | ✅ BldLoader.cs | ✅ (텍스트) | ✅ BLD↔JSON 왕복 바이트 동일 (tools/bld) |
| BLD 옵코드 인터프리터 (28개 슬롯 0xE4–0xFF) | ✅ | ⚠️ 부분적 | ❓ 종단 간 플레이된 적 없음; 피연산자 크기 고정 (EB/EC/F6/F7); 모든 슬롯 처리됨 (조용한 누락 없음) |
Fn1CD3 디스패치 (47개 케이스) | ✅ | ⚠️ 부분적 | ❓ 디컴파일에서 구현됨; 여러 케이스가 근사치 |
| MTP 맵 헤더/타일 | ✅ MapLoader.cs / LocalMapView.cs | ✅ (구조) | ⚠️ 레이아웃 디코딩됨, 프레임별 비교는 안 됨 |
| ANM 애니메이션 (XOR-델타 RLE) | ✅ 런타임, PNG 폴백 | ⚠️ | ❓; 저장소에 ANM 스프라이트시트 없음 (Assets/Animations/ 비어 있음) |
| ICN/CMP 타일 | ❌ (사전 변환됨) | — | TileManager가 BMP 로드; Assets/Tilesets/ 비어 있음 |
세이브 파일 GAME1–6 (4096 B) | ✅ 파서 SaveManager.cs | ❓ | ❌ 원본 세이브 대비 왕복 검증되지 않음 |
스토리 상태 (b0057, props) | ✅ (읽기) | ❓ 의미 추론됨 | ❓ 플레이 중 의미 확인되지 않음 |
| 전투 (명중, 데미지, AI, 열, 탄약, 안개) | — (자체 로직) | ❌ 근사적 | ❌ RNG/공식이 원본과 비교된 적 없음 |
| 뷰포트 / 화면 레이아웃 | — | ⚠️ 근사적 | ❓ 정식 뷰포트 구조체 발견되지 않음 |
| 사운드 / 음악 | ❌ | ❌ | ❌ 형식 디코딩되지 않음 |
| 맵→BLD 트리거 매핑 | ⚠️ 부분적 | ❓ | 타일 속성 테이블 + [0x5460]:0x4602 변환 디코딩되지 않음 |
.BLD 스크립트를 로드하고 복호화하여 해석합니다 (대화, 메뉴, 상점, 다수의 디스패치 케이스) — 미구현 옵코드에 대해서는 조용한 격차가 있습니다..MTP 맵을 파싱하고, 실제 4096바이트 세이브 레이아웃을 읽고 씁니다.| 영역 | 상태 | 정식 문서 |
|---|---|---|
| BLD 형식, 암호, 옵코드 | 🟢 견고함 | docs/formats/bld-bytecode.md |
| 스토리 텍스트 (26개 BLD 전체) | 🟢 추출됨 | docs/story/STORY_TEXT.txt |
| 메모리 맵 (100+ 주소, 세그먼트) | 🟢 견고함 | docs/formats/memory-map.md |
| 월드 맵 / 로컬 맵 | 🟢 견고함 | docs/world-map.md |
| 전투 모델 | 🟡 ~90%, 일부 추론됨 | docs/combat-system.md |
| 경제 / 상점 / 재고 | 🟡 UI 흐름이 이제 라이브로 관찰됨 | docs/story/story-system.md |
| ANM 형식 | 🟢 문서화됨 | docs/formats/anm-format.md |
| 뷰포트 추상화 | 🔴 불완전 | docs/engine/viewport.md |
| 사운드 | 🔴 0% | — |
이것들이 진짜 블로커이며, §6의 로드맵은 이들에 의해 게이트됩니다.
docs/combat-system.md)19EF / 1000의 전투/이동 코드가 Reko 출력에서 누락됨; 해당 루틴을 복구해야 함. (docs/UNVERIFIED_DISCOVERIES.md §7)b0057 (0/1/2)과 인접한 b0055/b0056/b0058은 추론됨; 속성 ID 0x1C–0x23은 매핑되지 않음. (§5)0x32C6) + 변환 테이블 ([0x5460]:0x4602)이 디코딩되지 않음; 입구는 현재 맵을 손으로 걸어서 찾음 (시작 맵의 Citadel (34,10), ComStar (51,10)). (docs/context.md)0x246C 설정 구조체는 부분적으로만 매핑됨; push/pop 의미론 불명. (docs/engine/viewport.md)0x32C6을 읽는지. (§2)GAME* 로드→저장→비교는 수행되지 않음.docs/story/story-system.md)BldInterpreter.cs 기본 분기)2A02 대 다른 곳). (§1)실행 파일만으로의 RE에는 한계가 있습니다 (컴파일러 최적화 코드, 부재하는 세그먼트, 추론된 의미론). 게임에 실제로 무엇이 있는지 이해하기 위해 여러 종류의 소스를 교차 검증합니다 — 어느 것도 바이너리를 대체할 수는 없지만, 함께 의도를 해결하고 격차를 채웁니다:
docs/walkthrough/bt-walkthrough-1..3.md (내비게이션 및 이벤트 시퀀스).bt_* MCP 도구가 비교할 정확한 런타임 레지스터/메모리 상태를 제공함.우선순위: 동작에 대해서는 바이너리/에뮬레이터가 승리하고; 문서는 의도에 대해 권위가 있습니다. 문서나 기억에서 복구된 모든 주장은 재구현에 들어가기 전에 출처가 표시되고 바이너리에 대해 재검증됩니다. 전체 정책 (소스 클래스, 증거 태그 ✅/🟡/❓, 소스→검증 워크플로)은 docs/SOURCES.md에 있습니다.
순서는 의도적입니다: 더 많은 화면을 만들기 전에 데이터 경로와 동작을 증명하십시오. 각 게이트는 검증이지 기능이 아닙니다.
docs/rebuild/progress.md 및 위키를 정직하게 유지; 모든 주장을 검증됨 / 추론됨 / 알 수 없음으로 표시하고 날짜를 기입.19EF/1000 디컴파일/주석 (전투/이동). ← 2를 언블록w4FBC/push-pop 해결; 타일 속성 비트 완성.GAME* 파일 대비 세이브 왕복 검증.WINSCENE / ENDMECH / TINYLAND.단계별 상세 체크리스트는 docs/rebuild/roadmap.md에 있습니다; 단계 원장은 docs/rebuild/progress.md입니다.
docs/ RE 문서 (주제별 정식 문서: docs/INDEX.md)
reko/ Reko 디컴파일러 출력 (C + asm, 세그먼트별)
tools/
bld/ BLD 디코드 / JSON 왕복 / 스토리 추출
assets/ 에셋 추출 & 렌더링
analysis/ 바이너리 & 메모리 덤프 분석
playtest/ bt.py — MCP + 메모리 API를 통해 에뮬레이터 구동
BattleTechCHI/ Godot 4 + C# 재구현 (~4.9k 줄, ~45 스크립트)
Scripts/{Core,Data,Maps,BLD,Combat,UI}
Assets/ 맵 PNG 15개, 메크 스프라이트 44개, 화면 9개 (타일셋/ANM/폰트 비어 있음)
original/ 원본 게임 파일 (로컬 전용, gitignored)
BattleTechMcpTools/ Spice86 오버라이드 공급자 + 23개 bt_* MCP 도구
# 에뮬레이터 + MCP (트레이스용 그라운드 트루스)
fuser -k 20000/tcp 8086/tcp 2>/dev/null
: > /tmp/emu.log
dotnet exec bin/Debug/net10.0/UNBATTLETECH.dll \
--Exe "/path/to/UNBTECH.exe" --CDrive "/path/to/game/" \
--HeadlessMode Minimal --McpHttpPort 8086 --NoGui