TASVideos

Tool-assisted game movies
When human skills are just not enough

Submission #4473: Keylie & Kadmony's SNES Final Fantasy VI "sketch glitch" in 3:11:39.46

Console: Super NES
Game name: Final Fantasy VI
Game version: USA v1.0
ROM filename: Final Fantasy III (U) (V1.0) [!].smc
Branch: sketch glitch
Emulator: BizHawk 1.7.4
Movie length: 3:11:39.46
FrameCount: 691104
Re-record count: 40863
Author's real name: Clément Gallet, L.L.
Author's nickname: Keylie & Kadmony
Submitter: keylie
Submitted at: 2014-11-02 12:26:35
Text last edited at: 2017-06-21 10:12:47
Text last edited by: keylie
Download: Download (35618 bytes)
Status: published
Click to view the actual publication
Submission instructions
Discuss this submission (also rating / voting)
List all submissions by this submitter
List pages on this site that refer to this submission
View submission text history
Back to the submission list
Author's comments and explanations:

(Link to video)

The video is commented with subtitles.

Terra and her team are back to fight Kefka and save the world. This time, however, they didn't want to watch as Kefka uses the Statues to torn the world apart, so they skipped it directly to the final confrontation.

This tas is an improvement of the previously published tas by Erokky in 4:05:52.87 and the non-published tas by Catastrophe in 4:16:34.88, thanks to an extreme use of the sketch glitch.

This is the lua script used to make our life much easier

Tricks

Preemptive manipulation

Getting preempitves/side attacks is the basics of many JRPG TASes. In this case, all the randomness at the start of a fight (preemptive, startup ATB, monster vigor) is determined based on the time the fight triggered. More precisely, the game uses the number of frames (range 1-60) within one second of the in-game timer as the RNG seed. As a consequence, there are 60 different battle configurations possible. The method to trigger preemptives/side attacks is simply to delay the beginning of the fight. This works well on the world map, but on towns/dungeons, there is a frame rule concerning movement: we can only start walking 1 every 4 frames. Because of this, we can only have access to 15 configurations out of the 60 ones. To be able to change this frame rule, there are several possibilities:
  • Go in and out of the menu. You can set the frame rule you want by delaying the exit of the menu by 1, 2 or 3 frames. This is however very costly if you don't have any menuing to do.
  • Delay the enter in the dungeon from the world map. This is only useful for the first fight in the dungeon.
  • Delay the end of a previous winning fight. Fights usually have at least an XP gain message. You can delay the confirmation of this message which will alter the frame rule. Because most fights are escaped, this has a limited application. It is very useful for the Minecart sequence for example.
  • Add lag frames during the previous fight. By entering the inventory and moving items, it can make the game lag, which will alter the frame rule after the fight. The most reproducible way to add 1 lag frame is to switch the weapon and the buckler. Switching them again may add another lag frame, but this is definitively not an exact science. This trick is used extensively through the whole run.

Desperation attack

Desperation attacks are rather secret and powerful attacks in ff6. Under specific conditions, the attack command has 1/16 chance of triggering a character specific technique dealing massive damage to one enemy. Those conditions are:
  • The character must be in the near fatal status, when HPs are lower than 1/8 of max HPs
  • The number of battle ticks must be over 768. In other words, we have to wait for about 25 seconds after the beginning of the fight.
  • The character must not be in the Muddle, Image, Clear or Zombie status
  • You can only cast one desperation attack per character per fight
  • Gau, Umaro and special characters don't have a desperation attack

The desperation attacks are magical attacks that ignore the defense of the enemy. So the amount of damage only depends on the level, the magic stats of the caster and the random variation. Strago and Relm desperation attacks are different, they kill instantly the target.

Message speed tricks

Escaping fights is usually faster to do when getting a preemptive or side attack. Sometimes, however, not all characters will run away immediately. The remaining characters will run away about two seconds after. This usually happens when the number of characters is higher than the number of enemies. In this case, there are two ways to get a faster run-away. The first solution is to get a front attack instead, and try to run away as soon as possible. This is used during Sabin scenario mainly, for the single Ghost fights. It saves about one second. The other solution is to set the Message Speed to 2 in the Options. In this case, all run-away during preemptives/side attacks will be perfect. The downside is of course that each battle message text box will be longer by about 16 frames. This includes the "Preemptive"/"Side attack" message and every command message. This is used twice in this run, during Mt Kolts and during Terra scenario, as there are many random fights and we control a team of three characters.

