News:

11 March 2016 - Forum Rules

Main Menu

Final Fantasy II Restored

Started by redmagejoe, December 10, 2019, 03:09:14 AM

Previous topic - Next topic

Leviathan Mist

Sorry I've been MIA, but it looks like you guys are hard at work still. Thanks for all your work on this project! I guess you probably don't need those savestates anymore huh? I might have to just start my run over with all the new changes. I'll start a new run this weekend.

Jiggers

WARP check code:

L3AB75:                 
  AB75  LDA $82     ; get spell ID         
  AB77  CMP #$D0    ; see if it is WARP             
  AB79  BNE L3AB9A  ; if not, branch elsewhere             
  AB7B  LDA $2D     ;   
  AB7D  LSR A       ; shift lowest bit into carry             
  AB7E  BCC L3AB70  ; if carry clear, branch elsewhere             
  AB80  LDA $19     ;             
  AB82  BEQ L3ABDB  ; if $19 = $0, branch elsewhere             
  AB84  LDA #$47    ; message ID         
  AB86  JSR F3ADB6  ; draw message window with "can't warp"           
  AB89  JSR F3ADE9               
  AB8C  JSR F3EE60               
  AB8F  LDX #$0B                 
  AB91  JSR F3B486               
  AB94  LDA #$01                 
  AB96  STA $A2                 
  AB98  CLC                     
  AB99  RTS                     


So for WARP to work, the low bit of $2D must be 0 (an even number), and $19 must be $0. Let me know which of those happens in that center area!
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

redmagejoe

#402
Hey Leviathan! No worries at all, I certainly know how life can sweep one away. We're glad to see you're well and back. :)

Any playtesting you're willing to do would be hugely appreciated. I've been doing Restored testing, which judging by the organized way abw has been doing the patches, is likely to have more oversights than less what with more changes. I can't imagine there'd be any bug in Bug Fix that isn't also in Restred, is what I'm trying to say, but either version you're willing to test out would be a great boon to us.

We've also been freeing up a lot of ROM space, so there's hope yet that we may have room for further enhancements down the line. And yeah, I guess we don't need the states since abw, Awesome and Powerful Wizard that he is, found all the places with those items and took care of them for Restored already. ;D




@Jiggers: I'm assuming that code chunk is more or less identical to Teleport's. I'll see if I can't make sense of that. If I could make an index of what IDs translate to what maps, it would be easier for me to give you useful info, but I'll see what I can do! I'm at a point where I can't return to Palamecia Castle in my current file, so I should probably consider starting a new one.

Jiggers

Quote from: redmagejoe on June 15, 2020, 06:16:46 PM@Jiggers: I'm assuming that code chunk is more or less identical to Teleport's. I'll see if I can't make sense of that. If I could make an index of what IDs translate to what maps, it would be easier for me to give you useful info, but I'll see what I can do! I'm at a point where I can't return to Palamecia Castle in my current file, so I should probably consider starting a new one.

OH, EXIT is a different spell. Okay, yeah, its the same thing:

L3ABAF:                 
ABAF  CMP #$E6    ; see if the spell is EXIT             
ABB1  BNE L3AB70               
ABB3  LDA $2D                 
ABB5  LSR A                   
ABB6  BCC L3AB70               
ABB8  LDA $19     ; if $19 is not $0...             
ABBA  BNE $AB84   ; branch to the "can't warp" part of WARP's code block             


Map IDs would be great! Keep an eye on $48 for that. $00 is the recovery room, $05 is the town, $5E is the rebellion HQ in that town, $2B is the inn, $27 is the item shop...

Something is wrong with the map decompressor though, because map file 04 is DEFINITELY the town, and map file 00 is definitely the recovery room the game starts in. Until we figure out a way to load these up in Tiled with proper graphics for the metatiles, it'll be difficult to know if the decompressor script is skipping maps or what.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

abw

Quote from: redmagejoe on June 13, 2020, 12:54:18 PM
I'll have to make a note to mention that on the hack page, now that load order matters.
We can also just take that part out of the patch - it's only freeing up 2 bytes, and we can't even really use them anyway as long as we're maintaining the addresses for the section that the translation patch overwrites. Actually, on that note, it would probably be better if the patch didn't overwrite 0x31628 - 0x3165D with FFs and just left it alone. In fact, it would probably be better if the patch didn't overwrite any sections of the ROM that it didn't need to at all.

Quote from: Jiggers on June 13, 2020, 05:42:02 PM
Oopsie on the shifting... Thanks for catching it though.
No problem!

Quote from: Jiggers on June 13, 2020, 05:42:02 PM
According to this, map $2F doesn't appear in the game? But the disassembly still has it as being loaded at some point. Map $0E wins the award for showing up #20 times in the LUT!
Hmm, interesting. Anybody want to place bets on which map *that* turns out to be? :P

Quote from: Jiggers on June 15, 2020, 04:25:04 PM
Yeah, this is just for metatiles. Still have to find exactly how many of those are in the game's data, then find out what graphic tiles they represent. But this doesn't contain any teleport coordinates or anything... so kind of useless if there's no bugs in the map layouts.  :P
On the other hand, it's very useful if you wanted to make a map editor or something :thumbsup:.

Quote from: redmagejoe on June 15, 2020, 05:10:43 PM
The entirety of Palamecia Castle, once entered, is supposed to prevent the player from escaping via Teleport or Warp, as is handled in many other places in the game "An energy field prevents you from warping out". This includes, apparently, most of 7F of the castle. However, there's an area in the center of 7F, which is accessed via a different set of stairs such that it's one floor but with two separate "areas" divided by walls, where it's completely possible to teleport out. I'm hard pressed to believe this was intentional, but I'd also think that it would be the entire floor that has a "no teleport" flag set.
That one's another of Alex Jackson's gems from https://gamefaqs.gamespot.com/boards/563414-final-fantasy-ii/56873163. Another curiosity is the Arena B1 map: it has encounters when you enter it from B2, but has no encounters when you enter it from 1F. Based on that, I suspect we might find that things like teleport and encounter flags are set based on the individual transitions between areas instead of on the entire map.

redmagejoe

Well that at least confirms it wasn't meant to be something one can teleport out of, plus knowing why it behaves that way will make it easier to fix.

As to your remark about the patch, do you suggest that I remove that entire part from the translation patch? Will the translation patch in its current form continue to handle DTE properly (see: behaving the way it is right now) if I were to revert that to the original JP code?

abw

0x31628 - 0x3165D at least is just blanking out code the patch doesn't use; since the old code there isn't used any more, just leaving it alone would decrease both patch size and risk of incompatibility with other patches. Ditto for 0x176EB - 0x1770F (blanking out the unused space at the end of the battle message list) and 0x1BFD6 - 0x1BFF1 (blanking out the unused space at the end of the bank 6 dialogue), though those text data areas are probably less likely to have conflicts with non-text-related patches; I'm not sure about the other RLE sections off the top of my head.

Jiggers

L3CAFF:                 
  CAFF  CMP #$C0                 
  CB01  BNE F3CB20               
  CB03  JSR F3D8EE               
  CB06  LDA #$00                 
  CB08  JSR F3FE03               
  CB0B  LDX $45       ; = $0 when leaving first town, $1 when leaving dreadnaught town
  CB0D  LDA $B4C0,X   ; get X or Y coordinate from this table           
  CB10  SEC                     
  CB11  SBC #$07      ; subtract 7 to get player position           
  CB13  STA $27       ; save position           
  CB15  LDA $B4E0,X   ; get X or Y coordinate from second table           
  CB18  SEC                     
  CB19  SBC #$07      ; subtract 7 to get player position                     
  CB1B  STA $28       ; save position           
  CB1D  JMP L3C0B8                         


These seem to be the exit-to-overworld coordinates. First byte is first town, second byte is the town by the Dreadnaught building area.

L00_B4C0:
.byte  $5B,$AD,$AB,$78,$47,$47,$E6,$EB,$D5,$35,$6B,$39,$32,$B1,$A0,$E9,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
L00_B4E0:
.byte  $74,$3A,$34,$E7,$4B,$48,$B3,$AE,$1C,$7B,$2B,$84,$B7,$0E,$8F,$B2,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00

So while $48 is the map ID, $45 seems to be... location ID? It keeps track of what overworld spot you're in. I'm at a disadvantage because I don't know the names of these locations...

