Player (65)
Joined: 4/21/2011
Posts: 232
Save X - fight up to Jenova Save Y - fight up to Yuffie, glitch into Save X state How is this faster? Is the time of the first save being completely ignored???
Joined: 3/18/2006
Posts: 971
Location: Great Britain
I think, under SDA segmented-run rules, it is ignored because it is not part of the speed run. The glitch only requires one save of the "real run"; this could be at rocket town. Play from new-game until Jenova and die (not a speed run). Then decide to continue the segmented run by loading the rocket town save. Fight Yuffie and warp to the final bosses. SDA already has precedent for using this kind of technique. This sort of thing can also be used to manipulate the RNG and enemy formation possibilities in FF7. Segmented runs of FF7 (and other games) would have to power off the hardware every time they made a mistake otherwise; in order not to manipulate the RNG/enemy formation. But they don't, they get a game-over or soft-reset instead. Thus intentionally, or unintentionally, changing what goes on in the speed run when they load and continue.
Joined: 11/22/2004
Posts: 1468
Location: Rotterdam, The Netherlands
It's so nice to see this is still being worked on. If I'm not mistaken it's only FFII and FFVII that still need to get a TAS on this site (out of the numbered ones).
Post subject: Re: Yuffie Warp Glitch
Lil_Gecko
He/Him
Player (94)
Joined: 4/7/2011
Posts: 520
antd wrote:
Thanks Lil_Gecko, that script is great! I should be continuing work with the glitched run at some point; almost done with disc one.
You're welcome. I am also glad to see you're still working on it. Keep up the great work.
Post subject: Audio commentary: opinions?
Joined: 3/18/2006
Posts: 971
Location: Great Britain
I'm thinking about adding audio commentary to the 'glitched' run. This is the TAS that contains no battles/boss fights. I think it might be useful so that I can explain the HUD/stats (lua script) which is displayed on screen. And I can explain the small glitches and time-savers that are difficult to see. I could talk about how many 'stutters' each segment requires, and how many battles I would have got without using this technique, etc. It may also add some enjoyment to the otherwise boring/battle-less run.
Post subject: Do you consider this a glitch?
Joined: 3/18/2006
Posts: 971
Location: Great Britain
I want to attempt a 'glitchless' run after this. In this run there will be no glitches :D However, I'm unsure as to whether 'stuttering' is a glitch or not. Stuttering is where Cloud walks the last frame of a 'run'; thereby counting the 'run' as a 'walked' step. This lowers the danger value resulting in fewer random encounters. The game thinks the step was a walk rather than a run. Is this considered a glitch or not? And should it be banned in a glitchless run of the game?
Patashu
He/Him
Joined: 10/2/2005
Posts: 4017
I think 'what is a glitch' / 'what is not a glitch' should be determined by psychological reaction from a typical viewer.
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Former player
Joined: 3/27/2010
Posts: 270
Honestly, I'd 'loosely' consider it a glitch. More of a trick really since you "trick" the game into thinking you're walking instead of running. Really just manipulation tactics instead of glitching. Typical people would not even notice it, I don't think at least, if it's frame perfect and all. Then again, I'm positive it's not something the developers intended... ehh yeah you get the point :p hopefully. Although, entertainment wise, for me at least, the more battles the better, as long as you don't repeat enemies encountered over and over.
Lil_Gecko
He/Him
Player (94)
Joined: 4/7/2011
Posts: 520
I'd consider it more of a trick than a glitch tbh. I don't see any reason to ban it from a glitchless run.
Post subject: Difficult things to optimise
Joined: 3/18/2006
Posts: 971
Location: Great Britain
I'm encoding the glitched run now. It is from New Game to the end of Disc 1. Here's a list of things that might be difficult to optimise: 1. Random Encounter Pattern: We have the entire walking route, and thus random encounter pattern, plotted on BrutalAl's random encounter calculator spreadsheet. However, we are limited to manual calculations. For this to be optimised, someone would have to write a program in order to find the fastest way through the game. At the moment I'm plotting the route manually a few segments at a time. This means inputting 'stutter' or 'menu glitch' into the calculator and seeing which method is faster, over a number of segments. The optimal way would be to plot the whole game from the very first field; clearly infeasible doing this manually. A sloppy random encounter pattern may waste tens of minutes!! 1.5 Step Fraction: This is related to point 1. It may sometimes be faster to waste a frame in order to reset the step fraction. If the step fraction is 1 frame away from overflowing, and if a high step fraction results in a battle, then it would be faster to waste a frame by overflowing the step fraction in a 'safe' field. I will be able to release a 'frame perfect' route once the game has been completed. This will allow other TASers to properly plan their routes and optimise it as necessary. 2. Party Members: Some party members say more than others. I suppose a script of the game exists somewhere. Choosing the immediate party members that say the fewest words, or the fewest characters, would be most desirable.
Post subject: ffvii disc1 'glitched test run': YouTube
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Link to video TAS: 3:47:24 Garland (PS2): ~4:32:xx Farringa (PC): ~4:31:xx
Editor, Player (68)
Joined: 1/18/2008
Posts: 663
.......
true on twitch - lsnes windows builds 20230425 - the date this site is buried
Former player
Joined: 3/27/2010
Posts: 270
True wrote:
.......
Point of saying ....... ? -- About the video, just like I feared from a glitched run... It would be boring without the battles. Vault only more than likely.
Post subject: It will not be submitted
Joined: 3/18/2006
Posts: 971
Location: Great Britain
I am not planning to submit this. It is just being used as a test run, and to find glitches, time-savers, etc. I'm only doing this as I'm curious as to what kind of completion time is possible.
Former player
Joined: 2/19/2007
Posts: 424
Location: UK
Why not submit it? Finding out how fast it can be completed is one of the main points of this site isn't it? I think the glitchless run would be much more fun to watch, but that doesn't mean that the glitched run isn't valuable too. Regarding the glitchless run: I think you should refrain from using stutter-walking and the menu trick, though I wouldn't have that much against the former. I would hope that a glitchless run would be able to show off some of the different kinds of enemies in the game, but I guess speed constraints will force you to manipulate the fastest enemy group at the expense of variety.
Post subject: no verification
Joined: 3/18/2006
Posts: 971
Location: Great Britain
The glitched run also starts from a savestate (at emerald weapon), and I lost my verification movie-file when my HDD died. Although, it is technically possible to verify that I didn't cheat. But that would require some knowledge of the game and investigating the RAM.
Why not submit it? Finding out how fast it can be completed is one of the main points of this site isn't it? I think the glitchless run would be much more fun to watch, but that doesn't mean that the glitched run isn't valuable too.
Yeah, perhaps. The vault seems like a place where second-rate TASes end up. So, personally, I don't have much motivation to submit it here.
tasvideos.org/vault.html wrote:
Previously we only published movies people found entertaining ...
:P!
Regarding the glitchless run: I think you should refrain from using stutter-walking and the menu trick, though I wouldn't have that much against the former.
Yeah, the menu glitch will definitely not be used in a glitchless run. I will immediately escape all random encounters anyway.
Joined: 4/1/2012
Posts: 8
If you were really curious about how fast it could be completed you could do an estimation based on the speed runs and subtract the fights and other time spent preparing for boss battles... I think an entertaining glitch run would include these: No battle skipping glitch No save data glitch Healthy use of the Saga Frontier warp glitch and other scene skipping techniques Less than ~2:00 completion time. Some of the best Japanese TAS use text commentary and never audio commentary. I think there's a lot of good to not disturbing the wonderful music of a RPG with someone's voice.
Post subject: "saga frontier glitch"
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Of course I did that. Specifically I'm interested in seeing the game beaten in the fastest time, within limits. I feel opening the disc tray is too much hardware abuse. I am aiming to abuse the game's software rather than the hardware.
Post subject: Re: "saga frontier glitch"
Joined: 4/1/2012
Posts: 8
antd wrote:
Of course I did that. Specifically I'm interested in seeing the game beaten in the fastest time, within limits. I feel opening the disc tray is too much hardware abuse. I am aiming to abuse the game's software rather than the hardware.
There's nothing wrong with doing something for personal enjoyment only. Everyone wants to see a good and watchable FFVII TAS some day, though.
Post subject: pause glitch solved
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Lil_Gecko got me interested in looking at the Disassembly for FF7 again. I found a glitch some time ago, the Pause Glitch, where if you repeatedly Pause and unPause in a battle, the in-game Timer slows down (the animation doesn't slow down if done perfectly). In practice, when I pause the game, the PauseFlag is set to 1 before the AnimFlag. This means the Timer is paused before the animation is frozen. The delay varies, usually 2-3 frames. I took a look at the assembly language and reversed it to this function (pseudocode) :
Language: C

{ if ( !*(sub_676578() + 2644) ) { EnterCriticalSection(&CriticalSection); ++dw_FrameCounter; /* Increment FrameCounter by 1 */ if ( !b_AnimFlag ) /* Is Animation frozen? [?] If yes, leave */ { /* If Animation not frozen: */ if ( !b_PauseFlag ) /* Is Battle Paused? If yes, leave */ { /* If Battle is not Paused: */ dw_TFraction += 1092; /* Increment TimerFraction by 1092 */ if ( dw_TFraction >> 16 ) /* Is TimerFraction > 65535? (TFraction/65536) */ { ++dw_TSeconds; /* If yes, increment TimerSeconds by 1 */ dw_TFraction & 0xFFFF; /* Reset TimerFraction to 0 */ } dw_T2Fraction += 1092; /* Increment Timer2Fraction by 1092 */ if ( dw_T2Fraction >> 16 ) /* Is Timer2Fraction > 65535? */ { /* Check Timer Direction Flag (up or down) */ if ( b_T2DirF & 2 ) /* If yes, check if T2DirF = 2? */ { ++dw_T2Seconds; /* If yes, increment Timer2Seconds by 1 (CountUp) */ } else { if ( dw_T2Seconds ) /* If no, and not 0, decrement Timer2Seconds by 1 (CountDwn) */ --dw_T2Seconds; } dw_T2Fraction & 0xFFFF; /* Reset T2Fraction to 0 */ } } } LeaveCriticalSection(&CriticalSection); } }
EDIT: Solved. Battle animation flag updates every 4th frame, whereas the Pause flag updates every frame. So it is possible to pause-unpause before an animation frame goes by.
Post subject: RNG: random number table
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Lil_Gecko wrote:
while true do
crit1=math.floor((memory.readbyte(0xf83f5)+memory.readbyte(0xf83e9)-memory.readbyte(0xF8589))/4);
crit2=math.floor((memory.readbyte(0xf845d)+memory.readbyte(0xf8451)-memory.readbyte(0xF8589))/4);
crit3=math.floor((memory.readbyte(0xf84c5)+memory.readbyte(0xf84b9)-memory.readbyte(0xF8589))/4);
rnd1 = memory.readbyte(0x83084+memory.readbyte(0x62e10+(memory.readbyte(0x62e18)+1)%8));
rnd2 = memory.readbyte(0x83084+memory.readbyte(0x62e10+(memory.readbyte(0x62e18)+2)%8));
rnd2=rnd2*256;
rnd0=rnd1+rnd2;
crit_rng=math.floor((rnd0*99)/65535)+1;
if crit1>=crit_rng then
gui.text(0,50,"Critical Hit from Character 1!");
else
gui.text(0,50,"");
end;
if crit2>=crit_rng then
gui.text(0,60,"Critical Hit from Character 2!");
else
gui.text(0,60,"");
end; 
if crit3>=crit_rng then
gui.text(0,70,"Critical Hit from Character 3!");
else
gui.text(0,70,"");
end;
gui.text(0,30,"Ennemy 1 crit% = "..crit1.." "..crit2.." "..crit3);
gui.text(0,40,"crit_rng = "..crit_rng);
emu.frameadvance();
end;
This script predicts when the RNG is in the right spot not when to attack. This should be done either 8 or 4 frames earlier.
Would it be possible for this script to take the random number list into account? This way it could show the next 200 frames and if they will be critical hits or not? Here is the random number table used in battle. (From 0x83084 to 0x831A4):
00083080		            63 06 F0 23 F8 E5 A8 01 C1 AE 7F 48 	
00083090		7B B1 DC 09 22 6D 7D EE 9D 58 D5 55 24 39 7A DF 	
000830A0		8E 54 6C 1B C0 0B D0 43 D8 9A 47 5D 21 02 17 4B 	
000830B0		DB 11 AF 70 CD 4D 34 49 72 91 2D 62 97 59 45 F7 	
000830C0		6E 46 AA 0A A3 C8 31 92 38 FA D4 E6 CB F3 DE 6B 	
000830D0		BB F1 1C 3C D6 AD B2 A9 DD 57 42 95 0C 79 25 1F 	
000830E0		BC E7 AC 5B 83 28 76 F2 18 DA 87 A1 61 6F BE 5A 	
000830F0		5E 51 EF B0 C9 15 74 89 BD D1 A2 75 D7 99 85 4C 	
00083100		4F D2 BF 4A 20 08 56 A0 50 3A 67 26 41 33 B7 BA 	
00083110		FB 30 CF 7C 84 2C 32 E9 1D 16 82 78 A4 80 65 5F 	
00083120		0E 27 B9 19 C3 A7 B6 00 3B FC 88 E1 C6 93 FE 8B 	
00083130		D9 B8 13 69 2F 64 12 37 FD 77 E2 B5 04 E0 1A 8C 	
00083140		8F B4 CC F9 60 EB 29 E3 90 A5 68 3D 81 73 3F AB 
00083150		7E B3 0F CE C4 35 94 96 86 71 D3 2A E4 9F 9C EC 	
00083160		4E 14 F5 EA 40 A6 F6 03 98 C5 07 F4 2B C2 3E E8 	
00083170		9B 36 53 2E 8D 0D 52 10 66 1E ED 8A 44 9E 05 FF 	
00083180		5C C7 6A CA 00
The function chooses numbers (rnd1 and rnd2) from this table.
Lil_Gecko
He/Him
Player (94)
Joined: 4/7/2011
Posts: 520
Unfortunately the random number pointer (from 62e10 to 62e18) moves in a non-linear pattern making it impossible to determine in advance what numbers will be used and when. Plus when the ennemy readies a move the pointer at 62e18 makes a bump skipping some numbers from the pointer table and I don't see a way to know in advance when this bump is gonna occur. I guess the only way to do it is to use the script and advance 200 frames to know when Critical will happen.
Post subject: How the hell to optimize this
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Yep, that's right. It's the random encounter problem again. The issue at hand is how to best avoid random encounters: 1. Menu Glitch (83 frames): Opening the menu at the same time as a battle. Does not reset the danger value. 2. Accept a Battle (685 frames): Accept a battle and escape. Resets the danger value. 3. Stutter (x frames): Amazing, almost free. Can only avoid 'close encounters'. Does not reset the danger value A combination of these will be used. Here's an example segment: We want to find the most efficient path through here; using the 3 options given above. If you touch a blue line you get a battle. The red dots show the character's steps. In this case, the default route shown here is simply running through the segment and accepting every battle. Stuttering has the effect of making the danger value increase by 1/4 compared to that of running. Thus, it makes the red line less steep, it flattens the line out more. As you can see, using the menu glitch too many times will put you further into the blue-line jungle. I've reverse engineered the important random encounter routines from the disassembly: The script I wrote generates the graph above showing the random encounter pattern of any segment. Simply modify the global values at the top of the script for where you are in the game (leave at default to generate the above graph). My programming skills are still new (aka poor); only 4 days learning Python :P So, I have no clue how I can optimize this whole thing (or even 1 segment at a time). You can see the battle routine in the script. Here's the Python script:
Language: Python

## Random Encalculator v0.2 by antd ## import numpy as np import pylab as pl # random number table: rnlist = [0xB1, 0xCA, 0xEE, 0x6C, 0x5A, 0x71, 0x2E, 0x55, 0xD6, 0x00, 0xCC, 0x99, 0x90, 0x6B, 0x7D, 0xEB, 0x4F, 0xA0, 0x07, 0xAC, 0xDF, 0x8A, 0x56, 0x9E, 0xF1, 0x9A, 0x63, 0x75, 0x11, 0x91, 0xA3, 0xB8, 0x94, 0x73, 0xF7, 0x54, 0xD9, 0x6E, 0x72, 0xC0, 0xF4, 0x80, 0xDE, 0xB9, 0xBB, 0x8D, 0x66, 0x26, 0xD0, 0x36, 0xE1, 0xE9, 0x70, 0xDC, 0xCD, 0x2F, 0x4A, 0x67, 0x5D, 0xD2, 0x60, 0xB5, 0x9D, 0x7F, 0x45, 0x37, 0x50, 0x44, 0x78, 0x04, 0x19, 0x2C, 0xEF, 0xFD, 0x64, 0x81, 0x03, 0xDA, 0x95, 0x4C, 0x7A, 0x0B, 0xAD, 0x1F, 0xBA, 0xDD, 0x3E, 0xF9, 0xD7, 0x1A, 0x29, 0xF8, 0x18, 0xB3, 0x20, 0xF6, 0xD1, 0x5E, 0x34, 0x92, 0x7B, 0x24, 0x43, 0x88, 0x97, 0xD4, 0x0F, 0x35, 0xAA, 0x83, 0x68, 0x27, 0xA8, 0xD5, 0xBE, 0xFA, 0x14, 0x31, 0xAF, 0x10, 0x0D, 0xD8, 0x6A, 0xCE, 0x23, 0x61, 0xF3, 0x3D, 0xA4, 0x08, 0x33, 0xE3, 0xA9, 0x38, 0xE6, 0x93, 0x1D, 0x1C, 0xF0, 0x0E, 0x87, 0x59, 0x65, 0x82, 0xBC, 0xFF, 0xFE, 0x7E, 0x8F, 0xC1, 0x1E, 0xF5, 0xCB, 0x49, 0x02, 0x32, 0x09, 0xC4, 0x8E, 0xC6, 0x2B, 0x40, 0xA7, 0x17, 0x76, 0x3B, 0x16, 0x2A, 0xC8, 0xFB, 0xB2, 0x58, 0xA5, 0x15, 0xAE, 0x25, 0xCF, 0x46, 0xC7, 0x48, 0xB4, 0x0A, 0x3F, 0xC9, 0x06, 0x85, 0x51, 0x89, 0x62, 0x4D, 0x12, 0x8C, 0xEA, 0xA2, 0x98, 0x4B, 0x79, 0x6F, 0x5C, 0x47, 0x30, 0x1B, 0xE7, 0xC5, 0x22, 0x9C, 0xE8, 0x96, 0x3A, 0xE4, 0x7C, 0xE0, 0x69, 0xA1, 0xB7, 0x05, 0x39, 0x74, 0x01, 0x9F, 0xBD, 0xC3, 0x84, 0xFC, 0x77, 0x86, 0x13, 0x4E, 0xBF, 0xF2, 0x53, 0x5B, 0xED, 0x21, 0x8B, 0x6D, 0xC2, 0x41, 0xB6, 0xDB, 0x3C, 0xD3, 0x28, 0xEC, 0x2D, 0xE2, 0x9B, 0xA6, 0x42, 0x52, 0x57, 0x5F, 0xE5, 0xAB, 0xB0, 0x0C] ### change some of these: stepid = 24 # set current stepid in field bloop = 13 # set current battle loop in field danger = 0 # set current danger value in field distance = 128 # set field distance in steps run = 113 # set danger increment for running walk = run/4 # danger increment for walking runwalk = run # set whether to 'run' or 'walk' through the field dlimit = 0 total_steps = 0 ## graph stuff: x1 = [] y1 = [] x2 = [] y2 = [] x3 = [] y3 = [] def ShowMyGraph(): plot1, = pl.plot(x1,y1,'r.') plot2, = pl.plot(x2,y2,'b_') plot3, = pl.plot(x3,y3,'-') pl.title('Random Encounter Pattern') pl.xlabel('Step') pl.ylabel('Danger Value') pl.xlim(0.0,150.0) # change x-axis range if needed pl.ylim(0.0,10000) # change y-axis range if needed pl.legend([plot1,plot2], ('Route', 'Battles'), 'best', numpoints=1) #pl.xticks(arange(201, step=50)) # change amount of x-axis numbers pl.show() def PlotSteps(): x1.append(total_steps) y1.append(danger) x2.append(total_steps) y2.append(dlimit) x3.append(total_steps) y3.append(dlimit) ### random encounter stuff: # increment StepID and grab rnd number: def GoStepID(): global stepid, bloop, rnd stepid = (stepid + 1) & 0xFF # increment stepid + reset if > 255 if stepid == 0: # increment battle loop by 13 if 0 bloop = (bloop + 13) & 0xFF rnd = (rnlist[stepid] - bloop) & 0xFF # grab a rnd byte from rnlist # call this function to take *1* step: def BattleCheck(): global dinc, danger, rnd, dlimit, walk, total_steps if runwalk == walk: # let's see if we are running or walking dinc = walk # set the danger increment accordingly else: dinc = run danger = (danger + dinc) & 0xFFFF # increment danger value + reset if > 65535 GoStepID() # this is for preemptive rnd GoStepID() # this is for battle; +2 stepID = 1 step dlimit = ((rnd +1) *256) & 0xFFFF # calc danger limit for battle total_steps += 1 # calculate total steps (for graph only) PlotSteps() # just plots the graph if danger <= dlimit: # if danger is over limit it's battle time print "Next step is SAFE!\n" print "rnd: %d danger: %d, dlimit %d, stepid : %d total: %d\n" % (rnd, danger, dlimit, stepid, total_steps) else: print "Random Encounter on next stepid: %d!\n" % (stepid) print "rnd: %d danger: %d, dlimit %d, stepid : %d total: %d\n" % (rnd, danger, dlimit, stepid, total_steps) danger = 0 # danger is reset in battle while distance > 0: # travel through the whole field BattleCheck() distance = distance - 1 ShowMyGraph()
Please install Python (2.7.x) if you would like to run the script: https://code.google.com/p/winpython/downloads/list Any help or advice on a possible algorithm would be appreciated :D
Patashu
He/Him
Joined: 10/2/2005
Posts: 4017
Every time you hit an encounter, there are three possible ways you can deal with it - reset glitch, run from the battle and stutter just enough to skirt over it. So, you can branch execution and examine what results of each of those three branches: 1) Reset glitching it, adding the associated frame cost and continuing at the same danger level; 2) Accepting it, adding the associated frame cost and continuing at danger level 0; 3) Calculating how long ago you would have needed to start stuttering to baaarely miss it (only allowing you to stutter immediately after the last reset glitch/accepetd battle, or beginning of the graph, whichever comes first), adding the associated frame cost and continuing at the danger level that just mised the battle. However, if you can't go far back enough to stutter over it (for example, for your example graph, if reset glitch was chosen for the encounter at step 30, it can stutter as far back as immediately after the reset glitch, since stuttering further back than that is a different universe - and if stutter was chosen for the encounter at step 30, we could go all the way back to the last danger level 0 and attempt to stutter and still not make it) then this option is skipped. In each of the possibilities we've picked, we wait until the next battle, and again try reset glitch/accept battle/stutter starting after last event, again adding the associated frame costs to the total frame cost spent manipulating so far. Finally, in each string of possibilities (how we dealt with each encounter), when it reachess the end of the graph, we note what we did and how low the frame cost. Once we're tried all strings of possibilities, we sort by frame cost and recall the cheapest. This is a very dumb backtracking algorithm but it works in the case of few enouncters to deal with (For example, in your graph there are 19 encounters - at worst you'd try 3^19 universes, but most of the encounters won't be reache by most universes, and a lot of the time stuttering won't help, so in reality it's a lot lower). If you need it to be smarter and more efficient, maybe something like alpha-beta pruning could apply here? (Google it, but basically alpha-beta pruning is used for exploring trees of possible future moves and picking the best outcome - it's a rule that lets you ignore all branches if they can't possibly beat a prevously evaluated branch using perfect play.)
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Joined: 1/22/2008
Posts: 319
Location: Brasil
I just missed the explanatioan i cant find anymore How is the battles avoided? What comand is used to get that error message, and win the battle without fighting?
Run..Run...Run.....