Archipelago
Archipelago copied to clipboard
Bug: Items not sent/received correctly when switching roms
What happened?
I tried to play 2 super metroid seeds "at the same time" using AP. I created a server using 2 yaml files. I connected SNI client using the first one. I played until I was stuck. Then I rebooted my SNES and started playing the other world. I had remote items enabled in both worlds.
At first it seemed like things were working fine. World 2 received some items that had been collected in world 1. However, some item checks in World 2 seemed as if they were performing an item check in both World 1 and World 2.
At some point I switched back to World 1 and eventually got stuck. Eventually with the help of strotlog we realized I should have had varia. However, it seemed that varia and some other items never made it to World 1 and some times never made it to World 2.
I noticed that if I typed commands in the SNI Client window that it thought I was connected as the first world regardless of which rom was loaded.
What were the expected results?
I had been hoping I could switch between the worlds by simply loading a different rom on my snes. It seems like it does work correctly if I remember to kill SNI client whenever I switch roms. I'd rather not have to do that as it seems error prone. I might forget and then lose items.
Software
While playing
Armchair analysis
SNIClient bug. Steps that should work for hitting the bug:
- Join a multi with multiple SNES yamls (worlds) for yourself
- Create the AP .sfc files corresponding to your worlds' patches and copy them all to FXPAK Pro (a generic SNES cart for playing on hardware)
- Leave SNIClient running on PC and go to SNES
- Start playing your world 1
- Reset FXPAK Pro to its menu (might need to be via controller hotkey?)
- Start playing your world 2
* I think DKC3's Client.py actually does check for its ROM ID regularly, so DKC3 may not be affected. All other SNIClient games likely are affected.
The symptoms that dagit encountered on his stream were very consistent with a theory that SNIClient has no knowledge of when the FXPAK Pro changes ROMs, thus SNIClient thinks the whole time that it's talking to world 1.
- SNI may be a bit of a factor, at least making the steps succeed a lot of the time on emulators. I'm guessing for all emulators, SNI usually manages to start throwing errors to SNIClient as soon as the emulator changes ROMs. SNIClient then responds to the error by exiting the game watcher loop and checking the identity of the ROM.
--
Next day edit:
- SNIClient likely doesn't pay attention to when RetroArch (emulator) changes ROMs either! That should mean there are emulator steps to encountering this bug corresponding to the steps above.
- I checked with jsd1982 and learned SNI is not designed to automatically monitor ROM changes. So if some LUA emulators happen to cause SNI errors when they change ROMs, it's merely a lucky side effect, and we need to stop relying on that behavior since it doesn't exist for other systems.
- For the games where SNIClient monitors vanilla SRAM values directly (LTTP and DKC3), as part of the fix, there is a common race condition that needs to be additionally covered by the fix. Sequence:
- \1. SNIClient: Check ROM is the one we think it is (new regular check to be added to LTTP, already exists in DKC3)
- \2. User: loads ROM+SRAM with a different world
- \3. SNIClient: Read SRAM and send checks out from the wrong world
- A similar race can happen on all games when receiving items from AP (step 0: SNIClient receives new item from AP, step 3: write new item to wrong world). This race is much more difficult/impossible to fix generically, as there's no "atomic test and set" operation other than writing one in ASM. It's also relatively rare due to new item and ROM change having to coincide in a very short time.
Added more info at the end of my analysis.