Levelup stats are slightly random, yes. However, those slight gains level out with time... you might need to manipulate a few levels for specific gains needed for the next boss, but overall you will lose time as the game balances you out.
Joined: 5/30/2009
Posts: 135
Location: Top of the pops
Each point in Strength (and by extension, Attack) makes a respectable difference, and four frames for an extra point of Strength seems pretty damn tiny. For example, 36 Attack at level 7 has a base damage of ~46, while 38 has ~49. You can triple that for Braver. Extra points in Strength and Magic (if it's used at all) could very well be important early on; Braver is barely able to kill Dark Nation as-is, for example. It's entirely possible to keep stats at their upper limit:
Now that the Baseline for the next Level has been found, we must still work
out how much the current Stat may rise. This is worked out by first
calculating the following value:
Stat Difference = Rnd(1..8) + Baseline - Current Stat
This difference is then capped at 0 to 11 inclusive, and then the following
table is used to look up the final stat gain:
Difference Stat Gain
0- 3 0
4- 6 1
7- 9 2
10-11 3
From this, we can see that you can only go a maximum of 5 points over the
Baseline before you cannot gain any more points, and if you are more than 8
points under the Baseline, you will automatically get the full 3 point gain.
Over the course of 98 levels, this makes sure that you never stray too far
from your intended average stat.
This also means that stats do not need to be manipulated after every battle if they need to be at a certain level later, as 2 or 3 level gains will most likely be enough to raise them back up.
The only other stats I can think of as being useful to raise are HP, Luck (for faster crit manipulation) and maybe Dexterity, as some of the early fights (Motor Ball, Jenova*Birth) get pretty long, and this might allow for an extra turn somewhere.
In other tactics, all I can think of is that maybe Lunatic High would be useful somewhere, but by the time Red would get it there aren't really many long fights left.
Joined: 7/17/2004
Posts: 985
Location: The FLOATING CASTLE
For that number of frames it seems that more stats should be a big win. Especially early on. In Final Fantasy 1 I added a lot more than that to pump stats on the first couple levels. But after that I just went as fast as I could.
Unless you have the whole thing planned out, it's impossible to tell. Since this is still coming together, it's probably best to keep track of how high your stats could be. If there's ever a question about whether higher stats would cut down a boss fight or something then you can hack a savestate and try it out. But for a few frames here and there, if it saves one attack in one fight then it is going to be a win.
I'm not sure how ZeXr0 fared with his efforts. We talked a bit on Friday, but the site's been down most of the time since then.
If that doesn't work out, I should still be able to get around a few bugs in PCSX and hopefully cross-compile you an exe that has a TAS the battle for me (TM) button hacked in. Though, I'm not sure how that's going to work.
My first impulse is to make the dumbest bot possible. It would probably work in all battles, but that's probably a bad idea if there are already ideal strategies (i.e., sets of battle commands that could be hard-coded into the bot) that just need a lot of luck manipulation.
So... what's the strat?
I could probably write something very simple in Java that you could use to brute-force. You'd have to record the results manually (OCR libraries are unreliable, and I don't know of any way to read the internal memory of another program).
Joined: 3/18/2006
Posts: 971
Location: Great Britain
I think a dumb bot would be excellent.
I wrote a long post but deleted it.
There's no real strategy, just critical hits and making GS hit the right person with the right attack. The latter part is no problem.
The problem is that it takes a very long time to test when you can get a critical-hit. I mean extremely long... this is because if you change an attack by 1 frame, it will have consequences on future critical-hits/enemy behaviour. It is difficult to explain. For a bot, the constant recalculations would be simple.
It takes an unreasonable amount of time, and by unreasonable, I mean I have not yet been able to get the desired outcome and I'm up to 5000 re-records for only this battle. This is why I definitely cannot do the battle manually.
You mean OCR as in optical character recognition? I think I'd rather use AutoHotkey for that... but even then, I assume the hit sparks would occasionally occlude the damage numbers on striking an enemy and muck up everything, so maybe not.
FYI, [url=http://memoryhacking.com[/url]Memory Hacking Software[/url] can also do memory search on any running process (in userland, at least.) It also has a bunch of other hacking tools and a scripting language with some Win32 API wrappers, some of which are able to send simulated input. For whatever reason, I could never get that working when I tried it with FCEU a couple years ago, but it definitely seems within the realm of possibility.
But yeah, I think hacking teh src should be fine, assuming I can cross-compile.
Huh. So do you attack even if the tail is up?
Joined: 3/18/2006
Posts: 971
Location: Great Britain
It dies way before then :D
This is my best attempt. It's from my previous run though. Looks easy...
http://www.youtube.com/watch?v=k1SM2NUraWQ
Oh, the only thing worth mentioning to do with the strat is Barret needs to pull off a critical limit break.
Here's something I quickly hacked up, it's very very simple.
http://apo123.pastebin.com/d5f4ec7d
JDK 1.6 and JRE 6
First set the mouse X and Y to be within the window of whatever emulator you're using (this should work for any emulator if the controls are modified accordingly). You can use the Test Mouse button to move the mouse to those X and Y coordinates to see where it'll end up.
Modify the code within mainloop() to do whatever actions you want the bot to perform. You will probably have to modify the key values to match your controls.
First, modify the loadState() function to match whichever savestate you want to be loading.
Frames go like this:
doFrame(CONTROLS)
For example, to hold left and X for one frame, just do:
doFrame(LEFT, X)
Keys are reset to none every frame.
Leaving it null just advances one frame without sending any keys.
incrementedFrame()'s first parameter tells it how many times to run. I've built in a counter to increment, so if you wanted to test an attack on every frame just do this:
// Wait counter frames
incrementedFrame(counter);
// Hit X to attack
doFrame(X);
// Wait one second so the damage appears and can be recorded
incrementedFrame(60);
You may modify the body of incrementedFrame as you wish.
After mainloop() is run, the mouse will move back to where it was when you clicked the button.
Sorry about the GUI, this was my first time using Swing.
Feel free to modify this as you wish.
If you don't feel comfortable modifying the code/mainloop and want a specific set of commands to be hardcoded, or just want part of the code modified, let me know via PM.
I... think so. I just assumed he was intending you to use the code he posted.
Roughly, you'd copy the pastebin he linked into a text file, save it as something like "c:\stuff\bot.java", and then press winkey+r to open the Run box, and compile it by entering "javac c:\stuff\bot.java"
You'd could then run the bot by entering "java bot" and a GUI would appear. It would apparently automate the input and frame-advancing part of the manipulation for you, but wouldn't be able to tell if something good or bad happened from a particular set of inputs. Still, not a bad trick, if it works.
I could be wrong about any of that, though; I know little about Java.
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Ok, thanks. I PM'd him.
Couldn't we modify this Java thing to somehow look at the attack value in PCSX address space. Then it could just stop brute forcing once it sees an attack of over 50? at this point in time, any attack over 50 would be critical. It takes less than 15 frames to see if an attack is critical or not. So it would be quite fast.
Hopefully the current java thing works, it would probably allow me to complete the GS fight.
I'm sure it's possible, but there doesn't seem to be any such library in Java itself. I know for certain that AutoHotkey can both send input to an emulator, and call any Windows function (such as memory reading) so that's another option.
By the way, how well does FF7 sync when you're TASing? If it desyncs even occasionally, that could be a problem.
I recently started using the PCSX emulator, for I had heard that (maybe) "Frame Advance" function can be used to help determine the exact probability of certain outcomes. Here I think about the dropped items, or lackthereof, with the left and right Wonder Catcher in Gold Saucer.
Questions:
Assuming that the probability is frame-dependant, how do I go about this?
If it is not frame dependant, what else can I do to figure this out?
Note: Equally I want to figure out the probability of Cloud saying "...Ugh." after a Speed Square run.
In a word, yes. You can try a random event on every possible RNG state and record the probabilities. You'd use frame advance to make sure your inputs are precise. The way you've phrased this question, it seems like you're asking about reverse-engineering the pseudorandom number generator, which has little to do with frame advance, but which is often a part of what goes into producing a quality TAS.
But you probably don't need to go into that much depth.
Yes; the systems we TAS are "deterministic" meaning that doing the same things on the same frames will always produce the same results... I'm guessing you're just trying to manipulate a good dice roll/slot machine pull or whatever, and don't want a primer on reverse-engineering, so that FAQ link I just gave you should answer your questions. Feel free to post a follow-up question, in any case.
Sorry, I don't have much time these days. I didn't have internet, and I can't work this weekend.
Dromiceius, you should try to modify PCSX because I don't think I'll be able to do it soon.
I don't want to just pull a good dice roll. I am probably asking about reverse-engineering the number generator.
So say rolling the dice 10000 times and calculating the approximate likelihood of each drop is NOT what I want to do.
I couldn't imagine how frame advance would ever help me go around this problem of approximation, which is why I asked. Seems like it can't. Guess I have to reverse-engineer (no idea where to start though).
I don't understand this part thought
Random Number Generator state? I'm not sure how this differs from just pulling the lever 10000 times without frame advance.
Note: Would also be nice to know the probabilty of Cid or Tifa asking Cloud to Snowboard or play the Chocobo Races.
Random Number Generator state? I'm not sure how this differs from just pulling the lever 10000 times without frame advance.
In deterministic systems like a PSX, "probability" doesn't exist the way we generally understand it, because nothing is actually random. What we mistake for randomness is actually a calculation whose operands are simply very hard for us to predict. The outcome of a "random" event is often a function of a few bytes in memory on which are performed a series of mathematical operations several times a second. The numbers are "scrambled" but in a predictable way, which is why it's only pseudo-random. So just pulling the lever at arbitrary times instead of using frame-advance would bias the results depending on which PRNG states you happened to use.
To get the exact probability of a calculation based on time, you'd have to do a trial for each PRNG state, meaning that you'd "pull the lever" on an arbitrary frame N, record the result, reload a savestate from before you pulled the lever, frame advance to frame N+4, pull the lever, record the result.
And repeat that once and only once for each possible PRNG state. That would be exact, assuming time is the only variable. If you don't need it to be so precise, you could certainly be less stringent and still get reasonably accurate numbers.
I hope that clarifies things. It's late, I'm kind of groggy, and I'm still not sure why you want this information.
Shademp wrote:
Note: Would also be nice to know the probabilty of Cid or Tifa asking Cloud to Snowboard or play the Chocobo Races.
This is much more complicated. Unless you happen to know how and when the game decides the outcome of the event you're talking about, you can't very well test the probabilities, and so you'd have to reverse-engineer. Basically what that means is running the game in a debugger to decipher the relevant functions and memory addresses.
It's by no means an easy task if you don't know at least one assembly language, but PCSX has a debugger built in, and you can check romhacking.net for tutorials. All you really need are patience and time to learn the stuff.
Modified source via PM: http://apo123.pastebin.com/m1a4531ab
Also, I made sure the paste would last longer than a day this time...
All this bot does is simulate keyboard and mouse input. I've compiled a runnable .jar file, but it will only work for the controls given in the source (meaning it's probably worthless as it currently is).
Basically you want to modify the Mouse X and Mouse Y fields so when you click the Test Mouse button, the mouse jumps to a place within the emulator window. Otherwise, it'll be sending input to whatever window currently has focus.
Modifying this to read memory should be possible, but it is probably beyond my capabilities. OCR libraries (to read the game screen) are unreliable. Keep in mind I'm only a beginner, and this will have some bugs in it, small as it is. If anyone has suggestions for ways to improve my code or finds a bug, please let me know!
I pmed antd back about how to modify the source code, but basically the only lines that should need to be modified are the key definitions (lines 32-46) and the bot actions (lines 72-78).
AutoHotKey is definitely a good alternative, and may prove to be more useful than this simple bot.
adelikat wrote:
It started off fairly tame, but as more balls entered the picture it sure got a lot more entertaining.
Well for the moment I may have an idea of what to do, thanks very much, but didn't you mean to write "N+1" frame rather than "N+4"?
Too bad I don't know any assembly languages. Hopefully I won't have to go through all that trouble (though I have a second project going on too, which I will get back on working with soon. For the interested; http://forums.qhimm.com/index.php?topic=8597.msg107402#msg107402 )
Edit: Let's see if I understand this right... If I keep trying to roll the dice in the aforementioned manner, I will find a sequence, right? When I get back to the beginning of the sequence, then I find the exact probabilities?
(can't find anything in FAQ that helps me here) This is all assuming it is only time/frame based.
Well for the moment I may have an idea of what to do, thanks very much, but didn't you mean to write "N+1" frame rather than "N+4"?
No, actually- as I understand it, the PRNG in FF7 advances only every 4th frame.
Edit: Let's see if I understand this right... If I keep trying to roll the dice in the aforementioned manner, I will find a sequence, right? When I get back to the beginning of the sequence, then I find the exact probabilities?
(can't find anything in FAQ that helps me here) This is all assuming it is only time/frame based.