Skip to content

Skies of Arcadia Encounter Canceling #1701

Open
@RikkiGibson

Description

Is your feature request related to a problem? Please describe.
Skies of Arcadia notoriously telegraphs when a random encounter is going to happen by reading from the disk drive. This makes a pretty noticeable noise on console. You can do stuff like open the menu and heal up, then get a guaranteed encounter the instant you close the menu.

It turns out you can also use this to cancel encounters on console. In the ~1.5 seconds between hearing the disk drive and the battle starting, if you perform an action like opening a chest, climbing a ladder, etc., the battle won't start. It seems the step counter resets when you do this, so you can effectively cut the encounter rate in half in some areas when you pull this trick off.

It would be nice if this trick were also possible on emulator. For speedruns it would level the playing field more between those playing on original console and those on emulator, since obviously getting fewer random encounters saves time.

Describe the solution you'd like
The solution involves 2 things:

  1. Add an option to indicate to the user when flycast is reading from virtual GDROM. Perhaps a little icon or bit of text in the corner.
  2. Modify the virtual GDROM so that the access patterns used by the game take a similar amount of time as on real hardware. Currently the emulator is faster in this case, and the result is even when you know the GDROM is being read e.g. by logging it, there is not enough time to react and cancel an encounter.

Describe alternatives you've considered
I can't think of any reasonable alternatives which would achieve the goal.

Additional context
I tried to modify the emulator to accomplish this. And I kinda-sorta got something working, which can be seen in the attached video. The LOADING.. text appearing briefly in the bottom left, before climbing the ladder, indicates a canceled encounter. I was able to walk all the way back inside with no encounters, which is pretty much impossible to do without this trick.

emu.encounter.cancel.demo.mp4

First I modified the UI to show when a GDROM read is in progress. I did this by just exposing and reading the gd_hle_state.status in the UI, and showing "loading" text when the status was nonzero.

This showed a loading indicator the way I wanted, but the load went by too fast. In adhoc testing there was maybe 0.7 seconds to react to the loading text and cancel the encounter, which was about half the time I have on console. Very difficult to actually pull the trick off this way.

So, secondly, I tried to adjust read_sectors_to to be slow enough for this trick, ideally resulting in a similar speed as console.

I basically just tried inserting a 250ms access time if the requested sector is far enough away from the most recently read sector. This kinda worked, but had the effect of slowing down ordinary read workloads too much. It was just obvious when launching the game that things were now way too slow.

Also, my change was obviously only in the HLE emulation. I ended up adding the DC BIOS file later on, and tried again in gdromv3.cpp. I wasn't able to understand what would be equivalent to what I did for the HLE one. I found the getGDROMTicks function, but I wasn't sure what it meant. It looked like a constant return value was being used for large transfers, which I didn't understand. I expected larger and larger transfers to take more and more ticks to finish or something like that. I managed to show when it was reading, but the reads were generally too fast to do the trick most of the time.

I think to make this take a similar amount of time as console, without harming overall performance too much, might require a more complex simulation of the disk drive. Accounting for stuff like constant angular velocity, seek time, buffering, and so on. For example, I noticed on console that when you repeatedly open the in-game menu in Skies, you will generally only hear the disk drive crank and get a delay the first time you do it after a battle or some such. The subsequent times will have much less delay. This might be due to the disk drive buffering the read? When I did my "add 250ms" hack, the additional delay to open the menu was considerable and happened every time.

I poked around a bit to see if any other emulators tried to do more accurate simulation of the disk drive. It looks like PCSX2 does some work to do this. Possibly some of the same aspects they are simulating could be done here. It seems like a significant amount of work, though, and might be tricky to be sure whether a complex set of changes to the GDROM did not negatively impact other games.

Here is the branch. It's in a hacked up state, but may be of interest.

Thanks for reading, and for any thoughts/suggestions you may have.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions