
Reverse engineering di BattleTech: The Crescent Hawk's Inception
Reverse engineering di BattleTech: The Crescent Hawk's Inception (1988, MS-DOS; pubblicato da Infocom, engine di Westwood Associates) — e una ricreazione in Godot 4 / C# in corso d'opera.
Leggi questa sezione prima di fidarti di qualsiasi altra cosa in questo repo. Il progetto è due sforzi con maturità molto diversa, e la parola "fase" altrove nella documentazione significa codice scritto, non comportamento dimostrato.
Questo progetto produce due artefatti allo stesso tempo, e il secondo si basa sul primo:
(1) Il reverse engineering documentato. La decompilazione reko/, le specifiche in docs/, l'
emulatore Spice86 con strumenti MCP specifici per BattleTech, e il tooling Python. Questo è il vero lavoro di RE:
formati di file, testo della storia, mappa di memoria, e gran parte della logica dell'engine sono documentati e
verificati incrociando l'output del decompilatore e le tracce live dell'emulatore. È un deliverable a sé
stante, ed è anche la specifica per (2).
(2) La ricreazione (BattleTechCHI/). Un programma Godot 4 C# che deriva da (1): legge
i file dati originali (.BLD, .MTP, .ANM, salvataggi GAME*) e re-implementa il comportamento dell'engine
come documentato da (1). È fedele ai dati, non al comportamento, e non è mai stato
validato end-to-end rispetto all'originale.
Funzionano in parallelo, ma la direzione della dipendenza è fissa:
(2) può essere fedele solo quanto (1) è completo e verificato. Dove (1) dice inferito o aperto, (2) è un'ipotesi.
Ecco perché la roadmap mette la chiusura delle lacune del RE (Track 1) e la validazione differenziale di (2) rispetto all'emulatore (Track 3) prima del lavoro sulle funzionalità. Una ricreazione è buona solo quanto il reverse engineering su cui si basa.
Se stai cercando un port bit-exact, non esiste ancora. Se stai cercando un ambiente di RE assistito da strumenti più una ricostruzione data-driven che gira su asset originali, questo è quello che c'è.
Legenda: ✅ vero / fatto · ⚠️ parziale, approssimativo, o con lacune silenziose · ❓ sconosciuto / non verificato · ❌ assente
| Sistema | Legge i file originali a runtime | Il comportamento corrisponde all'originale | Validazione |
|---|---|---|---|
| Decifratura BLD + testo cifrato | ✅ BldLoader.cs | ✅ (testo) | ✅ round-trip BLD↔JSON byte-identico (tools/bld) |
| Interprete opcode BLD (28 slot 0xE4–0xFF) | ✅ | ⚠️ parziale | ❓ mai giocato end-to-end; dimensioni operandi fisse (EB/EC/F6/F7); tutti gli slot gestiti (nessun drop silenzioso) |
Dispatch Fn1CD3 (47 casi) | ✅ | ⚠️ parziale | ❓ implementato dalla decomp; diversi casi sono approssimazioni |
| Header/tile mappa MTP | ✅ MapLoader.cs / LocalMapView.cs | ✅ (struttura) | ⚠️ layout decodificato, non diffato frame-by-frame |
| Animazione ANM (XOR-delta RLE) | ✅ runtime, fallback PNG | ⚠️ | ❓; il repo non ha spritesheet ANM (Assets/Animations/ vuota) |
| Tile ICN/CMP | ❌ (pre-convertite) | — | TileManager carica BMP; Assets/Tilesets/ vuota |
File di salvataggio GAME1–6 (4096 B) | ✅ parser SaveManager.cs | ❓ | ❌ round-trip non verificato rispetto ai salvataggi originali |
Stato della storia (b0057, props) | ✅ (legge) | ❓ significato inferito | ❓ semantica non confermata in gioco |
| Combattimento (to-hit, danno, AI, calore, munizioni, nebbia) | — (logica propria) | ❌ approssimativo | ❌ RNG/formule mai diffati rispetto all'originale |
| Viewport / layout schermo | — | ⚠️ approssimativo | ❓ nessuna struct viewport canonica individuata |
| Suono / musica | ❌ | ❌ | ❌ formato non decodificato |
| Mappatura trigger mappa→BLD | ⚠️ parziale | ❓ | tabella proprietà tile + traduzione [0x5460]:0x4602 non decodificate |
.BLD e interpretarli (dialoghi, menu, negozi, molti casi di dispatch)
— con lacune silenziose sugli opcode non implementati..MTP, e leggere/scrivere il vero layout di salvataggio da 4096 byte.| Area | Stato | Doc canonica |
|---|---|---|
| Formato BLD, cifrario, opcode | 🟢 solido | docs/formats/bld-bytecode.md |
| Testo della storia (tutti i 26 BLD) | 🟢 estratto | docs/story/STORY_TEXT.txt |
| Mappa di memoria (100+ indirizzi, segmenti) | 🟢 solido | docs/formats/memory-map.md |
| Mappa del mondo / mappe locali | 🟢 solido | docs/world-map.md |
| Modello di combattimento | 🟡 ~90%, alcuni inferiti | docs/combat-system.md |
| Economia / negozi / scorte | 🟡 flusso UI ora osservato live | docs/story/story-system.md |
| Formato ANM | 🟢 documentato | docs/formats/anm-format.md |
| Astrazione viewport | 🔴 incompleto | docs/engine/viewport.md |
| Suono | 🔴 0% | — |
Questi sono i veri blocchi; la roadmap in §6 è vincolata a essi.
docs/combat-system.md)19EF / 1000 manca dall'
output di Reko; quelle routine devono essere recuperate. (docs/UNVERIFIED_DISCOVERIES.md §7)b0057 (0/1/2) e i vicini b0055/b0056/b0058 sono inferiti;
gli ID proprietà 0x1C–0x23 non mappati. (§5)0x32C6) + tabella di traduzione
([0x5460]:0x4602) non decodificate; gli ingressi sono attualmente trovati camminando a mano la mappa
(Citadel (34,10), ComStar (51,10) sulla mappa iniziale). (docs/context.md)0x246C è solo
parzialmente mappata; semantica push/pop sconosciuta. (docs/engine/viewport.md)0x32C6 per
il movimento. (§2)GAME* non è stato fatto.docs/story/story-system.md)BldInterpreter.cs)2A02 vs altrove). (§1)Il RE dal solo eseguibile ha limiti (codice ottimizzato dal compilatore, segmenti assenti, semantica inferita). Per capire cosa c'è effettivamente nel gioco verifichiamo incrociando diversi tipi di fonte — nessuna può sostituire il binario, ma insieme risolvono l'intento e colmano le lacune: