This run beats NES (Famicom) "Hokuto no Ken 4: Shichisei Hakenden: Hokuto Shinken no Kanata e" in about 7m15s, using "moonwalk glitch" and "talking ship glitch".
Game objectives
- Emulator used: BizHawk 2.10 (NesHawk core)
- Aims for fastest time
- Major skip glitch
About the game
"Hokuto no Ken 4: Shichisei Hakenden: Hokuto Shinken no Kanata e" is a sequel to Hokuto no Ken 3. This game is a typical JRPG that features many original characters not present in the source material. Unfortunately, this game seems not so highly rated mainly due to its repetitiveness.
This game was never released outside Japan.
Run overview
Opening
I start the game with savedata 1, setting the message speed to "fast".
I name the hero "ゃ" for a game end glitch.
Maleid (マレード)
I escape from the town quickly using the moonwalk glitch.
In this run, I abuse this glitch to travel freely.
I go to Monpasa.
Monpasa (モンパサ)
I buy a leather shoes (かわのくつ) for a game end glitch.
I go to Legenda.
Legenda (レジェンダ)
I talk to two children to enable the event flags for a game end glitch.
I go to Cave to Nanto continent. On the way, I equip the leather shoes (かわのくつ) while manipulating a random encounter.
Cave to Nanto continent
I open a trapped chest, and fall to Ghosdoom Prison B3F.
Ghosdoom Prison (ゴズデーュム ろうごく (this is unpronounceable even for Japanese))
I talk to three prisoners on B3F to enable the event flags for a game end glitch.
Note: when I talk to the third prisoner, I took a wrong route and wasted one frame.
But, I couldn't save any frame by fixing this due to a random encounter after taking the stairs.
If you escape this prison with the moonwalk glitch, you will be brought back to the cave entrance. So, I escape through the valid exit.
I go to Suichou.
Suichou (スイチョウ)
I talk to four people to enable the event flags for a game end glitch.
I save the game in the training center. This is to take advantage of a memory region in savedata 1 for a game end glitch.
I go to Crosstown.
Crosstown (クロスタウン)
I talk to a woman to enable the event flag needed to activate a game end glitch.
I go to Southbass.
Southbass (サウスバース)
I talk to a person in a house to load a phrase pointer for a game end glitch.
I go to Galgtown to obtain a ship.
Note: I couldn't use Oupa's pirate ship. To obtain the pirate ship, you need to add Misshu (ミッシュ) to your party, but it prevents the execution of my game end glitch.
Galgtown (ガルグタウン)
I obtain a ship with the moonwalk glitch.
I stay on the ship and go to Raflens with the moonwalk glitch.
Raflens (ラフレンス)
I get off the ship, and execute the menu command "stats" (つよさ) to display the text "leather shoes" (かわのくつ).
I talk to the ship (this is the talking ship glitch). The game shows some glitchy text for a while, and shows an ending trigger message (a conversation between Kenshiro and Ryudo). This enables the ending flag, and the game executes the ending scene.
Moonwalk glitch
Digest video (Japanese)
If you press Up+Down or Left+Right, the hero does moonwalk.
- If you press U+D, the hero appears to move down, but actually he moves up.
- If you press L+R, the hero appears to move left, but actually he moves right.
And, when the hero does moonwalk, collisions with obstacles are detected based on the terrain on screen, rather than the map data. As a result, you can pass through many obstacles with this glitch.
This glitch allows you to move almost freely upward or rightward. But if you move downward or leftward, there are some restrictions (you can pass through two obstacle squares at most).
Other notes:
- You cannot pass through NPCs with the moonwalk glitch.
- To talk to a shop master, there must be a table between the hero and the shop master on screen.
Talking ship glitch
My blog post (Japanese)
In this game, when you talk to a ship, it says a completely unrelated message due to a bug.
The cause of this bug is that the game includes ships as talk targets. This game doesn't expect you talk to a ship, so if you do it, the game reads a pointer from out of bounds of the talk table for the current place (for the table, see PRG 9 $AA10).
If you talk to a ship in overworld, it just says a message intended for a person in Bahamon (バハモン).
But, if you perform the moonwalk glitch on a ship, you can bring the ship to other places. If you talk to the ship in this condition, the conversation changes depending on the place ID ($9A).
In some places, talk script pointer points to RAM area, which sometimes causes quite glitchy behaviour.
In this run, I perform the talking ship glitch in Raflens (ラフレンス) to execute $6D- as a talk script.
Game end glitch
The final goal is to execute the text script ID 0x00A0 (a conversation between Kenshiro and Ryudo). Once this is executed, the game enables the ending flag ($ED), and the ending scene is triggered immediately after the text processing is completed.
First, I explain about some memory:
addr | type | description |
---|---|---|
$6C | ptr | "menu command function pointer". In this run, I use the value 0x9C1F (corresponding to the menu command "stats" (つよさ)). |
$6E | ptr | previous text script pointer. |
$70 | ptr | previous phrase (frequently used word) pointer. |
$72 | u8 | zero when I perform the talking ship glitch. |
$6080-$6089 | u8[2*5] | the hero name. |
$6221-$6320 | u8[0x100] | event flags (bitset). |
$644A-$6813 | u8[0x3CA] | savedata 1 (copied from $6080-$6449, basically). |
$65EB-$66EA | u8[0x100] | event flags in savedata 1. |
When I talk to the ship in Raflens, the game reads a pointer $106D from out of bounds of the talk table of Raflens (PRG 9 $B0E0). This is the mirror of $6D, so the game executes $6D- as a talk script.
A talk script is an array of conditional talks, and it executes the first talk whose condition is met.
Conditional talks have a structure as follows:
type | description |
---|---|
u16le | header word (bit0-11:event flag ID of condition, bit12-15:text script count) |
u16le[] | array of text script ID |
Notes:
- If a conditional talk has a text script count of 0, the talk script aborts at that point.
- If a conditional talk has a nonzero text script count and event flag ID 0, it is executed unconditionally.
It will be easier to understand with the actual example in this run. Here is a memory dump of the moment I talk to the ship in Raflens:
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF ===================================================== 0x60 .. .. .. .. .. .. .. .. .. .. .. .. 1F 9C 21 A3 0x70 70 92 00 .. .. .. .. .. .. .. .. .. .. .. .. ..
- The talk script starts at $6D, so $6C can be ignored.
- $6D-$6E (0x219C) is a header word of the conditional talk. This conditional talk has 2 text scripts and will be executed if the event flag 0x19C is enabled.
- $6F-$70 (0x70A3) is the first text script ID of the conditional talk.
- $71-$72 (0x0092) is the second text script ID of the conditional talk, but actually this value itself can be ignored (more details later).
In this run, I enabled the event flag 0x19C by talking to a woman in Crosstown. So, this conditional talk will be executed.
The text script ID 0x70A3 is invalid, so the game reads the corresponding text script pointer from out of a table (PRG 4 $8304). In this case, the text script pointer is read from $644A (the hero name in savedata 1). I named the hero "ゃ" ([0x00, 0x66]), so the game executes $6600- as a text script.
$6600 points to the middle of the event flag bitset in savedata 1. In this run, I talked to many NPCs and wrote [0xF8, 0xB4] to $6617-$6618 (copied from $624D-$624E during saving). This is a text script command, and it means "output the phrase ID 0x1B4". So, the text script outputs it and terminates at 0xFF (finish command) at some point.
The phrase ID 0x1B4 is also invalid, so the game reads the corresponding phrase pointer from out of a table (PRG 4 $8000). In this case, the phrase pointer becomes 0xA03D. And, "previous phrase pointer" ($70-$71) is overwritten with this value. As a result, the next text script ID becomes 0x00A0 (which is why the original value of $71 can be ignored). This means the win condition is met.
Now, I explain how I build the memory content of $6D- shown above.
First, my party must be solo, because the previous phrase pointer will be overwritten when I open the menu if I have any allies.
$6C-$6D becomes 0x9C1F when I execute the menu command "stats" (つよさ). And, this command shows the hero's equipment, so $6E-$6F becomes 0xA321, the text script pointer of the text script ID 0x2D1 ("leather shoes" (かわのくつ)). This text script is useful because it doesn't contain any phrase and it doesn't clobber the previous phrase pointer.
0x9270 on $70-$71 is the phrase pointer of the phrase ID 0x101 ("とは "). This is generated from the message of the person in Southbass (かんきんされているこ"とは "わかったんだ).
There are many other combinations of text scripts and phrases. But so far, I have found only one acceptable solution.
Possible improvements
The talking ship glitch is so complicated that I'm not confident my solution is optimal. You might be able to find a better solution with some deeper investigation.