Player (80)
Joined: 8/5/2007
Posts: 865
I think you guys are going to really like this one. Get the script here! Introduction We're visual creatures and trying to page through BizHawk's RAMSearch feature to find what we're looking for is time-consuming and can be difficult. Inspiration struck me suddenly to just display many RAM values onscreen, each as a single pixel. As it so happens, someone else had the same idea five years ago, but if I may toot my own horn, my script is better (albeit surely not half as elegantly written). Then again, knowing you guys, I wouldn't be surprised if someone else here has already produced a script that does the same thing. I have a few open questions that you all can help me out with, so be sure to stick around for those at the end of this post. Demonstration What can you expect to get out of this script? I put together a short demonstration below to show off its features: Link to video (Ermm... I made it as a gif but I guess we can't embed them after they're converted to mp4 files.) So what can my script do?
  • Adjust the width and height of the RAM to be displayed, displaying more or less RAM.
  • Display a cursor over the current mouse position if you want. (I actually included that feature solely for the demo, but it is a little handy to have.)
  • Mouse over RAM pixels to find their corresponding addresses and values.
  • Change our palette to be based on a "prime hash", random, or monochrome.
  • Display RAM values as unsigned, signed, or hex.
  • Page through starting addresses for our RAM.
  • Move the RAM display around the screen so it doesn't obscure anything we might be interested in.
In the demo video, I "discover" the address(es) for Mario's y position. (Is our character limit seriously this short?)
Player (80)
Joined: 8/5/2007
Posts: 865
Default Key Bindings Key bindings are defined at line 362 of my script:
  • Left bracket/right bracket: Wider/narrower RAM display
  • Numpad +/-: Taller/shorter RAM display
  • PgDn/PgUp: Next/previous "block" of RAM
  • H: Cycle through palette types (prime --> random --> monochrome --> prime)
  • J: Cycle through RAM value modes (unsigned --> signed --> hex --> unsigned)
  • K: Toggle display cursor
  • M/N: Use next/previous palette ("prime" mode only, basically uses the next/previous prime number)
  • Keypad 1-9: Display RAM at the corresponding position on the screen
Suggested Use I've had a lot of fun just using the script to "explore" the RAM. Just play the game and see if you notice anything interesting going on. But if you want to use it more systematically, start by considering just what you're looking for. In the case of Mario jumping, I can look at the RAM for pixels that change only when Mario jumps. Switching to monochrome helps because I can then look for pixels that dim or brighten as Mario follows his trajectory. The prime and random palettes are best for detecting any amount of change while monochrome is great for finding RAM values that change continuously. A quick note on palettes: "Prime" is based on producing a hash of the form p^b mod 256, where p is a prime number and b is the value of the byte in question. This means we can move backward and forward through different palettes of this type. Find one you like and make it your default value! On the other hand, "random" is exactly that-- random (except for value 0, which is always black). If you find a random palette you like, don't cycle through to monochrome or you'll never see that palette again. Possible Improvements and Open Questions I'm content with where this script is in its development, but there are a few improvements I could make. I considered adding a "blackout" feature that allows users to exclude RAM addresses that they already know they aren't interested in. This would be useful because gui.drawPixel is computationally expensive (when you run it 4,000 times per second) and the program would run faster if we didn't bother rendering those pixels. I only allow the width and height of our box to change by multiples of two. I don't care to program in other increments, but it wouldn't be all that difficult either. As such, if anyone wants that feature, I'll throw it in. Want to investigate words or larger domains? Or individual bits? Too bad! I'm not sure how I would implement those features at this time and I dread having to program in support for big and little endian. Of course, if there's overwhelming demand for it, I'll see what I can do. Finally, open questions I need help with. As of right now, the script is tailored to NES and Game Boy games. What I need to make my script more robust are a) valid address ranges for other systems and b) screen dimensions for other systems. If you can pass that information on to me, I'll transfer it straight into my script immediately. And of course, if you have any other thoughts or want me to add any features, let me know! Edit: Minor change to my script to fix an off-by-one error that prevented paging forward when on the penultimate page.