Final Fantasy VI Ultimate version 2.02

Final Fantasy VI Ultimate

This is an attempt at the ultimate SNES ROM hack of Final Fantasy VI. It fixes every bug that could be identified, improves performance, brings over content from later releases, removes the censorship, and corrects the script where it has errors or inconsistencies, while staying true to Ted Woolsey's translation. On top of that come a few minor balance adjustments and quality of life features.

None of this would have been possible without everything8215's disassembly and years of work by the international fan community.

What sets it apart from other compilations is its breadth: the many fixes nobody had made before, the GBA content brought to the SNES, and the performance work.

Every change is listed below by section. Each has a number that never moves, the same number CHANGES.txt uses. For each fix I credit whoever, as far as I know, first found or fixed the problem. I wrote most fixes myself from those findings. The tremolo repair uses everything8215's GPL-licensed code, and official fixes are identified in their entries. CREDITS.txt describes the retained contribution and the research credits. Some fixes can only be written one way, such as correcting a single number or letter or pointing to the one right address, so a handful of the hundreds of fixes may match someone else's exactly. If you think a fix is credited wrongly, would rather not be named, or have any other feedback on the credits, please contact me at undac123@proton.me.

432Bug fixesFaults of the original game, fixed. Many were documented by players over thirty years; some were found while making this ROM hack. Each entry says what 1.0 did and what the game does now. 6PerformanceA lot of visual effects in battle slowed down the original game. Large portions of this slowdown are fixed, with the output kept intact. 11Backported contentThe extra dungeons, side quests, espers, spells and weapons of the Game Boy Advance release, brought to the SNES, with the GBA's music player and a bestiary of every enemy. 11Quality of lifeSmall changes that make the game easier to play, without changing what it asks of you. 15Censorship removedThe original graphics, the pub signs, Holy for Pearl, and the lines Nintendo of America's rules had softened, put back from the Japanese release. 121Script edits and fixesLines that stated the wrong fact, rule or speaker, checked against the Japanese script, plus typos and one spelling for every name. 4Balance changesA handful of deliberate changes to how the game plays. 3OtherChanges that fit none of the other sections. 11Unsolved issuesFaults of the original game still in this ROM hack, and why, plus six reports not reproduced.

For ROM hackers

Every entry has a note for other ROM hackers, hidden under "For ROM hackers", that says how the change was made. It is written for someone making the same change in an unmodified US 1.0 ROM (Final Fantasy III, version 1.0, without a copier header).

Addresses are written bank/offset: C2/220D is file offset 0x02220D. RAM addresses such as $3AA0 are in bank 7E. Routine and label names are those of everything8215's ff6 disassembly, whose local labels carry their 1.0 address. Every address in the notes was checked by script against a build of that disassembly that matches the 1.0 ROM byte for byte. Assembly is in its ca65 syntax.

"Replace" or "Change" means an edit of the same size or smaller. "Insert" means the change needs more bytes than it replaces: in a binary patch, overwrite whole instructions at that spot (4 bytes for a jsl) with a jsr or jsl to free space, and run the overwritten instructions plus the new ones there. A compressed block that grows moves to free space and its pointer changes.

A note marked Method cannot be given as 1.0 addresses, usually because the change needs more room than the 1.0 ROM has, and describes the approach instead.

Each note is written as if its change were the only one applied to 1.0. Free space is scarce in some banks (bank C1 has only a few dozen bytes), so several changes applied together may need their code placed elsewhere and reached with a jsl. Where a note builds on another entry, it names that entry's number.