Mercurial > vba-clojure
diff org/tas-submission.txt @ 614:b531d490859c
submitting to TAS...
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 22 Nov 2012 13:12:21 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/org/tas-submission.txt Thu Nov 22 13:12:21 2012 -0600 1.3 @@ -0,0 +1,287 @@ 1.4 +Pokemon Yellow Total Control Hack. Reprogramming the game from the inside! 1.5 + 1.6 +!! Game objectives 1.7 + 1.8 +* Emulator used: vba-rerecording 23.5 1.9 +* Reprogram the Game from the inside 1.10 + 1.11 +!! Comments 1.12 + 1.13 +I've included a detailed writeup here: 1.14 +http://aurellem.org/vba-clojure/html/total-control.html 1.15 + 1.16 +There is a video at: 1.17 +http://www.youtube.com/watch?v=p5T81yHkHtI with keypress visualizations 1.18 + 1.19 +The following are the highlights: 1.20 + 1.21 +! Introduction 1.22 + 1.23 +Think of pokemon yellow as creating a little universe with certain 1.24 +rules. Inside that universe, you can buy items, defeat rival trainers, 1.25 +and raise your pokemon. But within that universe, you are bound by the 1.26 +rules of pokemon. You can't build new buildings, or change the music, 1.27 +or change your clothes.. There are some games (like chess), where it 1.28 +is not possible to alter the rules of the game from within the 1.29 +game. No matter what moves you make in chess, you can never change the 1.30 +rules of the game so that it becomes checkers or basketball. The point 1.31 +of this run is to show that you CAN change the rules in pokemon 1.32 +yellow. There is a certain sequence of valid actions (like walking 1.33 +from one place to another or buying items) that will allow you to 1.34 +transform pokemon yellow into Pacman, or Tetris, or Pong, or a MIDI 1.35 +player, or anything else you can imagine. 1.36 + 1.37 + 1.38 +! Background 1.39 + 1.40 +The speedrun (http://tasvideos.org/2913S.html) by Felipe Lopes de 1.41 +Freitas (p4wn3r), beats pokemon yellow in only 1 minute and 36 1.42 +seconds. It does it by corrupting the in-game item list so that he can 1.43 +advance the list past its normal limit of 20 items. The memory 1.44 +immediately after the item list includes the warp points for the 1.45 +current map, and by treating that data as items and switching and 1.46 +dropping them, he can make the door from his house take him directly 1.47 +to the end of the game. 1.48 + 1.49 +When I first saw that speedrun, I was amazed at how fast pokemon 1.50 +yellow could be beaten, and that it was possible to manipulate the 1.51 +game from the inside, using only the item list. I wondered how far I 1.52 +could extend the techniques found in p4wn3r's run. 1.53 + 1.54 +The gameboy is an 8 bit computer. That means that ultimately, anything 1.55 +that happens in pokemon is a result of the gameboy's CPU reading a 1.56 +stream of 8 bit numbers and doing whatever those numbers mean. For 1.57 +example, in the gameboy, the numbers: 1.58 + 1.59 +62 16 37 224 47 240 37 230 15 55 1.60 + 1.61 +mean to check which buttons are currently pressed and copy that result 1.62 +into the "A" register. With enough numbers, you can spell out an 1.63 +interactive program that reads input from the buttons and allows you 1.64 +to write any program you want to the gameboy. Once you have assembled 1.65 +such a program and forced the game to run it, you have won, since you 1.66 +can use that program to write any other program (like Tetris or 1.67 +Pacman) over pokemon yellow's code. I call a program that allows you 1.68 +to write any other program a "bootstrapping program". So, the goal is 1.69 +to somehow get a bootstrapping program into pokemon yellow and then 1.70 +force yellow to run that program instead of its own. 1.71 + 1.72 +How can we spell out such a program? Everything in the game is 1.73 +ultimately numbers, including all items, pokemon, levels, etc. In 1.74 +particular, the item list looks like: 1.75 + 1.76 + 1.77 + item-one-id (0-255) 1.78 + item-one-quantity (0-255) 1.79 + item-two-id (0-255) 1.80 + item-two-quantity (0-255) 1.81 + . 1.82 + . 1.83 + . 1.84 + 1.85 + 1.86 +Let's consider the button measuring program [37 62 16 37 224 37 240 1.87 +37 230 15 55] from before. Interpreted as items and item quantities, it is 1.88 + 1.89 + lemonade x16 1.90 + guard spec. x224 1.91 + leaf stone x240 1.92 + guard spec. x230 1.93 + parlyz heal x55 1.94 + 1.95 +So, if we can get the right items in the right quantities, we can 1.96 +spell out a bootstrapping program. Likewise, when writing the 1.97 +bootstrapping program, we must be careful to only use numbers that are 1.98 +also valid items and quantities. This is hard because there aren't 1.99 +many different items to work with, and many machine instructions 1.100 +actually take 2 or even 3 numbers in a row, which severely restricts 1.101 +the types of items you can use. I ended up needing about 92 numbers to 1.102 +implement a bootstrap program. Half of those numbers were elaborate 1.103 +ways of doing nothing and were just there so that the entire program 1.104 +was also a valid item list. 1.105 + 1.106 +The final part of the hack is getting pokemon yellow to execute the 1.107 +new program after it has been assembled with items. Fortunately, 1.108 +pokemon keeps a number called a function pointer within easy reach of 1.109 +the corrupted item list. This function pointer is the starting point 1.110 +(address) of a program which the game runs every so often to check for 1.111 +poison and do general maintenance. By shifting an item over this 1.112 +function pointer, I can rewrite that address to point to the 1.113 +bootstrapping program, and make the game execute it. Without this 1.114 +function pointer, it would not be possible to take over the game. 1.115 + 1.116 +!! The Run 1.117 + 1.118 +! Pallet 1.119 + 1.120 +I start off and name my rival Lp/k. These characters will eventually be 1.121 +treated as items and shifted over the function pointer, causing it to 1.122 +execute the bootstrapping program that will soon be constructed. I 1.123 +start the run the same as p4wn3r's and restart the game while saving, 1.124 +so that the pokemon list is corrupted. By switching the 8th and 10th 1.125 +pokemon, I corrupt the item list and can now scroll down past the 20th 1.126 +item. I shift items around to increase the text speed to maximum and 1.127 +rewrite the warp point of my house to Celadon Dept. Store. (p4wn3r 1.128 +used this to go directly to the hall of fame and win the game in his 1.129 +run.) I deposit many 0x00 glitch items into the PC from my corrupted 1.130 +inventory for later use. Then, I withdraw the potion from the 1.131 +PC. This repairs my item list by overflowing the item counter from 1.132 +0xFF back to 0x00, though the potion is obliterated in the process. I 1.133 +then take 255 glitch items with ID 0x00 from the computer into my 1.134 +personal items. 1.135 + 1.136 +! Celadon Dept. Store 1.137 + 1.138 +Leaving my house takes me directly to Celadon Dept. store, where I 1.139 +sell two 0x00 items for 414925 each, giving myself essentially max 1.140 +money. I hit every floor of the department store, gathering the 1.141 +following items: 1.142 + 1.143 + +-------------------+----------+ 1.144 + |##| Item | Quantity | 1.145 + +--+----------------+----------+ 1.146 + |1 | TM02 | 98 | 1.147 + |2 | TM37 | 71 | 1.148 + |3 | TM05 | 1 | 1.149 + |4 | TM09 | 1 | 1.150 + |5 | burn-heal | 12 | 1.151 + |6 | ice-heal | 55 | 1.152 + |7 | parlyz-heal | 99 | 1.153 + |8 | parlyz-heal | 55 | 1.154 + |9 | TM18 | 1 | 1.155 + |10| fire-stone | 23 | 1.156 + |11| water-stone | 29 | 1.157 + |12| x-accuracy | 58 | 1.158 + |13| guard-spec | 99 | 1.159 + |14| guard-spec | 24 | 1.160 + |15| lemonade | 16 | 1.161 + |16| TM13 | 1 | 1.162 + +--+----------------+----------+ 1.163 + 1.164 + 1.165 +After gathering these items, I deposit them in the appropriate order 1.166 +into the item PC to spell out my bootstrapping program. Writing a full 1.167 +bootstrap program in one go using only items turned out to be too 1.168 +hard, so I split the process up into three parts. The program that I 1.169 +actually construct using items is very limited. It reads only from the 1.170 +A, B, start, and select buttons, and writes 4 bits each frame starting 1.171 +at a fixed point in memory. After it writes 200 or so bytes, it jumps 1.172 +directly to what it just wrote. In my run, I use this program to write 1.173 +another bootstrapping program that can write any number of bytes to 1.174 +any location in memory, and then jump to any location in memory. This 1.175 +new program also can write 8 bits per frame by using all the 1.176 +buttons. Using this new bootstrap program, I write a final 1.177 +bootstrapping program that does everything the previous bootstrapping 1.178 +program does except it also displays the bytes it is writing to memory 1.179 +on the screen. 1.180 + 1.181 +! Finale 1.182 + 1.183 +After completing this bootstrapping program, I go to the Celadon 1.184 +mansion, because I find the metaness of that building to be 1.185 +sufficiently high to serve as an exit point for the pokemon 1.186 +universe. I corrupt my item list again by switching corrupted pokemon, 1.187 +scroll down to my rival's name and discard until it is equal to the 1.188 +address of my bootstrapping program, and then swap it with the 1.189 +function pointer. Once the menu is closed, the bootstrapping program 1.190 +takes over, and I write the payload.... 1.191 + 1.192 +!! Other comments 1.193 + 1.194 +The entire video was played by the computer using bots. I used 1.195 +functional programming to write search programs over different 1.196 +possible game states to find the most efficient way of performing 1.197 +general actions. Some interesting things I developed but didn't use 1.198 +were pretty printing functions to display the game's internal data 1.199 +structures, and an "improbability drive" that forces improbable events 1.200 +to happen automatically using search. 1.201 + 1.202 +Here are a few example scripts: 1.203 + 1.204 + 1.205 + (defn-memo viridian-store->oaks-lab 1.206 + ([] (viridian-store->oaks-lab 1.207 + (get-oaks-parcel) ) ) 1.208 + ([ script \] 1.209 + (->> script 1.210 + (walk [↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 1.211 + ← ← ← ← ← ← ← ← ← 1.212 + ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 1.213 + ← ← 1.214 + ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 1.215 + ↓ ↓ ↓ ↓ ↓ ↓ ↓ 1.216 + → → → → → → → → 1.217 + ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 1.218 + ← ← ← ← ← 1.219 + ↓ ↓ ↓ ↓ 1.220 + ]) 1.221 + (walk-thru-grass 1.222 + [↓ ↓ ↓ ↓ ↓ ↓ ↓]) 1.223 + (walk [↓ ↓ ← ↓ ↓ ↓ ← 1.224 + ↓ ↓ ↓ ↓ ↓ ↓ 1.225 + → → → ↑]) 1.226 + 1.227 + (do-nothing 1) ) ) ) 1.228 + 1.229 + 1.230 +This script walks from the Viridian City pokemon store to Oak's 1.231 +Lab in the most efficient way possible. The walk-thru-grass function 1.232 +guarantees that no wild battles will happen by manipulating the game's 1.233 +random number generator. 1.234 + 1.235 + 1.236 + (defn-memo hacking-10 1.237 + ([] (hacking-10 (hacking-9) ) ) 1.238 + ([ script \] 1.239 + (->> script 1.240 + begin-deposit 1.241 + (deposit-held-item 17 230) 1.242 + (deposit-held-item-named :parlyz-heal 55) 1.243 + (deposit-held-item 14 178) 1.244 + (deposit-held-item-named :water-stone 29) 1.245 + (deposit-held-item 14 32) 1.246 + (deposit-held-item-named :TM18 1) 1.247 + (deposit-held-item 13 1) 1.248 + (deposit-held-item 13 191) 1.249 + (deposit-held-item-named :TM02 98) 1.250 + (deposit-held-item-named :TM09 1) 1.251 + close-menu) ) ) 1.252 + 1.253 + 1.254 +This script calculates the fastest sequence of key presses to deposit 1.255 +the requested items into a PC, assuming that the character starts out 1.256 +in front of a computer. 1.257 + 1.258 +!! Other Comments 1.259 + 1.260 +The final payload program is multiple programs. I created a reduced 1.261 +form of MIDI and implemented it in gameboy machine language. Then I 1.262 +translated a midi file from http://www.everyponysings.com/ into this 1.263 +reduced MIDI language. The payload program contains both the music 1.264 +data and the MIDI interpreter to play that data. The picture works in 1.265 +a similar way. There is code to translate a png file into a form that 1.266 +can be displayed on a gameboy, and other code to actually display that 1.267 +image. Both the image and the display code are also written by the 1.268 +final bootstrapping program. Even though my final payload is rather 1.269 +simple, you can write any program at all as the payload. The source 1.270 +for the sound and image displaying code is at 1.271 +http://hg.bortreb.com/vba-clojure. 1.272 + 1.273 +This entire project is open source and I encourage anyone who wants to 1.274 +take the code and play around! 1.275 + 1.276 + 1.277 +!! Suggested Screenshots 1.278 + 1.279 +* http://aurellem.org/pokemon-hack/code.png 1.280 +* http://aurellem.org/pokemon-hack/code2.png 1.281 +* http://aurellem.org/pokemon-hack/matrix.png 1.282 +* http://aurellem.org/pokemon-hack/matrix2.png 1.283 +* http://aurellem.org/pokemon-hack/pinkie-pie.png 1.284 + 1.285 +Or whatever you all think would be best. 1.286 + 1.287 +I encoded the video with/without button visualization here: 1.288 + 1.289 +* http://aurellem.org/pokemon-hack/rlm-yellow-hack.avi 1.290 +* http://aurellem.org/pokemon-hack/rlm-yellow-hack-no-buttons.avi