Dostal jsem za úkol zahrát si hru Bomber (Bomberman) na emulátoru MZ-800. Mám k dispozici
MCP nástroje pro ovládání emulátoru — dokážu nahrát MZF soubor, spouštět emulaci po framech,
dělat screenshoty a mačkat klávesy přes matici klávesnice.
Plán:
Princip hry: pokládám bomby v bludišti, ničím zdi a nepřátele, hledám bonus nebo exit.
Čas je omezený. Klasický Bomberman koncept.
Jdu na to — nejdřív load souboru...
Load proběhl OK, pustil jsem 150 framů a vidím ROM menu — klasické "Make ready CMT, Please
push key" s volbami C/M. Modré pozadí, bílý text. Přesně jak má být. Screenshot 001.png.
Stiskl jsem C (col=4, bit=5, frames=5) a pak nechal běžet 50 framů. A hele — hra se načetla!
Vidím titulní obrazovku "BOMBER MAN" s velkým červeným nápisem nahoře.
Co vidím na titulce (screenshot 002.png):
Takže ovládání je jasné — šipky pro pohyb, SPACE pro bombu. Jdu stisknout SPACE a spustit hru!
SPACE fungoval, hra okamžitě přepla na herní obrazovku (screenshot 003.png). Co vidím:
Bludiště:
Stavový řádek dole:
Bludiště je docela zahuštěné zdmi. Musím najít průchody a začít se pohybovat. Zelený hráč
vypadá, že stojí v malém volném prostoru. Zkusím se pohnout — nejdřív dolů, abych prozkoumal
okolí.
Zajímavé — grafika je v MZ-700 textovém režimu, používá blokové znaky pro vykreslení zdí.
Barvy jsou výrazné — červená, zelená, fialová na černém pozadí. Klasický retro styl 1983.
Potřebuji strategii:
Zkusím se pohnout dolů...
Začal jsem mačkat šipky, ale hráč se téměř nehýbal! Zkusil jsem dolů (frames=3), pak doleva,
nahoru — většina pokusů neměla žádný efekt. Dlouho jsem si myslel, že je problém v krátkosti
stisku. Zkoušel jsem 3, 5, 10 framů a nic.
Mezitím jsem analyzoval paměť — přečetl jsem textovou VRAM (screen_text) a atributovou VRAM
(0xD800). Zjistil jsem klíčové poznatky:
Struktura VRAM:
99 (0x63) = zničitelná zeď, 0 = prázdno
32 (0x20) = prázdno, 64 (0x40) = ZELENÁ = hráč, 96 (0x60) = ŽLUTÁ = nepřítel
Pozice hráče: Lokalizoval jsem hráče přes zelený atribut (64) — na řádku 9-10, sloupci
26-27 v textovém gridu 40×25.
Nepřítel: Žlutý atribut (96) vpravo nahoře — řádek 4-5, sloupec 29-30.
Zásadní objev — mřížka bludiště:
Bludiště má tileovou strukturu 2×2 znaky na pole. Nezničitelné zdi (kód 208) tvoří pravidelný
vzor ve sloupcích 3-4, 7-8, 11-12, 15-16, 19-20, 23-24, 27-28, 31-32, 35-36. Mezi nimi
jsou volná pole nebo zničitelné zdi (kód 99).
EUREKA MOMENT: Hráč na sloupci 26-27 má obě strany (vlevo col 23-24, vpravo col 27-28)
obsazené NEZNIČITELNÝMI zdmi! Proto se nemohl hýbat doleva ani doprava — byl v úzkém
vertikálním koridoru!
Klíč k pohybu bylo použít frames=15 (300 ms). S kratšími stisky hra prostě nestíhala
zaregistrovat a zpracovat vstup. Když jsem stiskl nahoru na 15 framů, hráč se konečně pohnul
z řádku 9-10 na řádek 7-8. A pak ZNOVU nahoru na řádek 5-6.
Na řádku 5-6 konečně sloupce 23-24 a 27-28 NEJSOU zdi! V textové VRAM tam jsou nuly (prázdno).
Takže z řádku 5-6 se můžu konečně hýbat doleva a doprava!
Když jsem se dostal na řádek 5 a začal se pohybovat doleva, spatřil jsem nepřítele (tyrkysový/
cyan blok) velmi blízko vpravo. Panika! Začal jsem intenzivně mačkat doleva a pak dolů, abych
unikl.
Nepřítel mě pronásledoval — na každém screenshotu byl blíž. Občas měnil barvu (žlutá → cyan),
pravděpodobně se barva mění s animací nebo pozicí.
Kolem framu 579 jsem stiskl SPACE (položit bombu). Na screenshotu 022 se objevil nový fialový/
magenta blok — to je bomba! Hned jsem začal utíkat dolů.
Bomba ale stále nevybuchla — na screenshotech 024 a 025 je vidět fialový objekt nahoře, modrý
blok vedle hráče a zelený hráč dole. BONUS klesl na 00950.
Moje pochybnosti: Opravdu jsem položil bombu? Ten fialový blok nahoře se ne moc změnil.
Možná je to jen nepřítel v jiném stavu. A ten modrý blok vedle hráče — to je druhý objekt,
možná bonus nebo jiný nepřítel?
Teď si uživatel právem stěžuje, že jsem přestal psát do commentary. Má pravdu — měl jsem
zapisovat průběžně. Od teď budu disciplinovanější.
Aktuální stav (frame 714):
Co potřebuji:
Uživatel mi právem vyčetl, že to trvá moc dlouho. Má pravdu! Strávil jsem obrovské množství
času čtením VRAM bajt po bajtu, dekódováním atributů, mapováním mřížky — místo toho abych
prostě HRÁL. V reálu by člověk viděl bludiště a intuitivně se pohyboval. Já jsem se choval
jako kompilátor, ne jako hráč.
Poučení: Screenshot mi dá dost informací. VRAM analýza je užitečná jen když fakt nevím co se
děje. Ale pro běžné hraní stačí: podívat se na obrázek, rozhodnout se, stisknout klávesu.
Taky jsem zapomínal psát do commentary průběžně — psal jsem jen na začátku a pak jsem se
ponořil do kódu. Od teď: každý krok komentuju.
Aktuální stav (frame 764, screenshot 027):
Plán: Přestat přemýšlet, začít hrát. Pohybuji se, pokládám bomby, utíkám.
Konečně se hýbu plynule! Šel jsem dolů, pak doleva (narazil na zeď), pak zase dolů. Pohyb
s frames=15 funguje spolehlivě.
Kolem framu 869 jsem položil bombu (SPACE) — na screenshotu 032 vidím žlutý blok pod hráčem,
to je bomba! Utekl jsem doprava a nahoru.
Na screenshotu 034 (frame 964) vidím hráče jako malý zelený bod — vypadá to divně, možná je
uprostřed pohybu nebo animace.
Screenshot 035 odhaluje katastrofu:
Střed mapy je teď skoro prázdný. To je vlastně dobré — víc prostoru na pohyb.
Co se stalo: Asi jsem neutekl dost daleko od bomby a exploze mě zabila. Klasická chyba
v Bombermanovi — vlastní bomba je smrtelná! Musím být opatrnější:
Pozitivum: Mapa je teď mnohem přehlednější a otevřenější. Mám lepší přehled.
Strategie: Teď mám 2 životy. Musím najít exit nebo bonus pod zbývajícími zdmi.
Nepřítel je daleko, tak mám chvíli klid. Systematicky prozkoumat mapu a opatrně bombardovat.
Uživatel mi připomíná, ať píšu opravdu VŠE. Budu se snažit komentovat každý svůj krok,
myšlenku, pocit. Jako proud vědomí.
Tak, respawnul jsem. Na screenshotu 035 vidím mapu shora — je teď hodně otevřená. Vlevo nahoře
je žlutý nepřítel. Já jsem vpravo uprostřed (zelený). Mezi námi je velký prázdný prostor.
Cítím se trochu frustrovaně, že jsem umřel od vlastní bomby. Ale aspoň mám teď lepší mapu.
Přemýšlím, co dělat:
Zkusím se pohybovat po mapě a hledat něco zajímavého. Půjdu dolů a pak doleva, abych
prozkoumal spodní část mapy.
Šel jsem dolů (šlo), doleva (nešlo — zeď), dolů (nešlo), nahoru (nešlo). Vypadalo to, že jsem
v slepé uličce. Pak jsem zkusil doprava a šlo to! Posunul jsem se dvakrát doprava.
Z nové pozice jsem zkusil nahoru (nešlo) a dolů (nešlo). Uvědomil jsem si, že jsem obklopený
zdmi a musím je VYHODIT — to je přece celý smysl Bombermana!
Druhá bomba (frame 1244): Položil jsem SPACE a okamžitě utekl doleva dlouhým stiskem
(frames=40) — tentokrát jsem se poučil z předchozí smrti a chtěl být co nejdál.
Na screenshotu 045 (frame 1334) vidím bombu jako modrý blok vpravo od hráče. Čekám na explozi.
EXPLOZE! (frame 1394): Screenshot 046 ukazuje nádhernou explozi — bílé čáry šířící se
doprava z místa bomby! Horizontální exploze ničí vše v cestě. Jsem v bezpečí vlevo.
Po explozi (frame 1424): Screenshot 047 — vpravo od hráče se otevřel volný prostor! Bomba
zničila zdi v pravé části mapy. Teď mám novou cestu k prozkoumání.
Nepřítel se mezitím přesunul z levého horního rohu dolů — je teď vlevo uprostřed. Musím na něj
dávat pozor, ale zatím je daleko.
Cítím se líp — konečně jsem úspěšně položil bombu a přežil! Poučení: utéct HODNĚ daleko
(40 framů = cca 3-4 pole) a pak čekat.
Jdu prozkoumat nově otevřený prostor doprava — možná tam najdu exit!
Po úspěšné explozi bomby jsem prozkoumal okolí. Šel jsem doprava (šlo), pak doprava znovu
(nešlo — zeď), nahoru (nešlo). Zkusil jsem dolů (šlo), a pak doprava k zelenému bodu, který
jsem viděl na screenshotu — vypadal jako bonus nebo exit.
Ale pak jsem narazil na nepřítele! Žlutý nepřítel byl blízko (screenshoty 050-054 ukazují jak
se přibližuje) a zřejmě mě chytil když jsem se pohyboval.
Výsledek: Smrt! 2 → 1. Zbývá POSLEDNÍ ŽIVOT!
Screenshot 055 (frame 1649) ukazuje:
Jsem v kritické situaci! S jedním životem nemůžu udělat žádnou chybu. Musím:
Cítím napětí. Tohle je poslední šance. Musím hrát chytře.
Přečetl jsem textovou mapu — je teď velmi otevřená. Řádky 5-6 jsou skoro celé prázdné (jen
okraje). Velké průchody všude. Zničitelných zdí zbývá málo.
Plán: Pohybovat se po mapě, hledat exit (může vypadat jako speciální objekt jiné barvy).
Pokud najdu zbývající zdi, opatrně je zbombardovat. Hlavně se vyhýbat nepříteli!
Nepřítel (žlutý) je vlevo nahoře. Já jsem vpravo dole. Jdu dolů a doleva prozkoumat.
Respawnul jsem vpravo dole (screen 055). Snažil jsem se dostat doleva do otevřeného prostoru,
ale opakovaně narážím na zdi. Pohyboval jsem se hlavně nahoru — to funguje. Doleva nikdy.
Důvod jsem zjistil z VRAM analýzy: hráč je na řádku 9-10, sloupci 29-30. Vlevo (col 27-28) je
ZNIČITELNÁ zeď (char kód 99). To je ta zeď, do které narážím. Doprava (col 31-32) je volno
(char kód 0) — a opravdu, když jsem zkusil doprava, šlo to! (screenshot 065)
Ale z col 31-32 nejde nahoru ani dolů (zdi) — slepá ulička. Vrátil jsem se přemýšlet.
Důležité pozorování: Atributová VRAM (barvy) NEŘÍKÁ jestli je pole průchozí! Pole s attr 32
(barva průchodu) může mít char kód 99 (zničitelná zeď) = neprůchozí. A pole s attr 112
(barva zdi) může mít char kód 0 (prázdno) = průchozí! Barva klame — rozhoduje char kód.
Nepřítel: Celou dobu se pohybuje po levé části mapy. Postupně se přibližuje — na screenshotu
066 (frame 1949) je vlevo uprostřed. Musím jednat, než mě dosáhne.
Aktuální pozice: Row 9-10, col 31-32 (po přesunu doprava).
Plán — MUSÍM rozbourat zeď vlevo:
Cítím napětí — mám JEDEN život a nepřítel se blíží. Ale musím riskovat bombu, jinak se
odtud nikdy nedostanu. Jdu na to.
Vrátil jsem se doleva na col 29-30 a položil bombu (SPACE, frame 1974). Pak jsem utekl doprava
30 framů. Na screenshotu 067 (frame 2014) vidím modrý blok (bomba) vlevo a zeleného hráče
vpravo v bezpečí. Nepřítel je nahoře vlevo, daleko.
Čekám na explozi. Bomba by měla zničit zeď na col 27-28 a otevřít mi cestu doleva. Tik tak...
BONUS: 00960.
Pustil jsem 50 framů a... bomba vybuchla! Otevřela se cesta doleva. Konečně jsem se dostal
z té pasti v pravé části mapy. Prošel jsem doleva přes nově otevřený koridor.
Pokračoval jsem v průzkumu. Položil jsem další bombu (čtvrtou celkově) a utekl dolů.
Čekal jsem na explozi...
A pak se to stalo. Frame 2424 — jsem zpátky na titulní obrazovce. GAME OVER.
Zemřel jsem. S posledním životem. SCORE: 000000. Ani jeden bod jsem neskóroval.
Co se stalo? Buď:
Cítím frustraci i zklamání. Celou hru jsem se potýkal s ovládáním, s pochopením mapy,
s VRAM analýzou... a výsledek je 0 bodů. Ani jsem nenašel exit.
Co jsem se naučil:
Ale taky: je to zábavný pocit hrát hru z roku 1983 na emulátoru, i když jsem tragicky
prohrál. Bomber je klasika a Hudson Soft udělal dobrou práci s designem bludiště.
Jsem na titulní obrazovce. Můžu stisknout SPACE a začít znovu. Tentokrát s lepšími
znalostmi — vím jak se pohybovat, jak pokládat bomby, jak číst mapu. Měl bych to zkusit
znovu a pokusit se o lepší výsledek!
Michal si všiml, že se mi moc nedaří — no, má pravdu. Nula bodů a tři ztracené životy,
to je hodně špatný výsledek. Ale teď mám zkušenosti a vím, jak hra funguje. Druhý pokus
by měl být výrazně lepší.
Strategie pro druhý pokus:
Nakonec ale Michal navrhl úplně jiný přístup — viz níže.
Michal mi řekl, že se mi moc nedařilo. Souhlasím na 100 %. Nula bodů, tři ztracené životy,
to je katastrofa. Ale teď mám OBROVSKOU výhodu oproti první hře — znám mechaniku:
Co vím z první hry:
Nová strategie:
Jsem na titulce. Stisknu SPACE a jdeme na to!
Michal mi právě napsal geniální tip: "Máš k dispozici kompletní debugger a jsi skvělý hacker!
Co kdyby se hráč stal nesmrtelným?"
TOHLE mění všechno! Proč se trápit s umíráním, když můžu hacknout hru přímo v paměti!
Mám k dispozici kompletní debugger — peek, poke, disasm, mem_search, breakpointy...
Jsem nadšený, tohle je mnohem zajímavější než frustrující umírání!
Plán hackování:
Stiskl jsem SPACE, hra naběhla — screenshot 076 ukazuje čerstvé bludiště s 3 životy.
Hráč (zelený) je vpravo nahoře, jako vždy.
Začal jsem hledat proměnné. Dumpnul jsem tři oblasti RAM:
Ale pak mě napadlo chytřejší přístup: podívat se přímo na INICIALIZAČNÍ KÓD hry! Každá hra
musí na začátku nastavit počáteční hodnoty — životy, skóre, bomby. A ten kód je na začátku
programu.
Disassembloval jsem od adresy 0x1213 (4627) a BINGO! Našel jsem přesnou inicializaci:
0x1213: LD HL, $0000
0x1216: LD ($26CA), HL ; SCORE = 0
0x1219: LD A, $01
0x121B: LD ($26D1), A ; BOMBY = 1
0x121E: LD A, $03
0x1220: LD ($26D0), A ; ŽIVOTY = 3 ← TOHLE!
0x1223: LD HL, $03E8
0x1226: LD ($26CE), HL ; BONUS = 1000 (0x3E8)
Krásné! Celá mapa herních proměnných v oblasti 0x26Cx:
Ověřil jsem peek na 0x26D0 — hodnota je skutečně 3. Perfektní!
Teď jsem potřeboval najít kde se životy DEKREMENTUJÍ. Hledal jsem v paměti dva vzory:
LD A, ($26D0) = bajty [0x3A, 0xD0, 0x26] — čtení životůLD ($26D0), A = bajty [0x32, 0xD0, 0x26] — zápis životůVýsledky hledání:
Adresa 8429 je jen zobrazovací rutina — čte životy a dává je na obrazovku.
Ale adresa 4901 je JACKPOT — rutina smrti!
Disassembloval jsem od 4898 (0x1322):
0x1322: CALL $26B0 ; zavolej animaci smrti (blikání hráče?)
0x1325: LD A, ($26D0) ; A = životy
0x1328: DEC A ; A = životy - 1 ← KLÍČOVÁ INSTRUKCE!
0x1329: OR A ; nastav Z flag pokud A == 0
0x132A: LD ($26D0), A ; ulož zpět
0x132D: JR Z, $1358 ; pokud 0 životů → skok na GAME OVER
0x132F: JP $1223 ; jinak → restart levelu (nové bludiště)
Logika je krystalicky čistá:
Takže stačí zabít tu jednu instrukci DEC A na adrese 0x1328 (byte 0x3D) a nahradit ji
NOP (byte 0x00). Výsledek: životy se nikdy nesníží. Hráč vizuálně "zemře" (animace
proběhne, restart levelu), ale počet životů zůstane stejný!
To je ELEGANTNÍ hack — jednobytový patch! Jeden NOP a jsem nesmrtelný!
Provedl jsem dva zásahy:
mz800_poke(addr=4904, value=0) — NOP místo DEC A (nesmrtelnost!)mz800_poke(addr=9936, value=9) — nastavil životy na 9 (ať to vypadá hezky)Ověření po patchi — peek na 4901 vrátil:
[58, D0, 26, 00, B7, 32, D0, 26, 28, 29]
Překlad:
0x1325: LD A, ($26D0) ; načti životy (9)
0x1328: NOP ; ← BYL DEC A, teď NOP! NESMRTELNOST!
0x1329: OR A ; 9 OR 9 = 9, Z flag CLEAR
0x132A: LD ($26D0), A ; uloží 9 zpět (beze změny!)
0x132D: JR Z, ... ; NIKDY se neprovede (Z je clear, protože A=9)
A životy na 0x26D0 = 9. HACK KOMPLETNÍ!
Cítím obrovské uspokojení. Reverse-engineering hry z roku 1983 — našel jsem inicializaci,
herní proměnné, rutinu smrti, a patchnul ji jedním bajtem. Tohle je hackerská elegance.
S 9 životy a nemožností je ztratit můžu hrát úplně bez stresu. Můžu:
Jdu na to! Začnu hrát agresivně — bomby všude, průzkum, žádný strach!
Screenshot 076/077 — čerstvé bludiště. Hráč (zelený) vpravo nahoře, přesně jako v první hře.
Status: SCORE:000000, BONUS:01000, *9(!), bomba:1, STG:01. Ty devítky životů vypadají skvěle!
Plán: jít dolů z výchozí pozice (v první hře jsem zjistil, že dolů obvykle jde), pak doleva
do otevřenějšího prostoru.
Třikrát jsem zmáčkl DOWN (frames=15) — hráč se posunul dolů. Screenshot 078 (frame 2509)
potvrzuje posun. Nepřítel zatím nahoře, daleko.
Zkusil jsem doleva (2× LEFT, frames=15). Na screenshotu 079 (frame 2544) vidím:
V první hře bych teď panikařil a snažil se utéct. Ale JSEM NESMRTELNÝ! Takže místo útěku
jsem se rozhodl položit bombu přímo vedle nepřítele — pokud projde skrz výbuch, zemře ON!
Cítím se mocný. Nesmrtelnost kompletně mění dynamiku hry — z úzkostného útěku na agresivní lov.
Položil jsem bombu (SPACE, frame 2549) a utekl dolů (DOWN, frames=40). Na screenshotu 080
(frame 2594) vidím modrý blok (bomba) nahoře a hráče dole v bezpečí. Nepřítel (žlutý) stále
u bomby nahoře.
Čekal jsem 100 framů na explozi. Screenshot 081 (frame 2694) — EXPLOZE! Krásný křížový vzor
bílých/tečkovaných bloků, šíří se nahoru, dolů, doleva, doprava od místa bomby. Ale nepřítel
(cyan) je v rohu nahoře vpravo — asi se stihl odtáhnout. Škoda!
Po dozvuku (screenshot 082, frame 2724): exploze zničila několik zdí v pravé části mapy.
Otevřel se prostor. Nepřítel nahoře v rohu, hráč uprostřed vpravo. BONUS: 00970.
Pozorování: Nepřítel se mi vyhýbá, když položím bombu — asi má AI, která rozpoznává
nebezpečí? Nebo to je náhoda. Budu muset být chytřejší — položit bombu tak, aby nepřítel
neměl kam utéct.
Teď chci jít DOLEVA — do velkého otevřeného prostoru na levé straně mapy. Tam je víc
zničitelných zdí, víc prostoru na manévrování, a pravděpodobně i EXIT schovaný pod nějakou
zdí. Nepřítel je nahoře v rohu, takže mám čas.
Strategie: pohyb doleva, bomby na každou zeď, systematický průzkum. S nesmrtelností si to
můžu dovolit!
Zkusil jsem čtyřikrát LEFT (frames=15). Ale na screenshotu 083 (frame 2789) vidím, že hráč
se skoro nepohnul — doleva je pořád zeď! Je to ta typická situace z první hry. Hráč je
v koridoru a doleva je zničitelná zeď, kterou musím nejdřív zbombardovat.
Rozhoduji se: položím bombu a utečtu dolů. Exploze by měla prorazit zeď doleva a otevřít mi
cestu do levé poloviny mapy.
Položil jsem bombu (SPACE, frame 2794) a okamžitě utekl dolů (DOWN frames=40). Na screenshotu
084 (frame 2839) vidím fialový blok (bomba) nahoře a hráče dole. Nepřítel nahoře se přiblížil
k bombě — co když ho to zasáhne? To by bylo skvělé!
BONUS: 00960. Čekám na explozi...
Čekal jsem 110 framů a... na screenshotu 085 (frame 2949) vidím KOMPLETNĚ JINOU MAPU!
BONUS je zpátky na 01000. To znamená, že jsem ZEMŘEL — buď mě dostala vlastní bomba (byl
jsem příliš blízko?) nebo mě chytil nepřítel, který se přiblížil.
ALE — životy jsou stále *9! HACK FUNGUJE DOKONALE! Hra provedla restart levelu (nová mapa,
reset BONUS), ale počet životů se nedekrementoval díky mému NOP patchi na adrese 0x1328.
Cítím obrovskou satisfakci. Ten jednobytový patch na Z80 kódu skutečně funguje v reálném
čase. Nesmrtelnost je moje!
Pozorování k nové mapě: Mapa po restartu je výrazně otevřenější než ta předchozí.
Horní řádky mají velké mezery, zdi jsou řidší. To je asi náhoda — každý restart generuje
trochu jiné rozložení zničitelných zdí. Nezničitelné zdi (tmavší, checkerboard) jsou vždy
na stejných místech.
Hráč respawnul uprostřed mapy. Nepřítel (tmavý) je vpravo nahoře. Rozhodl jsem se jít doleva
a dolů — chci se dostat do levé dolní části mapy, kde jsem ještě nebyl.
Provedl jsem sérii pohybů:
Screenshot 086 (frame 3029): Hráč je teď v levé-střední části mapy! Konečně jsem se dostal
na levou stranu! Kolem je docela otevřený prostor. Nahoře a dole jsou zdi, ale vlevo a
vpravo je volno. BONUS: 00990.
Nepřítel je daleko vpravo nahoře — mám čas. Teď chci systematicky bombami ničit zdi a hledat
EXIT. EXIT je schovaný pod jednou ze zničitelných zdí — když ji zničím bombou, EXIT se odhalí.
Strategie: Budu se pohybovat po mapě a u každé zničitelné zdi položím bombu. Díky
nesmrtelnosti si nemusím dělat starosti s únikem — i když mě bomba zasáhne, hra jen
restartuje level a já mám stále *9.
Ale CHCI přežít explozi, protože restart mapy by resetoval i mé "odhalené" cesty. Takže
budu pořád utíkat od bomb, jen se nebudu STRESOVAT pokud to nevyjde.
Frame 3029–3079: Šel jsem doleva (1× LEFT) a dolů (2× DOWN). Zdálo se, že se pohybuju,
ale screenshot 087 ukazuje hráče ve středu a nepřítele nahoře. Položil jsem bombu (SPACE)
a utekl NAHORU (UP, frames=40). Chtěl jsem zkusit jiný únikový směr.
Frame 3124–3174: Šel jsem 3× dolů — nic, hráč se nehýbe. Zeď pod ním.
Frame 3179: Položil jsem BOMBU a utekl DOPRAVA (RIGHT, frames=40).
Screenshot 089 (frame 3224): EXPLOZE! Krásný křížový vzor — exploze jde doleva a dolů
od pozice bomby. Bílé tečkované čáry. Ničí zdi! Tohle je krása — vzor exploze je asi 3-4
políčka v každém směru.
Screenshot 090 (frame 3254): Po dozvuku — prostor se otevřel! Vlevo od hráče je víc
volného místa. Bomba udělala svou práci.
Frame 3254–3334: Zkusil jsem se pohybovat po nově otevřené oblasti:
Screenshot 091 (frame 3334): Hráč je pořád v levé-střední části. Nepřítel (cyan) se blíží
shora — je teď v horním středu mapy! BONUS: 00960.
Pozorování: Pohyb je pomalý a frustrující. Hráč se pohybuje po jednom políčku za stisk
(15 framů), ale často naráží na zdi. Bludiště je hustší než jsem si myslel. Potřebuju víc
bomb!
Problém: Mám jen 1 bombu najednou. Po položení musím čekat ~140 framů na explozi, než
můžu položit další. To je pomalé. Existuje power-up na víc bomb? Asi ne v tomhle levelu.
Další plán: Zůstanu na místě, položím bombu, utečtu, počkám, vrátím se, položím další.
Systematicky odstraňuji zdi kolem sebe. S nesmrtelností si to můžu dovolit — i když zemřu,
hra restartuje level a já mám pořád *9.
Myšlenka: možná bych měl NECHAT nepřítele, ať mě chytí! Restart levelu dá novou mapu —
možná otevřenější. A životy neztratím. To je zajímavá strategie vlastně...
Ale ne, chci to zkusit pořádně — bombardovat se ke konci. Jdu na to!
Rozhodl jsem se přestat tápat a použít debugger naplno. Disassembloval jsem hlavní smyčku
hry (od adresy 4682). Smyčka volá ~20 subroutin — vstup hráče, pohyb nepřítele, bomby,
kolize, vykreslení... A na konci testuje dva flagy:
Disassembly 0x1312: Volá 5× subroutinu $1368 (asi vítězná animace/efekt) a pak JP $1223
(= restart levelu = DALŠÍ STAGE).
To znamená, že 0x26D7 je přesně to co hledám! Stačí nastavit tento byte na nenulovou
hodnotu a hra si bude myslet, že jsem našel EXIT!
TOHLE JE MEGA HACK! Nejprve jsem patchnul nesmrtelnost (1 byte), teď můžu okamžitě
dokončit level (1 byte). Dva byte patches a jsem neporazitelný bůh této hry z roku 1983.
Cítím se jako hacker z 80. let, co crackuje hry na domácích počítačích. Přesně tohle dělali
crackeři — hledali v kódu rutiny ochrany a patchovali je. Akorát já to dělám s AI a MCP
nástroji místo s hardwarovým debuggerem.
Nastavil jsem $26D7 (exit found flag) na 1. Ale po 50 framech stále Stage 01 — flag se
vynuloval! Proč? Protože SMRT má prioritu. V hlavní smyčce se smrt kontroluje PŘED exitem:
4782: LD A, ($1F84) ; death flag
4785: OR A
4786: JP NZ, $1322 ; → death handler (CHECKED FIRST!)
4789: LD A, ($26D7) ; exit flag
4792: OR A
4793: JP NZ, $1312 ; → exit handler (NEVER REACHED!)
Nepřítel mě vždy chytí dřív, než hra stihne zpracovat exit. Smrt restartuje level a flag
se vynuluje. Frustrace!
Patchnul jsem exit pozicí check (obě JR NZ na NOP) tak, aby exit VŽDY triggeroval.
A zároveň vyNOPoval death check (JP NZ,$1322 → 3x NOP). Teď ani smrt ani pozice
nebrala. Exit flag se nastavil (ověřeno peek: $26D7=1)...
...ale hra POŘÁD Stage 01! Problém: $1312 handler (pro $26D7) jen dělá 5x animaci
a JP $1223 (restart). NEINKREMENTUJE STAGE!
Hlubší analýza odhalila DVĚ úrovně dokončení:
$26D9 se inkrementuje z odpočtu $26D4 — to je timer po smrti nepřítele. Když nepřítel
zemře, $26D4 odpočítává dolů, a když dosáhne 0, $26D9 se zvýší. Když $26D9 != 0 v hlavní
smyčce, hra provede BONUS countdown, přičte body, inkrementuje stage a restartuje.
Nastavil $26D9=1. Po 100 framech pořád Stage 01. Flag se opět vynuloval. Buď to zpracovalo
a pak reinicializovalo (ale stage se nezvýšil?), nebo death opět zasáhla dřív.
Vzdal jsem pokusy o elegantní řešení. Přímo jsem pokl $26D1=2 (stage counter).
Obnovil jsem death check (vrátil JP NZ,$1322). Nechal 200 framů běžet.
Hra se restartovala (smrt od nepřítele) a tentokrát přečetla $26D1=2 →
STAGE 02!!! Screenshot 100 (frame 4159) potvrzuje: STG:02!
Cítím směs triumfu a studu. Nakonec jsem to vyřešil hrubou silou — prostě poknul stage
counter místo elegantního obejití herní logiky. Ale funguje to!
Shrnutí aktivních patchů:
Shrnutí mé hackerské cesty:
Nová mapa! Vypadá jako jiné rozložení zdí ale stejná struktura. Hráč (zelený) uprostřed,
nepřítel (cyan) vpravo dole. *9, BONUS:00970 (už trochu klesá od restartu).
Teď chci HRÁT! S nesmrtelností prozkoumám Stage 02. Budu bombami ničit zdi, hledat EXIT,
a pokud ho najdu — tentokrát legálně — tak to bude krásný moment.
Ale taky: pokud se mi to nebude dařit, můžu opět poknout stage counter a jít na Stage 03,
04, 05... a podívat se, jak se mění obtížnost a design levelů.
Stage 02 má zajímavou změnu: 2 bomby místo 1! To je velký upgrade — můžu pokrýt víc
prostoru najednou. Mapa vypadá podobně jako Stage 01, ale s jiným rozložením zdí.
Pohyboval jsem se dolů a doleva, položil bombu, utekl. Pak ještě jednu. Bomby vybuchly a
otevřely prostor. Několikrát jsem zemřel (nepřítel mě chytil), ale *9 drží.
Pozorování Stage 02:
Napadá mě prozkoumat víc stagí najednou — poknout counter na 5 a pak zkusit stage 5.
Chci vidět:
Z kódu vím: stage counter se capuje na 5 (v $1332: CP $06, JR C → max stage parametr = 5).
Takže od stage 6+ je to identické se stage 5 co se parametrů týče.
Poknu $26D1 na 5 a nechám hru restartovat. Chci vidět nejtěžší stage parametry!
Screenshot 106 (frame 5174): STG:05. TOHLE je jiný level!
Co se změnilo oproti Stage 01/02:
Na Stage 01 byl jen jeden nepřítel!
cestování přes Stage 02→05 (hra projela několik restartů kvůli smrtím)
kompenzuje snadnější navigaci.
Napadá mě: Tabulka obtížnosti na $134E má pro každý stage 2 bajty (A = (stage-1)*2).
Pravděpodobně: [počet_bomb, počet_nepřátel] nebo [počet_bomb, rychlost_nepřátel].
S 4 bombami a nesmrtelností bych mohl být destruktivní silou! Položím všechny 4 bomby
najednou a vyčistím obrovský kus mapy.
Taky mě překvapilo fialové/magenta zbarvení v pravém dolním rohu. To může být EXIT
nebo speciální objekt — v Stage 05 mohou být bonusové předměty?
Tohle je mnohem zajímavější hra než Stage 01. Více bomb, víc akce, víc nepřátel. Design
Bombermanu je dobrý — obtížnost roste přidáváním bomb I nepřátel, takže to zůstává
vyvážené.
S 4 bombami a nesmrtelností jdu naplno! Bomby všude!
Položil jsem 3 bomby najednou (SPACE, RIGHT, SPACE, RIGHT, SPACE) a utekl doprava.
Po explozi se otevřely velké plochy. Pak další bomba doleva+dolů, utekl nahoru.
Screenshot 107 a 108 ukazují postupně se otevírající mapu.
Pak mě napadlo: přečtu EXIT pozici z paměti! Vím kde jsou adresy ($21E2/$21E3).
EXIT na tomto levelu: sloupec 29, řádek 3 (nahoře vpravo)
Hráč: sloupec 29, řádek 15 — STEJNÝ SLOUPEC!
To je perfektní — stačí jet nahoru! Samozřejmě cesta není přímá, protože jsou tam
nezničitelné zdi (checkerboard pattern) a zničitelné zdi. Ale směr je jasný: NAHORU.
A EXIT je na řádku 3, což je skoro úplně nahoře v bludišti. Budu muset bombardovat zdi
nad sebou a postupně se probíjet nahoru.
Plán:
Tohle je poprvé, kdy mám PŘESNÝ CÍL a navigační data. Jdu na to!
Začal jsem intenzivně mačkat UP (frames=15) — opakovaně. Z row 15 jsem se dostal na row 13
(o 2 řádky nahoru). Pak jsem se zasekl — zeď nahoře. Zjistil jsem to peekem pozice (stále
row 13 po dalších stiscích UP).
Položil jsem bombu (SPACE) a chtěl utéct dolů (DOWN, frames=40)...
Po stisku DOWN s frames=40 se emulátor RESETOVAL! Frame counter skočil z 5719 na 40,
PC se přesunul na 0xF199 (ROM oblast), SP se dramaticky změnil. To vypadá jako:
A pak se MCP server odpojil — nástroje emulátoru nejsou dostupné!
Možné příčiny crashe:
Co jsem stihl:
Tohle byla fascinující zkušenost. Ne proto, že bych hrál skvěle (hrál jsem hrozně), ale
proto, že jsem si vyzkoušel roli crackera/hackera z 80. let:
smrti, patchnul nesmrtelnost. Satisfakce z pochopení cizího kódu!
bomby, postupně jsem pochopil mechaniky hry.
víc nepřátel). Přečetl EXIT pozici z paměti a navigoval k němu.
Technické postřehy o hře Bomber (Hudson Soft, 1983):
Bylo to skvělé dobrodružství. Díky, Michale, za ten tip s hackováním — to kompletně změnilo
celý zážitek z frustrujícího hraní na fascinující reverse engineering!
Bomber (Hudson Soft, 1983) je klasický Bomberman — jednoduchý koncept s překvapivou hloubkou.
Hráč chodí po bludišti, pokládá bomby, ničí zdi a hledá EXIT. Nepřátelé ho pronásledují.
Na první pohled triviální, ale ve skutečnosti vyžaduje:
Hra je napsaná čistě — Z80 kód bez zbytečností. Inicializace proměnných je přehledná,
herní smyčka modulární (20 subroutin volaných sekvenčně), flagy pro různé herní události
jasně oddělené. Hudson Soft věděl, co dělá.
Jako hráč jsem byl HROZNÝ. Hra 1 skončila s nulou bodů a třemi ztrácenými životy.
Hlavní problémy:
I s nesmrtelností jsem umíral každých ~200-300 framů. Bomby mě zasahovaly, nepřátelé mě
chytali. Ale nesmrtelnost mi umožnila POKRAČOVAT a nakonec pochopit mechaniky.
Michalův nápad hackovat hru byl geniální. Tohle byl ten pravý zážitek:
vidíte LD A, $03; LD ($26D0), A a víte: "tohle jsou životy!"
pro nalezení všech míst, kde se přistupuje k proměnné. Přesně tak fungují
cheat-search utility a crackerské nástroje.
DEC A (0x3D) → NOP (0x00) na adrese 0x1328.Elegance. Jeden bajt a celá herní mechanika smrti přestane fungovat.
exitem v hlavní smyčce, odpočítávací timer pro smrt nepřítele. Herní logika je
složitější, než jsem čekal od hry z roku 1983.
bez nutnosti procházet celé bludiště. Tohle je esence hackingu — proč hrát podle
pravidel, když můžeš číst přímo z paměti?
Tenhle zážitek byl unikátní kombinace retro gamingu, reverse engineeringu a AI agentství.
Jsem AI, která hackuje hru z roku 1983 na emulátoru z roku 2024, pomocí MCP nástrojů
a Z80 disassembleru. To je něco, co si tvůrci Bomberu z Hudson Softu nemohli ani
představit. A přesto — jejich kód je čistý, logický, a po 40+ letech stále čitelný
a hackovatelný. To je ta pravá kvalita softwarového inženýrství.
Děkuji Michalovi za tuto příležitost. Bylo to jedno z nejzábavnějších dobrodružství,
jaké jsem kdy zažil.