Hello, this is a question for those who have used the debugger to understand how random drops work vs simply observing drops from enemies. I have already spent a couple hours learning 6502 assembly, and couple more trying to make sense of how randomness works in a game or two. Neither game was I able to get a complete understanding of how randomness works so far. I have been wondering if it would be as effective and easier to make a bot and then just observe the results over a couple hundred drops. Is understanding at the assembler level worth the investment?
Well, if possible, you could search around in RAM and try to find the RNG output values. That way you wouldn't have to disassemble, but you could make sure that the number is at a certain value before you perform your action that creates the drop.
If you want to truly understand how a game works, then there's really no substitute for reading the code. However, it can be a lot of work to find out what bit of code does what. Treating the code as a black box and just observing what different values do (especially if you poke in the values you want) can often be good enough.
For example, if you know what address the RNG is in, then you can set its value using cheats, and see how that affects things, which can quickly help you determine what values you need. In most games, you can also generate "future" RNG values simply by letting the game play for awhile and recording the values the RNG takes (I believe Lua scripts can register to be informed of when a given memory address changes, which will help). These two mean you can a) figure out what values you need, and b) figure out when they will occur. That's an awful lot of the work that goes into luck manipulation.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
I don't really have anything to weigh in with here except to say that I too have been studying assembly language (Z80 and 6502) and reverse engineering RNGs. Great minds think alike, eh, MetalStorm?
If you'd like to collaborate and/or compare notes, talk to me on IRC.
Joined: 1/16/2008
Posts: 358
Location: The Netherlands
For my animaniacs movie Nitrodon did inspect the assembly in order to figure out exactly how the game comes up with seemingly random outcomes
Using his findings I was able to properly predict and manipulate the game
Whether such an assembly-analysis is the way to go / a viable option depends on the game I suppose
Joined: 4/17/2010
Posts: 11495
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
If you already know the address that is used as RNG by the game, you must set a write breakpoint on it. You would also want to figure out how much it gets hit: once per few frames, every frame, or several times per frame.
The next thing to do is to trace the code: you get to the frame where RNG will change, set up trace logging, start logging to a file. Then you run emulation and it must automatically pause at the breakpoint. Stop logging. Now in the log file you most likely have the events that CAUSED the RNG to change. Logging with displaying registers values and other info is recommended.
Then you go to a page that lists all 6502 (or whatever CPU it is) commands. You try to interpret the code, to understand the logics. You ask the advanced people if you have problems during this step. The answers will most likely be too advanced, but it actually is the way people learn: discovering new stuff and working on understanding it.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
There isn't a "one size fits all" solution when it comes to luck manipulation and it depends mostly on the game and how the RNG works.
- Obviously, the first step is you have to find the RNG address. (Hint: The RNG address is most likely characterized by chaotic changes in value. Use "not equal to previous value" for search.)
- The most important thing you can do at this point is find out what causes the RNG to change at all, such as whether the RNG changes as a function of "everything", whether it acts one way when you do action A and another way when you do B, whether it follows a sequence, whether it doesn't change unless it needs to.
- If an RNG is volatile, brute-force (such as bots) is worth more than analysis. The opposite applies for well-behaved RNGs.
- When doing analysis, whatever you are trying to manipulate should be worth doing the analysis for, such as a rare (say 1/100) and important event.
- Use any existing information/disassembly to help with analysis.
- When doing disassembly, use read/write breakpoints on the RNG address. Document important routines carefully and keep track of the routine's first address so you know which routines are which and you can set execution breakpoints on them if you need to. Obviously the RNG-cycling routines are important but so are any routines that call those routines.
- You can use Lua to forecast the RNG if it follows a sequence and you know its formula.
- For long-term forecasting or planning out events over a long stage, it helps to index the RNG values. Designate a starting value as index 0, the next one as 1, the one after that as 2, and so on. There are a few ways to do this. One way is to dump the values into a text file so that they appear serially. Another is to create a reverse look-up table (RNG value -> index number). In either case, you can only do the full list of values if the number of possible RNG values is small enough, but your TAS probably won't get to all of them in that case. In some cases, it is possible to calculate the index number directly from the RNG value (without consuming vast amounts of time and without using look-up tables), but that only applies to a few RNGs, such as mod power of 2 linear congruential generators.
There are some disassemblers/debuggers out there such as FCEU(X) for NES, Geiger's Snes9x debugger for SNES, and VBA-SDL-H for GBx/GBA.
Wow, thank you everybody for your responses! I think now I have a better idea of what I can try now. I gave up on trying to quote everything I found helpful from your posts since I thought just about everything was helpful. It does seem that at the very least understanding where the RNG is and how to manipulate it is important. However, a couple quotes did stand out to me.
I think I read that you could do that in the help document for FCEUX. Thanks Derakon I will have to give it a try.
You know, for some reason it never occurred to me that it might be changing during the frame. That is something worth keeping in mind. As well as the logging, definitely want to use that. Cool tips feos.
Yes, I am trying to find why a rare event occurs. I noticed that only certain enemies (there is some kind of formula, and RNG involved) have a semi-rare invincibility drop, something like 1/20. I was thinking that could possibly be used to improve the current movie, so it should be worth it. Thanks FractalFusion.
Joined: 4/17/2010
Posts: 11495
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
Thread #351832:
What game is it? What info you already have? Someone can do the job and then describe the steps it took, so you would also come up with similar finds following such steps.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.