Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
Hey dwangoAC,
I'm willing to help with the speed TAS competition. I will have some free time around AGDQ this year. I tried to PM you but you didn't seem to catch it.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
To add a bit more information, RNG for criticals cycles only when someone from your party is doing an attack. It doesn't cycle when you are doing a Tech or an Item, or when an enemy is doing an action.
Also, RNG values comes from a lookup table hardcoded in memory, and the initial index into that table is determined at game startup by the amount of time you spend in the window where you choose your save slot to load. If you have no save slot, this window does not appear and the index is set to 0.
So the only way to change the critical RNG is to save and reload, or to change the outcome of the previous battle.
All of this is for the SNES version though, I don't know about the DS version.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
You mean once ?
This is not like the 3 minutes CT TAS obsoleted the 2h17 any% TAS, which is currently the case with ff6. To me there is a problem when improving the first TAS with one that uses the sketch glitch (about 40 minutes cut) yields a different category, while using a game breaking glitch that can be triggered after 15 minutes does not get its own category.
I strongly support making the sketch TAS obsoleting the 4h TAS, and the lastest TAS on its own category.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
The recently published TAS has indeed total control over the scripting code of the game, but the second niconico video that I posted above (based on this post) is pure ACE (executing arbitrary assembly instructions).
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
ars4326 wrote:
My solution: Have the 'game-end glitch' obsolete the current 'sketch glitch' so that we'll have a consistent precedent, going forward. And if Keylie can find a workaround in the 'sketch glitch' category that enables the ending to be completed (e.g. by either making similar adjustments that were made here, or completing the World of Ruin, etc.), then I see no reason why the 'sketch glitch' branch couldn't be "grafted" back in.
I personally feel that the ending in the sketch glitch run is "correct" even with the softlock, because it was executed normally and the softlock is due to an external factor (one map does not have the NPC it should, which appear during the World of Ruin transition).
I understand the reason of this obsoletion, however I feel bad because it masks a great, rich and entertaining run with a poor and boring one.
I don't see how the ending in the sketch glitch run could be fixed. We don't have the kind of control with the sketch glitch to launch a particular cutscene.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
Kurabupengin wrote:
Shouldn't the category be "game end glitch" to fit in with the others?
I agree, this has been changed.
jlun2 wrote:
If it really bothers people, is it possible to modify the TAS so it won't softlock?
I investigate a bit, and yes, running the very end of the world destruction cutscene (after the Celes/Cid dialogue) before the ending sequence allows it to run until the end. This should not cost much time, just changing more colors on the configuration menu. If people think this is necessary, I will do this part again.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
Scepheo wrote:
If we can evaluate an expression (say, we allow only basic arithmetic operations) in O(1), this gives a complexity of O(y^log(n)).
If I'm not mistaken, for complexity of arithmetic problems, the size n of the input N is how much N takes in memory, meaning n = log_2(N), and not N itself. So the complexity of the above algorithm is more about O(y^(n*ln(2)/ln(10)))
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
All those low% routes are very interesting!
I'm just wondering about the spiral-path. Is it just to pass the low part of the room just above the breakable pipe, using the air in the room above (like here)? If so, this is such a detour for one single portion of a room!
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
Well, this method would take 15 minutes to get to the overworld, then about 20 seconds per death, meaning about 17 minutes of deaths (maybe less if we manage to get 0 HP on both characters). So a total of 32 minutes.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
I did a bit of more work about that glitch and came up with the same conclusions as Catastrophe, using the US version. To be exact, during the 52 Game Over:
- The game calls a subroutine, writing the return address into $062D-$062F
- The game calls another subroutine, writing the return address into $0630-$0632
- Addresses $0630-$0632 are rewritten many times (see code around C0/0159)
- The game returns from the second subroutine, writing $0630-$0632 into $E5-$E7
- The game then uses the address coded by $E5-$E7 as the current event
I didn't investigate yet how $0630-$0632 are rewritten. See below.
We could use this glitch to load the ending sequence. We could either manipulate $0630-$0632 to:
- code the address $CA1362 (or around that) leading to the beginning of the ending sequence
- code an address leading to somewhere in RAM or SRAM, and manipulate the content of that address to be the event B2 00 13 62 (jump to subroutine $CA1362), which jumps to the beginning of the ending sequence.
EDIT:
Catastrophe wrote:
I've been going about this by watching memory while frame advancing. So if multiple writes happen when I press A then it's impossible for me to follow.
Geiger's Snes9x Debugger is a very useful tool, as it allows you to put breakpoints on addresses been read, written or executed, and advance op by op.
EDIT2: $0630-$0632 are actually filled from horizontal/vertical scanline location!
C0/0153: AD3721 LDA $2137 Software latch for hor/vert counter
Necessary to fetch the hor/vert location later
C0/0156: AD3C21 LDA $213C Low byte of Horizontal scanline location
C0/0159: 8D3006 STA $0630 Stores into $0630
C0/015C: AD3C21 LDA $213C High byte of Horizontal scanline location (unused)
C0/015F: AD3D21 LDA $213D Low byte of Vertical scanline location
C0/0162: 8D3106 STA $0631 Stores into $0631
C0/0165: AD3D21 LDA $213D High byte of Vertical scanline location (unused)
C0/0168: AD3106 LDA $0631
C0/016B: CD3206 CMP $0632
C0/016E: 9003 BCC $0173 If vert scan is higher than $0632 then...
C0/0170: 8D3206 STA $0632 ...stores vert scan into $0632
$0632 stores the maximum of all vert scan apparently
C0/0173: 20D4C5 JSR $C5D4
C0/0176: 4C2BC6 JMP $C62B
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
I've been thinking again on this problem, which is likely to happen on many games. Here is a common case of loading screen:
- Thread 1 is refreshing the waiting screen (e.g. every 1/60s), waiting for thread 2 to finish
- Thread 2 is loading all the stuff for the next level
Because Thread 1 is refreshing the screen, it is considered as the main thread by Hourglass, so that frame boundaries are detected on that thread (based on Wait calls). However, Thread 2 is running wildly and is not synchronized with frames detected on Thread 1. This only solution I imagined to solve this theoretical problem is to consider that Thread 2 is doing instantly all the computations. Meaning when the main thread is waiting for another thread to finish, it always takes exactly 1 frame.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
Thanks Catastrophe for the work.
$12E8 is a copy of $E8 that is made at the beginning of a battle. At the end of the fight, the game copies back $12E8 into $E8.
At a game over, the game calls event B2: "call subroutine xxxxxx". Here is the code of this event (US rom actually, but the code is identical to the JAP version):
My interpretation of this code is that the game stores the current event pointer ($E5-$E7) into the event stack. The pointer to the top of the stack is precisely $E8. Then the game loads the address of the subroutine ($EB-$ED) into the event pointer ($E5-$E7), then increment $E8 by 3.
I guess that in the case of our glitch, we make the game call a subroutine for each Game Over without returning from the subroutine, so that in the end the event stack becomes overflowed.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
ALAKTORN wrote:
From that 2008 topic:
“Just playing around on my non-NG+ save and I "defeated" OP Lavos. There seems to be a bug where a person reivived by GreenDream is untargetable... I ended up targeting Lavos with a Full Tonic and it killed him somehow.
Then unfortunately the bug persisted and I couldn't heal Robo after Doors of Doom on the next form. Still, freaky. I actually can't figure out how to disable this bug and it's annoying. Hopefully it won't show up in my NG+.”
“So I guess I remembered wrong and it was an elixir that killed him. In any case, I managed to duplicate my success on the last two forms, technically finishing a LLG through OP Lavos without NG+ even.”
Weird bug, anyone knows what it is?
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
jlun2 wrote:
Any other uses for this glitch?
Well, every weapon can possibly cause a different glitch when attacking. I listed all of them and the executed assembler code here: https://github.com/clementgallet/ff6-tas/wiki/attacking-with-objects
Other than that, maybe blocking with an item that isn't a shield may provoke a glitch, but this is unlikely. I guess it only changes the sprite palette.
Equipping wrong items as an armor or an accessory gives weird stats, but nothing game-breaking as far as I know.
Fortranm wrote:
So both of the 2 different ways to break the game using 2 region specific glitches require more than half of the game to be finished in the end. This game is much better programmed than 1st gen Pokemon games after all. :P
Actually, the equip-anything glitch is available from the beginning when you take control of solo Terra. This is why I've been focusing on the JP version of the game. Just that the items needed to get one useable game-breaking glitch are not available until pretty far in the run :(
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
Fortranm wrote:
Great discovery! I thought it's a prank due to the date you posted the video. :P
When is the earliest point the glitch can be triggered? Do you have to proceed to the world of ruined like what the video shows?
Yeah, I happened to finish this route on April 1st, but this is totally legit.
You pointed out the problem of this route, and why I'm not working on the TAS. Each one of the items required for this glitch is available during late World of Balance, meaning after 2 hours of TAS. Also, we need to wait for 15 minutes during the fight so that the tick counter is at the right value.
I hope I can either find another useful setup, or rewrite my inventory somehow to get one of the four needed items.
Editor, Emulator Coder, Experienced Forum User, Published Author, Expert player
(2831)
Joined: 3/17/2013
Posts: 391
I managed to get ACE on ff6 japanese version.
Here is a proof of concept video:
Link to videoUser movie #21824914608942764
FF6 Japanese version features a glitch called equip-anything glitch, where you can equip any item at any equipment slot. To equip an item on a weapon slot, for example, you must:
* sell every weapon that a character can equip
* place the item in the last (256) slot
* select "Optimise"
During a fight, when you attack with a weapon, the game loads the weapon graphics properties from address $ECE400+8*id into $623B-$6242. Address $6240, which stores if the weapon has a short or long range animation, takes values between 0 and 4. According to this value, the game loads a different function, as shown below:
$C1/C217 AD 40 62 LDA $6240
$C1/C21A 29 7F AND #$7F
$C1/C21C 0A ASL A
$C1/C21D AA TAX
$C1/C21E 7C 21 C2 JMP ($C221,x)
Pointers:
$C1/C221 34 C2
$C1/C223 47 C2
$C1/C225 2B C2
$C1/C227 C0 C2
$C1/C229 21 C3
However, for items that are not weapons, address $6240 can store any value, so that the jump instruction above leads to many wrong addresses. Among all the wrong jumps, the one with address $6240 being 0x07 (weapons X-Ether, Gold Hairpin, Czarina Ring or Charm Bangle) is interesting because the game jumps to address C1/8D7A which holds:
$C1/8D7A 1B TCS Push accumulator to the stack pointer
...
$C1/8DE6 60 RTS
The accumulator happens to be 0x000E when instruction TCS is executed, so at the RTS instruction, the game pulls the value of address $000F-$0010 and jumps there. Address $000E-$000F is the battle ticks (i.e. the number of frames since the beginning of the fight) and address $0010 is often used to store a pointer to ROM, so it can takes several values. So we have many possibilities to jump here, but still inside the C1 bank. To jump outside the C1 bank and hopefully inside RAM or SRAM, we need to execute long jump instructions.
When searching for JML (5C) instructions inside the C1 bank, I found several jumps into SRAM:
Among all these options, the first one ($000F = 0xC7; $0010 = 0xCE) was found to be possible as sometimes $0010 holds 0xCE during the wrong jump. $AE606F corresponds to address $006F in SRAM, which is saved from address $166F in RAM. This address and following ones store:
$166F Shadow's Sprite set (03)
$1670 Shadow's Level adjustment factor (03)
$1671-$1676 Shadow's Name
The first instruction is then interpreted as ORA $03,S and we can manipulate the next 6 bytes by cleverly naming Shadow.
To trigger the ending, the way I found was to overwrite the event pointer, a 24-bit address that stores where in the list of events ($CA0000-$CCE5FF) we are. The event pointer is stored at $E5-$E7. However, during a fight, the game makes a backup to $12E5-$12E7. To trigger the ending, we need to store 0x1362 into $12E5. However, as we are using name characters to write instructions, we have a limited choice, namely bytes 20 - 5C, 60 - CC, CE - D1 and D3. Using the name of many characters, I could overcome the limitations and came up with this set of instructions:
AE/606F: 03 03 ORA $03,S Harmless
AE/6071: C2 20 REP #$20 16-bit accumulator
AE/6073: 80 8D BRA $6002 Jump to Terra's name
AE/6002: A9 C4 26 LDA #$25CA
AE/6005: 80 20 BRA $6027 Jump to Locke's name
AE/6027: 4A LSR A A is #$12E5
AE/6028: 85 A2 STA $A2 Stores to $A2
AE/602A: 80 20 BRA $604C Jump to Cyan's name
AE/604C: 48 PHA We push #$E5 to the stack for later
AE/604D: A9 C4 26 LDA #$26C4
AE/6050: 80 44 BRA $6096 Jump to Edgar's name
AE/6096: 4A LSR A A is #$1362
AE/6097: 92 A2 STA ($A2) Store to $12E5
AE/6099: 80 20 BRA $60BB Jump to Sabin's name
AE/60BB: A9 C2 2B LDA #$2BC2
AE/60BE: 80 20 BRA $60E0 Jump to Celes's name
AE/60E0: 4A LSR A A is #$15E1
AE/60E1: 28 PLP Pull Processor status register
This restores 8-bit accumulator
We couldn't use the standard SEP (E2) instruction
AE/60E2: 5C 7A 8D C1 JML $C18D7A This calls TCS then RTS to fix the stack pointer
and continue the normal flow.
We couldn't call directly TCS (1B)