Mercurial > vba-clojure
comparison org/total-control.org @ 611:d9f991cddad9
spellcheck
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 22 Nov 2012 11:24:52 -0600 |
parents | 4dd5ebf224cd |
children | 00c5cdfb9da7 |
comparison
equal
deleted
inserted
replaced
610:4dd5ebf224cd | 611:d9f991cddad9 |
---|---|
48 items and switching and dropping them, he can make the door from his | 48 items and switching and dropping them, he can make the door from his |
49 house take him directly to the end of the game. | 49 house take him directly to the end of the game. |
50 | 50 |
51 When I first saw that speedrun, I was amazed at how fast pokemon | 51 When I first saw that speedrun, I was amazed at how fast pokemon |
52 yellow could be beaten, and that it was possible to manipulate the | 52 yellow could be beaten, and that it was possible to manipulate the |
53 game from the inside, using only the item list. I wondeered how far I | 53 game from the inside, using only the item list. I wondered how far I |
54 could extend the techniques found in p4wn3r's run. | 54 could extend the techniques found in p4wn3r's run. |
55 | 55 |
56 The gameboy is an 8 bit computer. That means that ultimately, anything | 56 The gameboy is an 8 bit computer. That means that ultimately, anything |
57 that happens in pokemon is a result of the gameboy's CPU reading a | 57 that happens in pokemon is a result of the gameboy's CPU reading a |
58 stream of 8 bit numbers and doing whatever those numbers mean. For | 58 stream of 8 bit numbers and doing whatever those numbers mean. For |
63 mean to check which buttons are currently pressed and copy that result | 63 mean to check which buttons are currently pressed and copy that result |
64 into the "A" register. With enough numbers, you can spell out an | 64 into the "A" register. With enough numbers, you can spell out an |
65 interactive program that reads input from the buttons and allows you | 65 interactive program that reads input from the buttons and allows you |
66 to write any program you want to the gameboy. Once you have assembled | 66 to write any program you want to the gameboy. Once you have assembled |
67 such a program and forced the game to run it, you have won, since you | 67 such a program and forced the game to run it, you have won, since you |
68 can use that program to write any other program (like tetirs or | 68 can use that program to write any other program (like Tetris or |
69 pacman) over pokemon yellow's code. I call a program that allows you | 69 Pacman) over pokemon yellow's code. I call a program that allows you |
70 to write any other program a "bootstrapping program". So, the goal is | 70 to write any other program a "bootstrapping program". So, the goal is |
71 to somehow get a bootstrapping program into pokemon yellow and then | 71 to somehow get a bootstrapping program into pokemon yellow and then |
72 force yellow to run that program instead of its own. | 72 force yellow to run that program instead of its own. |
73 | 73 |
74 How can we spell out such a program? Everything in the game is | 74 How can we spell out such a program? Everything in the game is |
75 ultimately nunbers, including all items, pokemon, levels, etc. In | 75 ultimately numbers, including all items, pokemon, levels, etc. In |
76 particular, the item list looks like: | 76 particular, the item list looks like: |
77 | 77 |
78 #+begin_example | 78 #+begin_example |
79 item-one-id (0-255) | 79 item-one-id (0-255) |
80 item-one-quantity (0-255) | 80 item-one-quantity (0-255) |
110 The final part of the hack is getting pokemon yellow to execute the | 110 The final part of the hack is getting pokemon yellow to execute the |
111 new program after it has been assembled with items. Fortunately, | 111 new program after it has been assembled with items. Fortunately, |
112 pokemon keeps a number called a function pointer within easy reach of | 112 pokemon keeps a number called a function pointer within easy reach of |
113 the corrupted item list. This function pointer is the starting point | 113 the corrupted item list. This function pointer is the starting point |
114 (address) of a program which the game runs every so often to check for | 114 (address) of a program which the game runs every so often to check for |
115 poison and do general maintaiance. By shifting an item over this | 115 poison and do general maintenance. By shifting an item over this |
116 function pointer, I can rewrite that address to point to the | 116 function pointer, I can rewrite that address to point to the |
117 bootstrapping program, and make the game execute it. Without this | 117 bootstrapping program, and make the game execute it. Without this |
118 function pointer, it would not be possible to take over the game. | 118 function pointer, it would not be possible to take over the game. |
119 | 119 |
120 * The Run | 120 * The Run |
121 | 121 |
122 I start off and name my rival Lpk. These characters will eventually be | 122 I start off and name my rival Lp/k. These characters will eventually be |
123 treated as items and shifted over the function pointer, causing it to | 123 treated as items and shifted over the function pointer, causing it to |
124 execute the bootstrapping program that will soon be constructed. I | 124 execute the bootstrapping program that will soon be constructed. I |
125 start the run the same as p4wn3r's and restart the game while saving, | 125 start the run the same as p4wn3r's and restart the game while saving, |
126 so that the pokemon list is corrupted. By switching the 8th and 10th | 126 so that the pokemon list is corrupted. By switching the 8th and 10th |
127 pokemon, I corrupt the item list and can now scroll down past the 20th | 127 pokemon, I corrupt the item list and can now scroll down past the 20th |
128 item. I shift items around to increase the text speed to maximum and | 128 item. I shift items around to increase the text speed to maximum and |
129 rewrite the warp point of my house to Celadon Dept. Store. (p4wn3r | 129 rewrite the warp point of my house to Celadon Dept. Store. (p4wn3r |
130 used this to go directly to the hall of fame and win the game in his | 130 used this to go directly to the hall of fame and win the game in his |
131 run.) I deposit many 0x00 glitch items into the PC from my corrupted | 131 run.) I deposit many 0x00 glitch items into the PC from my corrupted |
132 inventory for later use. Then, I widthdraw the potion from the | 132 inventory for later use. Then, I withdraw the potion from the |
133 PC. This repairs my item list by overflowing the item counter from | 133 PC. This repairs my item list by overflowing the item counter from |
134 0xFF back to 0x00, though the potion is obliterated in the process. I | 134 0xFF back to 0x00, though the potion is obliterated in the process. I |
135 then take 255 glitch items with ID 0x00 from the computer into my | 135 then take 255 glitch items with ID 0x00 from the computer into my |
136 personal items. | 136 personal items. |
137 | 137 |
173 directly to what it just wrote. In my run, I use this program to write | 173 directly to what it just wrote. In my run, I use this program to write |
174 another bootstrapping program that can write to any number of bytes to | 174 another bootstrapping program that can write to any number of bytes to |
175 any location in memory, and then jump to any location in memory. This | 175 any location in memory, and then jump to any location in memory. This |
176 new program also can write 8 bits per frame by using all the | 176 new program also can write 8 bits per frame by using all the |
177 buttons. Using this new bootstrap program, I write a final | 177 buttons. Using this new bootstrap program, I write a final |
178 bootstrapping program that does everything the provious bootstrapping | 178 bootstrapping program that does everything the previous bootstrapping |
179 program does except it also displays the bytes it is writing to memory | 179 program does except it also displays the bytes it is writing to memory |
180 on the screen. | 180 on the screen. |
181 | 181 |
182 After completing this bootstrapping program, I go to the celadon | 182 After completing this bootstrapping program, I go to the Celadon |
183 mansion, because I find the metaness of that building to be | 183 mansion, because I find the metaness of that building to be |
184 sufficiently high to serve as an exit point for the pokemon | 184 sufficiently high to serve as an exit point for the pokemon |
185 universe. I corrupt my item list again by switching corrupted pokemon, | 185 universe. I corrupt my item list again by switching corrupted pokemon, |
186 scroll down to my rival's name and discard untill it is equal to the | 186 scroll down to my rival's name and discard until it is equal to the |
187 address of my bootstrapping program, and then swap it with the | 187 address of my bootstrapping program, and then swap it with the |
188 function pointer. Once the menu is closed, the boostrapping program | 188 function pointer. Once the menu is closed, the bootstrapping program |
189 takes over, and I write the payload.... | 189 takes over, and I write the payload.... |
190 | 190 |
191 * Infrastructure | 191 * Infrastructure |
192 | 192 |
193 The entire video was completely produced by bots --- I didn't manually | 193 The entire video was completely produced by bots --- I didn't manually |
194 play the game at all to produce this speedrun. Here is a brief account | 194 play the game at all to produce this speedrun. Here is a brief account |
195 of the infrastructure I build to make the video. The entire source of | 195 of the infrastructure I build to make the video. The entire source of |
196 the project is available at http://hg.bortreb.com/vba-clojure | 196 the project is available at http://hg.bortreb.com/vba-clojure |
197 | 197 |
198 The first step was to build a programatic interface to pokemon | 198 The first step was to build a programmatic interface to pokemon |
199 yellow. So, I downloaded vba-rerecording from | 199 yellow. So, I downloaded vba-rerecording from |
200 http://code.google.com/p/vba-rerecording/. After repairing their | 200 http://code.google.com/p/vba-rerecording/. After repairing their |
201 broken auto-tools scripts so that it would compile on GNU/Linux, I | 201 broken auto-tools scripts so that it would compile on GNU/Linux, I |
202 added a low level C interface that I could call from Java via | 202 added a low level C interface that I could call from Java via |
203 JNI. This C interface gives me basic control over the emulator: I can | 203 JNI. This C interface gives me basic control over the emulator: I can |
210 entirely functional interface to vba-rerecording. This interface | 210 entirely functional interface to vba-rerecording. This interface |
211 treats state of the emulator as an immutable object, and allows me to | 211 treats state of the emulator as an immutable object, and allows me to |
212 do everything I could do with the lower level C interface in a | 212 do everything I could do with the lower level C interface in a |
213 functional manner. Using this functional code, I wrote search programs | 213 functional manner. Using this functional code, I wrote search programs |
214 that take a particular game-state and try out different combinations | 214 that take a particular game-state and try out different combinations |
215 of button prosses to get any desired effect. By combining different | 215 of button presses to get any desired effect. By combining different |
216 styles of search with different initial conditions, I created high | 216 styles of search with different initial conditions, I created high |
217 level functions that could each accomplish a certain general task, | 217 level functions that could each accomplish a certain general task, |
218 like walking and buying items. For example, here is some actual code: | 218 like walking and buying items. For example, here is some actual code: |
219 | 219 |
220 #+begin_src clojure | 220 #+begin_src clojure |
243 (do-nothing 1)))) | 243 (do-nothing 1)))) |
244 #+end_src | 244 #+end_src |
245 | 245 |
246 This script walks from the Viridian City pokemon store to Oak's | 246 This script walks from the Viridian City pokemon store to Oak's |
247 Lab in the most efficient way possible. The walk-thru-grass function | 247 Lab in the most efficient way possible. The walk-thru-grass function |
248 gaurantees that no wild battles will happen by manipulating the game's | 248 guarantees that no wild battles will happen by manipulating the game's |
249 random number generator. | 249 random number generator. |
250 | 250 |
251 #+begin_src clojure | 251 #+begin_src clojure |
252 (defn-memo hacking-10 | 252 (defn-memo hacking-10 |
253 ([] (hacking-10 (hacking-9))) | 253 ([] (hacking-10 (hacking-9))) |
266 (deposit-held-item-named :TM09 1) | 266 (deposit-held-item-named :TM09 1) |
267 close-menu))) | 267 close-menu))) |
268 #+end_src | 268 #+end_src |
269 | 269 |
270 This script calculates the fastest sequence of key presses to deposit | 270 This script calculates the fastest sequence of key presses to deposit |
271 the requested items into a pc, assuming that the character starts out | 271 the requested items into a PC, assuming that the character starts out |
272 in front of a computer. | 272 in front of a computer. |
273 | 273 |
274 I also wrote functions that coudl grovel through the game's memory and | 274 I also wrote functions that could grovel through the game's memory and |
275 present the internal data structures in useable ways. For example, the | 275 present the internal data structures in usable ways. For example, the |
276 function =print-inventory= returns the current inventory in a human | 276 function =print-inventory= returns the current inventory in a human |
277 readable format. | 277 readable format. |
278 | 278 |
279 #+begin_src clojure :results output | 279 #+begin_src clojure :results output |
280 (com.aurellem.gb.items/print-inventory) | 280 (com.aurellem.gb.items/print-inventory) |
297 | 297 |
298 #+end_example | 298 #+end_example |
299 | 299 |
300 | 300 |
301 Armed with these functions, I constructed a bootstrapping program that | 301 Armed with these functions, I constructed a bootstrapping program that |
302 could be expressed as items. This is particurally hard, since many | 302 could be expressed as items. This is particularly hard, since many |
303 useful opcodes do not correspond any item, and the item quantities | 303 useful opcodes do not correspond any item, and the item quantities |
304 must all be less than 99. | 304 must all be less than 99. |
305 | 305 |
306 Here is the first bootstrapping program in all its glory. | 306 Here is the first bootstrapping program in all its glory. |
307 | 307 |
434 | 434 |
435 #+end_src | 435 #+end_src |
436 | 436 |
437 I use the glitch items 0x00 and 0xFF to great effect in my run. 0x00 | 437 I use the glitch items 0x00 and 0xFF to great effect in my run. 0x00 |
438 sells for almost half of max_money, and I use just 3 of them to | 438 sells for almost half of max_money, and I use just 3 of them to |
439 finance the purchace of all the other items I need. 0x00 is also a | 439 finance the purchase of all the other items I need. 0x00 is also a |
440 NO-OP in the gameboy's machine language, which means that I can stick | 440 NO-OP in the gameboy's machine language, which means that I can stick |
441 them anywhere where I need to break up an other wise illegal pair of | 441 them anywhere where I need to break up an other wise illegal pair of |
442 opcodes. 0xFF is also extremely useful because it is the end-of-list | 442 opcodes. 0xFF is also extremely useful because it is the end-of-list |
443 sentinel. Normally, the game will "compact" your items whenever you | 443 sentinel. Normally, the game will "compact" your items whenever you |
444 make a purchase or deposit. For example, if you deposit a pokeball, | 444 make a purchase or deposit. For example, if you deposit a pokeball, |
461 The final payload program is actually multiple programs. I created a | 461 The final payload program is actually multiple programs. I created a |
462 reduced form of MIDI and implemented it in gameboy machine | 462 reduced form of MIDI and implemented it in gameboy machine |
463 language. Then I translated a midi file from | 463 language. Then I translated a midi file from |
464 http://www.everyponysings.com/ into this reduced MIDI language. The | 464 http://www.everyponysings.com/ into this reduced MIDI language. The |
465 payload program contains both the music data and the MIDI interpreter | 465 payload program contains both the music data and the MIDI interpreter |
466 to play that data. The picture works in a similiar way. There is code | 466 to play that data. The picture works in a similar way. There is code |
467 to translate a png file into a form that can be displayed on a | 467 to translate a png file into a form that can be displayed on a |
468 gameboy, and other code to actually display that image. Both the image | 468 gameboy, and other code to actually display that image. Both the image |
469 and the display code are also written by the final bootstrapping | 469 and the display code are also written by the final bootstrapping |
470 program. Even though my final payload is rather simple, you can write | 470 program. Even though my final payload is rather simple, you can write |
471 any program at all as the payload. The source for the sound and image | 471 any program at all as the payload. The source for the sound and image |