
BattleTech: The Crescent Hawk's Inception engenharia reversa
Engenharia reversa de BattleTech: The Crescent Hawk's Inception (1988, MS-DOS; publicado pela Infocom, engine da Westwood Associates) — e uma recriação em andamento em Godot 4 / C# do mesmo.
Leia esta seção antes de confiar em qualquer outra coisa neste repositório. O projeto consiste em dois esforços com maturidades muito diferentes, e a palavra "fase" em outros lugares da documentação significa código escrito, não comportamento comprovado.
Este projeto produz dois artefatos ao mesmo tempo, e o segundo se apoia no primeiro:
(1) A engenharia reversa documentada. A descompilação em reko/, as especificações em docs/, o
emulador Spice86 com ferramentas MCP específicas para BattleTech, e o ferramental em Python. Este é o
trabalho real de RE: formatos de arquivo, texto da história, mapa de memória, e grande parte da lógica
da engine estão documentados e verificados cruzadamente com a saída do descompilador e traces ao vivo
do emulador. É um entregável por si só, e também é a especificação para (2).
(2) A recriação (BattleTechCHI/). Um programa em Godot 4 C# que deriva de (1): ele lê os
arquivos de dados originais (.BLD, .MTP, .ANM, saves GAME*) e reimplementa o comportamento da
engine conforme documentado por (1). É fiel aos dados, não fiel ao comportamento, e nunca foi
validado de ponta a ponta contra o original.
Eles rodam em paralelo, mas a direção da dependência é fixa:
(2) só pode ser tão fiel quanto (1) for completo e verificado. Onde (1) diz inferido ou em aberto, (2) é um chute.
É por isso que o roadmap coloca o fechamento das lacunas de RE (Trilha 1) e a validação diferencial de (2) contra o emulador (Trilha 3) antes do trabalho de funcionalidades. Uma recriação só é tão boa quanto a engenharia reversa que a sustenta.
Se você procura um port bit-exato, ele ainda não existe. Se você procura um ambiente de RE assistido por ferramentas mais uma reconstrução orientada a dados que roda sobre os assets originais, é isso que está aqui.
Legenda: ✅ verdadeiro / concluído · ⚠️ parcial, aproximado, ou com lacunas silenciosas · ❓ desconhecido / não verificado · ❌ ausente
| Sistema | Lê arquivos originais em runtime | Comportamento corresponde ao original | Validação |
|---|---|---|---|
| Descriptografia BLD + texto cifrado | ✅ BldLoader.cs | ✅ (texto) | ✅ round-trip BLD↔JSON byte-idêntico (tools/bld) |
| Interpretador de opcodes BLD (28 slots 0xE4–0xFF) | ✅ | ⚠️ parcial | ❓ nunca jogado de ponta a ponta; tamanhos de operando fixos (EB/EC/F6/F7); todos os slots tratados (sem descarte silencioso) |
Despacho Fn1CD3 (47 casos) | ✅ | ⚠️ parcial | ❓ implementado a partir da decomp; vários casos são aproximações |
| Cabeçalho/tiles do mapa MTP | ✅ MapLoader.cs / LocalMapView.cs | ✅ (estrutura) | ⚠️ layout decodificado, não comparado quadro a quadro |
| Animação ANM (RLE com delta XOR) | ✅ runtime, fallback PNG | ⚠️ | ❓; o repositório não tem spritesheets ANM (Assets/Animations/ vazio) |
| Tiles ICN/CMP | ❌ (pré-convertidos) | — | TileManager carrega BMP; Assets/Tilesets/ vazio |
Arquivos de save GAME1–6 (4096 B) | ✅ parser SaveManager.cs | ❓ | ❌ round-trip não verificado contra saves originais |
Estado da história (b0057, props) | ✅ (lê) | ❓ significado inferido | ❓ semântica não confirmada em jogo |
| Combate (to-hit, dano, IA, calor, munição, névoa) | — (lógica própria) | ❌ aproximado | ❌ RNG/fórmulas nunca comparados com o original |
| Viewport / layout de tela | — | ⚠️ aproximado | ❓ nenhuma struct canônica de viewport localizada |
| Som / música | ❌ | ❌ | ❌ formato não decodificado |
| Mapeamento de gatilho mapa→BLD | ⚠️ parcial | ❓ | tabela de propriedades de tile + tradução [0x5460]:0x4602 não decodificadas |
.BLD reais e interpretá-los (diálogo, menus, lojas, muitos
casos de despacho) — com lacunas silenciosas em opcodes não implementados..MTP reais, e ler/escrever o layout real de save de 4096 bytes.| Área | Estado | Doc canônico |
|---|---|---|
| Formato BLD, cifra, opcodes | 🟢 sólido | docs/formats/bld-bytecode.md |
| Texto da história (todos os 26 BLD) | 🟢 extraído | docs/story/STORY_TEXT.txt |
| Mapa de memória (100+ endereços, segmentos) | 🟢 sólido | docs/formats/memory-map.md |
| Mapa-múndi / mapas locais | 🟢 sólido | docs/world-map.md |
| Modelo de combate | 🟡 ~90%, algo inferido | docs/combat-system.md |
| Economia / lojas / estoque | 🟡 fluxo de UI agora observado ao vivo | docs/story/story-system.md |
| Formato ANM | 🟢 documentado | docs/formats/anm-format.md |
| Abstração de viewport | 🔴 incompleto | docs/engine/viewport.md |
| Som | 🔴 0% | — |
Estes são os bloqueadores reais; o roadmap na §6 depende deles.
docs/combat-system.md)19EF / 1000 está
ausente da saída do Reko; essas rotinas precisam ser recuperadas. (docs/UNVERIFIED_DISCOVERIES.md §7)b0057 (0/1/2) e vizinhos b0055/b0056/b0058 são inferidos;
IDs de propriedade 0x1C–0x23 não mapeados. (§5)0x32C6) + tabela de tradução
([0x5460]:0x4602) não decodificadas; entradas atualmente são encontradas percorrendo o mapa à mão
(Citadel (34,10), ComStar (51,10) no mapa inicial). (docs/context.md)0x246C está apenas parcialmente mapeada; semântica de push/pop desconhecida. (docs/engine/viewport.md)0x32C6 para
movimento. (§2)GAME* não foi feito.docs/story/story-system.md)BldInterpreter.cs)2A02 vs outro lugar). (§1)RE apenas a partir do executável tem limites (código otimizado pelo compilador, segmentos ausentes, semântica inferida). Para entender o que realmente está no jogo, verificamos cruzadamente vários tipos de fonte — nenhuma pode substituir o binário, mas juntas elas resolvem a intenção e preenchem lacunas: