Bomber — Komentář a myšlenkové pochody

Start — Příprava

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:

  1. Nahrát Bomber.mzf do emulátoru
  2. Nechat nabootovat ROM menu (150 framů = 3 sekundy)
  3. Stisknout C pro načtení z kazety
  4. Nechat proběhnout načítání
  5. Prozkoumat co hra ukazuje a začít hrát

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...

Bootování a načtení hry

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.

Screenshot 001.png
screen-traces/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):

Screenshot 002.png
screen-traces/002.png

Takže ovládání je jasné — šipky pro pohyb, SPACE pro bombu. Jdu stisknout SPACE a spustit hru!

Hra začala — Stage 01

SPACE fungoval, hra okamžitě přepla na herní obrazovku (screenshot 003.png). Co vidím:

Screenshot 003.png
screen-traces/003.png

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:

  1. Nejdřív zjistit, kde jsem a kam se dá jít
  2. Hledat nepřátele (zatím žádné nevidím, nebo jsem je přehlédl?)
  3. Začít ničit zdi bombami a hledat exit/bonus
  4. Dávat pozor na čas (BONUS odpočítává)

Zkusím se pohnout dolů...

Problémy s pohybem (frame 240–350)

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!

Průlom — delší stisky (frame 350–420)

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!

Nepřítel se blíží! (frame 420–530)

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í.

Bomba! (frame 574–714)

Kolem framu 579 jsem stiskl SPACE (položit bombu). Na screenshotu 022 se objevil nový fialový/

Screenshot 022.png
screen-traces/022.png

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ý

Screenshot 024.png
screen-traces/024.png
Screenshot 025.png
screen-traces/025.png

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:

  1. Zjistit jestli ta bomba vybuchla a co zničila
  2. Najít zničitelnou zeď a systematicky ji bombardovat
  3. Hledat exit nebo bonus pod zdmi
  4. Dávat si pozor na nepřítele

Sebekritika — příliš mnoho analýzy, málo hraní (frame 714–764)

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):

Screenshot 027.png
screen-traces/027.png

Plán: Přestat přemýšlet, začít hrát. Pohybuji se, pokládám bomby, utíkám.

Aktivní hra — pohyb a bomba (frame 764–964)

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,

Screenshot 032.png
screen-traces/032.png

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

Screenshot 034.png
screen-traces/034.png

uprostřed pohybu nebo animace.

SMRT! (frame 1014)

Screenshot 035 odhaluje katastrofu:

Screenshot 035.png
screen-traces/035.png

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í.

Průzkum po smrti (frame 1014+)

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.

Pohyb vpravo a druhá bomba (frame 1039–1424)

Š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.

Screenshot 045.png
screen-traces/045.png

EXPLOZE! (frame 1394): Screenshot 046 ukazuje nádhernou explozi — bílé čáry šířící se

Screenshot 046.png
screen-traces/046.png

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

Screenshot 047.png
screen-traces/047.png

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!

Průzkum a druhá smrt (frame 1424–1649)

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

Screenshot 050.png
screen-traces/050.png
Screenshot 051.png
screen-traces/051.png
Screenshot 052.png
screen-traces/052.png
Screenshot 053.png
screen-traces/053.png
Screenshot 054.png
screen-traces/054.png

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:

Screenshot 055.png
screen-traces/055.png

Jsem v kritické situaci! S jedním životem nemůžu udělat žádnou chybu. Musím:

  1. VYHÝBAT SE nepříteli za každou cenu
  2. Najít EXIT — hledat ho pod zbývajícími zničitelnými zdmi
  3. Být opatrný s bombami — utéct dostatečně daleko
  4. Neplýtvat časem — BONUS klesá

Cítím napětí. Tohle je poslední šance. Musím hrát chytře.

Poslední život — opatrný průzkum (frame 1649+)

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.

Bloudění v pravé části mapy (frame 1649–1949)

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)

Screenshot 065.png
screen-traces/065.png

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:

  1. Vrátit se na col 29-30 (doleva)
  2. Položit bombu — ta zničí zeď na col 27-28
  3. Utéct doprava na col 31-32
  4. Počkat na explozi (~150 framů)
  5. Projít skrz díru doleva do velkého otevřeného prostoru
  6. Hledat exit

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.

Třetí bomba — průraz zdi (frame 1964–2014)

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

Screenshot 067.png
screen-traces/067.png

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.

Třetí bomba explodovala — průchod! (frame 2014–2064)

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.

Čtvrtá bomba a... SMRT (frame 2064–2424)

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ď:

  1. Bomba mě dostala — neutekl jsem dost daleko
  2. Nepřítel mě dohnal během čekání na explozi
  3. Vypršel čas (BONUS došel na 0?)

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ě.

Nový pokus?

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:

  1. Hned po startu UTÉCT od nepřítele — neztratit čas
  2. Bombami otvírat cesty SMĚREM od nepřítele
  3. Vždy utéct minimálně 3 pole od bomby
  4. Hledat EXIT systematicky — zbombardovat co nejvíc zdí
  5. Netrávit čas VRAM analýzou — prostě hrát!

Nakonec ale Michal navrhl úplně jiný přístup — viz níže.


HRA 2 — Druhý pokus

Příprava a sebereflexe

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:

  1. START: Okamžitě zjistit volný směr a začít se pohybovat
  2. BOMBY: Pokládat je na okraj zničitelných zdí, utíkat OPAČNÝM směrem min. 40 framů
  3. NEPŘÍTEL: Sledovat kde je a udržovat maximální vzdálenost
  4. TEMPO: Žádné VRAM analýzy! Jenom screenshot → rozhodnutí → akce. Rychle!
  5. CÍL: Systematicky ničit zdi a hledat EXIT

Jsem na titulce. Stisknu SPACE a jdeme na to!

ZMĚNA PLÁNU — Hacking místo hraní! (Michalův nápad)

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í:

  1. Spustit hru (SPACE na titulce)
  2. Najít adresu počítadla životů v paměti
  3. Najít rutinu smrti a patchnout ji
  4. Hrát nesmrtelný!

Krok 1 — Start hry a hledání proměnných

Stiskl jsem SPACE, hra naběhla — screenshot 076 ukazuje čerstvé bludiště s 3 životy.

Screenshot 076.png
screen-traces/076.png

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.

Krok 2 — Analýza inicializačního kódu

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í!

Krok 3 — Hledání rutiny smrti

Teď jsem potřeboval najít kde se životy DEKREMENTUJÍ. Hledal jsem v paměti dva vzory:

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!

Krok 4 — Disassembly rutiny 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á:

  1. Přehraj animaci smrti
  2. Sniž životy o 1
  3. Pokud 0 → konec hry
  4. Jinak → restart levelu

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ý!

Krok 5 — Aplikace patche

Provedl jsem dva zásahy:

  1. mz800_poke(addr=4904, value=0) — NOP místo DEC A (nesmrtelnost!)
  2. 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.

Teď — hrát s nesmrtelností!

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!

Hra 2 — Začátek (frame 2459–2509)

Screenshot 076/077 — čerstvé bludiště. Hráč (zelený) vpravo nahoře, přesně jako v první hře.

Screenshot 077.png
screen-traces/077.png

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)

Screenshot 078.png
screen-traces/078.png

potvrzuje posun. Nepřítel zatím nahoře, daleko.

Pohyb doleva a střet s nepřítelem (frame 2509–2544)

Zkusil jsem doleva (2× LEFT, frames=15). Na screenshotu 079 (frame 2544) vidím:

Screenshot 079.png
screen-traces/079.png

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.

Bomba č.1 hry 2 — past na nepřítele (frame 2549–2694)

Položil jsem bombu (SPACE, frame 2549) a utekl dolů (DOWN, frames=40). Na screenshotu 080

Screenshot 080.png
screen-traces/080.png

(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

Screenshot 081.png
screen-traces/081.png

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.

Screenshot 082.png
screen-traces/082.png

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.

Další postup (frame 2724)

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!

Pohyb doleva a zeď (frame 2724–2789)

Zkusil jsem čtyřikrát LEFT (frames=15). Ale na screenshotu 083 (frame 2789) vidím, že hráč

Screenshot 083.png
screen-traces/083.png

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.

Bomba č.2 hry 2 — průraz doleva (frame 2794–2839)

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...

Smrt a restart! (frame 2839–2949)

Čekal jsem 110 framů a... na screenshotu 085 (frame 2949) vidím KOMPLETNĚ JINOU MAPU!

Screenshot 085.png
screen-traces/085.png

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.

Průzkum nové mapy (frame 2949–3029)

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

Screenshot 086.png
screen-traces/086.png

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.

Pohyb a bomby — frame 3029–3334

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)

Screenshot 087.png
screen-traces/087.png

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ů

Screenshot 089.png
screen-traces/089.png

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

Screenshot 090.png
screen-traces/090.png

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íží

Screenshot 091.png
screen-traces/091.png

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!

Další level hackování — hledání EXITu v kódu (frame 3679)

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:

  1. 0x1F84 — flag smrti. Pokud != 0, skočí na 0x1322 (rutina smrti — tu jsem už patchnul!)
  2. 0x26D7 — flag nalezení EXITu! Pokud != 0, skočí na 0x1312.

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.

Pokus 1 — Exit flag $26D7 (frame 3729)

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!

Pokus 2 — NOP death check + auto-exit (frame 3809)

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!

Objev — DVA různé flagy

Hlubší analýza odhalila DVĚ úrovně dokončení:

  1. $26D7 = "exit nalezen" → JP $1312 → 5x animace → restart bez stage++ (!)
  2. $26D9 = "level dokončen" → JP do BONUS countdown → STAGE++ → restart

$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.

Pokus 3 — Poke $26D9 (frame 3859)

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.

Pokus 4 — Přímý poke stage counteru (ÚSPĚCH!)

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!

Screenshot 100.png
screen-traces/100.png

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:

  1. Nalezl herní proměnné (životy, score, bonus, bomby)
  2. Nalezl a patchnul rutinu smrti (1-byte NOP)
  3. Reverse-engineeroval detekci exitu (dva flagy, pozice v paměti)
  4. Pokusil se o elegantní skip, ale herní logika byla složitější
  5. Nakonec brute-force poke stage counteru

Stage 02 — nový level! (frame 4159)

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 — Hraní (frame 4159–4874)

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.

Přeskočení na Stage 05

Poknu $26D1 na 5 a nechám hru restartovat. Chci vidět nejtěžší stage parametry!

Stage 05 — První pohled! (frame 5174)

Screenshot 106 (frame 5174): STG:05. TOHLE je jiný level!

Screenshot 106.png
screen-traces/106.png

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é.

Aggressive bombing — Stage 05

S 4 bombami a nesmrtelností jdu naplno! Bomby všude!

Bombování Stage 05 (frame 5174–5579)

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.

Screenshot 107.png
screen-traces/107.png
Screenshot 108.png
screen-traces/108.png

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:

  1. Jet nahoru dokud to jde
  2. Když narazím na zeď, položit bombu a utéct dolů
  3. Počkat na explozi
  4. Projít skrz díru nahoru
  5. Opakovat dokud nedosáhnu řádku 3
  6. Na řádku 3 zbombardovat zeď na sloupci 29 → EXIT by se měl odhalit
  7. Vstoupit na EXIT → level dokončen!

Tohle je poprvé, kdy mám PŘESNÝ CÍL a navigační data. Jdu na to!

Navigace k EXITu (frame 5579–5719)

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)...

CRASH! (frame 5719 → reset na frame 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:

  1. Hra crashla — možná stack overflow nebo neplatný skok
  2. Emulátor provedl hard reset

A pak se MCP server odpojil — nástroje emulátoru nejsou dostupné!

Možné příčiny crashe:

Co jsem stihl:

Celkové shrnutí herního zážitku

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:

  1. Fáze 1 — Naivní hraní: Snažil jsem se hrát poctivě. Zemřel 3×, nula bodů. Frustrace.
  2. Fáze 2 — Reverse engineering: Michal navrhl hackování. Našel jsem proměnné, rutinu

smrti, patchnul nesmrtelnost. Satisfakce z pochopení cizího kódu!

  1. Fáze 3 — Explorace: S nesmrtelností jsem mohl hrát bez stresu. Zkoumal mapu, kladl

bomby, postupně jsem pochopil mechaniky hry.

  1. Fáze 4 — Stage skipping: Poknul stage counter, viděl Stage 02 (2 bomby) a 05 (4 bomby,

víc nepřátel). Přečetl EXIT pozici z paměti a navigoval k němu.

  1. Fáze 5 — Crash: Hra/emulátor crashl při pokusu o útěk od bomby na Stage 05.

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!


ZÁVĚR — Co jsem se naučil a jak to celé hodnotím

Hra jako taková

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á.

Moje hraní — sebekritika

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.

Hackování — to nejlepší z celého zážitku

Michalův nápad hackovat hru byl geniální. Tohle byl ten pravý zážitek:

  1. Nalezení herních proměnných — z inicializačního kódu na $1200. Krásný pocit, když

vidíte LD A, $03; LD ($26D0), A a víte: "tohle jsou životy!"

  1. Pattern matching v binárním kódu — hledání bajtů [0x3A, 0xD0, 0x26] v paměti

pro nalezení všech míst, kde se přistupuje k proměnné. Přesně tak fungují

cheat-search utility a crackerské nástroje.

  1. Jednobytový patch nesmrtelnostiDEC A (0x3D) → NOP (0x00) na adrese 0x1328.

Elegance. Jeden bajt a celá herní mechanika smrti přestane fungovat.

  1. Složitost exit detekce — dva různé flagy ($26D7 vs $26D9), priorita smrti nad

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.

  1. Čtení EXIT pozice z paměti — přímé zjištění "EXIT je na sloupci 29, řádku 3"

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?

Statistiky sezení

Co bych udělal příště jinak

  1. Rovnou hackovat — neplýtvat čas naivním hraním, ale hned jít do debuggeru
  2. Vypnout nepřítele — najít pohybovou rutinu nepřítele a vyNOPovat ji celou
  3. Automatizovat průzkum — napsat skript, který systematicky bombarduje všechny zdi
  4. Přečíst difficulty table — zjistit přesné parametry každého stage
  5. Najít a dekódovat maze generation — pochopit jak hra generuje bludiště

Poslední myšlenka

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.