0 - Starting Town
1 - Dreadnaught Building Town
2 - Dreadnaught Access Cave (Exits onto cave mouth) *
3 - Island In the Ocean (Exits onto cave mouth, not the single spot of land)
4 - Second Town Castle (right side)
5 - Above Second Town Castle (right side)
6 - Coliseum (on top of)
7 - Plains one tile right of castle in mountains by coliseum
8 - Winding mountain cave area with Stalactites and WzOgres
9 - Outside gold tower on island surrounded by mountains
A - Lake cave above waterfall, trapped by river tiles!
B - On the ocean, between some pincer-shaped mountains
C - Cave in the middle of some plains, mountains to the south. Cave has brains in it.
D - Snow plains cave!
E - Just some spot near some mountains and some plains, where Pudding enemies are?
F - Outside the castle in the mountains by the coliseum (left side)

Well there goes my idea that $45 is holding the entry-level map from the overworld. A bunch of towns are missing and don't call that code block when you exit them.

Was fun to test though.

* Could this be considered a bug, facing right in the cave mouth when exiting these places?
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

redmagejoe

#408
0 - Altair
1 - Bafsk (exit from using teleport rune in sewers side room)
2 - Bafsk Sewers (exit other end to where Dreadnought is)
3 - Black Mask Cave
4 - Fynn Castle (exit from using teleport rune in basement mask room)
5 - Exit point for Cyclone
6 - Palamecia Coliseum
7 - Exit point for Palamecia Castle (which you shouldn't be able to do, 7F bug)
8 - Deist Cavern
9 - Mysidian Tower (this is the one we want to change to one tile south, unless we can turn off the animation)
A - Semitt Falls Cave
B - Exit point for Leviathan when holding Crystal Rod
C - Mysidian Cave (Crystal Rod is here)
D - Snow Cavern
E - Exit point for Jade Passage, which isn't visible until the end of the game
F - I believe you end up here already in the airship after escaping Palamecia Castle, right before it becomes Castle Pandaemonium

I'm guessing 8 is to the north of Deist Castle on a smallish island? And E is to the west of the massive desert where the Coliseum and Palamecia Castle are? But yeah, I'm seeing a total lack of all the other towns, but these are at least exit points used at various points in the game. Even if this isn't exactly what you're looking for, I can tell you that provided your descriptions I was able to recall these points and can assure you that they are relevant to this investigation. They're most definitely "exit points" used for scripted events or tied to methods of exit unique to walking out of a map or using warp spells.




Out of curiosity, abw, are status effects applied by player weapons, or enemy physical attacks, affected by Magic Resist on the target? I was in a discussion with HCBailly who is currently running a Let's Play of Final Fantasy II, and mechanics discussions often come up in the comments. He is certain that Magic Resist plays a role in the chance of affliction, whereas I was under the impression this only affected spells. If he is correct, this means that Shell is by and far the most powerful endgame of the triad of Wall, Shell, Barrier, though Barrier arguably has more versatility at lower levels.

abw

Quote from: redmagejoe on June 16, 2020, 02:26:22 AM
Out of curiosity, abw, are status effects applied by player weapons, or enemy physical attacks, affected by Magic Resist on the target?
Indeed they are - the code for that starts at $0C:$B351. We actually touched on this point very briefly a few months ago in the context of bug fixes that affect balance - your party gains magic resist levels faster now that enemy target-all spells correctly affect each character's magic resist counter and higher magic resist levels increase their resistance to ailments.

Quote from: redmagejoe on June 16, 2020, 02:26:22 AM
If he is correct, this means that Shell is by and far the most powerful endgame of the triad of Wall, Shell, Barrier, though Barrier arguably has more versatility at lower levels.
Wall grants immunity to black magic (this is mixed blessing), Shell increases your magic resist level, which translates to more spell resist successes, and Barrier grants elemental resistance, which translates to full spell resist success against specific elements, so... yeah, at high levels, Shell > Barrier since it does everything Barrier does and then some.

redmagejoe

#410
I'm going to begin compiling a list of Map IDs knowing that $0048 holds that information. Keep an eye on the first post for updates to the list. I suppose it's not surprising to those more versed in NES programming than I, but $48 is repurposed during combat, it seems, reverting to its previous value (held in some other address I'm sure) until the end of combat. So $48 only holds Map ID while out of combat. The overworld also does not have an ID stored, as $48 remains the same as it was prior to exiting the map into the overworld.

I'm already noticing evidence of what abw had stated, about the behavior of the room you've entered being determined by how you entered it (which specific stairs/door/etc), as rooms that I'm fairly certain are on the same "screen" that could be accessed via walk through walls have completely different values in $48. More on this as I work on the list. This will likely make it easier to change the BGM of liberated Castle Fynn as well since it has distinct indices from occupied Castle Fynn.

First post has been updated with a WIP table of the Map IDs accessible before the end of the game. I will need to start up a new file to find the missing entries, but the majority of indices are there. Link is under the Resources header of the first post.

Might want to add to the list of bugs that the tiles on either side of the Snow Cavern entrance appear to be castle/town walls lodged in a mountain...

abw

Quote from: redmagejoe on June 17, 2020, 12:30:37 PM
I suppose it's not surprising to those more versed in NES programming than I, but $48 is repurposed during combat, it seems, reverting to its previous value (held in some other address I'm sure) until the end of combat.
Yup - one of the first things that happens when a battle starts is that the game stores a backup copy of $00-$AF at $7C00-$7CAF and then restores it after battle, so all of the addresses in that range are free to be used for different things during battle.

Jiggers

#412
I looked at what else is loaded by $48 when moving between maps and updated the WIP map list.

https://pastebin.com/GmXDyrLG

Which brings a new mystery: What is $67?

The $B200 table explains why the starting town is $04 in the decompressed map file thing.

The $B000 table must use the low 5 bits for something else, but the high 3 bits are basically the tileset. I looked through the ROM for graphics and since it loads about half a pattern table, that means I've counted 4 different tilesets... 0 = town, 2 = indoors... dunno the rest.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

redmagejoe

#413
EDIT: First post has been updated with the complete Map ID Table. Double-checked everything to ensure accuracy. Whether these are actually "Map IDs" in the conventional sense or simply some sort of identifier used based on which entrance/exit you've taken is debatable though, given that it seems designed to allow for specific behaviors under different circumstances. This theory is weakened, however, by the gratuitous use of these values in places where they're either completely unused or have no clear intention behind them, easily eating up at least a few dozen indices which didn't need to be.

All told, from my data-mining and with extensive knowledge of the game progression (having played through it at least 4 times from start to finish thanks to this project), I can say with confidence that there's a lot of strange choices for some of these behaviors that cause more bugs than they provide some sort of niche behavior or feature. Had ROM space allowing for the actual metatiles / map data, they easily could have put 1 or 2 more full "dungeons" with the map indices they didn't need to use.

Quote from: Jiggers on June 17, 2020, 08:07:57 PM
Which brings a new mystery: What is $67?

Consider this a knee-jerk response as I've literally only just now loaded it into RAM Watch and spent less than a minute looking at it, but the value only appears to change when I'm in a town and an NPC starts moving. The moment it stops, the value freezes. The moment they walk again, the value shifts.




Quote
  • Preemptive Strike notification comes after commands are issued. Enemy commands are issued, but should no longer give counter credit due to other fixes. Move Preemptive message to beginning of battle.

So below appears to be the relevant code for the above, which I haven't sat down and examined yet, but as I understand it, the game is essentially pushing the appropriate message into the buffer, but when the message displays later is handled differently. What currently happens is that if it's an Ambush, you're told as soon as the battle begins, and then enemy actions are carried out. Meanwhile, Preemptive Strikes are only announced after commands are executed, so it comes down to determining precisely what routines are being skipped/executed for Ambush and tweaking that behavior for Preemptive. Ambush is decided, message is pushed into buffer, enemy actions are decided, assuming this is the same as vanilla behavior, the routine for giving the player the chance to issue orders is then considered, but skipped, the message is displayed, and the round of combat commences. Preemptive meanwhile is pushed into message buffer, enemy actions are skipped, the routine for giving the player the chance to issue orders is run, the message is displayed, and the round of combat commences.

Assuming this is what's happening, I can see why the issue with Preemptive message exists, as it's just running through the same control flow, but with a different message at the same step. Ideally, we'd want a conditional to determine that a message display happens only in this specific case before the step where the routine for player issuing commands runs.


; data -> code
; control flow target (from $909C)
; call to code in a different bank ($0F:$FD46)
0x032318|$0C:$A308:20 46 FD JSR $FD46  ; wait for sprite 0 clear, then write $3B to PPU Control Register #1 and $39/$37 to VRAM Address Register #1
0x03231B|$0C:$A30B:AD 4A 7B LDA $7B4A  ; surprise battle indicator (0 = normal, 1 = monsters surprised party, 2 = party surprised monsters)
0x03231E|$0C:$A30E:F0 42    BEQ $A352 
0x032320|$0C:$A310:20 90 94 JSR $9490  ; write #$FF (space) to CHR buffer at $7600-$76FF
0x032323|$0C:$A313:A2 09    LDX #$09    ; Battle Message ID #$09: %u305B%u3093%u305B%u3044%u3053%u3046%u3052%u304D%u306E %u30C1%u30E3%u30F3%u30B9%uFF01%uFF01 (Preemptive Strike)
0x032325|$0C:$A315:AC 4A 7B LDY $7B4A  ; surprise battle indicator (0 = normal, 1 = monsters surprised party, 2 = party surprised monsters)
0x032328|$0C:$A318:88      DEY       
0x032329|$0C:$A319:D0 01    BNE $A31C 
0x03232B|$0C:$A31B:E8      INX        ; Battle Message ID #$0A: %u30E2%u30F3%u30B9%u30BF%u30FC%u306E %u305B%u3093%u305B%u3044%u3053%u3046%u3052%u304D%uFF01 (Ambushed!)
; control flow target (from $A319)
0x03232C|$0C:$A31C:86 64    STX $64   
0x03232E|$0C:$A31E:A9 B2    LDA #$B2    ; $05:$B295; battle message pointers
0x032330|$0C:$A320:85 63    STA $63   
0x032332|$0C:$A322:A9 95    LDA #$95    ; $05:$B295; battle message pointers
0x032334|$0C:$A324:85 62    STA $62   
0x032336|$0C:$A326:20 AB 9A JSR $9AAB  ; swap in PRG bank #$05, then given a pointer index in $64, copy bytes from the $64'th pointer in the pointer table at $62-$63 to $7D47,X=$AA until we read a 0 or X reaches #$11; save X to $7CBF
0x032339|$0C:$A329:A9 10    LDA #$10   
0x03233B|$0C:$A32B:85 44    STA $44   
0x03233D|$0C:$A32D:85 45    STA $45   
0x03233F|$0C:$A32F:A9 00    LDA #$00   
0x032341|$0C:$A331:85 6F    STA $6F   
0x032343|$0C:$A333:20 E7 95 JSR $95E7  ; given line length (interior window width) in $45, write string buffer $7D47 to $44 in the $6F'th page of $A8-$A9 (a.k.a. $7600,$44)
; call to code in a different bank ($0F:$FD5B)
0x032346|$0C:$A336:20 5B FD JSR $FD5B  ; wait for sprite 0 hit, then write $3A & #$EF to PPU Control Register #1, $38 to VRAM Address Register #1, then call $05:$BA00, $0D:$9800, and then swap in bank stored in $3E
0x032349|$0C:$A339:A9 04    LDA #$04   
0x03234B|$0C:$A33B:85 64    STA $64   
; call to code in a different bank ($0F:$FB42)
0x03234D|$0C:$A33D:20 42 FB JSR $FB42  ; call $05:$AA57
0x032350|$0C:$A340:A0 20    LDY #$20   
0x032352|$0C:$A342:20 9B 94 JSR $949B  ; wait for Y vblanks
; call to code in a different bank ($0F:$FD46)
0x032355|$0C:$A345:20 46 FD JSR $FD46  ; wait for sprite 0 clear, then write $3B to PPU Control Register #1 and $39/$37 to VRAM Address Register #1
0x032358|$0C:$A348:A9 04    LDA #$04   
0x03235A|$0C:$A34A:85 64    STA $64   
; call to code in a different bank ($0F:$FB46)
0x03235C|$0C:$A34C:20 46 FB JSR $FB46  ; call $05:$AB4F
; call to code in a different bank ($0F:$FD46)
0x03235F|$0C:$A34F:20 46 FD JSR $FD46  ; wait for sprite 0 clear, then write $3B to PPU Control Register #1 and $39/$37 to VRAM Address Register #1
; control flow target (from $A30E)
0x032362|$0C:$A352:20 8A A6 JSR $A68A  ; determine turn order for the current round
; call to code in a different bank ($0F:$FD5B)
0x032365|$0C:$A355:20 5B FD JSR $FD5B  ; wait for sprite 0 hit, then write $3A & #$EF to PPU Control Register #1, $38 to VRAM Address Register #1, then call $05:$BA00, $0D:$9800, and then swap in bank stored in $3E
0x032368|$0C:$A358:20 41 A7 JSR $A741  ; execute a complete round of combat
0x03236B|$0C:$A35B:4C 5E 90 JMP $905E


Perhaps inserting a JSR to whatever routine is responsible for printing battle messages immediately after the #$09 is loaded into A?

abw

Quote from: redmagejoe on June 17, 2020, 08:10:58 PM
So below appears to be the relevant code for the above, which I haven't sat down and examined yet, [...]
I was actually working on this earlier since I was documenting that section of code. I think you'll find that the situation is more complicated than it might seem at first, as the logic for when to display the surprise message is integrated with the logic for orchestrating the horizontal scrolls of the bottom part of the battle screen (which I also haven't fully examined yet :P).

Given the tight coupling and the fact that the message does work, I'm currently inclined to believe that the original behaviour was intentional even if we don't like it, so I'm voting for making this a Restored-only change.

Give the latest Restored patch a try and see what you think. The timing of the message is different from the original, but the original was kind of jittery with sliding back and forth so quickly, so I kind of like this version better anyway, but I'm not sure I'm totally happy with it yet.

In other news, I think I've finally stumbled across the code for updating battle poses/status display, so my current WIP is fixing that to more consistently work; after that, I'll probably tackle resetting battle commands and ailments for KO'd characters. I think I also know what code needs to run to handle monsters getting KO'd by poison, so that might come next.

redmagejoe

It looks good! I definitely don't see any reason for the interface to jerk around just to display the message before returning to its previous position. Definitely far better behavior than vanilla. And I don't see any reason not to include the change in Bug Fix. It would be the only entry in the series where it behaves the way it does in vanilla, and it seems more like an oversight than intentional design. I say we push it into Bug Fix when it's all tested. :)

abw

Quote from: redmagejoe on June 19, 2020, 02:17:48 PM
It looks good! I definitely don't see any reason for the interface to jerk around just to display the message before returning to its previous position. Definitely far better behavior than vanilla.
Alright, maybe we'll keep it this way, then.

Quote from: redmagejoe on June 19, 2020, 02:17:48 PM
And I don't see any reason not to include the change in Bug Fix. It would be the only entry in the series where it behaves the way it does in vanilla, and it seems more like an oversight than intentional design. I say we push it into Bug Fix when it's all tested. :)
A couple of minutes with Final Fantasy III shows that it also waits to notify you about your free turn until after you've finished entering commands, so that adds a lot of support to the theory that Final Fantasy II's behaviour is intentional.

redmagejoe

#417
Ew, really? What a terribly user-unfriendly decision. Now I have to go see if I'm remembering FF1 wrong and it did the same thing.

Okay, FF1 definitely did "Strike first!" before any commands. What a bizarre change to make for two entries in the series.

I'll leave it to your discretion whether it should go into Bug Fix or not. I don't think that would qualify as taking creative liberties, personally, and since remakes changed this behavior, I don't know that it would be presumptuous of us to change the behavior.

Vanya

Regardless of the label, it should definitely be "corrected".
It isn't presumptuous to make such an obvious change.
After all, it's just as likely that it was an error in FFII that then became an oversight in FFIII than it is to have been intentional.
There's really no way to know.
It might be useful to see how the latter games handle per-emptive and surprise attack messaging.
I'm pretty sure they all match up with FF1 and not 2 & 3.

redmagejoe

I know for a fact that 4, 5, 6, and 7, as well as remakes of 2, tell you that it's a preemptive strike the moment the battle initiates. I'd go with series convention over our speculated developer intention here, frankly, especially since it makes no sense without applying some really tortured logic. "Preemptive strike" would only make sense if your team knew they had the jump on the enemy before they decided their actions. Its current behavior is more like "You rolled a 20! Get a free turn!"