Run-away trick

The way the RNG works during fights is that you have a general counter stored in $BE which is used as an index in the random static array $C0FD00-$C0FDFF. Each time the game pulls a random number, it increases the RNG index by one. During the fight, when no action is playing, the RNG index increases by one unit per frame. When an action is starting, the game pulls several random numbers to compute the action random factors (random damage, miss, criticals, chance of giving status, etc.) and then the RNG index is frozen until the animation of the action ended. If several actions are queued, then the RNG index will just increase by the number of random numbers pulled between each action.

There are several ways to manipulate the RNG, which is very useful to get criticals, desperation attacks and to manipulate the enemies behavior. The first one is simply to delay an action so that the RNG index will be frozen at a different value, and subsequent actions will use different random numbers. However, this is only possible when no action was made before it (typically the first action of the fight). Sometimes, you want to cast actions as fast as possible to queue them before enemies actions. In that case, there is a very useful trick using the run-away (R+L).

The game checks about every two seconds (more often with the Haste status) if each character is running away. If it is the case, it pulls a random number between 1 and a character specific run-away constant (stored in $3D71, $3D73, $3D75, $3D77 for each character) and adds it to a counter (stored in $3D70, $3D72, $3D74, $3D76 for each character). If this counter gets over the run-away difficulty (usually 2 times the number of enemies) then the character will escape the fight. The important part here is that you can make the game pull random numbers, thus increasing the RNG index, even during action animations. Let's say the animation takes 4 seconds and you have 4 characters in your party. At the end of the animation, you can set the RNG index to 9 different values. This is also useful to try to cast the desperation attack as soon as possible after the time limitation is passed. This trick is not working for preemptive/side attack battles, as the run-away counters are not increasing.

If this tricks allows you to increase the RNG index during animations, you can also do the opposite. When no animation is played, you can freeze the RNG index by popping the "Can't run away" text box. This was used several times in the run.

Save/reset

During the game startup, some RNG values are initialised based on a value stored in SRAM. In details, after the introduction, the game increments the address $307FF1 (or $1FF1 in SRAM). Then, when you load a save slot or you start a new game, it adds 13 to $307FF1 and also stores this value into $1FA1 and $1FA4 (determines how many steps until next fight), $1FA2 and $1FA3 (determines which enemy formation will be fought), $1FA5 (determines which enemy formation pack will be fought on the Veldt) and $1F6D (determines the NPC behaviour, the Lete river encounter randomness, the fish randomness, etc.). The address $307FF1 is not contained in one of the 3 save slots, meaning that whatever slot you loaded, you will get the same randomness. During this run, we saved and reset the game twice to set all the encounter randomness to other values, which was useful to get the right fight at the right time.

Because we are supposed to make the TAS from a clear game state, address $307FF1 was never set before so the game is using an uninitialised value. BizHawk sets the entire SRAM memory as 0xFF, so this value was used as the seed of the encounter randomness. Moreover, the 2-byte integer $1F6E-$1F6F is also not initialised by the game. This value is the danger counter that increases at every step and is compared with a random number to determine if a battle occurs. This value is stored in the save slot, so you recover it when loading your save, but if you start a new game, the game will not initialise this value. In BizHawk, the RAM is filled with numbers that do not follow a specific pattern. The address $1F6E-$1F6F contains the integer 0xFDFB. This is a very high value, which explains why, in the TAS, a fight is triggered after one step in the Narshe cave.

Move across objects/event tiles

Simple clipping

Entering and exiting the menu at the right time allows you to move on the same tile as a moving guard. This is used during Locke scenario to skip Celes.

Simple party switch trick

During a few sequences in the game where you have multiple parties to manage, you can switch between parties using the Y button. If you press X to enter the menu and then Y during the fade-out, you will still switch to the next party and the menu will open for them. You can also press again Y during the fade-in before the menu opens to switch again to another party, and this can be iterated for as long as you want. During all that time, monsters on the field will move, but fights won't trigger if a monster gets close to you. This trick is used during the Kefka at Narshe sequence, to allow a monster to move close to you without triggering the fight, saving about 8 seconds.

Advanced party switch trick

A related trick can be used to go through a tile associated with an event without triggering it. To do that, press Y just before reaching the event tile and use the above trick (X then Y during the fade-out) to go back to the party with the menu opened. Then, change the leader of the party and close the menu. You are now able to move without triggering the event of the tile you were standing on. This trick was used to skip Inferno in Kefka's tower. This trick can be linked multiple times to disable continuous event tiles, which allowed us to move on a specific conveyor belt backwards, skipping another boss in the tower (Poltergeist).

Sketch glitch

In short

The sketch glitch is the major glitch used in this run. Missing the sketch command with Relm, for specific characteristics of the 28th spell of the first character, may induce a partial rewriting of your inventory, graphical glitches, freezing or even a softlock. This glitch is only available on the v1.0 version of the US rom.

How does it work?

During a successful sketch, the game will get which monster was sketched and look for the sprite of that monster in the memory. It will copy the sprite in the RAM and display a flipped version on the screen. When the sketch misses, the game will still do all the procedure except for the display. The origin of the problem is in function C2/F5D2:

  ...
  C2/F5E1: A0 03 00     LDY #$0003
  C2/F5E4: B1 76        LDA ($76),Y    (get the enemy slot)
  C2/F5E6: 0A           ASL            (multiply by 2)
  C2/F5E7: AA           TAX
  C2/F5E8: C2 20        REP $20
  C2/F5EA: BD 01 20     LDA $2001,X    (get the enemy id in this slot)
  C2/F5ED: AA           TAX
  C2/F5EE: 7B           TDC
  C2/F5EF: E2 20        SEP $20
  C2/F5F1: 22 D1 24 C1  JSL $C124D1    (load the enemy sprite)
  ...
During a successful sketch, instruction LDA ($76),Y loads the enemy slot number (between 0 and 5), and get the monster id by looking at the array $2001-$200C containing the id (16-bit integer) of the 6 monsters present in battle. However, when the sketch misses, instruction LDA ($76),Y loads 0xFF instead of the enemy slot number. So LDA $2001,X is wrongly fetching the 16-bit integer $20FF-$2100 as the enemy id. This address is in the middle of the battle spell table. $20FF contains information about the usability of the 28th spell of the first character (was used/available). $2100 contains the aiming byte of the 28th spell of the first character.

The function C1/24D1 and sub-functions are executed with an incorrect enemy id. The next problem arises in function C1/215F. This function loads the disposition of tiles in an enemy sprite. Indeed, tiles are stored in one dimension in the game memory, and it uses a mapping to place the tiles to build a two-dimensional sprite. The list of mappings for each enemy sprite is located starting $D2A820. This function loads the mapping corresponding to the enemy id and stores it in the array $822D-$824C. From this array, the game derives the height and the width of the enemy sprite in tile units. This is the critical portion of the function:

  C1/21B8: A6 00        LDX $00
  C1/21BA: C2 20        REP #$20       (set 16-bit accumulator)
  ...
  C1/21BE: BD 2D 82     LDA $822D,X    (get mappings for this row of tiles of the bitmap)
  C1/21C1: F0 0B        BEQ $21CE      (if none of the tiles in this row are set, branch)
  ...
  C1/21C7: E8           INX
  C1/21C8: E8           INX
  C1/21C9: E0 20 00     CPX #$0020
  C1/21CC: D0 F0        BNE $21BE      (loop for all 16 rows. When this loop exits,
                                        X will hold the # of rows in the image
                                        that have any valid tiles times 2.)
The game computes the height of the sprite as the number of valid (non-zero) tiles in the mapping. Keep in mind that if the enemy id is wrong, the mapping array will also be wrong. If this mapping array starts with the 0 value, the computed height of the enemy sprite will be zero.

Now, the most important function is function C1/22A5 which copies each tile of the enemy sprite from ROM to RAM, depending on the mapping array. This function is basically a double 'for' loop on the width and height of the enemy sprite. Then, a tile is copied for every bit set in the mapping array. Here is the portion of the code that decrements the sprite height and loops, at the end of the function:

  C1/22D7: CE 53 82     DEC $8253    (decrement adjusted monster height/8, iow, its tile height)
  C1/22DA: D0 C9        BNE $22A5    (loop if we haven't finished processing/copying
                                      all the rows of the monster's tiles.)
Notice that the game *first* decrements the height, and then checks if it's non-zero. What happens if the height is zero in the first place? The variable becomes 255, so the game will assume that the sprite has a tile height of 256! This is a very high value, the maximum tile height planned by the game is 16. This will lead to many more tile copies than normally, which will overwrite many other memory locations.

Which variables affect the outcome of the glitch?

As said earlier, the game will load the availability and the aiming of the 28th spell of the first character, and interpret them as the enemy id. During battle startup, the spell list of all character present in the battle is compressed and stored for each character. The compression is as followed: the whole spell list is placed in a table of three columns. If a row does not contain any spell known by a character present in the battle, that row is deleted. The remaining table is placed in the Magic menu for each character, with only their known spells. If we want to have a spell in the 28th slot, we have to learn at least 10 spells that will each one fill a different row. The route for the present TAS is to learn:
  • Cure (Lv1), Fire (Lv3), Antdot (Lv6) and Drain (Lv12) with Terra's natural magic
  • Sleep (10 AP), Mute (13 AP) and Slow (15 AP) with Siren
  • Bio (13 AP) and Break (20 AP) with Shoat
  • Muddle (15 AP) and Imp (20 AP) with Stray

Here is how the magic list looks like during a fight where all 10 spells are present. 10 rows are filled so that Break is placed at the 28th position.

  Cure     Cure 2    Cure 3
  Life     Life 2    Antdot
  Remedy   Regen     Life 3
  -------------------------
  Scan     Slow      Rasp
  Mute     Safe      Sleep
  Muddle   Haste     Stop
  Bserk    Float     Imp
  Rflect   Shell     Vanish
  Haste2   Slow2     Osmose
  Warp     Quick     Dispel
  -------------------------
  Fire     Ice       Bolt
  Poison   Drain     Fire 2
  Ice 2    Bolt 2    Bio
  Fire 3   Ice 3     Bolt 3
  Break    Doom      Pearl
  Flare    Demi      Quartr
  X-Zone   Meteor    Ultima
  Quake    W.Wind    Merton
  -------------------------
Now that we know how to place a spell at the 28th position, we can focus on the characteristics of the spell that affect the sketch glitch. First, the aiming of the spell consists of an 8-bit integer where each bit has a different meaning:
  • Bit 0 = Cursor Moveable
  • Bit 1 = One Side Only
  • Bit 2 = Autoselect both parties
  • Bit 3 = Autoselect one party
  • Bit 4 = Auto Confirm
  • Bit 5 = Multiple Selection possible
  • Bit 6 = Cursor Start on Enemy
  • Bit 7 = Random selection among all enemies and allies

There are 13 different aiming bytes represented in this game:

  • 0x00 (Self): Warp
  • 0x01 (Allies or enemies, single): Safe, Haste, Bserk, Rflect, Shell, Vanish, Life, Life 2
  • 0x02 (Self): Quick
  • 0x03 (Allies, single target): Antdot, Remedy, Regen, Life 3
  • 0x04 (Allies and enemies, multi target): Quake, W Wind, Merton
  • 0x21 (Allies or enemies, single or multi target): Float, Cure, Cure 2, Cure 3
  • 0x29 (Allies or enemies, multi or single target): Haste 2
  • 0x41 (Enemies or allies, single target): Poison, Drain, Break, Doom, Pearl, Flare, Scan, Slow, Rasp, Mute, Sleep, Muddle, Stop, Imp, Osmose, Dispel
  • 0x43 (Enemies, single target): Demi
  • 0x61 (Enemies or allies, single or multi target): Fire, Ice, Bolt, Fire 2, Ice 2, Bolt 2, Bio, Fire 3, Ice 3, Bolt 3
  • 0x69 (Enemies or allies, multi or single target): Slow 2
  • 0x6A (Enemies, multi target): X-Zone
  • 0x6E (Enemies, multi target): Quartr, Meteor, Ultima

We used in this route the 0x41 aiming byte because it gives access to the shortest setups. The second characteristics is the availability of the spell. It is represented as a 8-bit integer, whose bit 7 is set if the spell is not available (grayed) or cleared if it is. When the game updates the availability of the spell (function C2/5763), the integer is shifted right and the new availability bit is stored in bit 7. At the beginning of the battle, the integer is initialised as 0xFF and the game updates the availability of every spell.

During the fight, the game calls this update function when:

  • The holder of the spell received a MP heal by an item. Items having the "Concerns MP" flag set are Tincture, Ether, X-Ether, Elixir, Megalixir, Sleeping Bag and Tent.
  • The holder of the spell consumes MP using the Magic, X-Magic, Esper or Lore commands. Spells costing 0 MP don't trigger the update.
  • The holder of the spell is imped or de-imped.

The game does not call the update function when:

  • The holder of the spell attacks with a weapon with the "critical MP" property (like the Rune Edge), thus reducing his MPs.
  • The holder gets the Mute status. In this case, the Magic command is disabled, not every individual spell, as opposed to the Imp status where every spell except Imp are disabled.

For example, if we want to place the integer 0x83 (or 0b10000011) in the availability byte, we can do the following:

  1. Start the fight with the 28th spell available (0x01111111)
  2. Use a Tincture on the first character (0x0011111)
  3. Use a second Tincture (0x00011111)
  4. Use a third Tincture (0x00001111)
  5. Use a fourth Tincture (0x00000111)
  6. Use Imp on the first character (0x10000011)

During a sketch, we saw that the game is using the mapping array $822D-$824C to determine if a tile must be copied from ROM to RAM. During a sketch glitch, however, as the sprite height is incorrectly set to 256, the corresponding mapping array will be $822D-$842C, overflowing the next portion of memory. Addresses from $824D to $8258 store local variables, but addresses starting $8259 store the offsets of each enemy position. These offsets depend on the formation mold. Every enemy formation is using a specific formation mold, which gives the coordinates and maximal dimension of every enemy. There are 13 different molds used in the game. Each formation mold will lead to overwriting different parts of memory during a sketch glitch.

Taking advantage of the sketch glitch

The main beneficial outcome of the sketch glitch is to erase part of your in-battle inventory ($2686-$2B85). At the end of the battle, the game loads the in-battle inventory into the general inventory ($1869-$1A68). Thus all items that appeared during the sketch glitch are kept. The in-battle inventory stores 5 bytes per item:

  • Byte 0: Item id
  • Byte 1: Item flags
    • 0x08: Is a shield
    • 0x10: Is a weapon
    • 0x20: Can be thrown
    • 0x40: Is a tool
    • 0x80: Not usable as an item in battle
  • Byte 2: Item targeting
    • 0x01: Cursor Moveable
    • 0x02: One Side Only
    • 0x04: Autoselect both parties
    • 0x08: Autoselect one party
    • 0x10: Auto Confirm
    • 0x20: Multiple selection possible
    • 0x40: Cursor Start on Enemy
    • 0x80: Random selection among all enemies and allies
  • Byte 3: Item quantity
  • Byte 4: Item equipability
    • 0x01: Onscreen character 0 can't equip item
    • 0x02: Onscreen character 1 can't equip item
    • 0x04: Onscreen character 2 can't equip item
    • 0x08: Onscreen character 3 can't equip item

Added to the fact that you have access to a bunch of new items, the sketch glitch also allows you to change the characteristics of an item without changing its type. Indeed, on some item slots, only part of the characteristics will be overwritten. Thanks to this, you are able to flag any item, leading to useful tricks like:

  • Flagging an item as a weapon or a shield and equip it during the fight. The item will be kept in your equipment after the fight. All special effects of the item will be operative even if the item is not in the right spot (e.g. a Moogle Charm in the right hand will still remove random encounters)
  • Flagging an item as usable in fight and use it
  • Duplicating an item by overwriting its quantity

The Japanese equip-anything glitch still applies here. This glitch, only possible in the Japanese version of the game, allows you to equip an item in an equipment slot if:

  1. you put that item in the 255th slot
  2. you don't have any item in your inventory that fits in that slot
  3. you select Optimize
In the US version of the game, the developers disabled the 255th slot, but a sketch glitch can still put an item in that slot. You can then move that item into an equipment slot by the same method.

The sketch glitch also overwrite the in-battle Magic menu. This menu starts at address $208E for the first character and contains 4 bytes for each spell:

  • Byte 0: Spell id
  • Byte 1: Spell availability
  • Byte 2: Aiming byte
  • Byte 3: Spell MP cost
We don't have as much freedom as the inventory, but a sketch glitch can give inaccessible magics. Magics are not only white/black/grey magics that we learn during the game, but also Espers, Skeans, SwdTechs, Blitz, Dances, Slots, Magitek, Lores, enemy attacks, desperation attacks and Interceptor attacks.

Also, for a few formation molds (2, 4 and 8), the sketch glitch overwrites the command list. This list is stored starting $202E and takes three bytes per command:

  • Byte 0: Command id
  • Byte 1: Command availability
  • Byte 2: Aiming byte

Unfortunately, those molds are known to freeze the game easily.

The consequences of the sketch glitch for each mold and spell setup can be generated from this lua script which outputs a spreadsheet.

Goggles glitch

If a character attacks with the Goggles item (which can be placed here thanks to the sketch glitch) and another character opens the Magic menu at the same time, the menu will show items from the inventory if scrolled up or down. If an item is used, the character will cast the magic whose id corresponds to the id of the item. For example, if a character uses the Antidote item (id 0xF2) in the glitched Magic menu, he will cast Cyan's desperation attack Back Blade (id 0xF2). In this run, we used the Goggles glitch with the items Black Belt (id 0xD5) and X-Potion (id 0xEA) to cast the magics Engulf (id 0xD5) and Bababreath (id 0xEA). Because Black Belt is not a usable item, a sketch glitch is needed to flag it as usable. The magic Bababreath is normally cast by the boss Phunbaba on the party, it removes the target from the battle. It also works when casting on an enemy. The magic Engulf is described below.

Engulf

There is an enemy in the game called Zone Eater in the World of Ruin who has the Engulf attack. This attack removes the target from the battle. If all the party is engulfed, the party is sent inside the Triangle Island cave, where the secret character Gogo can be recruited. Thanks to the sketch glitch, the Engulf magic can be cast by a character as soon as Relm is recruited, in the World of Balance. If cast by a character, the magic will auto-target an enemy, so Muddle is necessary to be able to cast it on a character. In that case, if the entire party is engulfed, it will be sent inside the Triangle Island cave. If the party exists the cave using the light exit on top (using a Warp Stone won't work), it will appear on the Triangle Island in the World of Ruin. The airship will have the same coordinates as where it was left. Because of this, the party will be stuck if the airship was not left on the island beforehand.

Unused tricks

Sleeping Bag

When you make an item usable in fight thanks to the sketch glitch, most items that were not supposed to be used will cast Fire. Some items, however, will have its own effect. When using a Sleeping Bag on someone, it will recover all his MPs with no item animation. Compared to a Tincture or an Elixir, the Sleeping Bag is about 100 frames faster to use. It could have been possible to use it instead of the Tincture in the run, but the required sketch glitch before being able to use the Sleeping Bag made this strat slower in the end.

Other glitched weapons

The sketch glitch can allow a character to equip as a weapon every item in the game. When a character attacks, the game loads the weapon graphics from $ECE400+8*id to $626B-$6272. Address $6270 (unknown purpose, launching flag?) varies between 0 and 4 for regular weapons. This address is used in the following code:
  C1/C269:    AD7062      LDA $6270
  C1/C26C:    297F        AND #$7F
  C1/C26E:    0A          ASL A
  C1/C26F:    AA          TAX
  C1/C270:    7C73C2      JMP ($C273,X)

  Pointers to code

  C1/C273:    86C2        (00)
  C1/C275:    99C2        (01)
  C1/C277:    7DC2        (02)
  C1/C279:    12C3        (03)
  C1/C27B:    73C3        (04)
For glitched weapons, however, address $6270 can take arbitrary values. So the above code will jump to a random place within C1 bank.

Tier change

With a sketch glitch against a formation mold 4, with a 0x41 aiming spell and 0xBF availability, the second command of the third character will be replaced with the command 32, which triggers the tier change during the Kefka fight. In this case, the tier change will load another enemy formation depending on the aiming of the command. The binary representation of the aiming value is the following two-bytes integer:

  0 0 foe6 foe5 foe4 foe3 foe2 foe1 0 0 0 0 char4 char3 char2 char1
So we can load enemy formations with an id as high as 16143, knowing that formations are normally included between 0 and 575. This leads to aberrant formations.

Goggles glitch with other menus

The Goggles glitch was used in this run with the Magic menu. It can be used with many more menus, but this was not actually deeply tested:
  • SwdTech: Cyan will cast a magic whose id will be the id of the item + a constant (85). Indeed, the game indexed the SwdTechs starting 0, and adds a constant to get the corresponding magic id. For example, if you use the item Fire Shield (id 96) in the glitched SwdTech menu, Cyan will cast the magic Tek Laser (id 181 = 96 + 85). The magic seems to automatically target the enemy, even if the target was set to be on the party.
  • Blitz: We couldn't get it to work
  • Tools: Edgar will damage the enemy, and sprites will start to move in an odd way through the screen
  • Rage: Not tested, but we supposed that it would not have any effect, because there are 256 rages already
  • Slots: Setzer will cast a magic whose id is stored in the address $C24E4A + itemid. For example, if Setzer uses the Potion item (id 0xE9) in the glitched Slots menu, he will cast the magic whose id is stored in $C24F33 which is the desperation attack MoogleRush (id 0xFA).
  • Command: Instead of opening a sub-menu, we can change character by using X or Y. If done right, the command menu of the new character will be glitched as the item menu. This should allow us to cast any command.

Alternative wrong warps

There are at least three ways to do the Engulf wrong warp:
  • The Engulf spell can be written in the magic list using the sketch glitch
  • The Engulf spell can be cast using the Goggles glitch, by using the Black Belt item
  • When triggering the sketch glitch against formation mold 3, the variable ($3EBC) that stores if the whole party was engulfed is rewritten. For specific sketch glitch setups, this variable is rewritten to a value that indicates that the party was engulfed. The downside is that a sketch glitch against mold 3 is followed by a freeze of the game, which can take minutes. This is however the safest way to do the wrong warp for an unassisted speedrun.

Comparison

Location Present TAS Erokky TAS Difference Cumulative difference Commentary
Introduction 8083 8065 18 18 Emulator differences probably
Magitek Armor to Whelk 18526 17217 1291 1309 A slightly different route. Also because of uninitialised RAM, we got an extra fight in the cave
Whelk fight 22301 21007 -15 1294 Closing the command window before the end of the fight saves a bit of time
Terra escape 44434 43973 -833 461 We run away the two random fights
Marshal Lobo fight 47618 47143 14 475
To Figaro Castle 53861 53491 -105 370
Figaro Castle 77000 76608 22 392 We waited more than 2 seconds for the Lete River manipulation, but only loosing 22 frames... maybe thanks to 1-letter names?
M-Tek fight 79488 79196 -100 292 We got a Metal Kick instead of a Tek Laser
To the Cave 83456 83201 -37 255 1-letter names
Cave 88470 88027 188 443 We made characters escape so Terra got the level up
South Figaro 90774 90214 117 560 We bought a Goggles and set the Message Speed to 2
Mt Kolts 100509 101987 -2038 -1478 Faster escaping thanks to the Message Speed 2 and no fight won
Vargas fight 105318 107004 -208 -1686 Better Sabin ATB
Road to Returner's Hideout 110166 112006 -154 -1840 Another fast escape
Returner's Hideout 121114 124203 -1249 -3089 Better river manipulation
Lete river 126839 131640 -1712 -4801 Didn't win the two mandatory fights
Ultros 1 129450 134126 125 -4676 Slower fight due to underleveled Terra
Team splitting 132320 137081 -85 -4761 Renaming
Locke Scenario 136256 153356 -12339 -17100 Skipping Celes
TunnelArmor 139253 156372 -19 -17119
Terra scenario 152729 170285 -437 -17556 Faster escaping thanks to the Message Speed 2
Doma 191574 211485 -2355 -19911 One less Grunt during a fight, Battle Speed 1 for Leader
Phantom Train 210362 229993 280 -19631 More solo Bomb :(
Rizopas 225496 245074 53 -19578 Battle Speed 1, making more attacks from the enemies so more lag
Veldt 246759 271176 -4839 -24417 No farming for Snare, but bad RNG
End of Sabin scenario 256117 281353 -819 -25236 Perfect escape underwater
Narshe 269312 294999 -451 -25687 Guard clip
Kefka 271815 297538 -36 -25723
Terra cutscene 282969 308794 -102 -25825 Renaming
Road to Zozo 295418 319649 1594 -24231 Save and Reset
Zozo 302660 327460 -569 -24800 Solo Sabin
Dadaluma 305371 330239 -68 -24868
Road to the Opera 331710 355225 1353 -23515 One extra fight on the way and more menuing
Opera 372754 396797 -528 -24043 ...I don't know
Rats 373878 397807 114 -23929 Bad rat RNG
Ultros 2 379291 403410 -190 -24119
Airship cutscene 393629 417694 54 -24065 Having Sabin and Edgar here costs time
Road to Vector 395520 419501 84 -23981 Longer menuing
Before Ifrit 404124 428660 -555 -24536 One less fight
Ifrit 405779 431504 -1189 -25725 Ifrit escape trick
To Number 024 411286 437030 -19 -25744
Number 024 414305 438515 1534 -24210 Old TAS used the Muddle/Phantom/Snare technique. We don't have Snare
Before Minecart 425280 449571 -81 -24291
Minecart 432868 457921 -762 -25053 Better enemy formations by putting Sabin in the first slot
Number 128 435748 461410 -609 -25662
Before Cranes 440598 466230 30 -25632 Lost time for ATB manipulation
Cranes 442010 467876 -234 -25866 Didn't need to steal Debilitator
Esper World 464383 490296 -47 -25913
Narshe cutscene 472604 496579 1938 -23975 Stop by on the Island to kill an Intangir
Cave to the Sealed Gate 490097 516111 -2039 -26014 Less fights
Road to Vector 499955 526013 -44 -26058
Banquet 530121 560087 -3908 -29966 Didn't go for the Charm Bangle
Road to Thamasa 554823 583468 1321 -28645 Second save and reset
Fire House 571283 600354 -426 -29071 Better Bomb placement
Flame Eater 573908 603178 -199 -29270 Morph saves time
Road to Esper Cave 586853 616255 -132 -29402
Before Ultros 593763 621863 1302 -28100 Won two fights for XP and MP
Ultros 3 595989 624204 -115 -28215
Rest of Esper Cave 606442 633106 1551 -26664 First sketch glitch to get Flame Shields
Before Leo 614754 641425 -7 -26671
Leo 619067 647522 -1784 -28455 Saved time with the Flame Shields
Rest of the cutscene 644204 672744 -85 -28540
Road to Kefka tower 655568 821759 -137651 -166191 Wrong Warp
Road to Guardian 671076 844652 -7385 -173576 Skip Inferno and Moogle Charms
Three Statues 679348 857351 -4427 -178003 Well, only two Statues
Kefka cutscene 688189 867318 -1126 -179129 Skip Terra cutscene
Kefka 689323 883418 -14966 -194095 Thanks Bababreath
End 691104 885172 27 -194068

Known improvements

  • Based on the above comparison table, it could have been faster to set Battle Speed to 6 just after the Phantom Train before Rizopas. We think Rizopas appearance is delayed when actions are made during the fight. And having the Battle Speed set to 1 caused the enemies to attack more often.
  • Some fights in Doma Castle were not good, especially the Grunt and Cadet fight.
  • The RNG on Sabin scenario was very bad: we got 3 fights against a single Bomb during the Phantom train (costing 3 seconds) and we got the unescapable fight against Templars and Soldiers on the Veldt. The latter is dependent on an uninitialised value in the RAM, which is set arbitrary by the emulator. The former, however, may be avoided by swapping scenarios (putting Terra last).
  • We forgot that we would need the Magic command on many people during Kefka tower, and thus Espers equipped. We had to lose time by equipping them one by one during the tower, we could have equipped them during just before the Opera.
  • We unequipped Sprint Shoes from Locke at the end of his scenario, but he is taking a few steps after that is affected by the presence of Sprint Shoes. We could have taken the Sprint Shoes from Terra instead.
  • Rhizopas skip
  • Kefka Tower skip and Kefka fight skip

Special Thanks

  • masterZed for first documenting the sketch glitch. This was really useful to disassemble the glitch
  • amaurea for writing a very complete lua script. It still had a few bugs, but fixing them didn't take us a long time and it was heavily useful for producing the tas.
  • Tanooki Teabag for discovering the Goggles glitch
  • simon for helping with the tas and writing a program which outputs the optimal magic route for the sketch glitch
  • Yousei, Novalia Spirit, Mnrogar, Imzogelmo, Cless, assassin, Lenophis, Terii Senshi, abyssonym, and many other for all the work that has been done in the past 10 years for disassembling ff6 code
  • Lord J for concentrating all this information into a very useful program: ff6usME
  • Catastrophe for making the previous ff6 tas with sketch glitch route, which was useful to use for comparison. Also thanks for suggesting the ultimate spell: Bababreath, and the work for optimising the end game
  • LCC for his deep knowledge of the game, for finding a few tricks that was helpful in the tas.
  • Erokky for doing the previous tas and writing very valuable information in the submission text

Suggested screenshots


FractalFusion: Changed game name to "Final Fantasy VI" to match that of the current publication.


turska: Judging.
turska: Accepting for publication to Moons in a new "sketch glitch" branch.

Spikestuff: Publishing.


Similar submissions (by title and categories where applicable):